#ifndef TCP_PROTOCOL_H
#define TCP_PROTOCOL_H

#ifdef __cplusplus
extern "C" {
#endif
	
//******************************************** Включаемые файлы *********************************************

#include "flash_mem.h"


//************************************ Глобальные (публичные) константы *************************************

//значения сигнатуры, которое является признаком действительной команды или ответа
#define TCP_CMD_SIGNATURE          (0x31434D44) // "1CMD"

#define TCP_CMD_HDR_SIZE           (sizeof(tcp_cmd_hdr_t))
#define TCP_CMD_RESP_SIZE          (sizeof(tcp_resp_hdr_t))

#define TCP_CMD_RX_DATA_SIZE_MAX   (512)
#define TCP_CMD_TX_DATA_SIZE_MAX   (512)

#define TCP_DEFAULT_CMD_PORT       (11114)
#define TCP_DEFAULT_DATA_PORT      (11115)

// Размер пароля для записи настроек
#define TCP_PASSWD_SIZE           (32)

// Проверка параметров
#define TCP_EXIT               exit:
#define TCP_GOTO_EXIT          goto exit
#define TCP_CHECK_VAL(cond)    if (cond < TCP_ERR_OK) { TCP_GOTO_EXIT; }



//******************************************* Определения типов *********************************************

// Флаги, описывающие особенности платы
typedef enum 
{
    // Установленный микроконтроллер (примеч. - запас 4 бита)
    // Признак, что установлен микроконтроллер GD32F450
    DEV_FLAGS_MCU_GD32F450  = (uint32_t) 0x00000001,  

    // Установленная ПЛИС (примеч. - запас 4 бита)
    // Признак, что установлен GW1N-UV9EQ144C6/I5
    DEV_FLAGS_FPGA_GW1N9    = (uint32_t) 0x00000010,

    // Заводские настройки не записаны
    DEV_FLAGS_FACTORY_INFO_IS_EMPTY  = (uint32_t) 0x00000100,
    // Сетевые настройки не записаны
    DEV_FLAGS_NET_INFO_IS_EMPTY      = (uint32_t) 0x00000200,
    // Адрес, выделенный DHCP-сервером, проверен 
    DEV_FLAGS_ADDR_ESTABLISHED       = (uint32_t) 0x00000400,

} tcp_dev_flags_t;


// заголовок команды
typedef struct 
{
    uint32_t sign;
    uint32_t cmd;       //код команды (реально используются 0-255)
    uint32_t par;       //параметр (соответствует value и index в usb)
    uint32_t data_len;  //кол-во данных на передачу в байтах
    uint32_t resp_len;  //кол-во ожидаем данных на прием в байтах
} tcp_cmd_hdr_t;


// заголовок ответа
typedef struct 
{
    uint32_t sign;
    int32_t  res; //код возврата (0 - ОК, <0 - ошибка)
    uint32_t len; //кол-во данных в ответе
} tcp_resp_hdr_t;


// Коды ошибок, возвращаемые модулем при завершении управляющей команды
typedef enum 
{
    TCP_ERR_OK                      = 0,     /**< Команда выполнена успешно */
    
    TCP_ERR_CMD_WASNT_EXECUTED      = -1001, /* Команда не выполнена из-за внутренней ошибки */
    TCP_ERR_UNKNOWN_CMD             = -1002, /* Неподдерживаемый код команды */
    TCP_ERR_INVALID_CMD_PARAMS      = -1003, /* Неверные параметры переданной команды */
    TCP_ERR_CMD_SIGNATURE           = -1004, /* Неверный признак начала команды */
    TCP_ERR_INVALID_CMD_DATA_SIZE   = -1005, /* Неверное количество данных в команде */

    TCP_ERR_INVALID_PASSWORD        = -1010, /* Неверный пароль для изменения настроек */
    TCP_ERR_DATA_IS_EMPTY           = -1011, /* Запрошенная информация пуста или повреждена */
    
    TCP_ERR_FPGA_REG_NACK           = -1020, /* Обращение к регистру ПЛИС вернуло ответ NACK */
    TCP_ERR_FPGA_REG_ERROR          = -1021, /* Обращение к регистру ПЛИС вернуло ответ ERROR */
    TCP_ERR_FPGA_REG_WT_TOUT        = -1022, /* Не удалось дожлаться ответ на обращение к регистру ПЛИС */
    TCP_ERR_FPGA_REG_FORMAT         = -1023, /* Ошибка формата слова при обращении к регистру ПЛИС */
    
    //! todo - подумать над ошибками самодиагностики
} tcp_resp_errs_t;


// Структура для записи сетевых пользовательских настроек
typedef struct
{
    char cur_passwd[TCP_PASSWD_SIZE];
    char new_passwd[TCP_PASSWD_SIZE];
    fm_user_settings_data_t settings;
} tcp_eth_cfg_hdr_t;



// Структура для записи заводских настроек
typedef struct
{
    char cur_passwd[TCP_PASSWD_SIZE];
    char new_passwd[TCP_PASSWD_SIZE];
    fm_factory_mem_data_t settings;
} tcp_factory_mem_data_hdr_t;


// Коды команды протокола обмена с модулями
// Примечание: от 1 до 127 (0x01...0x7F)
typedef enum 
{
    // Получение информации об устройстве
    TCP_CMD_GET_DEV_INFO        = 0x01,
    // Установить\получить сетевые настройки
    TCP_CMD_ETH_CFG_SET         = 0x02,
    TCP_CMD_ETH_CFG_GET         = 0x03,
    // Читать\записать заводские настройки
    TCP_CMD_FACTORY_DATA_SET    = 0x04,
    TCP_CMD_FACTORY_DATA_GET    = 0x05,
    // Читать\записать калибровки 
    TCP_CMD_CBR_DATA_WR         = 0x06,
    TCP_CMD_CBR_DATA_ER         = 0x07,
    TCP_CMD_CBR_DATA_RD         = 0x08,
    // Читать\записать область пользовательских данных 
    TCP_CMD_CMN_DATA_WR         = 0x09,
    TCP_CMD_CMN_DATA_ER         = 0x0A,
    TCP_CMD_CMN_DATA_RD         = 0x0B,

    // Управление потоками
    TCP_CMD_STREAMS_ENABLE      = 0x10,
    TCP_CMD_STREAMS_DISABLE     = 0x11,
    TCP_CMD_STREAMS_START       = 0x12,
    TCP_CMD_STREAMS_STOP        = 0x13,
    // Управление сокетами данных
    TCP_CMD_CREATE_DATA_SOCKET  = 0x14,
    TCP_CMD_DELETE_DATA_SOCKET  = 0x15,
    
    //! Установить\получить настройки синхронизации
    // TCP_CMD_SYNC_CFG_SET         = 0x07,
    // TCP_CMD_SYNC_CFG_GET         = 0x08,

    // Разрыв соединения по сокетам данных и неиспользуемым сокетам команд
    TCP_CMD_DROP_DATA_CON       = 0x20,
    // Записать\прочитать пользовательскую переменную
    TCP_CMD_SET_USER_VAR        = 0x21,
    TCP_CMD_GET_USER_VAR        = 0x22,
    // Сброс модуля
    TCP_CMD_RESET_MODULE        = 0x23,
    
    // Запись\чтение регистра ПЛИС
    TCP_CMD_FPGA_REG_READ       = 0x30,
    TCP_CMD_FPGA_REG_WRITE      = 0x31,
    // Сброс ПЛИС
    TCP_CMD_RELOAD_FPGA         = 0x32,
    // Перевод МК в загрузчик
    TCP_CMD_GO_TO_BOOT          = 0x33,

    // Получить код ошибки
    TCP_CMD_GET_LAST_ERROR      = 0x40,

} tcp_cmd_codes_t; 




//************************************ Глобальные (публичные) переменные ************************************

// Нет


//******************************** Объявления глобальных (публичных) функций ********************************

// Нет


#ifdef __cplusplus
}
#endif

#endif // TCP_PROTOCOL_H


//*********************************************** КОНЕЦ ФАЙЛА ***********************************************
