#ifndef _NEOII_API_H_
# define _NEOII_API_H_

# include "_pthreadtypes.h"
# include <fcntl.h>
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <sys/stat.h>
# include "IDTDef.h"

# define PAYMENT_APP_FOUR_CHAR_CODE(a, b, c, d)         (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a)))
# define PAYMENT_APP_MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))

/*@brief payment SDK modules 16M flash address*/
# define PAYMENT_SDK_16M_BEGIN (0x04A00000)
# define PAYMENT_SDK_16M_END   (0x04CFFFFF)

/*@brief payment application modules 16M flash address*/
# define PAYMENT_APP_16M_BEGIN (0x04D00000)
# define PAYMENT_APP_16M_END   (0x04FFFFFF)

/*@brief payment SDK modules 32M flash address*/
# define PAYMENT_SDK_32M_BEGIN (0x05000000)
# define PAYMENT_SDK_32M_END   (0x057FFFFF)

/*@brief payment application modules 32M flash address*/
# define PAYMENT_APP_32M_BEGIN (0x05800000)
# define PAYMENT_APP_32M_END   (0x05FFFFFF)

/*@brief payment SDK modules ram address*/
# define PAYMENT_SDK_RAM_ADDR (0x70400000u)
# define PAYMENT_SDK_RAM_SIZE (0x100000u)

/*@brief payment application modules shared ram address*/
# define PAYMENT_SHM_RAM_ADDR (0x70500000u)
# define PAYMENT_SHM_RAM_SIZE (0x100000u)

/*@brief payment application modules ram address*/
# define APP_SDRAM_HEAP_ADDR (0x70600000u)
# define APP_SDRAM_HEAP_SIZE (0xA00000u)

/*@brief the maximum number of applications*/
# define APP_MAX_NUMBER         (10)

# define PAYMENT_TASK_PRIO_MIN  (20u)
# define PAYMENT_TASK_PRIO_MAX  (24u)
# define PAYMENT_TASK_STACK_MIN (256u)
# define PAYMENT_TASK_STACK_MAX (0xFFF0u)

/*@brief File system flags*/
/*! Any write to the filehandle is appended to end of the file */
# define APP_FILE_APPEND (1 << 0)
/*! If the opened file exists, it will be truncated to zero length before opened */
# define APP_FILE_TRUNC  (1 << 1)
/*! If the opened file does not exist, it will be created before opened */
# define APP_FILE_CREAT  (1 << 2)
/*! The opened file may only be read */
# define APP_FILE_RDONLY (1 << 3)
/*! The opened file may only be written */
# define APP_FILE_WRONLY (1 << 4)
/*! The opened file may be both read and written */
# define APP_FILE_RDWR   (APP_FILE_RDONLY | APP_FILE_WRONLY)
/*! Any writes to the filehandle will never be cached but flushed directly */
# define APP_FILE_DIRECT (1 << 5)
/*! If FILE_CREAT and FILE_EXCL are set, FILE_open() shall fail if the file exists */
# define APP_FILE_EXCL   (1 << 6)

/*@brief Posix flags*/
# define APP_O_RDWR     0xA000 /**< Open for reading and writing. */
# define APP_O_CREAT    0x0002 /**< Create file if it does not exist. */
# define APP_O_EXCL     0x0008 /**< Exclusive use flag. */
# define APP_O_NONBLOCK 0x0400 /**< Non-blocking mode. */

/*! @brief File system seek mode */
# define APP_FILE_SEEK_SET 0u
# define APP_FILE_SEEK_CUR 1u
# define APP_FILE_SEEK_END 2u

# define pdFALSE           ( (long) 0 )
# define pdTRUE            ( (long) 1 )

# define pdPASS            ( pdTRUE )
# define pdFAIL            ( pdFALSE )

# define OS_MUTEX_SIZE     (0x24)
# define OS_SEMA_SIZE      (0x2C)

typedef void (* Payment_Entry)(void * param);

typedef struct _payment_api_t_ {
    Payment_Entry app_payment_entry;
} payment_api_t;

/**
 * @brief Firmware Application info struct */
typedef struct _payment_app_head_info_ {
    unsigned int header;         /* four char code header */
    unsigned int version;        /* version for app */
    unsigned int begin;          /* app start address */
    unsigned int size;           /* app size, needed for upgrade and sig check */
    void *       table;          /* app function table address */
    const char * app_identifier; /* optional app name string pointer */
    void *       param;          /* app entry function parameter */
    unsigned int priority;       /*app task priority, should be 20~24*/
    unsigned int stacksize;      /*app task statck*/
    unsigned int text_end;       /*app text end address*/
    unsigned int data_start;     /*app data start address*/
    unsigned int data_end;       /*app data end address*/
    unsigned int bss_start;      /*app bss start address*/
    unsigned int bss_end;        /*app bss end address*/
} payment_app_head_info;

/**
 * @brief Payment application return status */
typedef enum _payment_status_ {
    PAYMENT_Success,    /*!< Success */
    PAYMENT_NotReady,   /*!< not ready */
    PAYMENT_Malloc_err, /*!< malloc failed */
    PAYMENT_Busy,
    PAYMENT_Incorrect_Arg, /*!< MSR input argument error */
    PAYMENT_Timeout,       /*!< MSR process timed out */
    PAYMENT_Data_Invalid,
    PAYMENT_Fail,     /*!< Failed */
    PAYMENT_Cancelled /*!< Cancel catched */
} payment_status;

/**
 * @brief Scheduling parameters required for implementation of each supported
 * scheduling policy.
 */
struct sched_param {
    int sched_priority; /**< Process or thread execution scheduling priority. */
};

/**
 * @brief Used to identify a thread.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_T
 */
typedef void            * pthread_t;

/**
 * @brief Used to identify a thread attribute object.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_ATTR_T.
 */
typedef void            * pthread_attr_t;

/**
 * @brief Used to identify a barrier.
 */
typedef void                * pthread_barrier_t;

/**
 * @brief Used to define a barrier attributes object.
 */
typedef void                * pthread_barrierattr_t;

/**
 * @brief Used for mutexes.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_MUTEX_T.
 */
typedef void            * pthread_mutex_t;

/**
 * @brief Used to identify a mutex attribute object.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_MUTEXATTR_T.
 */
typedef void            * pthread_mutexattr_t;

/**
 * @brief Used for condition variables.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_COND_T.
 */
typedef void            * pthread_cond_t;

/**
 * @brief Used to identify a condition attribute object.
 * Enabled/disabled by posixconfigENABLE_PTHREAD_CONDATTR_T.
 */
typedef void            * pthread_condattr_t;

/**
 * @brief Semaphore type.
 */
typedef void            * sem_t;

/**
 * @brief Message queue descriptor.
 */
typedef void * mqd_t;

/**
 * @brief Message queue attributes.
 */
struct mq_attr {
    long mq_flags;   /**< Message queue flags. */
    long mq_maxmsg;  /**< Maximum number of messages. */
    long mq_msgsize; /**< Maximum message size. */
    long mq_curmsgs; /**< Number of messages currently queued. */
};

/**
 * @brief Values of sigev_notify.
 */
/**@{ */
# define SIGEV_NONE   0 /**< No asynchronous notification is delivered when the event of interest occurs. */
# define SIGEV_SIGNAL 1 /**< A queued signal, with an application-defined value, is generated when the event of interest occurs. Not supported. */
# define SIGEV_THREAD 2 /**< A notification function is called to perform notification. */
/**@} */

