/*
 *
 */
 
#ifndef __CRD_UT10XX_H
#define __CRD_UT10XX_H

#include <usb.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

#define CRD_CC_GCC 0
#define CRD_CC_MSV 1

/* GNU C compliller definitions. */
#if defined (__GNUC__)
#define CRD_CC CRD_CC_GCC
#define CRD_EXPORT_SYMBOL
#define CRD_IMPORT_SYMBOL
#define CRD_DECLARE extern
/* Microsoft C compiller definitions. */
#elif defined (_WIN32)
#define CRD_CC CRD_CC_MSV
#define CRD_EXPORT_SYMBOL __declspec( dllexport )
#define CRD_IMPORT_SYMBOL __declspec( dllimport )
#ifdef CRD_UT10XX_LIB_COMPILATION
#define CRD_DECLARE CRD_EXPORT_SYMBOL extern
#else
#define CRD_DECLARE CRD_IMPORT_SYMBOL extern
#endif
/* Other C compillers are not supported. */
#else
#error "Unknown compiller"
#endif

/**
 * \defgroup interface_group External CRD-UT10XX interfaces
 * \brief Module contains all interfaces avaliable for external applications.
 * \{
 */

/**
 * \defgroup native_interface_group Native interface
 * \brief Module defines basic interface to all device features.
 * \{
 */

/**
 * \name PIN identifiers
 * \{
 */

/** \brief Security Officer (SO) PIN identifier. */
#define CRD_UT10XX_SO_PIN_ID 0
/** \brief User PIN identified. */
#define CRD_UT10XX_USER_PIN_ID 1
/** \} */


/**
 * \name Maximum values
 * \{
 */

/** \brief Maximum size of host frame including frame length and type. */
#define HF_MAX 130
/** \brief Maximum size of device frame including frame length and type. */
#define DF_MAX 130
/** \brief Maximum number of files stored in device. */
#define FILES_NO_MAX 16
/** \} */

/**
 * \name Error codes
 * \{
 */

/** \brief Undefined error. */
#define ERR_CRD_UT10XX_UNDEF -1
/** \brief Session with device can not be open. */
#define ERR_CRD_UT10XX_LOCK -2
/** \brief Session with device can not be close. */
#define ERR_CRD_UT10XX_UNLOCK -3
/** \brief Session with device is closed. */
#define ERR_CRD_UT10XX_SESSION_CLOSED -4
/** \brief Error during message receive from device. */
#define ERR_CRD_UT10XX_RECEIVE -5
/** \brief Error during message transmition to device. */
#define ERR_CRD_UT10XX_TRANSMIT -6
/** \brief Buffer is too small to write all data. */
#define ERR_CRD_UT10XX_TOO_SMALL_BUF -7
/** \brief Buffer is to large to read it all. */
#define ERR_CRD_UT10XX_TOO_LARGE_BUF -8
/** \brief Library is unable to set up device interface. */
#define ERR_CRD_UT10XX_SET_UP -9
/** \brief This key number is not supported by device. */
#define ERR_CRD_UT10XX_WRONG_KEY -10
/** \brief Device is not supported by this version of library. */
#define ERR_CRD_UT10XX_NOT_SUPPORTED -11
/** \brief Argument is out of range. */
#define ERR_CRD_UT10XX_ARG_RANGE -12
/** \brief Parameter is not initialized. */
#define ERR_CRD_UT10XX_NOT_INIT -13

