#ifndef _MQTT_H
#define _MQTT_H

#include "CH57x_common.h"		//CH57X 库包含头文件
#include "MQTTPacket.H"
#include "net.h"
#include "check_fun.h"
#include "SRAM_Variable_Address.h"
#include "BLV_Dev_Action.h"

#ifndef MQTT_EN
#define MQTT_EN  1
#endif

#define USER_NAME 	"34D0B8108D15&a1STn6qUB4r"
#define PASSWORD  	"d9c0248ec19854b56d7bb79c30e34c54d68875a6"
#define DOMAIN_NAME "a1STn6qUB4r.iot-as-mqtt.cn-shanghai.aliyuncs.com"
#define CLIENT_ID  	"34D0B8108D15|securemode=3,signmethod=hmacsha1|"

#define SUB_TOPIC  	"sub_topic"
#define PUB_TOPIC  	"pub_topic"

#define SRAM_MQTT_RECEIVE_START   0x030000      //MQTT接收缓存起始地址
#define SRAM_MQTT_RECEIVE_END     0x030FFF      //MQTT接收缓存结束地址
#define SRAM_MQTT_RECEIVE_LEN     0x400         //MQTT单个接收缓存长度


#define  CmdID_LEN              4
#define  DeviceID_LEN           6
#define  UTCTime_LEN            6

#define  CMD_HEAD_ERROR        0x00   //指令头错误
#define  CMD_SUCCESS           0x01   //执行成功
#define  CMD_CRC_ERROR         0x02   //CRC验证失败
#define  CMD_DEC_ERROR         0x03   //解密失败
#define  CMD_DEV_NO            0xe1   //设备未激活

#define  SRAM_MQTT_DEVICE_LIST_START   0x031000
#define  SRAM_MQTT_DEVICE_LIST_END     0x0313FF

#define Struct_CFG_Dev_Freego_Name_Len   20    //名称长度限制
#define Struct_CFG_Dev_Freego_Map_LEN    24    //新增设备结构体长度  不包括参数类型02
#define CFG_Dev_Freego_Map_MAX           40    //支持的最大设备数 分配内存和tcp发送有1K的限制
#define HtolCpy(pdata, datau32)   {pdata[0] = (datau32>>24)&0x000000ff;pdata[1] = (datau32>>16)&0x000000ff; \
	pdata[2] = (datau32>>8)&0x000000ff;pdata[3] = (datau32>>0)&0x000000ff;pdata[4] = ((SysTick_1ms%1000)>>8); \
	pdata[5] = (SysTick_1ms%1000);}//将u32的数按高字节存放在pdata        

typedef enum
{
	CMD_PKT,
	CMDID_PKT,
	DEVICE_ID_PKT = 5,
	UTC_PKT = 11,
	PRAM_PKT = 17,
}FREEG_PKT_E;
	
#pragma pack(1)

typedef struct
{
	UINT8 init_flag:1;										                       /* 初始化标志位 */
	UINT8 con_flag:1;										                       /* 已连接MQTT服务器标志位 */
	UINT8 pub_flag:1;											                   /* 已发布会话消息标志位 */
	UINT8 sub_flag:1;											                   /* 已订阅会话标志位 */
	UINT8 tout_flag:1;											                   /* 超时标志位 */
	UINT8 domain_dns:1;                                       //mqtt域名解析标志
	UINT8 reconnect:2;                                        //超时重连次数
	
	UINT8 dns_en:1;                                          //使能域名解析
	UINT8 mqtt_socket:7;                                     //存放mqtt 套接字
	
	UINT16 packetid;											                   /* 包ID */
	
	UINT8 MyBuf[RECE_BUF_LEN];                              /* 定义一个临时缓冲区 */
	
	UINT8 des_ip[4]; 																			//目标ip
	uint16_t keepAliveInterval;                                //保持在线时间
	UINT32 sour_port;																			//源端口
	
	char* domain_name;                                        //域名
	char* clientID;                                           //clientID
	char *username;							                               /* 用户名 */
	char *password;								                           /* 服务器登陆密码 */
	char *sub_topic;								                           /* 订阅的会话名，为了自发自收，应与发布的会话名相同 */
	char *pub_topic;									                       /* 发布的会话*/
	
	UINT32 Sram_read_addr;                   //MQTT接收处理地址
	UINT32 Sram_write_addr;                   //MQTT接收地址
	
	uint8_t mqtt_sta;         //2023-03-17
	uint32_t wait_cot;        //2023-03-17
	uint8_t mqtt_cfail_num;   //2023-03-17
	
}MQTT_INFO;