/**
 * @brief Signal value.
 */
union sigval {
    int    sival_int; /**< Integer signal value. */
    void * sival_ptr; /**< Pointer signal value. */
};

/**
 * @brief Signal event structure.
 */
struct sigevent {
    int              sigev_notify;                               /**< Notification type. A value of SIGEV_SIGNAL is not supported. */
    int              sigev_signo;                                /**< Signal number. This member is ignored. */
    union sigval     sigev_value;                                /**< Signal value. Only the sival_ptr member is used. */
    void             ( * sigev_notify_function ) (union sigval); /**< Notification function. */
    pthread_attr_t * sigev_notify_attributes;                    /**< Notification attributes. */
};

/**
 * @brief pthread detach state.
 */
/**@{ */
# define PTHREAD_CREATE_DETACHED 0 /**< Detached. */
# define PTHREAD_CREATE_JOINABLE 1 /**< Joinable (default). */
/**@} */

/**
 * @brief Returned to a single thread after a successful pthread_barrier_wait.
 *
 * POSIX specifies that "The constant PTHREAD_BARRIER_SERIAL_THREAD is defined in <pthread.h> and its value shall be distinct from any other value returned by pthread_barrier_wait()."
 * So it's defined as negative to distinguish it from the errnos, which are positive.
 */
# define PTHREAD_BARRIER_SERIAL_THREAD ( -2 )

/**
 * @brief Mutex types.
 */
/**@{ */
# ifndef PTHREAD_MUTEX_NORMAL
#  define PTHREAD_MUTEX_NORMAL 0 /**< Non-robust, deadlock on relock, does not remember owner. */
# endif
# ifndef PTHREAD_MUTEX_ERRORCHECK
#  define PTHREAD_MUTEX_ERRORCHECK 1 /**< Non-robust, error on relock,  remembers owner. */
# endif
# ifndef PTHREAD_MUTEX_RECURSIVE
#  define PTHREAD_MUTEX_RECURSIVE 2 /**< Non-robust, recursive relock, remembers owner. */
# endif
# ifndef PTHREAD_MUTEX_DEFAULT
#  define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL /**< PTHREAD_MUTEX_NORMAL (default). */
# endif
/**@} */

/**
 * @brief Mutex attribute object.
 */
typedef struct pthread_mutexattr_internal {
    int iType; /**< Mutex type. */
} pthread_mutexattr_internal_t;

/**
 * @brief Mutex.
 */

typedef struct  _mutex_t {
    unsigned char data[OS_MUTEX_SIZE];
} mutex_t;

typedef struct pthread_mutex_internal {
    long                         xIsInitialized; /**< Set to pdTRUE if this mutex is initialized, pdFALSE otherwise. */
    mutex_t                      xMutex;         /**< RTOS mutex. */
    void *                       xTaskOwner;     /**< Owner; used for deadlock detection and permission checks. */
    pthread_mutexattr_internal_t xAttr;          /**< Mutex attributes. */
} pthread_mutex_internal_t;

/**
 * @brief Compile-time initializer of pthread_mutex_internal_t.
 */
# define RTOS_POSIX_MUTEX_INITIALIZER \
    ( &( (pthread_mutex_internal_t)    \
    {                                    \
        .xIsInitialized = pdFALSE,       \
        .xMutex = { { 0 } },             \
        .xTaskOwner = NULL,              \
        .xAttr = { .iType = 0 }          \
    }                                    \
    )                               \
    )

typedef struct  _os_sem {
    unsigned char data[OS_SEMA_SIZE];
} os_sem;

/*! @brief Type for counting semaphore */
typedef struct semaphore_counting {
    os_sem       semaphore;
    unsigned int max_cnt;
} semaphore_counting_t;

/**
 * @brief Condition variable.
 */
typedef struct pthread_cond_internal {
    long                 xIsInitialized;     /**< Set to pdTRUE if this condition variable is initialized, pdFALSE otherwise. */
    mutex_t              xCondMutex;         /**< Prevents concurrent accesses to iWaitingThreads. */
    semaphore_counting_t xCondWaitSemaphore; /**< Threads block on this semaphore in pthread_cond_wait. */
    int                  iWaitingThreads;    /**< The number of threads currently waiting on this condition variable. */
} pthread_cond_internal_t;

/**
 * @brief Used for time in microseconds.
 */
typedef unsigned long useconds_t;

/**
 * @brief Compile-time initializer of pthread_cond_internal_t.
 */
# define RTOS_POSIX_COND_INITIALIZER \
    ( &( (pthread_cond_internal_t)    \
    {                                   \
        .xIsInitialized = pdFALSE,      \
        .xCondMutex = { { 0 } },        \
        .xCondWaitSemaphore = { { 0 } }, \
        .iWaitingThreads = 0            \
    }                                   \
    )                              \
    )

/**
 * @brief Compile-time initializers.
 */
/**@{ */
// #define PTHREAD_COND_INITIALIZER         RTOS_POSIX_COND_INITIALIZER  /**< pthread_cond_t. */
# define PTHREAD_COND_INITIALIZER NULL

/**
 * @brief To use this initializer, posixconfigENABLE_PTHREAD_MUTEX_T needs to be set to 1 in RTOS_POSIX_portable_default.h.
 */
// #define PTHREAD_MUTEX_INITIALIZER    RTOS_POSIX_MUTEX_INITIALIZER /**< pthread_mutex_t. */
# define PTHREAD_MUTEX_INITIALIZER NULL

# define SPIFFS_OBJ_NAME_LEN       (48)

// spiffs file descriptor index type. must be signed
typedef short spiffs_file;
// spiffs file descriptor flags
typedef unsigned short spiffs_flags;
// spiffs file mode
typedef unsigned short spiffs_mode;
// object type
typedef unsigned char spiffs_obj_type;

struct spiffs_t;

// Block index type. Make sure the size of this type can hold
// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size
typedef unsigned short spiffs_block_ix;
// Page index type. Make sure the size of this type can hold
// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size
typedef unsigned short spiffs_page_ix;
// Object id type - most significant bit is reserved for index flag. Make sure the
// size of this type can hold the highest object id on a full system,
// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2
typedef unsigned short spiffs_obj_id;
// Object span index type. Make sure the size of this type can
// hold the largest possible span index on the system -
// i.e. (spiffs_file_system_size / log_page_size) - 1
typedef unsigned short spiffs_span_ix;

/* spi read call function type */
typedef int (* spiffs_read)(unsigned int addr, unsigned int size, unsigned char * dst);
/* spi write call function type */
typedef int (* spiffs_write)(unsigned int addr, unsigned int size, unsigned char * src);
/* spi erase call function type */
typedef int (* spiffs_erase)(unsigned int addr, unsigned int size);

/* file system check callback report operation */
typedef enum {
    SPIFFS_CHECK_LOOKUP = 0,
    SPIFFS_CHECK_INDEX,
    SPIFFS_CHECK_PAGE
} spiffs_check_type;

/* file system check callback report type */
typedef enum {
    SPIFFS_CHECK_PROGRESS = 0,
    SPIFFS_CHECK_ERROR,
    SPIFFS_CHECK_FIX_INDEX,
    SPIFFS_CHECK_FIX_LOOKUP,
    SPIFFS_CHECK_DELETE_ORPHANED_INDEX,
    SPIFFS_CHECK_DELETE_PAGE,
    SPIFFS_CHECK_DELETE_BAD_FILE
} spiffs_check_report;