/** \brief General error transmited by device. */
#define ERR_CRD_UT10XX_DEV -100
/** \brief Device returns that command is wrong. */
#define ERR_CRD_UT10XX_DEV_WRONG_CMD (ERR_CRD_UT10XX_DEV - 0)
/** \brief Device returns that command is not allowed. */
#define ERR_CRD_UT10XX_DEV_CMD_NOT_ALLOWED (ERR_CRD_UT10XX_DEV - 1)
/** \brief Device returns that given PIN is wrong. */
#define ERR_CRD_UT10XX_DEV_WRONG_PIN (ERR_CRD_UT10XX_DEV - 2)
/** \brief Point passed to ECDH shared info primitive is not on curve. */
#define ERR_CRD_UT10XX_DEV_WRONG_EC_POINT (ERR_CRD_UT10XX_DEV - 3)
/** \brief Device returns that key of given number does not exist. */
#define ERR_CRD_UT10XX_DEV_NO_KEY (ERR_CRD_UT10XX_DEV - 4)
/** \brief Device returns that given arguments are out of range. */
#define ERR_CRD_UT10XX_DEV_ARG_RANGE (ERR_CRD_UT10XX_DEV - 5)
/** \brief Device returns that transmit frame has wrong syntax. */
#define ERR_CRD_UT10XX_DEV_FRAME_SYNTAX (ERR_CRD_UT10XX_DEV - 6)
/** \brief Device returns that transmit frame is out of range. */
#define ERR_CRD_UT10XX_DEV_FRAME_RANGE (ERR_CRD_UT10XX_DEV - 7)
/** \} */

/**
 * \brief Elliptic curve domain paramethers structure.
 */
typedef struct CRD_UT10XX_ecc_params_t
{
	/** \brief Unique id number. */
	int id;
	/** \brief Number of encoding octets for single field element. */
	int field_octets;
	/** \brief Number of encoding octets for generator order. */
	int order_octets;
	/** \brief ASCII string containing short name of domain. */
	const char *name;
	/** \brief Number of octets of asn1_named. */
	int asn1_named_octets;
	/** \brief ASN.1 object identifier of this domain. */
	const unsigned char *asn1_named;
	/** \brief ASN.1 encoding for AlgorithmIdentifier in SubjectPublicKeyInfo. */
	const unsigned char *asn1_named_alg;
	/** \brief Number of octets of asn1_named. */
	int asn1_specified_octets;
	/** \brief ASN.1 encoded domain paramether structure. */
	const unsigned char *asn1_specified;
}
CRD_UT10XX_ecc_params_t;

/**
 * \brief Function returns domain paramethers by its id. 
 *
 * \param[in] id -
 *   unique identifier of elliptic curve domain paramethers.
 *
 * \return
 *   - pointer to domain parameters structure with specified id,
 *   - 0 if there is no domain with this id.
 */
CRD_DECLARE const CRD_UT10XX_ecc_params_t* CRD_UT10XX_get_ecc_params(int id);

/**
 * \brief Configuration structure.
 */
typedef struct CRD_UT10XX_conf_t
{
	/** \brief Device information bits. */
	int info;
	/** \brief Device name octets. */
	char name[11];
	/** \brief Number of wrong SO PINs which cause device eraseing. */
	int so_pin_limit;
	/** \brief Number of wrong User PINs which cause device locking. */
	int user_pin_limit;
	/** \brief SO PIN. */
	char so_pin[8];
	/** \brief User PIN. */
	char user_pin[8];
}
CRD_UT10XX_conf_t;

/**
 * \brief Information structure. 
 */
typedef struct CRD_UT10XX_info_t
{
	/** \brief Device information bits. */
	int info;
	/** \brief Device name octets. */
	char name[11];
	/** \brief Actual number of wrong SO PIN trys. */
	int so_pin_trys;
	/** \brief Actual number of wrong User PIN trys. */
	int user_pin_trys;
	/** \brief Number of wrong SO PINs which cause device eraseing. */
	int so_pin_limit;
	/** \brief Number of wrong User PINs which cause device locking. */
	int user_pin_limit;
	/** \brief Main number of device firmware version. */
	int main_ver;
	/** \brief Sub number of device firmware version. */
	int sub_ver;
	/** \brief Number of total public memory octets. */
	int public_mem;
	/** \brief Number of avaliable public objects. */
	int public_objs;
	/** \brief Maximum number of ECC keys which can be stored. */
	int keys_num;
	/** \brief Number of supported ECC domains. */
	int ecc_num;
	/** \brief Pointer to supported domain. */
	const CRD_UT10XX_ecc_params_t *ecc_params;
}
CRD_UT10XX_info_t;

/**
 * \brief Key information structure.
 */
