#ifndef _GLOBALDEF_H_
#define _GLOBALDEF_H_

#include "../_Lib-3.5/CMSIS/stm32f10x.h"
#include  "./network/nettimer.h"
#include "./network/timeout.h"


extern uint8_t g_bPrintfDebug;
#define UP_DEVICE_TYPE_GATE 0x0101 // 网关A
#define UP_DEVICE_FIRMWARE 0x03 // APP程序

enum {
    LOG_00 = 0x00, //执行错误
    LOG_01 = 0x01, // 执行成功
    LOG_02 = 0x02, //数据模块忙，稍后再试
    LOG_03 = 0x03, // 监控处理器忙，
    LOG_04 = 0x04,  // 监控处理器通讯超时
    LOG_05 = 0x05,  // 查询记录不存在
    LOG_10 = 0x10,  // 监控处理器序列号不存在
    LOG_11 = 0x11, //  密文数据解密错误

    LOG_CRC = 0xC1, // 校验错误
    LOG_XSP = 0xC2, // 处理显示屏的数据
    LOG_NOTAXID = 0xC3, // 报税口号不存在
    LOG_NOGUNID = 0xC4, // 枪号不存在
    LOG_COLL_TIMOUT = 0xC5, //采集器返回超时
    LOG_COLL_ENCPYST = 0xC6, // 采集器返回明文密文状态错误
    LOG_COLL_BUSY    = 0xC7, // 采集判断加油机忙
    LOG_CRC1         = 0xC8, // lora接收检验错误
    LOG_LORA_HEADERROR = 0xC9, // lora接收数据头不是fefe
};


enum {
    UPDATE_PROG_NULL = 0x00,
    UPDATE_PROG_FROM_NET = 0x01,
    UPDATE_PROG_FROM_GATEWAY = 0x02,
};
extern char g_upLinkTopic[64];
extern char g_logupLinkTopic[64];

extern timeout_t g_taxSendTime;
extern timeout_t g_taxDataTime;
extern uint8_t g_curSendCmd;
typedef struct _updata_prog {
    uint32_t sn[64];
    uint32_t appVr[64];
    uint8_t status[64];// 状态码
    uint16_t num;
    uint8_t upCount; // 上报的次数
    uint8_t updateProgFrom; // 升级程序的开源
    timeout_t upStatusOut;
    uint8_t rec0x16; // 接收到16指令，
    OS_TMR update_total_time;
}updateProg;
extern updateProg g_updateProg;
/* LED 灯的记录 */
#define LED_M_QUICK 1
#define LED_M_LOW 5
enum {
    LED_DISP_NULL = 0,
    LED_DISP_VERSION = 1,
    LED_DISP_NOINIT = 2,
    LED_DISP_COLLNUM = 3,
    LED_DISP_CONNET = 4,
    LED_DISP_LORA = 5,
};
#pragma pack(push,1)
typedef union _LED_16_{
    uint16_t status;
    struct {
        uint16_t led01 : 1;
        uint16_t led02 : 1;
        uint16_t led03 : 1;
        uint16_t led04 : 1;
        uint16_t led05 : 1;
        uint16_t led06 : 1;
        uint16_t led07 : 1;
        uint16_t led08 : 1;
        uint16_t led09 : 1;
        uint16_t led10 : 1;
        uint16_t led11 : 1;
        uint16_t led12 : 1;
        uint16_t led13 : 1;
        uint16_t led14 : 1;
        uint16_t led15 : 1;
        uint16_t led16 : 1;
    }__attribute__((packed))led;
}__attribute__((packed))Led16;
#pragma pack(pop)
typedef struct _LED_STATUS_{
    uint8_t ledM; // M灯的情况 快闪还是慢闪
    Led16 led16;
    uint16_t collNum; // 采集器个数
    uint8_t status;  // 灯当前的状态
    uint32_t timer; // 持续时间
}__attribute__((packed)) LedStatus;
extern LedStatus g_ledStatus;
/*时间信息记录*/
typedef struct _CUR_TICK_{
    uint32_t powerTime; // 上电时间
    uint32_t curTime; // 当前时间

}CurTick;
extern CurTick g_curTick;
typedef struct _FIRMWARE_EXPLAIN_{
    uint16_t dd;
    uint8_t ff;
    uint16_t nn;
}__attribute__((packed)) FirmwareExpl;
extern FirmwareExpl g_firmwareExpl;
/*采集器的状态 和软询查每个采集器的次数*/
typedef struct COLL_RUN_MSG_{
    uint8_t checkNum;  // 采集器轮询的次数 超过5次则上报服务器
    uint8_t updateStatus; // 升级的状态码
    int lorastatus;
}CollRunMsg;

