/***************************************************************************//**
  @file
  Файл содержит параметры для протокола обмена между загрузчиком и приложением.
  Включает в себя коды ошибок, типы для описания передаваемых параметров команд,
  и константы для определения значений этих полей
  *****************************************************************************/
#ifndef __LBOOT_PRT_H__
#define __LBOOT_PRT_H__

#include <stdint.h>

/** Коды ошибок */
typedef enum {
    /** Выполнено без ошибок */
    LBOOT_ERR_SUCCESS                       =     0,
    /** Код первой ошибки бутлоадера */
    LBOOT_ERR_OFFSET                        = -1000,
    /** Передана неверная подпись */
    LBOOT_ERR_UNCORRECT_SIGN                = -1000,
    /** Попытка записать нестабильную версию прошивки в качестве резервной копии
        (определяется по флагу в определенном месте в прошивке) */
    LBOOT_ERR_UNSTABLE_RECOV_WR             = -1001,
    /** Передаваймый файл прошивки предназначен для другого устройства
        (название устройства в прошивке не совпало с тербуемым (переданным
         в параметре запроса от прилоения или дефолтным)) */
    LBOOT_ERR_FIRMWARE_FOR_INVALID_DEVICE    = -1002,
    /** Неверный признак команды начала записи в прошивку */
    LBOOT_ERR_UNCORRECT_START_SIGN           = -1003,
    /** Нельзя записать данный тип прошивки (основной или резервной). Возникает
        либо если идет попытка записать резервную, когда приложение в запросе
        это запретило, либо в случае, если идет попытка перезаписать единственно
        верную на текущий момент прошивку (напрмер попытка переписать основную,
        когда нет резервной) */
    LBOOT_ERR_WR_DISABLED                    = -1004,
    /** Ошибка записи во flash-память блока прошивки (аппратная)*/
    LBOOT_ERR_FLASH_WRITE                    = -1005,
    /** Неверный стартовый адрес в записываемой прошивке - вектор сборса
        указывает на место не внутри прошивки */
    LBOOT_ERR_UNCORRECT_FIRM_RESET_ADDR      = -1006,
    /** Неверная длина данных в управляющем запросе */
    LBOOT_ERR_INVALID_REQ_DATA_LENGTH        = -1007,
    /** Неверная операция. В данном режиме работы загрузчика эта операция
        не может быть выполнена */
    LBOOT_ERR_INVALID_OPERATION              = -1008,
    /** Попытка записать упакованную прошивку, когда данная версия загрузчика
        ее не поддерживает */
    LBOOT_ERR_UNSUP_UNPACK                   = -1009,
    /** Упакованная прошивка закончилась, хотя формат архива требует еще данных */
    LBOOT_ERR_UNPACK_NOT_COMPLETE            = -1010,
    /** Ошибка проверки целостности записанной прошивки после завершения записи */
    LBOOT_ERR_FW_INTEGRITY_CHECK             = -1011,
    /** Попытка записать в сектор, где прошивки не должно быть. Возникает
        при размере прошивки, выходящем за размер отведенного для нее места в
        памяти */
    LBOOT_ERR_INVALID_SECTOR                 = -1012,
    /** Попытка записать прошивку без подписи, когда приложение в запросе этого
        не разрешило */
    LBOOT_ERR_FIRM_WITHOUT_SIGN_DISABLED     = -1013,
    /** Неверный хеш прошивки (при записи без подписи) */
    LBOOT_ERR_INVALID_HASH                   = -1014,
    /** Попытка записать прошивку для разработчиков, когда приложение этого не разрешило */
    LBOOT_ERR_DEVELOP_FIRM_DISABLE           = -1015,
    /** Неподдерживаемый код специальной команды */
    LBOOT_ERR_INVALID_CMD_CODE               = -1016,
    /** Неверные параметры специальной команды */
    LBOOT_ERR_INVALID_CMD_PARAMS             = -1017,
    /** Неверная сигнатура команды */
    LBOOT_ERR_INVALID_CMD_SIGN               = -1018,
    /** Нет резервной копии прошивки */
    LBOOT_ERR_RESERV_COPY_NOT_PRESENT        = -1019,
    /** Нет основной прошивки */
    LBOOT_ERR_APPLICATION_NOT_PRESENT        = -1020,
    /** Неверный размер записываемой прошивки (выходит за допустимые пределы) */
    LBOOT_ERR_INVALID_APPL_SIZE              = -1021,
    /** Неверный размер записываемых данных защищенных пользовательских */
    LBOOT_ERR_PROT_DATA_INVALID_SIZE         = -1022,
    /** Запись пользовательских данных запрещена аппаратно */
    LBOOT_ERR_PROT_DATA_WR_DISABLED          = -1023,
    /** Ошибка проверки правильности данных после записи */
    LBOOT_ERR_PROT_DATA_CHECK                = -1024,
    /** Неверный адрес регистра при чтении информации загрузчика */
    LBOOT_ERR_INVALID_REG_ADDR               = -1025,
    /** Операция отменена другим запросом */
    LBOOT_ERR_ABORTED_BY_ANOTHER_REQ         = -1026,
    /** Неверный формат упакованного файла */
    LBOOT_ERR_INVALID_XZ_FORMAT              = -1027,
    /** Неверный формат подписи */
    LBOOT_ERR_INVALID_SIGN_FORMAT            = -1028,
    /** Ошибка при сравнении записанного содержимого во flash-память */
    LBOOT_ERR_FLASH_COMPARE                  = -1029,
    /** Ошибка стирания flash-памяти */
    LBOOT_ERR_FLASH_ERASE                    = -1030,
    /** Не выбрана прошивка для записи/чтения */
    LBOOT_ERR_CUR_FIRMWARE_NOT_SELECTED      = -1031,
    /** Неизвествный тип прошивки */
    LBOOT_ERR_UNKNOWN_FIRMWARE_TYPE          = -1032,
    /** Ошибка разрешения записи во flash-память */
    LBOOT_ERR_FLASH_WRITE_ENABLE             = -1033,
    /** Ошибка запрета записи во flash-память */
    LBOOT_ERR_FLASH_WRITE_DISABLE            = -1034,
    /** Ошибка записи кода защиты памяти контроллера во flash-память */
    LBOOT_ERR_FLASH_WRITE_RDP_LVL            = -1035,
    /** Некорректный формат файла прошивки */
    LBOOT_ERR_INVALID_FILE_FORMAT            = -1036,
    /** Файл не содержит hash прошивки */
    LBOOT_ERR_HASH_NOT_PRESENT               = -1037,
    /** Файл содержит неподдерживаемое кол-во блоков данных */
    LBOOT_ERR_INVALID_DATA_BLOCK_CNT         = -1038,
    /** Неверный номер региона прошивки */
    LBOOT_ERR_INVALID_REGION_NUM             = -1039,
    /** Не обнаружены данные для главного региона */
    LBOOT_ERR_NO_MAIN_REGION                 = -1040,
    /** Данный файл не разрешено использовать в качестве указанного типа прошивки */
    LBOOT_ERR_FILE_NOT_ALLOWED_FWTYPE        = -1041,
    /** Прошивка не для данного типа чипа */
    LBOOT_ERR_FILE_NOT_FOR_CUR_CHIPTYPE      = -1042,
    /** Отсутствует подпись в файле прошивки */
    LBOOT_ERR_FILE_SIGN_NOT_PRESENT          = -1043,
    /** Мета-формат не поддерживается устройством */
    LBOOT_ERR_FILE_METAFILE_FMT_NOT_SUPPORTED= -1044,
    /** Для данного устройства прошивка должен использоваться мета-формат файла прошивки */
    LBOOT_ERR_FILE_METAFILE_FMT_REQUIRED     = -1045,
    /** Невозможно расшифровать переданные данные */
    LBOOT_ERR_CANT_DECRYPT_DATA              = -1046,
    /** Данные прошивки должны быть зашифрованы */
    LBOOT_ERR_ENCRYPTION_REQUIRED            = -1047,
    /** Не обнаружены данные прошивки в принятом файле */
    LBOOT_ERR_FIRMWARE_DATA_NOT_PRESENT      = -1048,
    /** Использован неверный ключ шифрования прошивки */
    LBOOT_ERR_INVALID_ENCRYPTION_KEY         = -1049,
    /** Не обнаружено корректного окончания передаваемого файла */
    LBOOT_ERR_END_OF_FILE_NOT_DETECTED       = -1050,
} t_lboot_errs;