/* file system check callback function */
typedef void (* spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report,
  unsigned int arg1, unsigned int arg2);

/* file system listener callback operation */
typedef enum {
    /* the file has been created */
    SPIFFS_CB_CREATED = 0,
    /* the file has been updated or moved to another page */
    SPIFFS_CB_UPDATED,
    /* the file has been deleted */
    SPIFFS_CB_DELETED
} spiffs_fileop_type;

/* file system listener callback function */
typedef void (* spiffs_file_callback)(struct spiffs_t * fs, spiffs_fileop_type op, spiffs_obj_id obj_id,
  spiffs_page_ix pix);

// spiffs spi configuration struct
typedef struct {
    // physical read function
    spiffs_read  hal_read_f;
    // physical write function
    spiffs_write hal_write_f;
    // physical erase function
    spiffs_erase hal_erase_f;
} spiffs_config;

typedef struct spiffs_t {
    unsigned int          fs_num;
    // file system configuration
    spiffs_config         cfg;
    // number of logical blocks
    unsigned int          block_count;

    // cursor for free blocks, block index
    spiffs_block_ix       free_cursor_block_ix;
    // cursor for free blocks, entry index
    int                   free_cursor_obj_lu_entry;
    // cursor when searching, block index
    spiffs_block_ix       cursor_block_ix;
    // cursor when searching, entry index
    int                   cursor_obj_lu_entry;

    // primary work buffer, size of a logical page
    unsigned char *       lu_work;
    // secondary work buffer, size of a logical page
    unsigned char *       work;
    // file descriptor memory area
    unsigned char *       fd_space;
    // available file descriptors
    unsigned int          fd_count;

    // last error
    int                   err_code;

    // current number of free blocks
    unsigned int          free_blocks;
    // current number of busy pages
    unsigned int          stats_p_allocated;
    // current number of deleted pages
    unsigned int          stats_p_deleted;
    // flag indicating that garbage collector is cleaning
    unsigned char         cleaning;
    // max erase count amongst all blocks
    spiffs_obj_id         max_erase_count;

    unsigned int          stats_gc_runs;

    // cache memory
    void *                cache;
    // cache size
    unsigned int          cache_size;
    unsigned int          cache_hits;
    unsigned int          cache_misses;

    // check callback function
    spiffs_check_callback check_cb_f;
    // file callback function
    spiffs_file_callback  file_cb_f;
    // mounted flag
    unsigned char         mounted;
    // user data
    void *                user_data;
    // config magic
    unsigned int          config_magic;
} spiffs;

struct spiffs_dirent {
    spiffs_obj_id   obj_id;
    unsigned char   name[SPIFFS_OBJ_NAME_LEN];
    spiffs_obj_type type;
    unsigned int    size;
    spiffs_page_ix  pix;
};

typedef struct {
    spiffs *        fs;
    spiffs_block_ix block;
    int             entry;
} spiffs_DIR;

# define file_dir_stream spiffs_DIR
typedef struct spiffs_dirent file_entry;

typedef struct _file_dir_entry {
    file_dir_stream stream;
    /* dir entry struct */
    file_entry      entry;
} file_dir_entry;

/**
 * @brief Generic protocol structure
 */
typedef struct _serialProtocolBlock {
    unsigned int magic;
    unsigned int guard1;
    unsigned int headerLen;
    char         protName[16];
    char         headerString[24];
    unsigned int trailerLen;
    char         trailerString[24];
    unsigned int lengthOffset;
    unsigned int lengthSize;
    unsigned int endian;
    unsigned int minimumLength;
    unsigned int noMatchFlag;
    unsigned int guard2;
} serialProtocolBlock;

# define SERIAL_RESPONSE_Q_NAME_SIZE 20
typedef struct _serialRegistration {
    char                        qName[SERIAL_RESPONSE_Q_NAME_SIZE];
    int                         protFlag;
    struct _serialProtocolBlock protDesc;
} serialRegistration;

typedef enum {
    CRYPTO_DECRYPT_OP,
    CRYPTO_ENCRYPT_OP,
    CRYPTO_CERT_SIGN_OP,
    CRYPTO_CERT_VALID_OP,
    CRYPTO_BDK_IPEK_OP,
} Crypto_op_t;

/**
 * Define the comm callback function to receive the V4 Protocol packets
 * received by the device from an external source (IP/USB/RS-232)
 * It should be registered using the comm_registerV4Callback,
 * Data callback will contain command, sub-command, and data from V4 packet
 * Signature (int, BYTE, BYTE, BYTE*, int) =  response code, command, sub-command, data, dataLen
 */
typedef void (* sysV4Comm_callBack)(int port, unsigned char cmd, unsigned char subcmd, unsigned char * data, int len);

/**
 * Define the comm callback function to receive the general Protocol packets
 * received by the device from an external source (IP/USB/RS-232)
 * It should be registered using the comm_registerProtocol,
 * Data callback will contain port and command string
 */
typedef void (* sysProtocol_callBack)(int port, unsigned char * cmd);

/**
 * Define the comm callback function to get the async url data <br/>
 * It should be passed as a parameter in the async HTTP request.
 * Signature (int, char*, BYTE*, int) = http status code, headers, Data, data length
 */
typedef void (* httpComm_callBack)(unsigned char * data, int size);

/**
 * Define the comm callback function to get FTP file transfer status <br/>
 * It should be passed as a parameter in a FTP request,
 * Signature (int, int, int) = response code, current block, total blocks
 * RESPONSE CODES:
 *		100 = FILE DOWNLOAD STARTED
 *		101 = FILE BLOCK XX OF XX RECEIVED
 *		102 = FILE DOWNLOAD COMPLETED
 *		103 = FILE DOWNLOAD TERMINATED PREMATURELY
 *
 */
typedef void (* ftpComm_callBack)(int response, int curblock, int totalblock);

/**
 * Define the  callback function to receive the ADF daemon Protocol packets
 * received by the ADF layer
 * It should be registered using the comm_registerAdfCallback,
 * Data callback will contain the whole packet and length
 * Signature (BYTE*, int) =  data, dataLen
 */
typedef void (* sysAdfComm_callBack)(unsigned char * packet, int len);

