#ifndef _NET_PROC_H_
#define _NET_PROC_H_
#include "stm32f10x.h"
//#include "os.h"
#include "includes.h"
#include "device.h"
#include "gateway.h"
//#include "net_proc.h"
#include "../dev_mgr/taxctrl/tax_ctrl.h"
//#include "oiltank.h"
//#include "net_ctrl.h"
#include "../network/downlink.h"
#include "../network/uplink.h"
#include "net_ctrl.h"
#include "../gateway_collect/gateway_collect.h"


#define UPDATE_TOTAL_PERIOD (10*60)//(5*60) //(500*10)//*60) // 1为1S， 5为5S 5*60：5分钟


#define UPDATE_EACH_TIME 300
extern uint8_t RadioRxPayload[255];

enum {
    UP_PROG_FROM_NET = 0x22, // 来源来网络
    UP_PROG_FROM_GAT = 0x44, //来源来网关
};
enum { // 升级结果类型
    UPDATE_RECEIVE_UPDATEFLAG = 0x11, // URL的地址与长度不匹配
    UPDATE_SAMEVERSION, // 和当前版本相同
    UPDATE_FAILE_NOCOLLECT, // 此采集器不在本网关下
    UPDATE_DOWNLOADFILE_FAILED, //文件下载失败,即文件大小小于2个字节
    UPDATE_HTTP_ERROR,  //HTTP返回错误码
    UPDATE_DOWNLOADFILE_SUCCESS, // 文件下载成功
    UPDATE_CRCERROR, // 文件包中的CRC与实际不符
    UPDATE_URL_FILE_TYPE_ERROR, // URL中的文件信息与文件包中的信息不一致
    UPDATE_DEVICETYPEERROR, // 升级设备类型不匹配
    UPdATE_FILE_LEN_ERROR,  // 升级文件长度超过128个字节
    UPDATE_SUCCESS, // 升级成功
    UPDATE_RETURN_SUCESS, // 回退
//    UPDATE_SUCESS, // 升级程序成功
//    UPDATE_TYPEERROR, // 升级类型不匹配 当前升级文件不是网关的，或不是本采集器的
//    UPDATE_FIXCHARERROR, // 文件包中的固定字符错误
//    UPDATE_TOTALLENERROR, // 文件包中的长度与实际长度不对应该
//    UPDATE_FILEVERSION, // 文件包中的版本和当前文件名中的版本不一致
//    UPDATE_FAILED , // 升级失败
//    UPDATE_UPDATEING, // 升级中
//    UPDATE_FINISH, // 升级完成
};

typedef enum net_msg_type {
	/* 以下为外部交互信息 */
	/* uplink, 设备侧 ---> 后端服务器 */
	net_msg_type_none,
	net_msg_type_lot = 1,
	net_msg_type_trans = 2,
	net_msg_type_oiltank = 3,
	net_msg_type_gps = 4,
	net_msg_type_gateway = 5,
	net_msg_type_log = 6,
	net_msg_type_debug = 7,
	
	/* downlink 后端服务器 ----> 设备侧 */
	net_msg_type_rsv = 0x80,
	net_msg_type_config = 0x81,
	net_msg_type_update = 0x82,
	net_msg_type_chnbind = 0x83,
	net_msg_type_commnd = 0x84,
	net_msg_type_reboot = 0x85,

	/* 以下为内部交互信息，通过内部lora局域网交互升级包 */
	net_msg_type_timer,

	/* Gateway ----> Node */
	net_msg_type_update_start = 0x13,
	net_msg_type_update_continues = 0x14,
	net_msg_type_update_retransmit_rsp = 0x15,
	net_msg_type_update_ack_status = 0x16,	

	/* Node ---->  Gateway */	
	net_msg_type_update_retransmit_req = 0x22,
	net_msg_type_update_status = 0x21,		

	/* 网关绑定相关 */
	net_msg_type_bind_req = 0x40,
	net_msg_type_bind_rsp = 0x41,
	net_msg_type_node_echo = 0x42,
	net_msg_type_gw_echo = 0x43,
} net_msg_type;