/** Общие флаги состояния загрузчика */
typedef enum {
    /** Признак, что есть действительная резервная копия */
    LBOOT_STATEFLAGS_RESERV_VALID       = 0x00000001,
    /** Признак, что есть действительная основная прошивка */
    LBOOT_STATEFLAGS_APP_VALID          = 0x00000002,
    /** Признак, что разрешено записывать резервную копию прошивки */
    LBOOT_STATEFLAGS_RESERV_WR_EN       = 0x00000004,
    /** Признак, что разрешено записывать основную копию прошивки */
    LBOOT_STATEFLAGS_APP_WR_EN          = 0x00000008,

    /** Признак, что интерфейс Ethernet проинициализрован */
    LBOOT_STATEFLAGS_ETH_INIT           = 0x00000010,
    /** Признак, что интерфейс RS-232/485 проинициализирован */
    LBOOT_STATEFLAGS_RS_INIT            = 0x00000020,
    /** Признак, что интерфейс USB проинициализирован */
    LBOOT_STATEFLAGS_USB_INIT           = 0x00000040,
    /** Признак, что интерфейс CAN проинициализирован */
    LBOOT_STATEFLAGS_CAN_INIT           = 0x00000080,


    /** Признак, что есть действительная резервная копия */
    LBOOT_STATEFLAGS_RESERV2_VALID      = 0x00000100,
    /** Признак, что есть действительная основная прошивка */
    LBOOT_STATEFLAGS_APP2_VALID         = 0x00000200,
    /** Признак, что разрешено записывать резервную копию прошивки */
    LBOOT_STATEFLAGS_RESERV2_WR_EN      = 0x00000400,
    /** Признак, что разрешено записывать основную копию прошивки */
    LBOOT_STATEFLAGS_APP2_WR_EN         = 0x00000800,



    /** Признак, что после загрузки прошивки не нужно стартовать application */
    LBOOT_STATEFLAGS_DONT_START         = 0x00080000,
    /** Признак, что идеть запись приложения без подписи */
    LBOOT_STATEFLAGS_NO_SIGN            = 0x00200000
} t_lboot_flags;