enum {
    COLL_STATUS_OFFLINE = 0x00 , // 离线线
    COLL_STATUS_ONLINE = 0x01 , // 在线
};
typedef union _check_gun_{
    uint8_t status[2]; // 枪是否轮询完成
    uint16_t status1;
}checkGunStatus;
typedef struct _gun_status_{
    checkGunStatus gunSta;
}GunStatus;
extern GunStatus g_checkGun[16];

#define UPDATE_COLLECT_TOTALTIME 900000 // 升级总的时间
#define UPDATE_CONTINUE_TIME 300 // 升级续传每条间隔的时候300毫秒
#define UPDATE_REPEAT_TIME  7000 // 接收重传超时的时间 2S
#define UPDATE_READSTATUS_TIME 10000 // 升级完成 到读取升级状态的时间
#define UPDATE_READSTATUS_TIME_GATEWAY 60000 // 升级完成 到读取升级状态的时间

typedef struct _lora_info_{
    uint32_t coll_sn; // 采集器的SN
    uint8_t loraindex; // 所在信道
    uint16_t sendNum; //发送的包的个数
    uint16_t rcvNum; //接收的包的个数
}__attribute__((packed)) loraInfo;

typedef struct _LORA_COLL_MSG_{ // lora信息切换
    uint8_t collNum; // 采集器的个数
    uint8_t step;   // 步骤 第一步：当前信道读取 第二步：切换信道读取， 第三步：
    loraInfo info[16];
    uint16_t lora_rcvCount;
    uint16_t lora_sendCount;
}__attribute__((packed)) LoraCollMsg;
extern LoraCollMsg g_loraCollMsg;
/*运行数据*/
typedef struct _RUN_DATA_{
    uint8_t factory; // 1:英泰  2：拓盛
    uint8_t ballowRead58; // 时间到了，是否允许向采集器读取58指令 0:允许， 1：不允许
    uint8_t bfirstSend0x56; // 是否是上电第一次发送心跳包，1：是第一次 0：不是
    uint8_t bfirstRead0x83; // 第一次读取83指令 1:第一次读取  0：不是
    uint8_t bRead0x58;  // 是否读取0x58指令
    uint8_t bRead1053;
    uint8_t read1053Num;
    uint8_t bReadData; // 可以读取业务数据了
    uint16_t collstatus; // 所有采集器心跳包是否已经读取，按位判断，那位是1那位就读取过
    uint8_t curCollIndex; // 当前采集器的索引
    uint16_t rssi_lora; // lora信息强度
    uint16_t rssi_4G; // 4G信息强度
    uint8_t timeSendStatus; // 第5分钟发送一次状态信息的标志 0：不发送 1：发送
    uint8_t bsendgatewayfirmMsg; // 发送固件信息
    uint8_t daStatus[16][2][8];
    CollRunMsg collrunMsg[16];
    uint8_t bInitNetProc; // 是否创建网络队列
    uint8_t bServerRead58; // 是否是服务器读取58指令
    uint16_t updateDeviceTyp; // 升级类型 0x0101：网关；0x0201；采集器：0x0301:液位仪采集器；0x0401：屏采集器
    uint8_t bUpdate; // 正在升级中
    uint32_t startUpdateTotalTime; // 重传开始时间记录
    uint32_t repeatUpdateTime; // 接收到重传指令型时间记录
    uint32_t readUpdateStatusTime; // 读取升级状态的时间记录
    uint8_t bsendUpdateStatus; // 向服务器发送状态码
    uint8_t bResetUpdate; // 升级完成后，需要上报服务器
    uint8_t bReadMingWenData; // 读取密文的数据
    uint8_t firstReadNum; // 上电第一次按默认时间读取多少次
    uint16_t task_no; // 升级的任务号，给采集使用的
    uint8_t cregStatus;  // 网络注册状态
    uint8_t bchangelora; // 当前要执行切换信道的函数
    uint8_t curloraIndex; //  当前的信息编号
    uint8_t nextlorIndex; //要切换的信道的索引
    uint8_t key1disp; // 按键1 显示lora信道
    uint8_t bInstallFinish; // 安装完成
    uint8_t bUpdateHost;  //是否是主设备  1：网关升级网关时为主设备 2：网关升级采集器时的主设备  其它为从设备，升级时，从设备不处理0x22指令
    uint16_t collerr; // 不是本网关下，出现采集器的个数
    uint8_t bRef12; // 外部电压是5V还是12V 1：12V 0：5V
    uint8_t bNetCmd;
}RunData;
extern RunData g_runData;
typedef struct _DATA_4G_{
    uint8_t flag;  // 重连的次数，根据这个次数，要确定每次重边的时间间隔
    uint8_t bconnect4G; // 是否连接4G
    uint8_t errorTime; // 4G断开的时间 如果断开1小时，则芯片复位重新启动
}Da4G;
extern Da4G g_data4G;
/*采集器固件信息不需要存储到EEPROM中*/
typedef struct COLL_MSG_{
    uint32_t device_sn; // 采集器的版本号
    uint32_t bootloaderVr; // bootloader版本
    uint32_t appVr; // app版本号
    uint32_t resetNum; // 复位次数
    uint8_t resetType; // 最后一次复位类型
    uint32_t runTime; //运行时长
    uint32_t voltage; // 电压
    uint32_t temperature; // 温度
    uint8_t updateStatus; // 升级状态码
    uint8_t uuid[12]; // 芯片ID号
}CollMsg;
/* 网关固件信息存储 这个只有在产测时写入，要程序中不再写入*/
typedef struct _GATEWAY_HARDWARE_MSG_{
    uint8_t bInit; // 是否初始化过
    uint32_t gateway_sn; // 网关的sn
    uint16_t devicType;  // 类型
    uint16_t factoryMsg; // 厂家信息
    uint16_t seqNo ; // 生产批次号
    uint32_t data; // 生产日期
    uint8_t pcbVersion; // 硬件（PCB）版本
    uint32_t sqare; //备用
}__attribute__((packed)) GateHareWareMsg;