# if defined(__cplusplus)
extern "C" {
# endif /*_cplusplus. */

/*
 * Writes the string pointed by format to the standard output
 *
 * @param format - strings that contains the text to be written to standout
 * @return on success the total number of characters written is returned, or else negative number is returned
 */
int
printf(const char * format, ...);

/*
 * Writes the string pointed by format to the provided output buffer
 *
 * @param buf -  output buffer, must large enough to contain the entire resulting string.
 * @param fmt_s - strings that contains the text to be written to the buffer.
 *                 A terminating null character is automatically appended after the content.
 * @return on success the total number of characters written is returned,
 *  (This count does not include the additional null-character automatically appended at the end of the string).
 *  Or else negative number is returned
 */
int
sprintf(char * buf, const char * fmt_s, ...);

/*
 * Cause the thread into sleep
 *
 * @param seconds - number of seconds that the thread will sleep
 * @return Zero if the requested time has elapsed, or the number of seconds left to delay, if the call was interrupted by a signal
 *               handler
 */
unsigned int
sleep(unsigned int seconds);

/*
 * Cause the thread into sleep
 *
 * @param msec - number of milliseconds that the thread will delay
 *
 */
void
msleep(unsigned int msec);

/*
 * Cause the thread into sleep
 *
 * @param usec - number of microseconds that the thread will delay
 * @return Zero if the requested time has elapsed, return -1 on error
 *
 */
int
usleep(useconds_t usec);

/*
 * Allocate the memory block and return a pointer to it
 *
 * @param size - this is the size of the block in bytes
 * @return on success return the pointer of the memory block or else NULL
 */
void *
malloc(size_t size);

/*
 * Deallocate the memory previously allocated by a call to calloc, malloc or realloc
 *
 * @param ptr - this is the pointer of the memory previously allocated by a call to calloc, malloc or realloc. If a NULL pointer is
 *                          passed as argument, no action occurs
 */
void
free(void * ptr);

/*
 * Allocate the zero-initialized memory block and return a pointer to it
 *
 * @param nmemb - the number of elements to be allocated
 * @param size - this is the size of element
 * @return on success return the pointer of the memory block or else NULL
 */
void *
calloc(size_t nmemb, size_t size);

/*
 * Attempts to resize the memory block pointed to ptr
 *
 * @param ptr - this is the pointer of the memory previously allocated by a call to calloc, malloc or realloc
 * @param size - this is the size of the block in bytes
 * @return on success return the pointer of the memory block or else NULL
 */
void *
realloc(void * ptr, size_t size);

/*
 * Allocate the shared memory block and return a pointer to it
 *
 * @param size - this is the size of the block in bytes
 * @return on success return the pointer of the memory block or else NULL
 */
void *
shm_malloc(size_t size);

/*
 * Deallocate the shared memory previously allocated by a call to calloc, malloc or realloc
 *
 * @param ptr - this is the pointer of the memory previously allocated by a call to calloc, malloc or realloc. If a NULL pointer is
 *                          passed as argument, no action occurs
 */
void
shm_free(void * ptr);

/*
 * Allocate the zero-initialized shared memory block and return a pointer to it
 *
 * @param nmemb - the number of elements to be allocated
 * @param size - this is the size of element
 * @return on success return the pointer of the memory block or else NULL
 */
void *
shm_calloc(size_t nmemb, size_t size);

/*
 * Attempts to resize the shared memory block pointed to ptr
 *
 * @param ptr - this is the pointer of the shared memory previously allocated by a call to calloc, malloc or realloc
 * @param size - this is the size of the block in bytes
 * @return on success return the pointer of the memory block or else NULL
 */
void *
shm_realloc(void * ptr, size_t size);

/*
 * Create a new thread
 *
 * @param thread - this is the pointer of the thread
 * @param attr - this is thread attribution
 * @param start_routine - thread start routine
 * @param arg - pointer of the arguments
 * @return on success return 0, fail return non-zero
 */
int
pthread_create(pthread_t * thread, const pthread_attr_t * attr, void *(*start_routine)(void *), void * arg);

/*
 * Cancel a thread
 *
 * @param thread - this is the thread to cancel
 * @return on success return 0, fail return non-zero
 */
int
pthread_cancel(pthread_t thread);

/*
 * Destroy a thread
 *
 * @param thread - this is the thread to destroy
 * @return on success return 0, fail return non-zero
 */
int
pthread_destroy(pthread_t thread);

/*
 * Exit a thread
 *
 * @param value_ptr - this is the pointer of the return value
 */
void
pthread_exit(void * value_ptr);

/*
 * Detach a thread
 *
 * @param thread - this is the thread to detach
 * @return on success return 0, fail return non-zero
 */
int
pthread_detach(pthread_t thread);

/*
 * join a thread
 *
 * @param thread - this is the thread to join
 * @param retval - if retval is not NULL, it will be the return value of pthread
 * @return on success return 0, fail return non-zero
 */
int
pthread_join(pthread_t thread, void ** retval);

/*
 * Compare if two threads are the same
 *
 * @param t1 - this is first thread to be compared
 * @param t2 - this is second thread to be compared
 * @return on success return 0, fail return non-zero
 */
int
pthread_equal(pthread_t t1, pthread_t t2);

/*
 * Get the thread's pthread_t structure
 *
 * @return on success return pthread_t structure, fail return NULL
 */
pthread_t
pthread_self(void);

/*
 * Get thread's schedparam
 *
 * @param thread - this is the thread
 * @param policy - this is the pointer of policy
 * @param param - this is the pointer of param
 * @return on success return 0, fail return non-zero
 */
int
pthread_getschedparam(pthread_t thread, int * policy, struct sched_param * param);

/*
 * Set thread's schedparam
 *
 * @param thread - this is the thread
 * @param policy - this is the policy
 * @param param - this is the pointer of param
 * @return on success return 0, fail return non-zero
 */
int
pthread_setschedparam(pthread_t thread, int policy, const struct sched_param * param);

/*
 * Initialize thread's attribution
 *
 * @param attr - this is the pointer of attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_init(pthread_attr_t * attr);

/*
 * Destroy thread's attribution
 *
 * @param attr - this is the pointer of attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_destroy(pthread_attr_t * attr);

/*
 * Get detach state
 *
 * @param attr - this is the pointer of attribution
 * @param detachstate - this is the pointer of detach state
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_getdetachstate(const pthread_attr_t * attr, int * detachstate);

/*
 * Get schedparam from thread attribution
 *
 * @param attr - this is the pointer of attribution
 * @param param - this is the pointer of param
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_getschedparam(const pthread_attr_t * attr, struct sched_param * param);

/*
 * Get stack size of thread
 *
 * @param attr - this is the pointer of attribution
 * @param stacksize - this is the pointer of stack size
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_getstacksize(const pthread_attr_t * attr, size_t * stacksize);

/*
 * Set detach state
 *
 * @param attr - this is the pointer of attribution
 * @param detachstate - this is the detach state
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_setdetachstate(pthread_attr_t * attr, int detachstate);

/*
 * Set schedparam
 *
 * @param attr - this is the pointer of attribution
 * @param param - this is the pointer of param
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_setschedparam(pthread_attr_t * attr, const struct sched_param * param);

/*
 * Set stack size of thread
 *
 * @param attr - this is the pointer of attribution
 * @param stacksize - this is the  stack size
 * @return on success return 0, fail return non-zero
 */
int
pthread_attr_setstacksize(pthread_attr_t * attr, size_t stacksize);

/*
 * Initialize thread barrier
 *
 * @param barrier - this is the pointer of barrier
 * @param attr - this is the pointer of barrier attribution
 * @param count - this is the count of barrier
 * @return on success return 0, fail return non-zero
 */
int
pthread_barrier_init(pthread_barrier_t * barrier, const pthread_barrierattr_t * attr, unsigned count);

/*
 * Destroy thread barrier
 *
 * @param barrier - this is the pointer of barrier
 * @return on success return 0, fail return non-zero
 */
int
pthread_barrier_destroy(pthread_barrier_t * barrier);

/*
 * Wait for thread barrier
 *
 * @param barrier - this is the pointer of barrier
 * @return on success return 0, fail return non-zero
 */
int
pthread_barrier_wait(pthread_barrier_t * barrier);

/*
 * Initilize thread mutex
 *
 * @param mutex - this is the pointer of the mutex
 * @param attr - this is the pointer of the mutex attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);

/*
 * Initialize thread mutex
 *
 * @param mutex - this is the pointer of the mutex
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_destroy(pthread_mutex_t * mutex);

/*
 * Lock thread mutex
 *
 * @param mutex - this is the pointer of the mutex
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_lock(pthread_mutex_t * mutex);

/*
 * try to lock thread mutex
 *
 * @param mutex - this is the pointer of the mutex
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_trylock(pthread_mutex_t * mutex);

/*
 * Lock thread mutex with timeout
 *
 * @param mutex - this is the pointer of the mutex
 * @param abstime - this is the timeout
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_timedlock(pthread_mutex_t * mutex, const struct timespec * abstime);

/*
 * Unlock thread mutex
 *
 * @param mutex - this is the pointer of the mutex
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutex_unlock(pthread_mutex_t * mutex);

/*
 * Initialize thread mutex attribution
 *
 * @param attr - this is the pointer of the mutex attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutexattr_init(pthread_mutexattr_t * attr);

/*
 * Destroy thread mutex attribution
 *
 * @param attr - this is the pointer of the mutex attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutexattr_destroy(pthread_mutexattr_t * attr);

/*
 * Get the type of thread mutex attribution
 *
 * @param attr - this is the pointer of the mutex attribution
 * @param type - this is the pointer of the type
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutexattr_gettype(const pthread_mutexattr_t * attr, int * type);

/*
 * Set the type of thread mutex attribution
 *
 * @param attr - this is the pointer of the mutex attribution
 * @param type - this is the type
 * @return on success return 0, fail return non-zero
 */
int
pthread_mutexattr_settype(pthread_mutexattr_t * attr, int type);

/*
 * Initialize thread condition
 *
 * @param cond - this is the pointer of the condition
 * @param attr - this is the pointer of the condition attribution
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * attr);

/*
 * Destroy thread condition
 *
 * @param cond - this is the pointer of the condition
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_destroy(pthread_cond_t * cond);

/*
 * Signal thread condition
 *
 * @param cond - this is the pointer of the condition
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_signal(pthread_cond_t * cond);

/*
 * Broadcast thread condition
 *
 * @param cond - this is the pointer of the condition
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_broadcast(pthread_cond_t * cond);

/*
 * Wait for thread condition
 *
 * @param cond - this is the pointer of the condition
 * @param mutex - this is the pointer of the mutex
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex);

/*
 * Wait for thread condition with timeout
 *
 * @param cond - this is the pointer of the condition
 * @param mutex - this is the pointer of the mutex
 * @param abstime - this is the timeout
 * @return on success return 0, fail return non-zero
 */
int
pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, const struct timespec * abstime);