typedef struct _update_msg_format {
        uint16_t rcv_device_type; // 接收设备的类型
        uint32_t rcv_device_id; //接收设备的SN
        uint16_t des_device_type;//升级设备的类型
        uint32_t des_device_id;//升级设备的SN
        uint32_t update_version; //升级版本
	char  url[128];
}__attribute__((packed)) update_msg_format;

// 0x13指令 下行，启动升级指令
typedef struct _ota_start_info {   
        uint16_t rcv_device_type;// 接收设备的类型 和SN
        uint32_t  rcv_device_id;
        uint16_t  des_device_type;//被升级设备的设备类型和id
        uint32_t  des_device_id;
        uint32_t  update_version;//升级包类型和版本；
        uint32_t  total_bytes;//升级包总长度和校验码
        uint16_t  time;  // 每包间隔时常

}__attribute__((packed)) ota_start_info_t;
// 0x14 0x15 指令 连续包 和重传包指令
typedef struct _ota_continues_info { 
    uint16_t rcv_device_type;// 接收设备的类型 和SN
    uint32_t  rcv_device_id;
    uint16_t  des_device_type;//被升级设备的设备类型和id
    uint32_t  des_device_id;
    uint16_t  total_pkgs; // 升级包的总个数
    uint16_t  sub_pkg_id; //升级包的编号
    uint8_t   sub_pkg_len; //每包的长度
//	uint32_t *pkg_content;
}__attribute__((packed)) ota_continues_info_t;
// 0x22指令 请求重传包指令
typedef struct _ota_retransmit_req {//重传请求
        uint16_t  rcv_devict_type; //接收设备
        uint32_t  rcv_device_id; //接收设备
        uint16_t  repeat_sub_pkg_id;
}__attribute__((packed)) ota_retransmit_req_t;

// 0x16指令  网关通知采集器去升级采集器
typedef struct _ota_lineoffupdate_collect {
    uint16_t master_device_type; // 主设备类型
    uint32_t master_device_sn;   // 主设备SN
    uint16_t slave_device_type;  // 从设备类型
    uint32_t slave_device_sn;    // 从设备 SN
    uint16_t des_device_type;    // 升级目标设备类型
    uint32_t des_device_sn;      // 升级目标设备SN
    uint32_t reserve;            // 预留
}__attribute__((packed)) ota_lineoffupdate_coll_t;

// 0x23 指令，
typedef struct _ota_updatestatus_up { // 升级状态上报
    uint16_t rcv_device_type;// 接收设备的类型 和SN
    uint32_t  rcv_device_id;
    uint16_t  des_device_type;//被升级设备的设备类型和id
    uint32_t  des_device_id;
    uint32_t  des_device_bootVr; //被升级设备的bootloader版本
    uint32_t  des_device_appVr;  // 被升级设备的APP版本
    uint8_t   status; // 升级状态码
    uint32_t  reserve;  // 预留
}__attribute__((packed)) ota_updatestatus_up_t;

typedef struct _inner_msg_format {
	uint16_t frame_header;      //帧头
	uint16_t fcs;               //帧校验
	uint32_t seq_no;            //消息序列号
	uint8_t  proto_ver;         //协议版本
	uint8_t  type;              //消息类型
	uint16_t len;               //消息长度
	char 	 info[160];
} inner_msg_format_t;



typedef struct _server_msg_header {
    uint16_t frame_header;      //帧头
    uint8_t  proto_ver;         //协议版本 0x01
    uint32_t seq_no;            //消息序列号
    uint8_t  msgtypeFirst;      //一级消息类型 0x01:系统类  0x02:状态类 0x03:数据类 0x04:产测类
    uint16_t msgtypeSecd;       // 二级消息类型
    uint16_t len;               //消息长度
    char 	 info[1024];
}__attribute__((packed)) sverMsgHeader;




#define		FRAME_HEADER_LEN		12

#if 1
//#define		MQTT_SERVER_IP			"8.142.80.166"
#define		MQTT_SERVER_IP			"test-mqtt.cpyypt.cn"
#else
#define		MQTT_SERVER_IP			"39.100.96.218"
#endif
//#define		MQTT_SERVER_PORT		"1883"
#define		MQTT_SERVER_PORT		"9000"