/** Поддерживаемые загрузчиком возможносит (доступны с версии 1.4) */
typedef enum {
    /** поддержка интерфейса Modbus RTU */
    LBOOT_FEATURES_INTF_MODBUS_RTU       = 0x00000001,
    /** поддержка интерфейса TFTP */
    LBOOT_FEATURES_INTF_TFTP_CLIENT      = 0x00000002,
    /** поддержка интерфейса USB */
    LBOOT_FEATURES_INTF_USB              = 0x00000004,
    /** поддержка интерфейса CAN LSS */
    LBOOT_FEATURES_INTF_CAN_LSS          = 0x00000008,
    /** поддержка интерфейса TFTP-сервер */
    LBOOT_FEATURES_INTF_TFTP_SERVER      = 0x00000010,
    /** поддержка интерфейса HTTP-сервер */
    LBOOT_FEATURES_INTF_HTTP_SERVER      = 0x00000020,

    /** поддержка аппаратного признака перехода загрузчика в режим по-умолчанию */
    LBOOT_FEATURES_HW_DEFAULT_MODE       = 0x00000100,
    /** поддержка аппаратного признака восстановления приложения из резервной копии */
    LBOOT_FEATURES_HW_RECOVERY           = 0x00000200,
    /** использование режима начальной инициализации режима по-умолчанию в течении таймаута */
    LBOOT_FEATURES_STARTUP_DEFAULT_MODE  = 0x00000400,

    /** поддержка записи защищенного блока данных */
    LBOOT_FEATURES_PROT_DATA             = 0x00001000,
    /** аппаратная защита блока данных */
    LBOOT_FEATURES_PROT_DATA_HW          = 0x00002000,
    /** защита блока данных подписью */
    LBOOT_FEATURES_PROT_DATA_SIGN        = 0x00004000,
    /** проверка прошивки с помощью ХЕШ-функции */
    LBOOT_FEATURES_CHECK_HASH            = 0x00010000,
    /** проверка прошивки с помощью подписи */
    LBOOT_FEATURES_CHECK_RSA             = 0x00020000,
    /** использование формата метафайла вместо прямой записи */
    LBOOT_FEATURES_METFILE_FMT           = 0x00040000,
    /** поддержка дешифровки данных */
    LBOOT_FEATURES_DECRYPTION            = 0x00080000,

    /** поддержка сжатия прошивки с помощью XZ */
    LBOOT_FEATURES_XZ                    = 0x00100000,

    /** поддержка второго региона для записи прошивки */
    LBOOT_FEATURES_FW_REG2               = 0x01000000
} t_lboot_features;