/*
 * Initialize semaphore
 *
 * @param sem - this is the pointer of the semaphore
 * @param pshared - pshared is ignored. Semaphores will always be considered "shared".
 * @param value - this is the initial value
 * @return on success return 0, fail return non-zero
 */
int
sem_init(sem_t * sem, int pshared, unsigned value);

/*
 * Destroy semaphore
 *
 * @param sem - this is the pointer of the semaphore
 * @return on success return 0, fail return non-zero
 */
int
sem_destroy(sem_t * sem);

/*
 * Post semaphore
 *
 * @param sem - this is the pointer of the semaphore
 * @return on success return 0, fail return non-zero
 */
int
sem_post(sem_t * sem);

/*
 * Wait for semaphore
 *
 * @param sem - this is the pointer of the semaphore
 * @return on success return 0, fail return non-zero
 */
int
sem_wait(sem_t * sem);

/*
 * try to wait for semaphore
 *
 * @param sem - this is the pointer of the semaphore
 * @return on success return 0, fail return non-zero
 */
int
sem_trywait(sem_t * sem);

/*
 * Wait for semaphore with timeout
 *
 * @param sem - this is the pointer of the semaphore
 * @param abstime - this is the timeout
 * @return on success return 0, fail return non-zero
 */
int
sem_timedwait(sem_t * sem, const struct timespec * abstime);

/*
 * get semaphore value
 *
 * @param sem - this is the pointer of the semaphore
 * @param sval - this is the pointer of the value
 * @return on success return 0, fail return non-zero
 */
int
sem_getvalue(sem_t * sem, int * sval);

/*
 * Open message queue
 *
 * @param name - this is the name of the message queue
 * @param oflag - this is the flags, Supported oflags: O_RDWR, O_CREAT, O_EXCL, and O_NONBLOCK
 * @param mode - this is the mode, argument is not supported.
 * @param attr - this is the pointer of attribution
 * @return on success return mqd_t, fail return NULL
 */
mqd_t
mq_open(const char * name, int oflag, mode_t mode, struct mq_attr * attr);

/*
 * Close message queue
 *
 * @param mqdes - this is the message queue
 * @return on success return 0, fail return non-zero
 */
int
mq_close(mqd_t mqdes);

/*
 * Receive message queue
 *
 * @param mqdes - this is the message queue
 * @param msg_ptr - this is the pointer of the message
 * @param msg_len - this is the length of message queue
 * @param msg_prio - this is the priority of the message queue
 * @return on success return size of the queue, fail return 0
 */
ssize_t
mq_receive(mqd_t mqdes, char * msg_ptr, size_t msg_len, unsigned int * msg_prio);

/*
 * Send message queue
 *
 * @param mqdes - this is the message queue
 * @param msg_ptr - this is the pointer of the message
 * @param msg_len - this is the length of message queue
 * @param msg_prio - this is the priority of the message queue
 * @return on success return zero, fail return none-zero
 */
int
mq_send(mqd_t mqdes, const char * msg_ptr, size_t msg_len, unsigned msg_prio);

/*
 * Receive message queue with timeout
 *
 * @param mqdes - this is the message queue
 * @param msg_ptr - this is the pointer of the message
 * @param msg_len - this is the length of message queue
 * @param msg_prio - this is the priority of the message queue
 * @param abstime - this is the timeout
 * @return on success return size of the queue, fail return 0
 */
ssize_t
mq_timedreceive(mqd_t mqdes, char * msg_ptr, size_t msg_len,
  unsigned * msg_prio, const struct timespec * abstime);

/*
 * Send message queue with timeout
 *
 * @param mqdes - this is the message queue
 * @param msg_ptr - this is the pointer of the message
 * @param msg_len - this is the length of message queue
 * @param msg_prio - this is the priority of the message queue
 * @param abstime - this is the timeout
 * @return on success return zero, fail return none-zero
 */
int
mq_timedsend(mqd_t mqdes, const char * msg_ptr, size_t msg_len,
  unsigned int msg_prio, const struct timespec * abstime);

/*
 * Get message queue attribution
 *
 * @param mqdes - this is the message queue
 * @param mqstat - this is the pointer of attribution
 * @return on success return zero, fail return none-zero
 */
int
mq_getattr(mqd_t mqdes, struct mq_attr * mqstat);

/*
 * Unlink message queue
 *
 * @param name - this is the name of the message queue
 * @return on success return zero, fail return none-zero
 */
int
mq_unlink(const char * name);

/*
 * Find an existing queue
 *
 * @param name - this is the name of the message queue
 * @return on success return mqd_t, fail return NULL
 */
mqd_t
mq_find(const char * name);

/*
 * Retrun rtos error number
 *
 * @return error number
 */
int
rtos_errno();

/*
 * Create timer
 *
 * @param clockid - this is the id of the clock
 * @param evp - this is the pointer of signalevent
 * @param timerid - this is the id of the timer
 * @return on success return zero, fail return none-zero
 */
int
timer_create(clockid_t clockid, struct sigevent * evp, timer_t * timerid);

/*
 * Delete timer
 *
 * @param timerid - this is the id of the timer
 * @return on success return zero, fail return none-zero
 */
