/*************************************************************************************************
 * Copyright (c) 2015 TTControl GmbH. All rights reserved.                                       *
 * Schoenbrunnerstrasse 7, A-1040 Wien, Austria. office@ttcontrol.com                            *
 *************************************************************************************************/

/**********************************************************************************************//**
 *
 * \file Download.hpp
 *
 * \brief Download Library API
 *
 * The download library API provides functions to read and modify the memory of the
 * complete range of ECUs and I/O modules produced by TTControl GmbH.
 *
 * \section usage Basic usage of the download library
 *
 * The basic usage of the download library is as follows:
 * - initialize the library
 * - register driver(s) used for communication
 * - initialize driver(s)
 * - connect to node(s)
 * - perform one or more of the following tasks:
 *     - read/write/erase memory
 *     - download hex file
 * - disconnect from node(s)
 * - deinitialize driver(s)
 * - deregister driver(s)
 * - deinitialize the library
 *
 * Example:
 *
 * \code
 *
 * int main(int argc, char *argv[])
 * {
 *     DLDResut_t result;
 *     unsigned short nodes_found = 0U;
 *     DLDIPAddress_t local_address = { {10, 0, 0, 1}, DLD_BIG_ENDIAN };
 *     DLDIPAddress_t multicast_address = { {239, 0, 0, 1}, DLD_BIG_ENDIAN };
 *
 *     // initialize the library
 *     result = DLD_Init( "./targets"           // directory containing the target configuration files
 *                      , DLD_LOG_LEVEL_INFO    // log only messages with severity above or equal to this log level
 *                      , "output.log"          // the log file
 *                      , NULL                  // do not use progress callback
 *                      , NULL                  // do not use power cycle callback
 *                      );
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // register UDP driver
 *     result = DLD_Driver_Register_UDP( local_address          // local IPv4 address (used to specifies the network interface card)
 *                                     , multicast_address      // multicast IPv4 address (must match the configuration of the node)
 *                                     , 8500                   // port number
 *                                     );
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // initialize UDP driver
 *     result = DLD_Driver_Init();
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // connect to nodes
 *     result = DLD_Connect( NULL               // scan all node numbers
 *                         , 0UL                // see line above
 *                         , 7UL                // send connect messages for 7 seconds
 *                         , true               // perform automatic reset
 *                         , true               // perform compatibility check
 *                         , &nodes_found       // after the function returns, this variable holds the number of connected nodes
 *                         );
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // download application to first node
 *     if ( nodes_found > 0U )
 *     {
 *         result = DLD_Download_Flash_File( 0U                    // download application to first node
 *                                         , "application.hex"     // the application file
 *                                         );
 *
 *         if ( result != DLD_RESULT_OK )
 *         {
 *             // an error occurred
 *             return result;
 *         }
 *     }
 *
 *     // disconnect from nodes
 *     result = DLD_Disconnect();
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // deinitialize UDP driver
 *     result = DLD_Driver_Deinit();
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // deregister UDP driver
 *     result = DLD_Driver_Deregister_All();
 *
 *     if ( result != DLD_RESULT_OK )
 *     {
 *         // an error occurred
 *         return result;
 *     }
 *
 *     // deinitialize the library
 *     result = DLD_Deinit();
 *
 *     // now we are done
 *
 *     return result;
 * }
 *
 * \endcode
 *
 *************************************************************************************************/

#ifndef DOWNLOAD_HPP_
#define DOWNLOAD_HPP_

/**********************************************************************************************//**
 * \mainpage Download Library API
 *
 * \version 1.2.0
 * \date    16.12.2015
 *
 * This document describes the \ref Download.hpp "API" of the download library.
 *
 *************************************************************************************************/

/*************************************************************************************************
 *                                         I N C L U D E S                                       *
 *************************************************************************************************/
#ifdef __linux__
    #include <stdbool.h>
#endif /* __linux__ */

#include <cstdint>
#include "APDB.h"
#include "BLDB.h"
#include "FIDB.h"

/*************************************************************************************************
 *                                          D E F I N E S                                        *
 *************************************************************************************************/
#ifdef _WIN32
    #define DOWNLOAD_API __declspec(dllexport) __cdecl
#else
    #define DOWNLOAD_API
#endif /* _WIN32 */

#define DLD_MAX_STRING_LENGTH           128U    /**< The maximum string length (make sure to
                                                     provide buffers of at least this size for
                                                     all output parameters of type char *).      */

/**
 * \name Result
 * \anchor enum_result
 *
 * Return values of the download library functions
 */
/*@{*/
#define DLD_RESULT_OK                   0       /**< Everything went fine.                       */
#define DLD_RESULT_INVALID_PARAMETER    1       /**< An invalid parameter has been provided.     */
#define DLD_RESULT_INVALID_SIGNATURE    2       /**< A configuration file's signature is invalid.*/
#define DLD_RESULT_FILE_NOT_FOUND       3       /**< A file could not be found.                  */
#define DLD_RESULT_INVALID_FORMAT       4       /**< The provided file's format is invalid.      */
#define DLD_RESULT_INVALID_FILE         5       /**< An invalid file has been provided, i.e.,
                                                     the file's type could not be detected.      */
#define DLD_RESULT_INVALID_HW_ID        6       /**< The provided file does not match the node's
                                                     hardware identifier.                        */
#define DLD_RESULT_ACCESS_DENIED        7       /**< Access to a certain node or memory range
                                                     has been denied.                            */
#define DLD_RESULT_INVALID_OPERATION    8       /**< The requested operation cannot be performed
                                                     as at least one prerequisite is not
                                                     satisfied.                                  */