typedef struct CRD_UT10XX_key_info_t
{
	/** \brief Key information bits. */
	int info;
	/** \brief Pointer to ECC domain parameters for this key. */
	const CRD_UT10XX_ecc_params_t *ecc_params;
	/** \brief UTF-8 string which contains key name. */
	char name[22];
	/** \brief Encoding of public key X coordinate. */
	char pub_x[32];
	/** \brief Encoding of public key Y coordinate. */
	char pub_y[32];
}
CRD_UT10XX_key_info_t;

/**
 * \brief Device structure.
 */
typedef struct CRD_UT10XX_t
{
	/**
	 * \name LibUSB fetures
	 * \{
	 */
	
	/** \brief Pointer to USB device defined by LibUSB. */
	struct usb_device *hw;
	/** \brief Pointer to USB device handle defined by LibUSB. */
	struct usb_dev_handle *handle;
	/** \brief USB device product string. */
	char product_string[256];
	/** \brief USB device serial number. */
	char serial_number[256];
	/** \} */
	
	/**
	 * \name Low level interface functions
	 * \{
	 */
	
	/** \brief Function which opens device to read or write. */
	int (*open)(struct CRD_UT10XX_t *ut);
	/** \brief Function which closes device if it is no longer need. */
	int (*close)(struct CRD_UT10XX_t *ut);
	/** \brief Function which reads at most \a octets from device. */
	int (*read)(struct CRD_UT10XX_t *ut, unsigned char *buf, int octets, int timeout_ms);
	/** \brief Function which writes to device. */
	int (*write)(struct CRD_UT10XX_t *ut, const unsigned char *buf, int octets);
	/** \} */
	
	/**
	 * \name Device information and configuration structures
	 * \{
	 */
	
	/** \brief Device configuration structure. */
	CRD_UT10XX_conf_t conf;
	/** \brief Device information structure. */
	CRD_UT10XX_info_t info;
	/** \brief Information about device keys. */
	CRD_UT10XX_key_info_t keys[4];
	/** \} */
	
	/**
	 * \name Device file system information
	 * \{
	 */
	
	/** \brief Maximum number of files which can be stored. */
	int files_no;
	/** \brief Table with free sectors avaliable in device public memory. */
	unsigned char free_sectors[128];
	/** \brief Table with file types. */
	int file_types[FILES_NO_MAX];
	/** \brief Table with file sizes. */
	int file_sizes[FILES_NO_MAX];
	/** \brief Table with names of all files. */
	char file_names_tb[FILES_NO_MAX * 32];
	/** \brief Table of pointers to file names. */
	char *file_names[FILES_NO_MAX];
	/** \} */
	
	/**
	 * \name Implementation specific data.
	 * \{
	 */
	
	/** \brief Indicate if session with device is open or close. */
	int session_is_open;
	/** \brief Indicate if device is still attached to host. */
	int present;
	/** \brief Table for error stack. */
	char err[4096];
	/** \brief Pointer to next device attached to host. */
	struct CRD_UT10XX_t *next;
	/** \} */
}
CRD_UT10XX_t;

/**
 * \name Library management functions
 * \{
 */

/**
 * \brief Library initialization.
 *
 * \return
 *   - nonegative value if library is initialized properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_lib_init(void);

/**
 * \brief Library finish.
 *
 * \return
 *   - nonegative value if library is finished properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_lib_finish(void);

/**
 * \brief Find all devices attached to host.
 *
 * \return
 *   - nonegative value which is equal to number of founded devices,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_lib_find_devices(void);

/**
 * \brief Actualize library data structures.
 *
 * \return
 *   - zero if actualization was finished successfully,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_lib_actualize_devices(void);

/**
 * \brief Short description of library error.
 *
 * \param[in] err -
 *   library error code.
 *
 * \return
 *   - pointer to character string which describes error,
 *   - zero pointer if there is no such error code.
 */
CRD_DECLARE const char* CRD_UT10XX_lib_error_desc(int err);