int
timer_delete(timer_t timerid);

/*
 * Set timer
 *
 * @param timerid - this is the id of the timer
 * @param flags - this is the flags
 * @param value - this is the pointer of itimerspec
 * @param ovalue - this is the pointer of old itimerspec
 * @return on success return zero, fail return none-zero
 */
int
timer_settime(timer_t timerid, int flags, const struct itimerspec * value,
  struct itimerspec * ovalue);

/*
 * Get timer
 *
 * @param timerid - this is the id of the timer
 * @param value - this is the pointer of itimerspec
 * @return on success return zero, fail return none-zero
 */
int
timer_gettime(timer_t timerid, struct itimerspec * value);

/*
 * Get overrun of the timer
 *
 * @param timerid - this is the id of the timer
 * @return on success return zero, fail return none-zero
 */
int
timer_getoverrun(timer_t timerid);

/*
 * Returns the current value for the specified clock, clock_id
 *
 * @param clock_id - This is ignored, by default it's CLOCK_REALTIME
 * @param tp - this is the pointer of itimerspec
 * @return on success return zero, fail return none-zero
 */
int
clock_gettime(clockid_t clock_id, struct timespec * tp);

/*
 * Format the file system
 *
 * @return on success return zero, fail return none-zero
 */
int
format();

/*
 * Open a file
 *
 * @param pathname - this is the path of the file
 * @param flags - this is the flags of the operation
 * @return on success return handler of the file, fail return error code
 */
int
open(const char * pathname, int flags, ...);

/*
 * Open a file by mode
 *
 * @param pathname - this is the path of the file
 * @param mode - this is the mode of operation
 * @return on success return handler of FILE, fail return NULL
 */
FILE *
fopen(const char * pathname, const char * mode);

/*
 * Close a file
 *
 * @param fd - this is the handler of the file
 * @return on success return zero, fail return none-zero
 */
int
close(int fd);

/*
 * Close a file strem
 *
 * @param stream - this is the pointer of the file stream
 * @return on success return zero, fail return none-zero
 */
int
fclose(FILE * stream);

/*
 * Read a file
 *
 * @param fd - this is the handler of the file
 * @param buf - this is the pointer of the buffer
 * @param len - this is the length need to read
 * @return on success return the length of data, fail return zero or less then len
 */
ssize_t
read(int fd, void * buf, size_t len);

/*
 * Read a file by stream
 *
 * @param ptr - pointer to a block of memory with a size of at least (size*count) bytes, converted to a void*
 * @param size - each element to be read
 * @param nmemb - number of elements, each one with a size of size bytes
 * @param stream - pointer to a FILE object that specifies an input stream
 * @return on success return the the total number of elements, fail return zero or less then nmemb
 */
size_t
fread(void * ptr, size_t size, size_t nmemb, FILE * stream);

/*
 * Write a file
 *
 * @param fd - this is the handler of the file
 * @param buf - this is the pointer of the buffer
 * @param len - this is the length need to write
 * @return on success return the length of data, fail return zero or less then len
 */
ssize_t
write(int fd, const void * buf, size_t len);

/*
 * Write a file by stream
 *
 * @param ptr - pointer to the array of elements to be written, converted to a const void*
 * @param size - bytes of each element to be written
 * @param nmemb - number of elements, each one with a size of size bytes
 * @param stream - pointer to a FILE object that specifies an output stream
 * @return on success return the total number of elements successfully written is returned, fail return zero or less then len
 */
size_t
fwrite(const void * ptr, size_t size, size_t nmemb, FILE * stream);

/*
 * Seek offset in a file
 *
 * @param fd - this is the handler of the file
 * @param offset - this is the offset of the file
 * @param whence - this is the value of whence. SEEK_SET, SEEK_CUR and SEEK_END
 * @return on success return the offset, fail return error code
 */
off_t
lseek(int fd, off_t offset, int whence);

/*
 * Seek offset in a file stream
 *
 * @param stream - pointer to a FILE object that identifies the stream
 * @param offset - this is the offset of the file
 * @param whence - this is the value of whence
 * @return on success return zero, fail return non-zero
 */
int
fseek(FILE * stream, long offset, int whence);

/*
 * Remove a file
 *
 * @param path - this is the path of the file
 * @return on success return zero, fail return none-zero
 */
int
remove(const char * path);

/*
 * Rename a file
 *
 * @param old_path - this is the old path
 * @param new_path - this is the new path
 * @return on success return zero, fail return none-zero
 */
int
rename(const char * old_path, const char * new_path);

/*
 * Garbage collection function
 *
 * @param size - this is the size to collection
 * @return on success return zero, fail return none-zero
 */
int
gc(unsigned int size);

/*
 * Get the status information of the file
 *
 * @param fd - this is the handler of the file
 * @param buf - this is the pointer of the status information
 * @return on success return zero, fail return none-zero
 */
int
fstat(int fd, struct stat * buf);

/*
 * Open directory
 *
 * @param fd_entry - the pointer of the entry
 * @return on success return zero, fail return none-zero
 */
int
opendir(file_dir_entry * fd_entry);

/*
 * Close directory
 *
 * @param fd_entry - the pointer of the entry
 * @return on success return zero, fail return none-zero
 */
int
closedir(file_dir_entry * fd_entry);

/*
 * Get the entry of the directory
 *
 * @param fd_entry - the pointer of the entry
 * @param dir_name - this is the name of the directory
 * @return on success return one, fail return other values
 */
int
getentry(file_dir_entry * fd_entry, unsigned char * dir_name);

/*
 * checks whether the calling process can access the file pathname.
 *
 * @param pathname - the pointer of the path name
 * @param mode - accessibility check(s) to be performed F_OK, R_OK, W_OK, and X_OK
 * @return on success return 0, fail return -1
 */
int
access(const char * pathname, int mode);

/*
 * examines the argument stream and returns its integer descriptor.
 *
 * @param stream - the pointer of the file stream
 * @return on success return file descriptor, fail return -1
 */
int
fileno(FILE * stream);

/*
 * Send data from SDK to firmware through virtual memory
 *
 * @param data - this is the pointer of data block to be sent
 * @param len - this is the size of the data block
 * @return on success return 0, fail return non-zero
 */
int
daemon_app_send(unsigned char * data, int len);

/*
 * Receive data from firmware to SDK through virtual memory
 *
 * @param data - this is the pointer of data block to be received
 * @param len - this is the size of the data block
 * @param timeout - timeout 1 second= 1000
 * @return on success return 0, fail return non-zero
 */
int
daemon_app_receive(unsigned char * data, int * len, int timeout);

/**
 * Register External V4 Protocol commands Callback
 * Pass a pointer to a callback that will receive V4 communications
 *
 * @param cBack - V4 Protocol Comm callback
 * @param identifier - Unique identifier to register the callback to.
 *
 */
void
comm_registerV4Callback(sysV4Comm_callBack cBack, char * identifier);

/**
 * Sends a V4 Packet to the connected OS/Host
 *
 * @param port
 * @param command - Command
 * @param subCommand - subCommand
 * @param status IDG command status
 * @param data - Data
 * @param dataLen - dataLen
 *
 */
void
comm_sendV4Packet(int port, unsigned char command, unsigned char subCommand,
  unsigned char status, unsigned char * data, int dataLen);

/**
 * Register generic protocol
 *
 * @param nPorts - The number of interface
 * @param registrationBlock - The pointer of the registrationBlock
 * @return on success return zero, fail return none-zero
 */