#define DLD_RESULT_OPERATION_FAILED     9       /**< The requested operation failed.             */
/*@}*/

/**
 * \name Log Level
 * \anchor enum_log_level
 *
 * Log levels used for classification/filtering of log messages
 */
/*@{*/
#define DLD_LOG_LEVEL_DEBUG             0U      /**< Log level for debug messages.               */
#define DLD_LOG_LEVEL_INFO              1U      /**< Log level for notifications.                */
#define DLD_LOG_LEVEL_WARNING           2U      /**< Log level for warnings.                     */
#define DLD_LOG_LEVEL_ERROR             3U      /**< Log level for errors.                       */
/*@}*/

/*@}*/

/**
 * \name Driver Type
 * \anchor enum_driver_type
 *
 * Supported driver types
 */
/*@{*/
#define DLD_DRIVER_TYPE_CAN             0U      /**< CAN driver.                                 */
#define DLD_DRIVER_TYPE_UDP             1U      /**< UDP driver.                                 */
/*@}*/

/**
 * \name CAN Driver
 * \anchor enum_can_driver
 *
 * Selects the CAN driver to be used
 */
/*@{*/
#define DLD_CAN_DRIVER_PCAN_USB         0U      /**< Driver for PCAN-USB adapters.               */
#define DLD_CAN_DRIVER_PCAN_PCI         1U      /**< Driver for PCAN-PCI and PCAN-PCI Express
                                                     adapters.                                   */
#define DLD_CAN_DRIVER_CANPRO_USB       2U      /**< Driver for Softing CANpro USB adapters.     */
/*@}*/

/**
 * \name CAN Channel
 * \anchor enum_can_channel
 *
 * Selects the CAN channel to be used
 */
/*@{*/
#define DLD_CAN_CHANNEL_0               0U      /**< CAN channel 0.                              */
#define DLD_CAN_CHANNEL_1               1U      /**< CAN channel 1.                              */
#define DLD_CAN_CHANNEL_2               2U      /**< CAN channel 2.                              */
#define DLD_CAN_CHANNEL_3               3U      /**< CAN channel 3.                              */
#define DLD_CAN_CHANNEL_4               4U      /**< CAN channel 4.                              */
#define DLD_CAN_CHANNEL_5               5U      /**< CAN channel 5.                              */
#define DLD_CAN_CHANNEL_6               6U      /**< CAN channel 6.                              */
#define DLD_CAN_CHANNEL_7               7U      /**< CAN channel 7.                              */
/*@}*/

/**
 * \name CAN Baudrate
 * \anchor enum_can_baudrate
 *
 * Selects the CAN baudrate to be used
 */
/*@{*/
#define DLD_CAN_BAUD_RATE_5K            5U      /**< CAN baudrate 5kbps.                         */
#define DLD_CAN_BAUD_RATE_10K           10U     /**< CAN baudrate 10kbps.                        */
#define DLD_CAN_BAUD_RATE_20K           20U     /**< CAN baudrate 20kbps.                        */
#define DLD_CAN_BAUD_RATE_33K           33U     /**< CAN baudrate 33kbps.                        */
#define DLD_CAN_BAUD_RATE_47K           47U     /**< CAN baudrate 47kbps.                        */
#define DLD_CAN_BAUD_RATE_50K           50U     /**< CAN baudrate 50kbps.                        */
#define DLD_CAN_BAUD_RATE_83K           83U     /**< CAN baudrate 83kbps.                        */
#define DLD_CAN_BAUD_RATE_95K           95U     /**< CAN baudrate 95kbps.                        */
#define DLD_CAN_BAUD_RATE_100K          100U    /**< CAN baudrate 100kbps.                       */
#define DLD_CAN_BAUD_RATE_125K          125U    /**< CAN baudrate 125kbps.                       */
#define DLD_CAN_BAUD_RATE_250K          250U    /**< CAN baudrate 250kbps.                       */
#define DLD_CAN_BAUD_RATE_500K          500U    /**< CAN baudrate 500kbps.                       */
#define DLD_CAN_BAUD_RATE_800K          800U    /**< CAN baudrate 800kbps.                       */
#define DLD_CAN_BAUD_RATE_1M            1000U   /**< CAN baudrate 1000kbps.                      */
/*@}*/

/**
 * \name CAN Identifier Format
 * \anchor enum_can_id_format
 *
 * Selects the CAN identifier format to be used
 */
/*@{*/
#define DLD_CAN_ID_STANDARD             0U      /**< CAN standard identifier (11-bit).           */
#define DLD_CAN_ID_EXTENDED             1U      /**< CAN extended identifier (29-bit).           */
/*@}*/

/**
 * \name Endian
 * \anchor enum_endian
 *
 * Provides information about the endian of a target CPU
 */
/*@{*/
#define DLD_BIG_ENDIAN                  0U      /**< Big endian (most significant byte at
                                                     lowest address).                            */
#define DLD_LITTLE_ENDIAN               1U      /**< Little endian (least significant byte at
                                                     lowest address).                            */
/*@}*/

/**
 * \name Action
 * \anchor enum_action
 *
 * Specifies the currently ongoing action
 */
/*@{*/
#define DLD_ACTION_NONE                 0U      /**< No action is ongoing.                       */
#define DLD_ACTION_CONNECTING           1U      /**< Signals that the connection to the node's
                                                     first stage bootloader is going to be
                                                     established.                                */
#define DLD_ACTION_IDENTIFYING          2U      /**< Signals that connected nodes are identified
                                                     right away.                                 */
