#ifndef _OTA_H_
#define _OTA_H_
#include "includes.h"
#include "device.h"
#include "gateway.h"
#include "../network_mgr/net_proc.h"
#include "../gateway_collect/gateway_collect.h"
#include "../network/timeout.h"


#define ONLOOKER_TIMEOUT_TIME           10
#define CONTINUOUS_TIMEOUT_TIME         300
#define RETRANSMIT_TIMEOUT_TIME         10    //重传时间
#define CONTINUOUS_TIMEOUT_TIME_MUX     900
#define CONTINUOUS_TIMEOUT_DELAY_TIME   3

#define OTA_TOTAL_TIMEOUT_TIME          900 //ucos定时器时间
#define OTA_TOTAL_TIMEOUT_TIME_TICK     (15*60*1000)//滴答定时器定时时间

#define OTA_CONTINUOUS_DIRECT     1
#define OTA_CONTINUOUS_DELAY      2
#define OTA_CONTINUOUS_CLOSE      0
#define OTA_CAD_FREE_DELAYTIME    300
#define OTA_CAD_OCCUPY_DELAYTIME  700
#define OTA_FIRST_DELAYTIME       2000

extern uint8_t ota_continuous_end_flag;
extern timeout_t ota_retransmit_delay;
extern uint8_t updata_state;
extern uint8_t cad_ch_activitydetected;
extern timeout_t ota_total_timer;
extern uint8_t  ota_total_timer_start;

//升级状态
#define START_UPDATA                  0x21  //已收到正确的升级指令
#define PACKET_LOSS_MORE              0x22  //丢包超标，升级结束
#define RETRANSMIT_TIMEOUT            0x23  //重传阶段超时，升级失败
#define UPDATA_CRC_ERROR              0x24  //升级包CRC校验失败
#define DEVICE_TYPE_ERROR             0x25  //目标设备类型不匹配
#define UPDATA_PACKAGE_LENGTH_ERROR   0x26  //长度不符
#define FIXED_CHARACTER_ERROR         0x27  //固定字符错误
#define UPDATA_DATA_SUCCESS           0x28  //升级包接收正确
#define UPDATA_TOTAL_TIMEOUT          0x29  //升级总时间超时
//#define BOOT_ERROR                    0x2A
#define UPDATA_SUCCESS                0x2A  //升级成功
#define UPDATA_BACK                   0x2B  //回退

//升级标记
#define UPDATA_FLAG  0x81
#define BACKOFF_FLAG 0x82
#define BACKOFF_OVER 0x83


#define OTA_UPDATE_BOOTROM_FLASH_START_ADDR  (0x08000000)                                                          //

#define OTA_UPDATE_APP1_FLASH_SIZE        (0x20000)                                                             //
#define OTA_UPDATE_APP1_FLASH_START_ADDR  (0x08020000)                                                          //
#define OTA_UPDATE_APP1_FLASH_END_ADDR    (OTA_UPDATE_APP1_FLASH_START_ADDR+OTA_UPDATE_APP1_FLASH_SIZE-1)       //

#define OTA_UPDATE_APP2_FLASH_SIZE        (0x20000)                                                             //
#define OTA_UPDATE_APP2_FLASH_START_ADDR  (0x08040000)                                                          //
#define OTA_UPDATE_APP2_FLASH_END_ADDR    (OTA_UPDATE_APP2_FLASH_START_ADDR+OTA_UPDATE_APP2_FLASH_SIZE-1)       //

#define OTA_UPDATE_APP3_FLASH_SIZE        (0x20000)                                                             //
#define OTA_UPDATE_APP3_FLASH_START_ADDR  (0x08060000)                                                          //
#define OTA_UPDATE_APP3_FLASH_END_ADDR    (OTA_UPDATE_APP3_FLASH_START_ADDR+OTA_UPDATE_APP3_FLASH_SIZE-1)       //

#define MAX_LOSS_PKG_COUNT              50          //最大丢包数，超过此数直接标记下载升级包失败。
typedef struct ota_pkg_info {
        uint16_t  des_device_type;
        uint32_t  des_device_id;
        uint16_t  rcv_device_type;
        uint32_t  rcv_device_id;
        //升级包类型和版本；
        uint32_t  update_type;
        uint32_t  update_version;
        //升级包总长度和校验码
        uint32_t  total_bytes;
        uint32_t  total_crc;
        uint16_t  total_pkgs;
        uint16_t  sub_pkg_id;

        uint16_t  ota_state;
        OS_TMR 	  ota_tmr;
        OS_TMR    ota_onlooker_tmr;
        OS_TMR    ota_continuous_tmr;
        OS_TMR    ota_retransmit_tmr;
        OS_TMR    ota_total_tmr;

        uint16_t  lastRightPkgNum;
        uint16_t  lossPkgIndex;
        uint16_t  lossPkgCounter;
        uint16_t  lossPkgId[MAX_LOSS_PKG_COUNT];

        uint16_t  retransLossPkts;  //重传丢包个数
        uint16_t  Send_interval; //发送间隔


} ota_pkg_info_t;

//设备固定信息，不需在app中写eeprom
typedef struct _device_fixed_info
{
    uint8_t Work_State;          //当前工作状态
}device_fixed_info_t;

extern device_fixed_info_t device_fixed_info;

//升级状态
typedef struct _updata_state
{
        uint16_t updata_flag;
        uint16_t backoff_begin;
        uint16_t backoff_over;
}updata_state_t;
extern updata_state_t updata_state_info;


extern void ota_process_handle(void);

extern void lora_gw_ota_proc(system_network_t *p_sys_net, gateway_collect_com_t *p_msg);

extern void gateway_lora_ota_proc(gateway_collect_com_t *p_msg);

extern int lora_gw_ota_info_Init(update_msg_format *p_update, uint32_t total_len, uint32_t total_crc);
extern void lora_gw_ota_start(system_network_t *p_sys_net);
extern void lora_gw_ota_continues(system_network_t *p_sys_net,uint32_t address);
#endif