/**
 * \brief Detail description of last ocured error.
 *
 * \param[in] ut -
 *   device for which error occured.
 *
 * \return Pointer to character string which describes error.
 */
CRD_DECLARE const char* CRD_UT10XX_lib_detail_error_desc(const CRD_UT10XX_t *ut);

/**
 * \brief Print detail description of last occured error to file.
 *
 * \param[in] ut -
 *   device for which error occured.
 * \param[in] fmt -
 *   format for single error line. Every line is printed to file \a fd by 
 *   command \c fprintf(fd, fmt, error_line). 
 * \param[in,out] fd -
 *   file open to write in text mode.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_lib_detail_error_desc_to_file(const CRD_UT10XX_t *ut, 
	const char *fmt, FILE *fd);
/** \} */

/**
 * \name Device access functions
 * \{
 */

/**
 * \brief Open session with device.
 *
 * This function has to be call before any other command. It reserves device 
 * for future use and does not allow other threads to use it in the same time.
 *
 * \param[in,out] ut -
 *   device to open.
 *
 * \return
 *   - zero value if device was opened properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_session_open(CRD_UT10XX_t *ut);

/**
 * \brief Close session with device.
 *
 * This function has to be call if device is no longer need.
 *
 * \param[in,out] ut -
 *   device to close.
 *
 * \return
 *   - zero value if device was closed properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_session_close(CRD_UT10XX_t *ut);

/**
 * \brief Get first device from library list.
 *
 * \return Pointer to first device (may be zero if no device is attached).
 */
CRD_DECLARE CRD_UT10XX_t* CRD_UT10XX_get_first(void);

/**
 * \brief Get device with given index number.
 *
 * \param[in] idx -
 *   number of device You want to get (devices are numbered from 0).
 *
 * \return Pointer to device with given index (may be zero if there is no 
 *   device with such number).
 */
CRD_DECLARE CRD_UT10XX_t* CRD_UT10XX_find_by_index(int idx);

/**
 * \brief Get device which has given name.
 *
 * \param[in] name -
 *   device name as UTF-8 string.
 *
 * \return Pointer to device with given name (may be zero if there is no 
 *   such device).
 */
CRD_DECLARE CRD_UT10XX_t* CRD_UT10XX_find_by_name(const char *name);

/**
 * \brief Get device which has given serial number.
 *
 * \param[in] serial_number -
 *   device USB serial number as UTF-8 string.
 *
 * \return Pointer to device with given serial number (may be zero if there is no 
 *   such device).
 */
CRD_DECLARE CRD_UT10XX_t* CRD_UT10XX_find_by_serial_number(const char *serial_number);

/**
 * \brief Find index of given device.
 *
 * \param[in] ut -
 *   pointer to device.
 *
 * \return
 *   - nonegative value which is equal to device index,
 *   - negative value when device was not founded.
 */
CRD_DECLARE int CRD_UT10XX_find_index_of(CRD_UT10XX_t *ut);

/**
 * \brief Find index of first ungenerated key.
 *
 * \param[in,out] ut - 
 *   device where key is searched.
 *
 * \return
 *   - nonegative value which is equal to key index,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_find_free_key(CRD_UT10XX_t *ut);

/**
 * \brief Find key with given name.
 *
 * \param[in,out] ut -
 *   device where key is searched.
 * \param[in] name -
 *   name of serched key.
 *
 * \return
 *   - nonegative value which is equal to key index,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_find_key_by_name(CRD_UT10XX_t *ut, const char *name);

/**
 * \brief Convert key to ASN.1 SubjectPublicKeyInfo.
 *
 * \param[in] key -
 *   key which should be convert to ASN.1 form.
 * \param[out] key_info -
 *   buffer for SubjectPublicKeyInfo ASN.1 encoding. If this pointer is 0, then 
 *   function returns number of encoding octets.
 * \param[in] key_info_octets -
 *   \a key_info buffer size.
 *
 * \return
 *   - nonegative value which is equal to SubjectPublicKeyInfo encoding,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_subject_public_key_info(const CRD_UT10XX_key_info_t *key, char *key_info, 
	int key_info_octets);
/** \} */