int
comm_registerProtocol(int nPorts, serialRegistration * registrationBlock);

/**
 * Register generic protocol callback
 *
 * @param cBack - Callback function
 * @param identifier - Unique identifier to register the callback to
 */
void
comm_registerProtocolCallback(sysProtocol_callBack cBack, char * identifier);

/**
 * Sends a protocol packet to host
 *
 * @param port - The number of interface
 * @param command - string of the data to be sent
 */
void
comm_sendProtocolPacket(int port, unsigned char * command);

/**
 * Register ADF Callback
 *
 * @param cBack - ADF Protocol Comm callback
 * @param identifier - Unique identifier to register the callback to.
 *
 */
void
comm_registerAdfCallback(sysAdfComm_callBack cBack, char * identifier);

/**
 * Performs a manual ftp file download from a supplied URL.
 * Saved to specified path.  If no path is specified, saved to temp location and path returned
 *  @param url The FTP url, must start with ftp://, ftps:// and include filename
 *  @param login Login credential as null terminated string. If anonymous, "ANONYMOUS"
 *  @param password Password, if required, as a null terminated string
 *  @param path Path to save the file, if null path sent, saves to temp location.
 *  @param callback Callback to receive FTP status messages
 *
 *  @return     SUCCESS
 *      ERROR, USER NOT VALIDATED TO PERFORM THIS FUNCTION
 *      ERROR, SERVER NOT RESPONDING
 *      ERROR, INVALID URL
 *      ERROR, UNABLE TO VALIDATE WITH SERVER
 *      ERROR, FILE NOT FOUND ON SERVER
 */
int
comm_downloadFTP(char * url, char * login, char * password, char * path, ftpComm_callBack * callback);

/**
 * Performs a manual ftp file upload to a supplied URL.
 *
 * BROADCAST NOTIFICATIONS:
 *		FILE UPLOAD STARTED
 *		FILE BLOCK XX OF XX SEND
 *		FILE UPLOAD COMPLETED
 *		FILE UPLOAD TERMINATED PREMATURELY
 *
 *  @param url The FTP url, must start with ftp://, ftps:// and include filename
 *  @param login Login credential as null terminated string. If anonymous, "ANONYMOUS"
 *  @param password Password, if required, as a null terminated string
 *  @param path Path to retrieve the file
 *  @param callback Callback to receive FTP status messages
 *
 *  @return     SUCCESS
 *      ERROR, USER NOT VALIDATED TO PERFORM THIS FUNCTION
 *      ERROR, SERVER NOT RESPONDING
 *      ERROR, INVALID URL
 *      ERROR, UNABLE TO VALIDATE WITH SERVER
 *      ERROR, FILE NOT FOUND ON PATH
 */
int
comm_uploadFTP(char * url, char * login, char * password, char * path, ftpComm_callBack * callback);

/**
 * Connect to a SMTP server to send an email message.  Supports TLS on/off, and authentication either Password or None.  Method blocks until message successfully sent or error occurs.
 * No authentication support for MD5, NTLM or Kerberos
 *
 * @param address The SMTP address/port, example smtp.mail.com:25
 * @param login Login credential as null terminated string. If none, pass null string
 * @param password Password, if required, as a null terminated string. If none, pass null string
 * @param useTLS 0 = no TLS, 1 = use TLS
 * @param from - Email address of the sender as null terminated string
 * @param to - Email addresses of the recipients, separated by semicolon.
 * @param cc - Email addresses of the cc recipients, separated by semicolon
 * @param subject - Subject as a null terminated stdring
 * @param body - Body as null terminated string
 *
 *  @return     SUCCESS
 *      ERROR, USER NOT VALIDATED TO PERFORM THIS FUNCTION
 *      ERROR, SERVER NOT RESPONDING
 *      ERROR, INVALID ADDRESS
 *      ERROR, UNABLE TO VALIDATE WITH SERVER
 *      ERROR, SENDER PARAMETER ERROR
 *      ERROR, RECIPIENTS PARAMETER ERROR
 *      ERROR, CC PARAMETER ERROR
 *      ERROR, BODY PARAMETER ERROR
 */
int
comm_sendEmail(const char * address, const char * login, const char * password, int useTLS, const char * from,
  const char * to, const char * cc, const char * subject, const char * body);


/**
 * HTTP Request
 *
 * For the limitation of resources, only one http/https is connected at the same time for multi-applications
 *
 * If Synchronous mode, this method blocks until a response is received or timeout. The value
 * returned will be the server response code (200 = success). Data will be saved in file "/response"
 *
 * If Asynchronous mode, this method will not block and return back either Success(0) or
 * or Failure(1).  A callback must be passed to receive the Async data when returned from server.
 *
 * @param url - valid URL as null terminated string. Must begin with http:// or https://
 * @param method - Valid Values: "GET" or "POST", as null terminated strings.
 * @param timeout - timeout, in milliseconds
 * @param headers - Null terminated string pairs for header, each separated by 0x1C FS
 * example "Content-Type=application/json<FS>Content-Length=250\0"
 * @param body - data body
 * @param bodyLen - Length of body
 * @param async - 0 = send async, 1 = send synchronous
 *  @param callback Callback to receive Async data
 *
 * @return RETURN_CODE - 0: Success 1: Failed if Async or server response code if Sync
 */
int
comm_httpRequest(char * url, char * method, int timeout, char * headers, int headerCount,
  unsigned char * body, int bodyLen, int async, httpComm_callBack callback);

/*
 * Open system log
 *
 * @param ident - this is the handler of the file
 * @param option - this is the option to log the file
 * @param facility - this is the type of program that log the file
 */
void
openlog(const char * ident, int option, int facility);

/*
 * System log function
 *
 * @param priority - this is the priority to log
 * @param format - this is the format that will be used in log file
 */
void
syslog(int priority, const char * format, ...);

/*
 * Close system log
 *
 */
void
closelog();

/*
 * Get log file through ftp
 *
 * @param url - this is url of ftp server
 * @param login - this is the user of ftp server
 * @param password - this is the passwrod of ftp server
 */
void
getlogcfg(char * url, char * login, char * password);

/*
 * Set certificate path for ethernet protocol
 *
 * @param path - this is path of the certificate for ethernet protocol
 * @return on success return zero, fail return none-zero
 */
int
set_CApath(char * path);