#define DLD_ACTION_AUTHENTICATING       3U      /**< Signals that identified nodes are
                                                     authenticated right away.                   */
#define DLD_ACTION_DOWNLOADING_2ND      4U      /**< Signals that the second stage bootloader
                                                     gets downloaded to an authenticated node.   */
#define DLD_ACTION_RETRIEVING_NODE_INFO 5U      /**< Signals that various information is going
                                                     to be retrieved from an authenticated node. */
#define DLD_ACTION_ERASING              6U      /**< Signals that a node's memory gets erased.   */
#define DLD_ACTION_READING              7U      /**< Signals that data gets read from a node's
                                                     memory.                                     */
#define DLD_ACTION_WRITING              8U      /**< Signals that data gets written to a node's
                                                     memory.                                     */
#define DLD_ACTION_FINALIZING_SECTORS   9U      /**< Signals that a node's flash sectors get
                                                     post processed after they have been
                                                     modified.                                   */
/*@}*/

/**
 * \name Item
 * \anchor enum_item
 *
 * Specifies a certain item for which memory information can be retrieved
 */
/*@{*/
#define DLD_ITEM_PDB                    0U      /**< The product descriptor block.               */
#define DLD_ITEM_BOOTLOADER             1U      /**< The first stage bootloader.                 */
#define DLD_ITEM_BLDB                   2U      /**< The first stage bootloader's descriptor
                                                     block.                                      */
#define DLD_ITEM_SECOND_STAGE           3U      /**< The second stage bootloader.                */
#define DLD_ITEM_SECOND_STAGE_BLDB      4U      /**< The second stage bootloader's descriptor
                                                     block.                                      */
#define DLD_ITEM_SECOND_STAGE_BUFFER    5U      /**< The second stage bootloader's RAM buffer.   */
#define DLD_ITEM_FPGA_IP_CORE           6U      /**< The FPGA IP core.                           */
#define DLD_ITEM_FIDB                   7U      /**< The FPGA IP core's descriptor block.        */
#define DLD_ITEM_CODESYS                8U      /**< The CODESYS application.                    */
#define DLD_ITEM_APPLICATION            9U      /**< A C application.                            */
#define DLD_ITEM_APDB                   10U     /**< A certain application's descriptor block.   */
#define DLD_ITEM_CRC_TABLE              11U     /**< The CRC table.                              */
#define DLD_ITEM_CONFIGURATION_DATA     12U     /**< A configuration data region.                */
#define DLD_ITEM_INTERNAL_FLASH         13U     /**< The internal flash memory.                  */
#define DLD_ITEM_EXTERNAL_FLASH         14U     /**< The external flash memory.                  */
#define DLD_ITEM_INTERNAL_EEPROM        15U     /**< The internal EEPROM.                        */
#define DLD_ITEM_EXTERNAL_EEPROM        16U     /**< The external EEPROM.                        */
/*@}*/

/*************************************************************************************************
 *                                            T Y P E S                                          *
 *************************************************************************************************/

/**
 *
 * \brief CAN Identifier
 *
 * Stores an identifier used for CAN communication.
 *
 */
typedef struct
{
    uint32_t id;        /**< CAN identifier (11-bit or 29-bit).                                  */
    uint8_t  format;    /**< CAN identifier format (see \ref enum_can_id_format
                             "CAN Identifier Format").                                           */
} DLDCANIdentifier_t;

/**
 *
 * \brief IP Address
 *
 * Stores an IPv4 address.
 *
 */
typedef struct
{
    uint8_t bytes[4];   /**< IPv4 address.                                                       */
    uint8_t format;     /**< The byte array's endian (see \ref enum_endian "Endian").            */
} DLDIPAddress_t;

/**
 *
 * \brief Memory Information
 *
 * Stores memory information of a certain item (see \ref enum_item "Item").
 *
 */
typedef struct
{
    uint32_t address;   /**< The item's start address.                                           */
    uint32_t size;      /**< The item's size in bytes.                                           */
} DLDMemoryInfo_t;

/**
 *
 * \brief CPU Information
 *
 * Stores useful information of a certain CPU.
 *
 */
typedef struct
{
    char    name[DLD_MAX_STRING_LENGTH];    /**< The name of the CPU.                            */
    uint8_t endian;                         /**< The CPU's endian (see \ref enum_endian
                                                 "Endian").                                      */
    uint8_t data_width;                     /**< The CPU's data width in bits.                   */
} DLDCPUInfo_t;

/**
 *
 * \brief Icon Information
 *
 * Stores additional information of a certain target ECU.
 *
 */
typedef struct
{
    char path[DLD_MAX_STRING_LENGTH];       /**< Path to the target ECU's icon.                  */
    char url[DLD_MAX_STRING_LENGTH];        /**< The target's associated URL.                    */
    char tooltip[DLD_MAX_STRING_LENGTH];    /**< THE target's tooltip text.                      */
} DLDIconInfo_t;

/**
 *
 * \brief Driver Information
 *
 * Stores useful information of a certain driver.
 *
 */
typedef struct
{
    uint8_t type;           /**< The driver's type (see \ref enum_driver_type "Driver Type").    */
    uint8_t index;          /**< The driver's index.                                             */
    void *  custom_data;    /**< Pointer to the driver's custom data.                            */
} DLDDriverInfo_t;

/**
 *
 * \brief Node Information
 *
 * Stores useful information of a certain node.
 *
 */