/**
 * \name Device command interface
 * \{
 */

/**
 * \brief Device initialization.
 *
 * Function is necessary to initialize internal data structures of the device. 
 * This call may take up to 40 seconds (it is dependent on supported domain).
 *
 * \param[in,out] ut -
 *   device to initalization (it has to be in CLEAR state).
 *
 * \return
 *   - nonegative value if device is initialized properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_dev_init(CRD_UT10XX_t *ut);

/**
 * \brief Device configuration.
 *
 * Function takes device \a ut and its member structure \a conf 
 * (\ref CRD_UT10XX_conf_t) to generate configuration command frame. 
 * During this operation such paramethers as:
 *   - device name,
 *   - configuration bits,
 *   - SO and User PIN,
 *   - limits or wrong PINs
 * are set up. Afer successfull call device is ready to its main tasks.
 *
 * \param[in,out] ut -
 *   device to configuration (it has to be in INIT state).
 *
 * \return
 *   - nonegative value if device is configured properly,
 *   - negative error code in other case.
 *
 * \attention 
 *   - Before configuration structure \a conf of \a ut device has 
 *     to be filled.
 *   - It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_dev_conf(CRD_UT10XX_t *ut);

/**
 * \brief Read information about device.
 *
 * After this call all avaliable informations about device are in \a info 
 * (\ref CRD_UT10XX_info_t) member structure of \a ut device.
 *
 * \param[in,out] ut -
 *   device about which information is readed.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 */
CRD_DECLARE int CRD_UT10XX_cmd_read_dev_info(CRD_UT10XX_t *ut);