/*
 * Encrypt && Decrypt using AES
 *
 * @param aucpKeyRam - input key, must be 16, 24, 32 bytes
 * @param auiKeyLen - length of key
 * @param aucpInputDataRam - input data
 * @param auiInputDataLen - length of input data
 * @param aucpOutputDataRam - output data
 * @param auipOutputDataLen - lengh of output data
 * @param apCipherSettings - optional cipherSettings, Set to NULL for default (iv is all 0x00, CBC mode, PKCS#7 padding)
 * @param aCryptOp - 1 for encrypt, 0 for decrypt
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_AES(unsigned char * aucpKeyRam, unsigned int auiKeyLen, unsigned char * aucpInputDataRam,
  unsigned int auiInputDataLen,
  unsigned char * aucpOutputDataRam, unsigned int * auipOutputDataLen, IDTCipherSettings * apCipherSettings,
  Crypto_op_t aCryptOp);
// int ADF_Crypto_encryptAES(unsigned char *aucpKeyRam, unsigned int auiKeyLen, unsigned char *aucpInputDataRam,
//	                          unsigned int auiInputDataLen, unsigned char *aucpOutputDataRam, unsigned int* auipOutputDataLen, IDTCipherSettings *apCipherSettings);
// int ADF_Crypto_decryptAES(unsigned char *aucpKeyRam, unsigned int auiKeyLen, unsigned char *aucpInputDataRam,
//	                          unsigned int auiInputDataLen, unsigned char *aucpOutputDataRam, unsigned int* auipOutputDataLen, IDTCipherSettings *apCipherSettings);

/*
 * Encrypt & Decrypt using Triple DES
 *
 * @param aucpKeyRam - input key, must be 16 or 24 bytes
 * @param auiKeyLen - length of key
 * @param aucpInputDataRam - input data
 * @param auiInputDataLen - length of input data
 * @param aucpOutputDataRam - output data
 * @param auipOutputDataLen - lengh of output data
 * @param apCipherSettings - optional cipherSettings, Set to NULL for default (iv is all 0x00, CBC mode, PKCS#7 padding)
 * @param aCryptOp - 1 for encrypt, 0 for decrypt
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_TDES(unsigned char * aucpKeyRam, unsigned int auiKeyLen, unsigned char * aucpInputDataRam,
  unsigned int auiInputDataLen,
  unsigned char * aucpOutputDataRam, unsigned int * auipOutputDataLen, IDTCipherSettings * apCipherSettings,
  Crypto_op_t aCryptOp);
// int crypto_app_encryptTDES(unsigned char *key, unsigned int keyLen, unsigned char *input,
//	                             unsigned int inputLen, unsigned char *output, unsigned int* outputLen, IDTCipherSettings *cipherSettings);
// int crypto_app_decryptTDES(unsigned char *key, unsigned int keyLen, unsigned char *input,
//	                             unsigned int inputLen, unsigned char *output, unsigned int* outputLen, IDTCipherSettings *cipherSettings);

/*
 * Encrypt using RSA Public Key
 *
 * @param aucpPublicKeyBuf - RSA Public Key
 * @param auiPublicKeyBufLen - length of RSA Public Key
 * @param aucpDataToEncrypt - input data
 * @param auiDataToEncryptLen - length of input data
 * @param aucpEncryptDataBuf - output data
 * @param auipEncryptDataBufLen - lengh of output data
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_encryptRSA(unsigned char * aucpPublicKeyBuf, unsigned int auiPublicKeyBufLen,
  unsigned char * aucpDataToEncrypt,
  unsigned int auiDataToEncryptLen, unsigned char * aucpEncryptDataBuf, unsigned int * auipEncryptDataBufLen);

/*
 * Decrypt using RSA Private Key
 *
 * @param aucpPrivateKeyBuf - RSA Private Key
 * @param auiPrivateKeytBufLen - length of RSA Private Key
 * @param aucpDataToDecrypt - input data
 * @param auiDataToDecryptLen - length of input data
 * @param aucpOutputDataBuf - output data
 * @param auipOutputDataBufLen - lengh of output data
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_decryptRSA(unsigned char * aucpPrivateKeyBuf, unsigned int auiPrivateKeytBufLen,
  unsigned char * aucpDataToDecrypt,
  unsigned int auiDataToDecryptLen, unsigned char * aucpOutputDataBuf, unsigned int * auipOutputDataBufLen);

/*
 * Sign using RSA Private Key
 *
 * @param aucpPrivateKeyBuf - RSA Private Key
 * @param auiPrivateKeyBufLen - length of RSA Private Key
 * @param aucpMessage - message data
 * @param auiMessageLen - length of message data
 * @param aucpSignDataBuf - signature data
 * @param auipSignDataLen - lengh of signature data
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_signRSA(unsigned char * aucpPrivateKeyBuf, unsigned int auiPrivateKeyBufLen, unsigned char * aucpMessage,
  unsigned int auiMessageLen,
  unsigned char * aucpSignDataBuf, unsigned int * auipSignDataLen);

/*
 * Validate using RSA Public Key
 *
 * @param aucpPublicKeyBuf - RSA Public Key
 * @param auiPublicKeyBufLen - length of RSA Public Key
 * @param aucpMessage - message data
 * @param auiMessageLen - length of message data
 * @param aucpSignDataBuf - signature data
 * @param auiSignDataLen - lengh of signature data
 *
 * @ return 0x0000~0x0050
 */
int
ADF_Crypto_validateRSA(unsigned char * aucpPublicKeyBuf, unsigned int auiPublicKeyBufLen, unsigned char * aucpMessage,
  unsigned int auiMessageLen,
  unsigned char * aucpSignDataBuf, unsigned int * auiSignDataLen);
// int crypto_fileToByteArray( char* filename,char* key, int* keyLen);

/*
 * Hash a BYTE array
 *
 * @param aucpPlain - unsigned char array to be hashed
 * @param auiPlainLen - length of unsigned char array
 * @param hashType - 0 for SHA1, 1 for SHA256
 * @param aucpHashed - output hashed data
 * @param auipHashLen - length of output hashed data
 *
 * @return 0x0000~0x0050
 */
int
ADF_Crypto_hashSHA(unsigned char * aucpPlain, unsigned int auiPlainLen, unsigned int hashType,
  unsigned char * aucpHashed, unsigned int * auipHashLen);
// int crypto_getIPEK(unsigned char* bdk, unsigned  int bdkLen, unsigned char* ksn, unsigned char * ipek);
// int crypto_getDerivedKey(unsigned char* ipek, unsigned char* ksn,unsigned char* derivedKey);
// int crypto_getDataKey(unsigned char* derivedKey, unsigned char* dataKey);
// int crypto_getPINKey(unsigned char* derivedKey, unsigned char* pinKey);
// int crypto_getMACKey(unsigned char* derivedKey, unsigned char* pinKey);

/*
 * Process DUKPT related functions
 *
 * @param IDTCryptoData - struct to organize all inputs and outputs
 * @param cipherSettings - optional cipherSettings, Set to NULL for default (iv is all 0x00, CBC mode, PKCS#7 padding)
 *
 * @return 0x0000~0x0050
 *
 * Variables in IDTCryptoData:
 * ---------------------------------------------
 * DUKPTMode (required) - 0 for TDES, 1 for AES
 * isIPEK (required) - 1 if key varible is IPEK, 0 for BDK
 * pkey (required) - address of ram: contains either BDK (TDES: 16 bytes, AES: 16 bytes) or IPEK (16 bytes)
 * keyLen (required) - either BDK or IPEK Length
 * pksn (required) - address of ram: contains ksn (10 bytes or 12 bytes)
 * ksnLen (required) - ksn Len
 * isDecryption (required) - 1 for decryption, 0 for encryption
 * keyVariant (required) - 0 for Data, 1 for PIN, and 2 for MAC
 * AESDUKPTKkeyType (required if DUKPTMode is 1 - AES) - 0 for TDES, 1 for AES-128
 * pdataToProcess (required) - address of ram: store input data to process
 * dataToProcessLen (required) - length of input data to process
 * pdataResults (required) - address of ram: store output processed result
 * pdataResultsLen (required) - address of length of output processed result
 *
 * Usages:
 * ---------------------------------------------
 * BDK/IPEK + KSN + encrypted/decrypted data -> encrypted/decrypted data
 * Options: TDES/AES, Data/PIN/MAC
 *
 */
// int ADF_Crypto_processDUKPT(IDTCryptoData* data, IDTCipherSettings* settings);

# ifdef __cplusplus
}
# endif

#endif // ifndef _NEOII_API_H_