#pragma pack(push,1)
typedef union _CONFIG_FLAG_{
    uint8_t value;
    struct {
        uint8_t bConfig_tab : 1; // 是否配置采集器路由表  0位
        uint8_t bConfig_qei : 1; //是否配置编码器  1位
        uint8_t benable_qei : 1; // 是否启用编码器路由表 1位
        uint8_t reserve_01 : 1; // 预留 1位
        uint8_t bConfig_xsp : 1; // 是否配置显示屏
        uint8_t reserve_02 : 3;  // 预留 3位
    }__attribute__((packed))bInit;
}__attribute__((packed))initMsg;
#pragma pack(pop)

/* 网关的固件信息存储*/
typedef struct _GATEWAY_SOFT_MSG_{
    uint8_t configNo; //  配置流水号
    initMsg bInitMsg; // 是否配置过
    uint8_t coll_num; // 此网关对应采集器的数量
    uint16_t time_interval; // 时间轮询
}__attribute__((packed)) GateConfigMsg;
/* 网关的版本信息*/
typedef struct _GATEWAY_VERSION_MSG_{
    uint32_t gate_bootloaderVr; //网关的bootloaderVr
    uint32_t pt_version; // 产测版本
    uint32_t gate_appVr; // appt版本
    uint32_t gate_appVr2; // app2的版本
    uint32_t gate_appVr3; // app3的版本
}__attribute__((packed)) GateVersionMsg;

typedef union _VOLTAGE_{
    uint32_t voltage; // 电压
    float fvoltage;
}voltage;
typedef union _TEMPERATURE_{
   uint32_t temperature; // 温度
   float ftemperature;
}temperature;

typedef struct _GATEWAY_MSG_{
    GateHareWareMsg hardwareMsg; //
    GateConfigMsg configmsg; // 软件信息
    GateVersionMsg verMsg; // 版本信息
    uint32_t gate_resetnum; //复位次数
    uint8_t gate_resetType; //最后一次复位类型
    uint32_t gate_runTime; // 运行时长
    voltage fVol;
    temperature fTemper;
    uint8_t Uuid[12];//UUID
    uint8_t Imei[15]; //IMEI
    uint8_t Iccid1[20];//ICCID1
    uint8_t Iccid2[20];//ICCID2
    uint8_t Iccid3[20];//ICCID3
    uint16_t devicTypeID; // 103 303  这个是读取上来的

}GateWayMsg;
/* mqtt IP地址 端口号*/
typedef struct _MQTT_IP_PORT_{
    uint8_t flag;
    char port[6]; // 端口号
    char ip[32]; //IP地址
    char admin[8]; // 用户名
    char password[16]; // 密码
}__attribute__((packed)) MqttIdPort;