//#define		MQTT_UPLINK_LOT_TOPIC		"LotDeviceInfo"  //LotDeviceInfo
#define		MQTT_UPLINK_LOT_TOPIC		"cpyypt/up/"//"/mqtt/topic"  //LotDeviceInfo //"/mqtt/downlink"
#define		MQTT_UPLINK_TRANS_TOPIC		"Transaction"
#define		MQTT_UPLINK_TANK_TOPIC		"OilTankLevel"
#define		MQTT_UPLINK_GPS_TOPIC		"GPSLocation"
#define		MQTT_UPLINK_GATEWAY_TOPIC	"GWDeviceInfo" //
#define		MQTT_UPLINK_LOG_TOPIC		"LogInfo"
#define		MQTT_UPLINK_DEBUG_TOPIC		"DebugInfo"

#define         MQTT_UPLINK_TOPIC  "cpyypt/up/"
#define         MQTT_DNLINK_TOPIC  "cpyypt/down/"
#define         MQTT_DNLINK_TOPIC_CASE "cpyypt/down/"

#define 	TOPIC_GET_BY_MSGTYPE(msg_type)		((msg_type == net_msg_type_lot)?(MQTT_UPLINK_LOT_TOPIC):\
				((msg_type == net_msg_type_trans)?(MQTT_UPLINK_TRANS_TOPIC):	\
				((msg_type == net_msg_type_oiltank)?(MQTT_UPLINK_TANK_TOPIC):	\
				((msg_type == net_msg_type_gps)?(MQTT_UPLINK_GPS_TOPIC):(MQTT_UPLINK_GATEWAY_TOPIC)))))

typedef void (*net_init)(char *device_id);
typedef void (*net_send)(char *buffer, uint32_t len);
typedef uint32_t (*net_recv)(char *buffer, uint32_t *len);

typedef struct _net_drv {
	net_init init;
	net_send send;
	net_recv recv;
} net_drv_t;

typedef enum DEV_WORK_STATE
{
        DEV_WORK_STATE_NORMAL,
        DEV_WORK_STATE_UPDATING,
        DEV_WORK_STATE_UPDATE_RETRANSMIT,
        DEV_WORK_STATE_ONLOOKER,                   //旁观者模式
        DEV_WORK_STATE_OTA_BEGIN,                  //开始升级模式
        DEV_WORK_STATE_OTA_CONTINUOUS,             //升级中连续收包模式
        DEV_WORK_STATE_OTA_RETRANSMIT,             //升级中重传模式
        DEV_WORK_STATE_OTA_UPGRADE_RCV_END,        //升级中升级包接收完成模式
        DEV_WORK_STATE_PT,                         //产测模式
        DEV_WORK_STATE_UNINIT,                     //出厂信息未初始化模式

        DEV_WORK_STATE_MAX
}DEV_WORK_STATE_T;

typedef struct _system_network {
        uint8_t memory[4][1024];		//必须4字节对齐
	uint8_t dev_type;
	uint8_t workstate;
	OS_Q  net_q;
	OS_SEM sem;
	OS_MEM net_m;
	OS_TMR net_tmr;
	void * net_hdl; // mqtt是否初始化
	net_send uplink_send; //4G 上传数据的函数指针
	net_send downlink_send; //4G 下载数据的函数指针
	uint32_t seq_no;
	char str[1024];
}system_network_t;


extern system_network_t	sys_net;

void NET_IMEI_ICCID_INFO_GET(char *imei, char *iccid);
void net_queue_insert(char *p_msg, uint32_t msg_len);
void * net_queue_mem_calloc(void);
int net_queue_mem_free(void * p_msg);
//void net_msg_frame_fill(gateway_collect_com_t *p_msg, uint8_t msg_type, uint16_t len);

extern void close_tcp_mqtt(void);

void svc_proc(uint32_t dev_type, uint32_t dev_id);
void * net_queue_mem_calloc_must(void);
//extern void collect_msg_frame_fill(gateway_collect_com_t *p_msg,uint8_t msg_type,uint16_t len);
extern void gateway_update_proc(uint8_t *data,uint8_t msg_len);
extern void gateway_update_collect_status(void);
extern void gateway_reset_send_update_status(void);

extern void uplink_net_send(char *buffer, uint32_t len);
extern void * uplink_net_init(char *device_id) ;
extern void gateway_update_gateway_proc(void);
extern void gateway_update_gateway_status(void);
#endif