/**
 * \brief Read information about device key.
 *
 * After call of this function all avaliable informations about device key 
 * with given index \a key_num are in \a keys[\a key_num] 
 * (\ref CRD_UT10XX_key_info_t) member structure of \a ut device.
 *
 * \param[in,out] ut -
 *   device where information about key is searched (it has to be in CONF 
 *   state).
 * \param[in] key_num -
 *   key index.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_read_key_info(CRD_UT10XX_t *ut, int key_num);

/**
 * \brief Read object from device public memory.
 *
 * \param[in,out] ut -
 *   device from which public object is readed (it has to be in CONF state).
 * \param[in] obj_num -
 *   number of object to read. Public objects are numbered from 0 and total 
 *   of avaliable objects can be found in \a info (\ref CRD_UT10XX_info_t) 
 *   member structure of \a ut device.
 * \param[out] obj -
 *   buffer for readed data (it has to have at least \ref PUBLIC_OBJ_OCTETS 
 *   octets).
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_read_public_obj(CRD_UT10XX_t *ut, int obj_num, char *obj);

/**
 * \brief Generate random bits.
 *
 * Function generates truly random bits (about 1500 bits per second).
 *
 * \param[in,out] ut -
 *   device uses to random bits generation.
 * \param[out] buf -
 *   buffer for random bits.
 * \param[in] octets -
 *   number of random octets to generate.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_rbg_generate_bits(CRD_UT10XX_t *ut, char *buf, int octets);

/**
 * \brief Unlock device.
 *
 * \param[in,out] ut -
 *   device which you want to unlock (it has to be in LOCK state).
 * \param[in] pin -
 *   character string which contains SO PIN (no more than 8 characters).
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_dev_unlock(CRD_UT10XX_t *ut, const char *pin);

/**
 * \brief Erase device.
 *
 * Function clears all private memory objects such as PINs and cryptographic 
 * keys. After successfull call device is in CLEAR state.
 *
 * \param[in,out] ut -
 *   device you want to erase (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains SO PIN (no more than 8 characters).
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_dev_erase(CRD_UT10XX_t *ut, const char *pin);

/**
 * \brief Change SO PIN.
 *
 * \param[in,out] ut -
 *   device for which SO PIN you want to change (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains SO PIN (no more than 8 characters).
 * \param[in] new_pin -
 *   character string which contains new SO PIN.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_change_so_pin(CRD_UT10XX_t *ut, const char *pin, 
	const char *new_pin);

/**
 * \brief Generate signature using ECDSA.
 *
 * Function generates signature using given key and digest. Resuly is 
 * writen to \a sign buffer in ASN.1 DER format.
 * \code
 *   SIGNATURE ::= SEQUENCE 
 *   {
 *       INTEGER r,
 *       INTEGER s
 *   }
 * \endcode
 *
 * \param[in,out] ut -
 *   device you want to use to signature generation (it has to be in CONF 
 *   state and has at least one key).
 * \param[in] pin -
 *   character string which contains User PIN (no more than 8 characters).
 * \param[in] key_num -
 *   index of key you want to use to sign.
 * \param[out] sign -
 *   buffer for signature.
 * \param[in] sign_octets -
 *   size of \a sign buffer in octets.
 * \param[in] digest -
 *   message digest to sigm.
 * \param[in] digest_octets -
 *   size of \a digest in octets.
 *
 * \return
 *   - nonegative value which is equal to signature len if operation is 
 *     done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_ecdsa_sign(CRD_UT10XX_t *ut, const char *pin, int key_num, 
	char *sign, int sign_octets, const char *digest, int digest_octets);

/**
 * \brief Change User PIN.
 *
 * \param[in,out] ut -
 *   device for which User PIN is changed (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 * \param[in] new_pin -
 *   character string which contains new User PIN.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention 
 *   - Changing User PIN by SO is allowed only if UPCNA (User Pin Change Not 
 *     Allowed) configuration bit is set.
 *   - It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_change_user_pin(CRD_UT10XX_t *ut, const char *pin, int pin_id, 
	const char *new_pin);

/**
 * \brief Generate cryptographic key.
 *
 * \param[in,out] ut -
 *   device for which ECC  key is generated (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 * \param[in] key_name -
 *   character string which contains name of generated key.
 * \param[in] key_num -
 *   index of generated key.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_cmd_generate_key(CRD_UT10XX_t *ut, const char *pin, int pin_id, 
	const char *key_name, int key_num);

/**
 * \brief Delete cryptographic key.
 *
 * \param[in,out] ut -
 *   device for which key is removed (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 * \param[in] key_num -
 *   index of key to delete.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_delete_key(CRD_UT10XX_t *ut, const char *pin, int pin_id, 
	int key_num);

/**
 * \brief Write object to device public memory.
 *
 * \param[in,out] ut -
 *   device for which public object is written (it has to be in CONF state).
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 * \param[in] obj_num -
 *   number of object to write. Public objects are numbered from 0 and total 
 *   of avaliable objects can be found in \a info (\ref CRD_UT10XX_info_t) 
 *   member structure of \a ut device.
 * \param[in] obj -
 *   buffer for readed data (it has to have at least \ref PUBLIC_OBJ_OCTETS 
 *   octets).
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_cmd_write_public_obj(CRD_UT10XX_t *ut, const char *pin, int pin_id, 
	int obj_num, const char *obj);

/**
 * \brief Check if given PIN is correct.
 *
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 *
 * \return
 *   - nonegative value if operation is done properly and PIN is correct,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_cmd_try_pin(CRD_UT10XX_t *ut, const char *pin, int pin_id);

/** \} */

/** \} */


/**
 * \defgroup fs_interface_group File system interface
 * \brief Module gives basic interface to file system in public memeory. 
 *
 * \{
 */

/**
 * \name File types
 * \{
 */

/** \brief Empty file. */
#define CRD_UT10XX_FT_EMPTY 0x00
/** \brief Uesr certificvate. */
#define CRD_UT10XX_FT_CRT 0x10
/** \brief CA certificvate. */
#define CRD_UT10XX_FT_CACRT 0x20
/** \brief Certification request file. */
#define CRD_UT10XX_FT_REQ 0x30
/** \brief Text file. */
#define CRD_UT10XX_FT_TXT 0x40
/** \brief HTML file. */
#define CRD_UT10XX_FT_HTML 0x50
/** \brief Configuration file. */
#define CRD_UT10XX_FT_CONF 0x60
/** \brief Binary data file. */
#define CRD_UT10XX_FT_BIN 0x70
/** \brief Unknown type file. */
#define CRD_UT10XX_FT_UNKN 0xF0
/** \} */

