//******************************************** Включаемые файлы *********************************************

#include "lboot_Port.h"
#include "crc.h"
#include "lip.h"
#include <stddef.h>


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

// Нет


//******************************************* Локальные константы *******************************************

//! Версия ПО
#ifndef PROJECT_VERSION
// Версия по умолчанию (константа должна быть добавлена в Makefile)
#define PROJECT_VERSION    "0.0.1" 
#endif

//! Имя устройства для загрузчика
#define LBOOT_DEV_NAME_FOR_BTLDR       "LTA"

//! Таймаут ожидания начала обновления (в мс.)
#define LBOOT_START_TIMEOUT             (30000)

//! Режим загрузчика
#define LBOOT_MODE                      (LBOOT_BOOTMODE_TFTP_SERVER)



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

//! Информация об устройстве и прошивке	
t_lboot_devinfo lboot_dev_info = 
{
    .devname = LBOOT_DEV_NAME_FOR_BTLDR,
    .serial = "",
    .soft_ver = PROJECT_VERSION,
    .brd_revision = "",
    .brd_impl = "",
    .spec_info = "",
};


//************************************* Локальные (приватные) переменные ************************************

//! Стандартный заголовок запроса на перепрошивку
static t_lboot_params lboot_params;

//! Информация для загрузчика.
//! Примечание - находится Эта структура должна находится по смещению 512 от начала прошивки, то
//! есть сразу за таблицей векторов из 128 векторов.
static const t_app_info lboot_app_info __attribute__ ((section(".appl_info"))) =
{
    .size    = sizeof(t_app_info), 
    .flags   = LBOOT_APP_FLAGS_STABLE, 
    .devname = LBOOT_DEV_NAME_FOR_BTLDR,
    .firm_version = PROJECT_VERSION,
}; 

//! Информация о загрузчике
static const t_lboot_info *lboot_btldr_info = (const t_lboot_info*)LBOOT_INFO_ADDR;


//***********************************************************************************************************
//******************************** Определения локальных (приватных) функций ********************************
//***********************************************************************************************************


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

void lboot_create_req_for_btldr(void)
{
    // Заполнение структуры
    lboot_params.hdr.flags   = LBOOT_REQ_FLAGS_RECOVERY_WR;
    lboot_params.hdr.devinfo = lboot_dev_info;
    lboot_params.hdr.timeout = LBOOT_START_TIMEOUT;

    #if (LBOOT_MODE == LBOOT_BOOTMODE_TFTP_SERVER)
        if (true == lip_ipv4_cur_addr_is_valid()) 
        {
            lboot_params.hdr.size = LBOOT_REQ_SIZE(tftp);
            lboot_params.hdr.bootmode = LBOOT_BOOTMODE_TFTP_SERVER;

            memset(&lboot_params.tftp, 0, sizeof(t_lboot_specpar_tftp));
            memcpy(lboot_params.tftp.mac, lip_eth_cur_mac(), LIP_MAC_ADDR_SIZE);

            lip_ipv4_addr_cpy(lboot_params.tftp.l_ip, lip_ipv4_cur_addr());
            lip_ipv4_addr_cpy(lboot_params.tftp.mask, lip_ipv4_cur_mask());
            lip_ipv4_addr_cpy(lboot_params.tftp.gate, lip_ipv4_cur_gate());

            lboot_params.tftp.crc = eval_crc16(0, (uint8_t*)&lboot_params, (lboot_params.hdr.size - sizeof(lboot_params.tftp.crc)));
        }
    #else
        #error "LBOOT_MODE not defined"
    #endif

    // Копирование структуры запроса по указанному адресу
    *(t_lboot_params *)LBOOT_REQ_ADDR = lboot_params;
}


void lboot_set_dev_name(char* NewValue, uint8_t size)
{
    memcpy(lboot_dev_info.devname, NewValue, size);
}


void lboot_set_serial(char* NewValue, uint8_t size)
{
    memcpy(lboot_dev_info.serial, NewValue, size);
}


void lboot_set_brd_rev(char* NewValue, uint8_t size)
{
    memcpy(lboot_dev_info.brd_revision, NewValue, size);
}



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