typedef struct
{
    char            serial_number[16];                  /**< The node's serial number.           */
    char            target_name[DLD_MAX_STRING_LENGTH]; /**< The node's target name.             */
    DLDDriverInfo_t driver;                             /**< Information about the driver the
                                                             node is connected through.          */
    uint32_t        target_id;                          /**< The target's identifier.            */
    uint32_t        bootloader_version;                 /**< The node's bootloader version:
                                                                bit 0-7  ... minor number
                                                                bit 8-15 ... major number        */
    uint8_t         node_number;                        /**< The node's address.                 */
} DLDNodeInfo_t;

/**
 *
 * \brief Target Information
 *
 * Stores useful information of a certain target.
 *
 */
typedef struct
{
    DLDCPUInfo_t  cpu;                                  /**< The target's CPU.                   */
    DLDIconInfo_t icon;                                 /**< The target's icon.                  */
    char          target_name[DLD_MAX_STRING_LENGTH];   /**< The target's name.                  */
    uint16_t      can_baudrates[14];                    /**< Holds the supported CAN baudrates.  */
    uint8_t       can_channels[8];                      /**< Holds the supported CAN channels.   */
    char          file_extension[8];                    /**< The target's default file extension.*/
    uint32_t      target_id;                            /**< The target's identifier.            */
    uint32_t      bootloader_version;                   /**< The target's bootloader version:
                                                                bit 0-7  ... minor number
                                                                bit 8-15 ... major number        */
    uint8_t       no_applications;                      /**< Holds the number of application
                                                             regions.                            */
    uint8_t       no_apdbs;                             /**< Holds the number of APDBs.          */
    uint8_t       no_config_data_regions;               /**< Holds the number of configuration
                                                             data regions.                       */
    uint8_t       no_can_baudrates;                     /**< Holds the number of supported CAN
                                                             baudrates.                          */
    uint8_t       no_can_channels;                      /**< Holds the number of supported CAN
                                                             channels.                           */
    uint8_t       no_int_flash_regions;                 /**< Holds the number of internal flash
                                                             regions.                            */
    uint8_t       no_int_eeprom_regions;                /**< Holds the number of internal EEPROM
                                                             regions.                            */
    uint8_t       no_ext_flash_regions;                 /**< Holds the number of external flash
                                                             regions.                            */
    uint8_t       no_ext_eeprom_regions;                /**< Holds the number of external EEPROM
                                                             regions.                            */
} DLDTargetInfo_t;

/**
 *
 * \brief APDB
 *
 * Stores the APDB (and some useful information) of a certain node.
 *
 */
typedef struct
{
    BL_APDB fields;             /**< The APDB fields.                                            */
    bool    application_valid;  /**< Indicates whether or not the application checksum is valid. */
    bool    block_valid;        /**< Indicates whether or not the APDB's header checksum is
                                     valid.                                                      */
} DLDAPDB_t;

/**
 *
 * \brief BLDB
 *
 * Stores the BLDB (and some useful information) of a certain node.
 *
 */
typedef struct
{
    BLDB_T fields;              /**< The BLDB fields.                                            */
    bool   bootloader_valid;    /**< Indicates whether or not the application checksum is valid  */
    bool   block_valid;         /**< Indicates whether or not the BLDB's header checksum is.
                                     valid.                                                      */
} DLDBLDB_t;

/**
 *
 * \brief FIDB
 *
 * Stores the FIDB (and some useful information) of a certain node.
 *
 */
typedef struct
{
    FIDB_T fields;              /**< The FIDB fields.                                            */
    bool   fpga_ip_core_valid;  /**< Indicates whether or not the application checksum is valid. */
    bool   block_valid;         /**< Indicates whether or not the FIDB's header checksum is
                                     valid.                                                      */
} DLDFIDB_t;

/**
 *
 * \brief Custom Data Pointer Type
 *
 * Pointer to custom data that can be used during registration of callback drivers.
 *
 */
typedef void * DLDCustomData_t;

/**
 *
 * \brief Result Type
 *
 * Return type of all DLD download library functions.
 *
 */
typedef int32_t DLDResult_t;