typedef struct _FIRMWARE_MSG_{ // 固件信息存储
    GateWayMsg gatewayMsg; // 网关的信息
    CollMsg collMsg[16];  //采集器固件信息
    MqttIdPort mqttidport; // mqtt的IP地址和端口
}FirmwareMsg;
extern FirmwareMsg g_firmwareMsg; // 网关 采集器固件信息存储
/*第一次上电 读取 0x83指令*/
typedef struct _READ_COLL_CMD_{
    uint8_t nodeCur; // 当前采集器索引
    uint8_t portCur; // 当前报税口索引
    uint8_t checknum[16][2]; // 报税器查询状态
    uint16_t stauts[2]; //  采集器报税口0状态
}ReadCollcmd;
extern ReadCollcmd g_readCmd83;
extern ReadCollcmd g_readCmd58;
extern ReadCollcmd g_readCmd56;
typedef struct _da_83_{
    uint32_t sn;
    uint8_t para;
    uint8_t taxNo;
}__attribute__((packed)) da83;

typedef struct _cmd_info_0x83_{
    da83 da[16];
    uint8_t front;
    uint8_t rear;
    uint8_t bread83;
}__attribute__((packed)) cmdInfo83;
extern cmdInfo83 g_cmdInfo83;

typedef struct _da_comm_queue_info{
    uint8_t type01; // 一级消息类型
    uint16_t type02; // 二级消息类型
    uint8_t da[128];
    uint8_t size;
}__attribute__((packed)) commDa;
#define COMM_QUEUE_SZIE  8
typedef struct _da_comm_queue{
    uint8_t front;
    uint8_t rear;
    commDa data[COMM_QUEUE_SZIE];
}__attribute__((packed))dacommQueue;
extern dacommQueue g_commQueue;
extern void init_comm_queue(void);
extern uint8_t save_comme_queue(uint8_t type1, uint16_t type2, uint8_t *data, uint8_t size);
extern uint16_t read_comm_queue(uint8_t *type1, uint16_t *type2, uint8_t *outda);


enum {
    ENCONDER_NO = 0,
    ENCONDER_EN = 1,
};
typedef struct _encoder_opt_da_{
    uint8_t bhaveEncoder; // 0: 没有编码器 1：带编码器
    uint8_t bEportfinish;  // 此报税口下的枪是否读取完成,等于此报税口下的枪数，则为读取完成
}__attribute__((packed)) EncodeOptDa;
extern EncodeOptDa g_encoderDa;

typedef struct _run_mqtt_data_{
    uint8_t bChangeMqtt; // 1：为切换mqtt 服务器
    uint8_t bChangeSuc; // 0：初始值 1: 切换成功 2： 切换连接失败
    uint8_t connectNum;  // 连接次数
    uint8_t mqttIdlen;
    uint8_t mqttPortlen;
    uint8_t mqttUserlen;
    uint8_t mqttPwdlen;
    MqttIdPort mqttMsg; // mqtt的IP地址和端口
}__attribute__((packed)) MqttRunDa;
extern MqttRunDa g_mqttRunDa;

typedef struct _config_log_data_{
    uint8_t bEnable; //是否开启 0：不开启 1：开启
    uint32_t settimer; // 上报设定的时间
    timeout_t time; // 超时时间
    uint32_t settimer2; // 只返回原始数据
    timeout_t time2; //
    uint8_t status;
    uint8_t collIndex;
    uint8_t taxInddex;
    uint8_t gunIndex;
    uint8_t curportno;
    uint8_t curgunno;

}__attribute__((packed)) LogCfigDa;
extern LogCfigDa g_logCfigDa;

typedef struct _sm4_key_{
    uint8_t flag[12]; // 标识字符
    uint32_t sn; // SN

}__attribute__((packed)) sm4Key;
typedef union _sm4_key_union_{
    uint8_t key[16];
    sm4Key keyda;
}__attribute__((packed)) Sm4Key;
extern Sm4Key g_sm4Key;
extern void get_sm4_key(void);

extern void init_log_info(void);
extern void init_queue(cmdInfo83 *da);
extern uint8_t en_queue_cmd83(cmdInfo83 *da, uint32_t sn, uint8_t para, uint8_t taxNo, uint8_t flag);
extern uint8_t de_queue_cmd83(cmdInfo83 *inda,da83 *outda);
#endif