/**
 * \name File type masks
 * \{
 */
 
/** \brief Printable file mask. */
#define CRD_UT10XX_FTM_PRINT 0x01
/** \} */

/**
 * \name File positions
 * \{
 */

/** \brief End of file. */
#define CRD_UT10XX_FPOS_END -1
/** \brief Begin of file. */
#define CRD_UT10XX_FPOS_BEGIN -2
/** \brief Current file position. */
#define CRD_UT10XX_FPOS_CUR -3
/** \} */

/**
 * \brief File structure.
 */
typedef struct CRD_UT10XX_file_t
{
	/** \brief Pointer to device structure. */
	CRD_UT10XX_t *ut;
	/** \brief File number. */
	int num;
	/** \brief File type. */
	int type;
	/** \brief File size in octets. */
	int size;
	/** \brief File name. */
	char name[29];
	/** \brief Table of 32 sectors with 128 bytes each. */
	int sectors[32];
	/** \brief Contents of the file. */
	char contents[4096];
	/** \brief Actual position of file pointer. */
	int fpos;
	/** \brief Variable is not 0 if file contents where flushed. */
	int flushed;
}
CRD_UT10XX_file_t;

/**
 * \brief Actualize file list in \ref CRD_UT10XX_t structure.
 *
 * \param[in,out] ut -
 *   device for which file list is actualized.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_fs_get_file_list(CRD_UT10XX_t *ut);

/**
 * \brief Clear device file system table.
 *
 * \param[in,out] ut -
 *   device for which file system table is cleared.
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_fs_clear(CRD_UT10XX_t *ut, const char *pin, int pin_id);

/**
 * \brief Read all data stored in file system.
 *
 * Readed string is in ASCII format and can be printed using %s specifier 
 * in standard C library.
 *
 * \param[in,out] ut -
 *   device which public memory is readed.
 * \param[out] str -
 *   table of characters for scanned data (it should be about 4 times lerger 
 *   than avaliable public memory).
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_fs_scan(CRD_UT10XX_t *ut, char *str);

/**
 * \brief Open file with given name.
 *
 * This function open file borth to read and write operations. If file with 
 * name \a file_name doesn't exist then it can't be open. 
 *
 * \param[in,out] ut -
 *   device for which file is opened.
 * \param[in] file_name -
 *   name of the file to open.
 *
 * \return 
 *   - pointer to file if operation is done properly,
 *   - zero pointer in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE CRD_UT10XX_file_t* CRD_UT10XX_file_open(CRD_UT10XX_t *ut, const char *file_name);

/**
 * \brief Create file with given name and type.
 *
 * Function checks if file of such file exist in the file system of \a ut. 
 * If not, then file with name \a file_name and type \a type is created 
 * and opened.
 *
 * \param[in,out] ut -
 *   device for which file is created.
 * \param[in] file_name -
 *   name of the file to create.
 * \param[in] type -
 *   type of file.
 *
 * \return 
 *   - pointer to file if operation is done properly,
 *   - zero pointer in other case.
 *
 * \attention 
 *   - To confirm file creation you have to use \ref CRD_UT10XX_file_flush 
 *     function to write all chnges to device.
 *   - It is necesarily to heve open device session.
 */
CRD_DECLARE CRD_UT10XX_file_t* CRD_UT10XX_file_create(CRD_UT10XX_t *ut, const char *file_name, 
	int type);

/**
 * \brief Get file type.
 *
 * \param[in,out] fd -
 *   file descriptor.
 *
 * \return
 *   - nonegative value which represents file type,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_file_type(CRD_UT10XX_file_t *fd);

/**
 * \brief Set printable mask if all characters are printable.
 *
 * \param[in,out] fd -
 *   file descriptor.
 *
 * \return
 *   - 1 if file is printable,
 *   - 0 in other case.
 */
CRD_DECLARE int CRD_UT10XX_file_type_set_printable_mask(CRD_UT10XX_file_t *fd);