/**********************************************************************************************//**
 *
 * \brief Log Callback Type
 *
 * Log callback functions can be registered at library initialization in order to allow
 * custom log channels.
 *
 * \param [in] severity     The log message's severity
 * \param [in] message      The log message
 *
 * \return void
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef void (*DLDLogCB_t)( uint32_t severity
                          , const char * const message
                          );

/**********************************************************************************************//**
 *
 * \brief Driver Initialization Callback Type
 *
 * The driver initialization callback function is called from the DLD Download Library
 * whenever a (registered) custom driver needs to be initialized.
 *
 * \param [in] custom_data      Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverInitCB_t)( void * custom_data );

/**********************************************************************************************//**
 *
 * \brief Driver Deinitialization Callback Type
 *
 * The driver deinitialization callback function is called from the DLD Download Library
 * whenever a (registered) custom driver needs to be deinitialized.
 *
 * \param [in] custom_data      Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverDeinitCB_t)( void * custom_data );

/**********************************************************************************************//**
 *
 * \brief Driver Empty Rx Queue Callback Type
 *
 * The driver empty receive queue callback function is called from the DLD Download Library
 * whenever the receive queue of a (registered) custom driver needs to be emptied.
 *
 * \param [in] custom_data      Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverEmptyRxQueueCB_t)(  void * custom_data );

/**********************************************************************************************//**
 *
 * \brief Driver UDP Read Callback Type
 *
 * The driver UDP read callback function is called from the DLD Download Library
 * whenever data shall be read from a (registered) custom UDP driver.
 *
 * \param [out] data            Data buffer that shall receive the read bytes
 * \param [in]  length          Maximum number of bytes to be read
 * \param [out] bytes_read      Actual number of bytes read
 * \param [in]  custom_data     Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverUDPReadCB_t)( uint8_t * const  data
                                       , uint32_t         length
                                       , uint32_t * const bytes_read
                                       , void *           custom_data
                                       );

/**********************************************************************************************//**
 *
 * \brief Driver UDP Write Callback Type
 *
 * The driver UDP write callback function is called from the DLD Download Library
 * whenever data shall be written via a (registered) custom UDP driver.
 *
 * \param [in] data             Buffer containing the data
 * \param [in] length           Number of bytes to be written
 * \param [in] custom_data      Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverUDPWriteCB_t)( const uint8_t * const data
                                        , uint32_t        length
                                        , void *          custom_data
                                        );

/**********************************************************************************************//**
 *
 * \brief Driver CAN Read Callback Type
 *
 * The driver CAN read callback function is called from the DLD Download Library
 * whenever data shall be read from a (registered) custom CAN driver.
 *
 * \param [in]  can_id          CAN identifier to read data from
 * \param [out] data            Data buffer that shall receive the read bytes
 * \param [in]  length          Maximum number of bytes to be read
 * \param [out] bytes_read      Actual number of bytes read
 * \param [in]  custom_data     Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverCANReadCB_t)( DLDCANIdentifier_t can_id
                                       , uint8_t * const    data
                                       , uint32_t           length
                                       , uint32_t * const   bytes_read
                                       , void *             custom_data
                                       );

/**********************************************************************************************//**
 *
 * \brief Driver CAN Write Callback Type
 *
 * The driver CAN write callback function is called from the DLD Download Library
 * whenever data shall be written via a (registered) custom CAN driver.
 *
 * \param [in] can_id           CAN identifier to write data to
 * \param [in] data             Buffer containing the data
 * \param [in] length           Number of bytes to be written
 * \param [in] custom_data      Pointer to the driver's custom data
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed with device specific error code
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDDriverCANWriteCB_t)( DLDCANIdentifier_t    can_id
                                        , const uint8_t * const data
                                        , uint32_t              length
                                        , void *                custom_data
                                        );

/**********************************************************************************************//**
 *
 * \brief Power Cycle Callback Type
 *
 * The power cycle callback function is called from the DLD Download Library
 * whenever a power cycle of connected nodes shall be performed.
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     failed to initiate power cycle
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDPowerCycleCB_t)( void );

/**********************************************************************************************//**
 *
 * \brief Progress Callback Type
 *
 * The progress callback function is called from the DLD Download Library
 * to report the progress of the current action. It can be used by the
 * application to abort an ongoing action.
 *
 * \param [in] current_action       The current active action
 * \param [in] current_progress     The current action's progress (in percent)
 *
 * \return int
 * \retval 0        everything fine
 * \retval != 0     application requests abort of the current action
 *
 **************************************************************************************************
 * \remarks
 *    - This function must be non-blocking in order to guarantee correct functionality of the
 *      DLD Download Library functions.
 *
 *************************************************************************************************/
typedef int32_t (*DLDProgressCB_t)( uint8_t current_action
                                  , uint8_t current_progress
                                  );