/** Коды команд загрузчика */
typedef enum {
    /** Команда запуска приложения */
    LBOOT_CMD_CODE_START_APPL   = 0x1,
    /** Восстановление резервной копии в качестве основной прошивки */
    LBOOT_CMD_CODE_RESERV_RECOV = 0x2,
    /** Запись защещенных пользовательских данных */
    LBOOT_CMD_CODE_WRITE_PROT_DATA = 0x3
} t_lboot_cmd_code;



/** код признака старта записи прошивки */
#define LBOOT_WRSTART_SIGN     0x5AA5
/** код признака спец-команды для загрузчика */
#define LBOOT_SPECCMD_SIGN     0x0FA55AFE

/** флаги для команды начала загрузки */
typedef enum {
    /** Признак, что записываем резервную копию, а не основную */
    LBOOT_STARTWR_FLAGS_RESERV_WR     = 0x0001,
    /** Признак, что записываем упакованную с помощью XZ прошивку */
    LBOOT_STARTWR_FLAGS_PACK_XZ      = 0x0002,
    /** Признак, что для подтверждения прошивки будет послан хеш, а не подпись */
    LBOOT_STARTWR_FLAGS_NOSIGN       = 0x0004,
    /** Признак, что после завершения загрузки не следует сразу запускать приложение */
    LBOOT_STARTWR_FLAGS_DONT_START   = 0x0008,
    /** Признак, что передается файл с метаданными нового формата */
    LBOOT_STARTWR_FLAGS_METAFILE     = 0x0010,
} t_lboot_startwr_flags;

/** тип, описывающий структуру данных, передаваемых с запросом начала прошивки */
typedef struct st_startwr_info {
    uint16_t sign; /**< признак - должен быть равен #LBOOT_WRSTART_SIGN */
    uint16_t flags; /**< набор флагов из #t_lboot_startwr_flags */
    uint32_t size;  /**< размер файла прошивки */
} t_lboot_startwr_info;

/** тип, описывающий структуру данных, передаваемых с командой загрузчику */
typedef struct st_speccmd_info {
    uint32_t sign; /**< признак - должен быть равен #LBOOT_SPECCMD_SIGN */
    uint32_t cmd_code; /**< код команды */
    uint32_t reserv;   /**< резерв */
    uint8_t params[0]; /**< опциональные параметры */
} t_lboot_speccmd_info;


/** параметры для команды #LBOOT_CMD_CODE_WRITE_PROT_DATA */
typedef struct st_cmd_params_wr_prot_data {
    uint32_t data_size; /**< размер данных в записываемом блока */
    uint32_t flags; /**< флаги - резерв */
} t_cmd_params_wr_prot_data;



#endif