/**
 * \brief Change name and type of the file.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[in] new_name -
 *   character string that contains new file name (at most 28 characters).
 * \param[in] type -
 *   definition of file type.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention To confirm file new name you have to use \ref CRD_UT10XX_file_flush 
 *   function to write all chnges to device. Calling rename without flush does 
 *   not introduce any changes in real device file system.
 */
CRD_DECLARE int CRD_UT10XX_file_rename(CRD_UT10XX_file_t *fd, const char *new_name, int type);

/**
 * \brief Set current file position.
 *
 * Function changes position of current file pointer. There are three special 
 * file positions
 *  - \ref CRD_UT10XX_FPOS_END (end of the file),
 *  - \ref CRD_UT10XX_FPOS_BEGIN (begin of the file),
 *  - \ref CRD_UT10XX_FPOS_CUR (current position).
 * After call function returns new value of file pointer. This means that call 
 * \c CRD_UT10XX_file_set_fpos(fd,CRD_UT10XX_FPOS_CUR) returns current position 
 * of file pointer.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[in] fpos -
 *   new file position.
 *
 * \return
 *   - nonegative value wchich represents value of file pointer after change,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_file_set_fpos(CRD_UT10XX_file_t *fd, int fpos);

/**
 * \brief Read octets from file.
 *
 * Function reads \a size of octets from \a fd file and copy it to \a buf 
 * buffer. If number of readed octets is smaller than \a size, then file 
 * pointer achived end of file.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[out] buf -
 *   buffer for data.
 * \param[in] size -
 *   number of octets to read.
 *
 * \return
 *   - positive value equal to number of readed octets,
 *   - zero if there is end of this file,
 *   - negative error code in other case.
 */
CRD_DECLARE int CRD_UT10XX_file_read(CRD_UT10XX_file_t *fd, char *buf, int size);

/**
 * \brief Write octets to file.
 *
 * Function writes octets contained in \a buf to file descriptor \a fd.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[in] buf -
 *   buffer with data.
 * \param[in] size -
 *   number of octets to write.
 *
 * \return
 *   - nonegative value equal to number of written octets,
 *   - negative error code in other case.
 *
 * \attention
 *   - Single file can not be larger than 4096 octets.
 *   - This function does not write octets to device (only storage them in 
 *     internal \a fd buffer). To write octets to device there is a need to 
 *     call \ref CRD_UT10XX_file_flush function.
 */
CRD_DECLARE int CRD_UT10XX_file_write(CRD_UT10XX_file_t *fd, const char *buf, int size);

/**
 * \brief Drops file data to device.
 *
 * This function writes all data stored in \a fd to real device. It was introduced 
 * to reduce number of writes to device EEPROM. This idea increases live time of 
 * EEPROM and reduces time (writing to EEPROM is rather slow). It is a good practice 
 * to use this function only before \ref CRD_UT10XX_file_close call.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_file_flush(CRD_UT10XX_file_t *fd, const char *pin, int pin_id);

/**
 * \brief Delete file.
 *
 * \param[in,out] fd -
 *   file descriptor.
 * \param[in] pin -
 *   character string which contains User or SO PIN (at most 8 characters).
 * \param[in] pin_id -
 *   PIN owner identification number. Use \ref CRD_UT10XX_SO_PIN_ID for SO 
 *   and \ref CRD_UT10XX_USER_PIN_ID for User.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_file_delete(CRD_UT10XX_file_t *fd, const char *pin, int pin_id);

/**
 * \brief Close file.
 *
 * Function coses file and removes unflushed changes.
 *
 * \param[in,out] fd -
 *   file descriptor.
 *
 * \return
 *   - nonegative value if operation is done properly,
 *   - negative error code in other case.
 *
 * \attention It is necesarily to heve open device session.
 */
CRD_DECLARE int CRD_UT10XX_file_close(CRD_UT10XX_file_t *fd);

/** \} */

/** \} */

#ifdef __cplusplus
};
#endif

#endif /* ifndef __CRD_UT10XX_H */