typedef struct
{
	UINT8 publish[65];         		   //发布会话名
	
	UINT8 sublish[65];         		   //订阅会话名
	
}MQTT_THEME;    //mqtt主题

typedef struct
{
	MQTT_THEME mqtt_theme;           //主题
	
	UINT8 domain_name[65];            //域名
	
	UINT8 clientID[65];               //clientID
	
	UINT8 username[65];							 /* 用户名 */
	
	UINT8 password[65];							/* 服务器登陆密码 */
	
}MQTT_BASIC_INFO;    //mqtt基本参数

typedef struct
{
	uint16_t keepAliveInterval;      //保持在线时间
	
	MQTT_BASIC_INFO* mqtt_basic_info;    //mqtt基本参数

}MQTT_DATA;


//typedef struct CFG_Freego_Map_Add*     CFG_Freego_Map_AddP;     //新增映射表指针 

//包括下一个节点指针 结构体大小是18个字节
typedef struct CFG_Freego_Map_Add
{
/*配置数据自带参数开始*/
	uint8_t ServerDevType;         //u8的设备类型，包括本地自带设备和485设备 
	uint8_t ServerDevAddr;         //u8的设备地址，本地自带设备地址默认为0，485设备地址需要填相应设备的实际地址
	uint16_t FreegoDevOutputLoop;        //回路地址 非场景 低字节为非零；  场景 高字节为非零
//	uint8_t DevLoopAddr[4];        //设备回路地址  分别对应设备类型  设备地址  回路地址L 回路地址H	
	uint8_t DevLoopName[20];        //设备回路地址的别名 
	
}__attribute__ ((__packed__))Struct_CFG_Freego_Map_Add;    //配置数据新增映射表结构体

#pragma pack()

#if MQTT_EN
extern	MQTT_INFO mqtt_info;
//extern	MQTT_INFO mqtt_info2;
#endif

UINT8 Transport_Open(MQTT_INFO* Mqtt_info, UINT8* des_ip, UINT32 sour_port);
UINT8 Transport_Close(UINT8 S);
//void MQTT_Connect(UINT8 S, char *username,char *password);
void MQTT_Connect(UINT8 S, char* clientID, char *username, char *password, int keepAliveInterval);
void MQTT_Subscribe(UINT8 S, char *topic);
void MQTT_Unsubscribe(UINT8 S, char *topic);
//void MQTT_Publish(UINT8 S, char *topic, char *payload);
void MQTT_Publish(UINT8 S, char *topic, UINT8 *payload, int payloadlen, int qos);
void MQTT_Pingreq(UINT8 S);
void MQTT_Disconnect(UINT8 S);
void CH57xNET_CreatTcpSocket(void);

UINT8 MQTT_Init(MQTT_INFO* Mqtt_info, char* domain_name, UINT8* des_ip, char* clientID, char *username, char *password, char* sublish, int keepAliveInterval);
UINT8 MQTT_Flash_Parameter_Init(MQTT_INFO* Mqtt_info);

void MQTT_SET_SUB_Topic(MQTT_INFO* Mqtt_info, char* topic);
void MQTT_SET_PUB_Topic(MQTT_INFO* Mqtt_info, char* topic);
void MQTT_Receive_Processing(void);
#endif