/*************************************************************************************************
 *                                        F U N C T I O N S                                      *
 *************************************************************************************************/
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/**********************************************************************************************//**
 *
 * \brief Returns the version of the DLD Download Library
 *
 *   This function can be used to retrieve the version
 *   of the DLD Download Library.
 *
 * \param [out] major       Major number of the DLD Download Library version
 * \param [out] minor       Minor number of the DLD Download Library version
 * \param [out] patch_level Patch level of the DLD Download Library version
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - This function can be called before initializing the DLD Download Library.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_Version( uint8_t * const  major
                                        , uint8_t * const  minor
                                        , uint16_t * const patch_level
                                        );

/**********************************************************************************************//**
 *
 * \brief Initializes the DLD Download Library
 *
 *   This function initializes the DLD Download Library. All log messages are written to
 *   the specified log file. By passing a valid pointer to a progress callback function,
 *   progress reporting can be enabled.
 *
 * \param [in] target_directory     Directory containing the target configuration files
 * \param [in] log_level            The minimum displayed log level
 * \param [in] log_file             Name of the log file
 * \param [in] progress_callback    Pointer to the progress callback function
 * \param [in] power_cycle_callback Pointer to the power cycle callback function
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - The log level can be used to filter out log messages with lower severity.
 *
 * \remarks
 *    - Progress reporting can be disabled by passing a null pointer (NULL) for parameter
 *      progress_callback.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Init( const char * const target_directory
                                 , uint32_t           log_level
                                 , const char * const log_file
                                 , DLDProgressCB_t    progress_callback
                                 , DLDPowerCycleCB_t  power_cycle_callback
                                 );

/**********************************************************************************************//**
 *
 * \brief Initializes the DLD Download Library
 *
 *   This function initializes the DLD Download Library. All log messages are repoted via
 *   the specified log callback function. By passing a valid pointer to a progress callback
 *   function, progress reporting can be enabled.
 *
 * \param [in] target_directory     Directory containing the target configuration files
 * \param [in] log_level            The minimum displayed log level
 * \param [in] log_callback         Pointer to the log callback function
 * \param [in] progress_callback    Pointer to the progress callback function
 * \param [in] power_cycle_callback Pointer to the power cycle callback function
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - The log level can be used to filter out log messages with lower severity.
 *
 * \remarks
 *    - The log mechanism can be disabled by passing a null pointer (NULL) for parameter
 *      log_callback.
 *
 * \remarks
 *    - Progress reporting can be disabled by passing a null pointer (NULL) for parameter
 *      progress_callback.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Init_Custom( const char * const target_directory
                                        , uint32_t           log_level
                                        , DLDLogCB_t         log_callback
                                        , DLDProgressCB_t    progress_callback
                                        , DLDPowerCycleCB_t  power_cycle_callback
                                        );

/**********************************************************************************************//**
 *
 * \brief Deinitializes the DLD Download Library
 *
 *   This function deinitializes the DLD Download Library.
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - This function does not disconnect from nodes before deinitializing the library. If the
 *      connected nodes shall be reset, the disconnect function must explicitly be called by the
 *      application. Otherwise the connected nodes remain in the second stage bootloader until
 *      a power cycle is performed.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Deinit( void );

/**********************************************************************************************//**
 *
 * \brief Sets the log level of the active log channel
 *
 *   This function sets the log level to the active log channel (file or log callback).
 *
 * \param [in] log_level    The minimum displayed log level
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Set_Log_Level( uint32_t log_level );

/**********************************************************************************************//**
 *
 * \brief Writes a log message to the active log channel
 *
 *   This function writes a log message to the active log channel (file or log callback).
 *
 * \param [in] log_level    The log message's severity
 * \param [in] message      The log message
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Write_Log( uint32_t           log_level
                                      , const char * const message
                                      );

/**********************************************************************************************//**
 *
 * \brief Registers a CAN driver for communication
 *
 *   This function registers a built-in CAN driver for communication.
 *
 * \param [in] driver                   The CAN driver to be used
 * \param [in] channel                  The CAN driver's channel to be used
 * \param [in] baudrate                 The CAN baudrate used for communication
 * \param [in] download_id              The CAN identifier used for download
 *                                      direction (host -> target)
 * \param [in] upload_id                The CAN identifier used for upload
 *                                      direction (target -> host)
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_CAN( uint32_t           driver
                                                , uint8_t            channel
                                                , uint16_t           baudrate
                                                , DLDCANIdentifier_t download_id
                                                , DLDCANIdentifier_t upload_id
                                                );

/**********************************************************************************************//**
 *
 * \brief \deprecated Registers a custom CAN driver for communication
 *
 *   This function registers a custom CAN driver for communication.
 *
 * \param [in] download_id              The CAN identifier used for download
 *                                      direction (host -> target)
 * \param [in] upload_id                The CAN identifier used for upload
 *                                      direction (target -> host)
 * \param [in] init_callback            Pointer to the driver initialization callback function
 * \param [in] deinit_callback          Pointer to the driver deinitialization callback function
 * \param [in] read_callback            Pointer to the driver CAN read callback function
 * \param [in] write_callback           Pointer to the driver CAN write callback function
 * \param [in] custom_data              Pointer to the driver's custom data
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - This function is deprecated since version 1.0.9. Use function
 *      DLD_Driver_Register_Custom_CAN2() instead.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_Custom_CAN( DLDCANIdentifier_t    download_id
                                                       , DLDCANIdentifier_t    upload_id
                                                       , DLDDriverInitCB_t     init_callback
                                                       , DLDDriverDeinitCB_t   deinit_callback
                                                       , DLDDriverCANReadCB_t  read_callback
                                                       , DLDDriverCANWriteCB_t write_callback
                                                       , DLDCustomData_t       custom_data
                                                       );

/**********************************************************************************************//**
 *
 * \brief Registers a custom CAN driver for communication
 *
 *   This function registers a custom CAN driver for communication.
 *
 * \param [in] download_id              The CAN identifier used for download
 *                                      direction (host -> target)
 * \param [in] upload_id                The CAN identifier used for upload
 *                                      direction (target -> host)
 * \param [in] init_callback            Pointer to the driver initialization callback function
 * \param [in] deinit_callback          Pointer to the driver deinitialization callback function
 * \param [in] empty_rx_queue_callback  Pointer to the driver CAN empty receive queue callback
 *                                      function
 * \param [in] read_callback            Pointer to the driver CAN read callback function
 * \param [in] write_callback           Pointer to the driver CAN write callback function
 * \param [in] custom_data              Pointer to the driver's custom data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_Custom_CAN2( DLDCANIdentifier_t        download_id
                                                        , DLDCANIdentifier_t        upload_id
                                                        , DLDDriverInitCB_t         init_callback
                                                        , DLDDriverDeinitCB_t       deinit_callback
                                                        , DLDDriverEmptyRxQueueCB_t empty_rx_queue_callback
                                                        , DLDDriverCANReadCB_t      read_callback
                                                        , DLDDriverCANWriteCB_t     write_callback
                                                        , DLDCustomData_t           custom_data
                                                        );

/**********************************************************************************************//**
 *
 * \brief Registers an UDP driver for communication
 *
 *   This function registers a built-in UDP driver for communication.
 *
 * \param [in] local_address        The host's local IPv4 address
 * \param [in] multicast_address    The multicast IPv4 address used for communication
 * \param [in] port_number          The port number used for communication
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_UDP( DLDIPAddress_t local_address
                                                , DLDIPAddress_t multicast_address
                                                , uint16_t       port_number
                                                );

/**********************************************************************************************//**
 *
 * \brief \deprecated Registers a custom UDP driver for communication
 *
 *   This function registers a custom UDP driver for communication.
 *
 * \param [in] init_callback            Pointer to the driver initialization callback function
 * \param [in] deinit_callback          Pointer to the driver deinitialization callback function
 * \param [in] read_callback            Pointer to the driver UDP read callback function
 * \param [in] write_callback           Pointer to the driver UDP write callback function
 * \param [in] custom_data              Pointer to the driver's custom data
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - This function is deprecated since version 1.0.9. Use function
 *      DLD_Driver_Register_Custom_UDP2() instead.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_Custom_UDP( DLDDriverInitCB_t     init_callback
                                                       , DLDDriverDeinitCB_t   deinit_callback
                                                       , DLDDriverUDPReadCB_t  read_callback
                                                       , DLDDriverUDPWriteCB_t write_callback
                                                       , DLDCustomData_t       custom_data
                                                       );

/**********************************************************************************************//**
 *
 * \brief Registers a custom UDP driver for communication
 *
 *   This function registers a custom UDP driver for communication.
 *
 * \param [in] init_callback            Pointer to the driver initialization callback function
 * \param [in] deinit_callback          Pointer to the driver deinitialization callback function
 * \param [in] empty_rx_queue_callback  Pointer to the driver empty receive queue callback
 *                                      function
 * \param [in] read_callback            Pointer to the driver UDP read callback function
 * \param [in] write_callback           Pointer to the driver UDP write callback function
 * \param [in] custom_data              Pointer to the driver's custom data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Register_Custom_UDP2( DLDDriverInitCB_t         init_callback
                                                        , DLDDriverDeinitCB_t       deinit_callback
                                                        , DLDDriverEmptyRxQueueCB_t empty_rx_queue_callback
                                                        , DLDDriverUDPReadCB_t      read_callback
                                                        , DLDDriverUDPWriteCB_t     write_callback
                                                        , DLDCustomData_t           custom_data
                                                        );

/**********************************************************************************************//**
 *
 * \brief Deregisters all registered drivers
 *
 *   This function deregisters all registered drivers.
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Deregister_All( void );

/**********************************************************************************************//**
 *
 * \brief Initializes all registered drivers
 *
 *   This function initializes all registered drivers.
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Init( void );

/**********************************************************************************************//**
 *
 * \brief Deinitializes all registered drivers
 *
 *   This function deinitializes all registered drivers.
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Driver_Deinit( void );

/**********************************************************************************************//**
 *
 * \brief Connects to nodes via all registered drivers
 *
 *   This function connects to nodes via all registered drivers.
 *
 * \param [in]  node_ids                Array of node IDs (i.e., node numbers) to scan for
 * \param [in]  size                    Size of the node ID array
 * \param [in]  duration                Specifies for how many seconds connect messages shall be
 *                                      sent during the connection procedure
 * \param [in]  automatic_reset         Indicates whether or not a soft reset shall be performed
 *                                      during the connection procedure
 * \param [in]  compatibility_check     Indicates whether or not the compatibility check shall be
 *                                      performed for found nodes
 * \param [out] nodes_found             Returns the number of nodes found
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - If the automatic reset flag is set, no power cycle is necessary to connect with nodes
 *      executing the CODESYS RTS.
 *
 * \remarks
 *    - To scan for all valid node IDs parameters \c node_ids and \c size must be set to NULL
 *      and zero, respectively.
 *
 * \remarks
 *    - Before calling this function, all registered drivers must explicitly be initialized by
 *      calling #DLD_Driver_Init.
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Connect( const uint8_t * const node_ids
                                    , uint8_t               size
                                    , uint32_t              duration
                                    , bool                  automatic_reset
                                    , bool                  compatibility_check
                                    , uint16_t * const      nodes_found
                                    );

/**********************************************************************************************//**
 *
 * \brief Disconnects from all connected nodes
 *
 *   This function disconnects from all connected nodes, i.e., it performs a soft reset of
 *   all connected the nodes.
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - After calling this function, all nodes start execution of their respective
 *      applications (if present).
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Disconnect( void );

/**********************************************************************************************//**
 *
 * \brief Sets the password of a connected node
 *
 *   This function sets the password of a connected node.
 *
 * \param [in] node         Index of the node
 * \param [in] password     The node's password
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Set_Node_Password( uint16_t           node
                                              , const char * const password
                                              );

/**********************************************************************************************//**
 *
 * \brief Retrieves node information of a connected node
 *
 *   This function retrieves the node information of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [out] node_info       Pointer to the node information structure receiving the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_Node_Info( uint16_t              node
                                          , DLDNodeInfo_t * const node_info
                                          );

/**********************************************************************************************//**
 *
 * \brief Retrieves target information of a connected node
 *
 *   This function retrieves the target information of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [out] target_info     Pointer to the target information structure receiving the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_Target_Info( uint16_t                node
                                            , DLDTargetInfo_t * const target_info
                                            );

/**********************************************************************************************//**
 *
 * \brief Retrieves memory information of a connected node
 *
 *   This function retrieves the memory information of a certain item of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [in]  item            The item (see \ref enum_item)
 * \param [in]  index           The item's index (only required for items with multiple entries)
 * \param [out] memory_info     Pointer to the memory information structure receiving the data
 * \param [out] name            Pointer to the character array receiving the item's name
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_Memory_Info( uint16_t                node
                                            , uint8_t                 item
                                            , uint8_t                 index
                                            , DLDMemoryInfo_t * const memory_info
                                            , char * const            name
                                            );

/**********************************************************************************************//**
 *
 * \brief Retrieves an APDB of a connected node
 *
 *   This function retrieves an APDB of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [in]  application     Name of the application
 * \param [out] apdb            Pointer to the APDB structure receiving the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_APDB( uint16_t           node
                                     , const char * const application
                                     , DLDAPDB_t * const  apdb
                                     );

/**********************************************************************************************//**
 *
 * \brief Sets an APDB of a connected node
 *
 *   This function sets an APDB of a connected node.
 *
 * \param [in] node             Index of the node
 * \param [in] application      Name of the application
 * \param [in] apdb             Pointer to the APDB structure containing the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Set_APDB( uint16_t                node
                                     , const char * const      application
                                     , const DLDAPDB_t * const apdb
                                     );

/**********************************************************************************************//**
 *
 * \brief Retrieves the BLDB of a connected node
 *
 *   This function retrieves the BLDB of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [out] bldb            Pointer to the BLDB structure receiving the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_BLDB( uint16_t          node
                                     , DLDBLDB_t * const bldb
                                     );

/**********************************************************************************************//**
 *
 * \brief Retrieves the FIDB of a connected node
 *
 *   This function retrieves the FIDB of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [out] fidb            Pointer to the FIDB structure receiving the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Get_FIDB( uint16_t          node
                                     , DLDFIDB_t * const fidb
                                     );

/**********************************************************************************************//**
 *
 * \brief Reads data from flash memory of a connected node
 *
 *   This function reads data from flash memory of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [in]  flash_address   Start address
 * \param [in]  length          Number of bytes to be read
 * \param [out] data            Data buffer that shall receive the read bytes
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Read_Flash( uint16_t        node
                                       , uint32_t        flash_address
                                       , uint32_t        length
                                       , uint8_t * const data
                                       );

/**********************************************************************************************//**
 *
 * \brief Writes data to the flash memory of a connected node
 *
 *   This function writes data to the flash memory of a connected node.
 *
 * \param [in] node             Index of the node
 * \param [in] flash_address    Start address
 * \param [in] length           Number of bytes to be written
 * \param [in] data             Buffer containing the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Write_Flash( uint16_t              node
                                        , uint32_t              flash_address
                                        , uint32_t              length
                                        , const uint8_t * const data
                                        );

/**********************************************************************************************//**
 *
 * \brief Erases the given range in flash memory of a connected node
 *
 *   This function erases the given range in flash memory of a connected node.
 *
 * \param [in] node             Index of the node
 * \param [in] flash_address    Start address
 * \param [in] length           Number of bytes to be erased
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Erase_Flash( uint16_t node
                                        , uint32_t flash_address
                                        , uint32_t length
                                        );

/**********************************************************************************************//**
 *
 * \brief Reads data from EEPROM of a connected node
 *
 *   This function reads data from EEPROM of a connected node.
 *
 * \param [in]  node            Index of the node
 * \param [in]  eeprom_address  Start address
 * \param [in]  length          Number of bytes to be read
 * \param [out] data            Data buffer that shall receive the read bytes
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Read_EEPROM( uint16_t        node
                                        , uint32_t        eeprom_address
                                        , uint32_t        length
                                        , uint8_t * const data
                                        );

/**********************************************************************************************//**
 *
 * \brief Writes data to the EEPROM of a connected node
 *
 *   This function writes data to the EEPROM of a connected node.
 *
 * \param [in] node             Index of the node
 * \param [in] eeprom_address   Start address
 * \param [in] length           Number of bytes to be written
 * \param [in] data             Buffer containing the data
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Write_EEPROM( uint16_t              node
                                         , uint32_t              eeprom_address
                                         , uint32_t              length
                                         , const uint8_t * const data
                                         );

/**********************************************************************************************//**
 *
 * \brief Erases the given range in EEPROM of a connected node
 *
 *   This function erases the given range in EEPROM of a connected node.
 *
 * \param [in] node             Index of the node
 * \param [in] eeprom_address   Start address
 * \param [in] length           Number of bytes to be erased
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Erase_EEPROM( uint16_t node
                                         , uint32_t eeprom_address
                                         , uint32_t length
                                         );

/**********************************************************************************************//**
 *
 * \brief Downloads a file to the flash memory of a connected node
 *
 *   This function downloads the given file to the flash memory of a connected node.
 *
 * \param [in] node         Index of the node
 * \param [in] file_name    The file name
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - Following input formats are supported:
 *          + Intel HEX
 *          + Motorola S-Record
 *          + CODESYS binary files (*.bin, *.app)
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Download_Flash_File( uint16_t           node
                                                , const char * const file_name
                                                );

/**********************************************************************************************//**
 *
 * \brief Downloads a file to EEPROM of a connected node
 *
 *   This function downloads the given file to the EEPROM of a connected node.
 *
 * \param [in] node         Index of the node
 * \param [in] file_name    The file name
 *
 * \return #DLDResult_t
 *
 **************************************************************************************************
 * \remarks
 *    - Following input formats are supported:
 *          + Intel HEX
 *          + Motorola S-Record
 *          + CODESYS binary files (*.bin, *.app)
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Download_EEPROM_File( uint16_t           node
                                                 , const char * const file_name
                                                 );

/**********************************************************************************************//**
 *
 * \brief Parses an array of arguments
 *
 *   This function parses an array of arguments and performs the provided operation(s).
 *
 * \param [in] arguments    Array of arguments
 * \param [in] size         Size of the argument array
 *
 * \return #DLDResult_t
 *
 *************************************************************************************************/
DLDResult_t DOWNLOAD_API DLD_Parse_Arguments( const char * * const arguments
                                            , uint32_t             size
                                            );

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* DLDDOWNLOAD_HPP_ */
