#include "gateway_collect.h"
#include "../../User/includes.h"
#include "../network_mgr/net_ctrl.h"
#include "../dev_mgr/taxctrl/tax_ctrl.h"
#include "../tax/tax.h"
#include "../network/uplink.h"
#include "../storage/AT24C128Opt.h"
#include "../network/downlink.h"
#include "../network_mgr/net_proc.h"
#include "me3616.h"
#include "../encode/encodeOpt.h"
#include "../network_mgr/net_ctrl.h"
#include "../network_mgr/sx1268/lora.h"
extern ME3616  air;


//void * lora_queue_mem_calloc_must(void);
//int lora_queue_mem_free(void * p_msg);
//void lora_queue_insert(char *p_msg, uint32_t msg_len);
uint64_t g_checkDa[16][2][8] = {0};
static uint32_t _seq_num[16] ={ 0};
uint8_t log_buff[256] = {0};
/*------------------------------------------------------------------
 *  网关向采集器下发数据 0x57指令
 *  参数：data:发送的数据
 *       len: 发送的数据长度
 *       tax:报税口编号
 *       uart: 串口号
 *       gun: 枪号
 *       porttype:协议类型 1:明文 2：密文
 *       seq: 流水号
 *       id: 设备SN
 *------------------------------------------------------------------*/
//void gateway_collect_cmd_set(uint8_t *data, uint8_t len, uint8_t uart, uint8_t prottype,uint32_t seq,uint32_t id,uint8_t gun)
void gateway_collect_cmd_set(uint8_t *data, uint8_t len,uint8_t coll_index, uint8_t tax, uint8_t uart, uint8_t gun, uint8_t prottype,uint32_t seq,uint32_t id)
{
    char *msg = NULL;
    uint8_t send_buf[128],send_size;
    uint16_t crc = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->seq_no = seq;
    p_msg->type = GATE_COLL_TAX_QUERY;
    p_msg->secondType = 0;
    p_msg->len = len + GATE_COLL_CMD5767_LEN +2;
    p_msg->taxinfo.data.device_sn = id;
    p_msg->taxinfo.data.device_type = 0x0201; // 0x01为报税器
    p_msg->taxinfo.data.coll_no = coll_index;
    p_msg->taxinfo.data.tax_no = tax;
    p_msg->taxinfo.data.gun_msgid = gun;
    p_msg->taxinfo.data.prot_type = prottype;
    p_msg->taxinfo.data.status = 0x00;
    p_msg->taxinfo.data.dataLen = len;

    memcpy(p_msg->taxinfo.data.info, data, len);
    send_size = len + GATE_COLL_HEAD_LEN + GATE_COLL_CMD5767_LEN;

    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.data.info[len] = crc&0xff;
    p_msg->taxinfo.data.info[len+1] = (crc>>8)&0xff;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
    up_send_log_srcdata(send_buf,send_size+2);

}
/*--------------------------------------------------------------------------------
 *  网关向采集器发送 0x56指令
 *  cmd :0x56指令
 *  0x56: 心跳指令
 * ------------------------------------------------------------------------------*/
void gateway_collect_set_cmd0x56(uint8_t cmd,uint8_t curCollIndex,int8_t pIndex,uint32_t device_sn)
{
    char *msg = NULL;
    //static uint32_t seq_num[16] ={ 0};
    uint8_t send_buf[128],send_size,_index = 0;
    uint16_t crc = 0;

    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    if(curCollIndex>0) _index = curCollIndex-1;
    if(_seq_num[_index]>=0xFFFFFFFF) _seq_num[_index] = 0;
    p_msg->seq_no = _seq_num[_index]++;
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->secondType = 0;


    p_msg->type = GATE_COLL_HEART_QUERY;
    p_msg->len =  GATE_COLL_CMD56_LEN + 2;
    send_size = GATE_COLL_HEAD_LEN + GATE_COLL_CMD56_LEN;

    p_msg->taxinfo.comdata.device_sn = device_sn;
    p_msg->taxinfo.comdata.coll_no = curCollIndex;

    p_msg->taxinfo.coll56da.devSn = device_sn;
    p_msg->taxinfo.coll56da.collIndex = curCollIndex;
    p_msg->taxinfo.coll56da.pIndex   =  pIndex;
    p_msg->taxinfo.coll56da.reserve1 = 0x00;
    p_msg->taxinfo.coll56da.reserve2 = 0x00;


    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.coll56da.info[0] = crc&0xff;
    p_msg->taxinfo.coll56da.info[1] = (crc>>8)&0xff;


    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }

    up_send_log_srcdata(send_buf,send_size+2);

}
/*--------------------------------------------------------------------------------
 *  网关向采集器发送 0x58指令
 *  cmd :0x58指令
 *  0x58: 固件信息上传指令
 * ------------------------------------------------------------------------------*/
void gateway_collect_set_cmd0x58(uint8_t cmd,uint8_t curCollIndex,uint32_t device_sn)
{
    char *msg = NULL;
    //static uint32_t seq_num[16] ={ 0};
    uint8_t send_buf[128],send_size,_index = 0;
    uint16_t crc = 0;

    gateway_collect_com_t *p_msg = NULL;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    if(curCollIndex>0) _index = curCollIndex-1;
    if(_seq_num[_index]>=0xFFFFFFFF) _seq_num[_index] = 0;
    p_msg->seq_no = _seq_num[_index]++;
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->secondType = 0;

    p_msg->type = GATE_COLL_FIRMMSG_QUERY;
    p_msg->len =  GATE_COLL_CMD58_LEN + 2;
    send_size = GATE_COLL_HEAD_LEN + GATE_COLL_CMD58_LEN;

    p_msg->taxinfo.comdata.device_sn = device_sn;
    p_msg->taxinfo.comdata.coll_no = curCollIndex;

    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.comdata.info[0] = crc&0xff;
    p_msg->taxinfo.comdata.info[1] = (crc>>8)&0xff;


    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
    if(cmd==0x56)
        up_send_log_srcdata(send_buf,send_size+2);

}

/*--------------------------------------------------------------------------------
 *  网关向采集器发送 0x59
 *  cmd :0x59 指令
 *  通知采集器设备重新启动
 * ------------------------------------------------------------------------------*/
void gateway_collect_set_cmd0x59(uint8_t curCollIndex,uint32_t device_sn)
{
    char *msg = NULL;
    //static uint32_t seq_num[16] ={ 0};
    uint8_t send_buf[128],send_size,_index=0;
    uint16_t crc = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    if(curCollIndex>0) _index = curCollIndex-1;
    if(_seq_num[_index]>=0xFFFFFFFF) _seq_num[_index] = 0;
    p_msg->seq_no = _seq_num[_index]++;
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->secondType = 0;
    p_msg->type = COLL_GATE_RESTART_QUERY;
    p_msg->len =  GATE_COLL_CMD59_LEN + 2;
    send_size = GATE_COLL_HEAD_LEN + GATE_COLL_CMD59_LEN;

    p_msg->taxinfo.comdata.device_sn = device_sn;
    p_msg->taxinfo.comdata.coll_no = curCollIndex;

    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.comdata.info[0] = crc&0xff;
    p_msg->taxinfo.comdata.info[1] = (crc>>8)&0xff;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
}
/*--------------------------------------------------------------------------------
 *  网关向采集器发送 0x5D
 *  cmd :0x5D 指令
 *  通知采集器设备重新启动
 * ------------------------------------------------------------------------------*/
void gateway_collect_set_cmd0x5D(uint8_t curCollIndex,uint32_t device_sn,uint16_t targettype,uint8_t cmd)
{
    char *msg = NULL;
    //static uint32_t seq_num[16] ={ 0};
    uint8_t send_buf[128],send_size,_index =0;
    uint16_t crc = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    if(curCollIndex>0) _index = curCollIndex-1;
    if(_seq_num[_index]>=0xFFFFFFFF) _seq_num[_index] = 0;
    p_msg->seq_no = _seq_num[_index]++;
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->secondType = 0;
    p_msg->type = COLL_GATE_RESTART_5D;
    p_msg->len =  GATE_COLL_CMD5D_LEN + 2;
    send_size = GATE_COLL_HEAD_LEN + GATE_COLL_CMD5D_LEN;

    p_msg->taxinfo.da5D.device_sn = device_sn;
    p_msg->taxinfo.da5D.coll_no = curCollIndex;
    p_msg->taxinfo.da5D.targettype = targettype;
    p_msg->taxinfo.da5D.cmd = cmd;
    p_msg->taxinfo.da5D.reserve = 0;
    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.da5D.info[0] = crc&0xff;
    p_msg->taxinfo.da5D.info[1] = (crc>>8)&0xff;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
}
/*--------------------------------------------------------------------------------
 *  网关向采集器发送 0x5B
 *  cmd :0x5B 指令
 *  通知采集器设备切换信道
 * ------------------------------------------------------------------------------*/
void gateway_collect_set_cmd0x5B(uint8_t curCollIndex,uint32_t device_sn,uint8_t index,uint8_t bpaEnable)
{
    char *msg = NULL;
    //static uint32_t seq_num[16] ={ 0};
    uint8_t send_buf[128],send_size,_index=0;
    uint16_t crc = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    if(curCollIndex>0) _index = curCollIndex -1;
    if(_seq_num[_index]>=0xFFFFFFFF) _seq_num[_index] = 0;
    p_msg->seq_no = _seq_num[_index]++;
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->secondType = 0;
    p_msg->type = COLL_GATE_CHANGE_LORAPA;
    p_msg->len =  GATE_COLL_CMD5B_LEN + 2;
    send_size = GATE_COLL_HEAD_LEN + GATE_COLL_CMD5B_LEN;

    p_msg->taxinfo.taxLora.device_sn = device_sn;
    p_msg->taxinfo.taxLora.coll_no = curCollIndex;
    p_msg->taxinfo.taxLora.paEnable = bpaEnable;
    p_msg->taxinfo.taxLora.loraPaindex = index;
    p_msg->taxinfo.taxLora.freq = 0;
    p_msg->taxinfo.taxLora.power = 0;
    p_msg->taxinfo.taxLora.bandwidth = 0;
    p_msg->taxinfo.taxLora.spreadingfactor = 0;
    p_msg->taxinfo.taxLora.codingrate = 0;
    p_msg->taxinfo.taxLora.preambleLen = 0;

    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.taxLora.info[0] = crc&0xff;
    p_msg->taxinfo.taxLora.info[1] = (crc>>8)&0xff;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
}
/*------------------------------------------------------------------
 *  网关向采集器下发数据 0x5C指令
 *  参数：data:发送的数据
 *       len: 发送的数据长度
 *       tax:报税口编号
 *       gun: 枪号
 *       seq: 流水号
 *       id: 设备SN
 *------------------------------------------------------------------*/
void gateway_collect_set_cmd0x5C(uint8_t *data, uint8_t len,uint8_t coll_index, uint8_t tax, uint8_t gun,uint32_t seq,uint32_t id)
{
    char *msg = NULL;
    uint8_t send_buf[128],send_size;
    uint16_t crc = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    memset(send_buf,0,sizeof(send_buf));

    p_msg->frame_header = 0xfefe;// 帧头
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->seq_no = seq;
    p_msg->type = GATE_COLL_ENCODER_QUERY;
    p_msg->secondType = 0;
    p_msg->len = len + GATE_COLL_CMD5C_LEN +2;
    p_msg->taxinfo.encoderda.device_sn = id;
    p_msg->taxinfo.encoderda.device_type = 0x0501; // 0x0501为编码器数据
    p_msg->taxinfo.encoderda.coll_no = coll_index;
    p_msg->taxinfo.encoderda.tax_no = tax;
    p_msg->taxinfo.encoderda.gun_msgid = gun;
    p_msg->taxinfo.encoderda.prot_type = 0;
    p_msg->taxinfo.encoderda.status = 0x00;
    p_msg->taxinfo.encoderda.dataLen = len;

    memcpy(p_msg->taxinfo.data.info, data, len);
    send_size = len + GATE_COLL_HEAD_LEN + GATE_COLL_CMD5C_LEN;

    crc = _crc16_get((uint8_t *)p_msg,send_size);
    p_msg->taxinfo.data.info[len] = crc&0xff;
    p_msg->taxinfo.data.info[len+1] = (crc>>8)&0xff;

   // data_dump("5C send:", (uint8_t *)send_buf, send_size+2);
    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, send_buf, send_size+2);
        lora_queue_insert((char *)msg, send_size+2);
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
    up_send_log_srcdata(send_buf,send_size+2);


}
/*----------------------------------------------------------------------------------
 *  透传指令 0x01 --- 0x1052
 * ---------------------------------------------------------------------------------*/
void gateway_collect_cmd_0x01_0x1052(uint8_t *data, uint16_t size)
{
    char *msg = NULL;
    uint8_t send_buf[128];
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t *)send_buf;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, data, size);
        lora_queue_insert((char *)msg, size);
        //data_dump("send 0x01-0x1052:",data,size);
        //printf("send 0x01-0x1052:\r\n");
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
}
/*----------------------------------------------------------------------------------
 *  组成编码器与抬枪信号正反序的数据
 * ---------------------------------------------------------------------------------*/
void create_0x01_0x1053(uint8_t *outdata,uint16_t *len,uint16_t rcvType,uint32_t rcvSn,uint16_t targetType,uint16_t targetSn,uint8_t optType, uint8_t cmdType,uint16_t optval)
{
    sys1053_2053 *msg = NULL;
    uint16_t crc = 0;
    uint8_t send_size = 0;
    gateway_collect_com_t *p_msg;

    p_msg = (gateway_collect_com_t*)outdata;
    p_msg->frame_header = 0xfefe;// 帧头
    p_msg->proto_ver = GATE_COLL_PROTOTYPE;
    p_msg->seq_no = 0;
    p_msg->type = 0x01;
    p_msg->secondType = 0x1053;
    p_msg->len = sizeof(sys1053_2053) +2;



    msg = (sys1053_2053*)(outdata+12);

    msg->firstLevelType = DEVICE_GATEWAY;
    msg->firstLevelSn   = downlink_config.gateway_id;
    msg->rcvDevType     = rcvType;
    msg->rcvDevSn       = rcvSn;
    msg->targetDevType  = targetType;
    msg->targetDevSn    = targetSn;
    msg->reserve        = 0;
    msg->optType        = optType;
    msg->cmdType        = cmdType;
    msg->cmdVal         = optval;
    msg->reserve01      = 0x00;

    send_size =  sizeof(sys1053_2053);
    crc = _crc16_get((uint8_t *)p_msg,send_size+GATE_COLL_HEAD_LEN);
    p_msg->taxinfo.info[send_size] = crc&0xff;
    p_msg->taxinfo.info[send_size+1] = (crc>>8)&0xff;


    *len = GATE_COLL_HEAD_LEN + send_size + 2;
    return;
}

/*----------------------------------------------------------------------------------
 *  设置编码器与抬枪信号正反序 0x01 --- 0x1053
 *   type: 0: 需要组数据  1： 服务器下发的，不用组数据，可直接下发
 * ---------------------------------------------------------------------------------*/
void gateway_collect_cmd_0x01_0x1053(uint8_t *data, uint16_t size)
{
    char *msg = NULL;
    uint8_t send_buf[128];
    gateway_collect_com_t *p_msg;


    memset(send_buf,0,sizeof(send_buf));

    p_msg = (gateway_collect_com_t *)send_buf;

    msg = (char *)lora_queue_mem_calloc_must();
    if(msg) {
        memcpy(msg, data, size);
        lora_queue_insert((char *)msg, size);
        data_dump("send 0x01-0x1053:",data,size);
        //printf("send 0x01-0x1052:\r\n");
    }
    else
    {
        lora_queue_mem_free(p_msg);
    }
}
static uint16_t _crc_get_gw(uint8_t *data, uint8_t size)
{
    uint8_t i, crc = 0;

    for(i = 0;i < size;i++){
        crc ^=data[i];
    }

    return crc;
}
/*网关向报税口下发的数据协议*/
int tax_cmd_set(uint8_t cmd, uint8_t *parm, uint8_t size, void *puser)
{
	int send_len;//ret = -1,
	uint8_t send_buf[64], *p_crc,  *fparm;//crc,
	tTaxCommFrame_t *p_tax_tx = (tTaxCommFrame_t *)send_buf;

	memset(send_buf, 0, sizeof(send_buf));
	p_crc = &send_buf[sizeof(tTaxCommFrame_t) + size];
	p_tax_tx->fhead = 0xbb;
	p_tax_tx->flen = 3+size;	//长度码为命令码、帧号、参数和校验码的字节数之和
	p_tax_tx->findex = 0xff; 	//帧号标识本帧的特征信息，帧号OFFH表示单帧命令;
	p_tax_tx->fcmd = cmd;
	fparm = &send_buf[sizeof(tTaxCommFrame_t)];
	memcpy(fparm, parm, size);

	//caculate crc val;
	*p_crc = _crc_get_gw(&p_tax_tx->findex, p_tax_tx->flen-1);//校验码为帧号、命令码和参数逐字节的逻辑和

	//send and rcv;
//	data_dump("tax send", (uint8_t *)p_tax_tx, p_tax_tx->flen + 2);
//	uart_msg_send(uart, (char *)p_tax_tx, p_tax_tx->flen + 2);
	send_len = p_tax_tx->flen + 2;
	memcpy(puser,p_tax_tx,send_len);

	return send_len;
}
/*-----------------------------------------------------------------------------------
 * 处理0x8C 指令
 * ---------------------------------------------------------------------------------*/
int tax_cmd_set_0x8C(uint8_t cmd,uint8_t *parm, uint8_t size, void *puser)
{
    int send_len;
    uint8_t send_buf[64], *p_crc, *fparm;

    tTaxCommFrame_t *p_tax_tx = (tTaxCommFrame_t*)send_buf;

    memset(send_buf,0,sizeof(send_buf));
    p_crc = &send_buf[sizeof(tTaxCommFrame_t)+size];
    p_tax_tx->fhead = 0xbb;
    p_tax_tx->flen = 3 + size;
    p_tax_tx->fcmd = cmd;
    p_tax_tx->findex = 0xFF;

    fparm = &send_buf[sizeof(tTaxCommFrame_t)];
    memcpy(fparm, parm, size);
    *p_crc = _crc_get_gw(&p_tax_tx->findex, p_tax_tx->flen-1);//校验码为帧号、命令码和参数逐字节的逻辑和

    data_dump("tax send", (uint8_t *)p_tax_tx, p_tax_tx->flen + 2);
    send_len = p_tax_tx->flen + 2;
    memcpy(puser,p_tax_tx,send_len);

    return send_len;
}


static uint16_t _crc_get1(uint8_t *data, uint8_t size)
{
	uint8_t i, crc = 0;

	for(i = 0;i < size;i++){
		crc ^=data[i];
	}

	return crc;
}

extern int tax_0x83_anaylse(void *puser, uint8_t *data, uint8_t data_len);
extern int tax_0x86_anaylse(void *puser, uint8_t *data, uint8_t data_len);
extern int tax_0x89_anaylse(void *puser, uint8_t *data, uint8_t data_len);
//明文接收数据处理
int tax_rcv_analyze(uint8_t *data,void *puser)
{
    int ret = 1;//, rcv_size = 0;
    uint8_t *p_crc, crc, *fparm;//,hbit = 0;
    tTaxCommFrame_t *p_tax_rx;
    p_tax_rx = (tTaxCommFrame_t *)data;
    crc = _crc_get1(&p_tax_rx->findex, p_tax_rx->flen-1);
    p_crc = &data[p_tax_rx->flen + 1];

    if((p_tax_rx->fhead == 0xBB)&&(crc == *p_crc)) {
        if((p_tax_rx->findex != 0xFF)  ){ // 帧号
            if((p_tax_rx->findex&0x80) != 0x80) return ret;
        }
        if(p_tax_rx->flen<8) return ret; // 长度小于8个，为帧格式错误
        fparm = &data[sizeof(tTaxCommFrame_t)];
        switch(p_tax_rx->fcmd)
        {
        case 0x83:
            tax_0x83_anaylse(puser,fparm,p_tax_rx->flen-3);
            ret = 0x83;
            return ret;
//            break;
        case 0x86:
            if(data[4] == 0x00) return ret;
            tax_0x86_anaylse(puser,fparm,p_tax_rx->flen-3);
            ret = 0x86;
            return ret;
//            break;
        case 0x89:
            if(data[4] == 0x00) return ret;
            tax_0x89_anaylse(puser,fparm,p_tax_rx->flen-3);
            ret = 0x89;
            return ret;
//            break;
        }

    }
    return ret;
}

/////////////////////////////////////////////////////////////////

//密文数据
//extern uint16_t _crc16_get(uint8_t *_buff,uint32_t _len);
extern int _ytsf_data_code(uint8_t *buff, uint8_t *len);
extern int _ytsf_data_decode(uint8_t *buff, uint8_t *len);

//密文发送数据参数部分
int ytsf_cmd_set(uint8_t port, uint8_t cmd, uint8_t *parm, uint8_t size, void * puser)
{/* 帧头(1)+帧长度(1)+帧号(1)+端口号(1)+命令码(1)+参数[n]+CRC校验码[2] */
//	int ret = -1;
	uint8_t  send_buf[128], send_size, *fparm;
	uint16_t *p_crc;//, crc;
	tYTSFCommFrame_t *p_tax_tx = (tYTSFCommFrame_t *)send_buf;

	memset(send_buf, 0, sizeof(send_buf));
	p_crc = (uint16_t *)&send_buf[sizeof(tYTSFCommFrame_t) + size];
	p_tax_tx->fhead = 0xbb;
	p_tax_tx->flen = 5+size;	//长度码为命令码、帧号、参数和校验码的字节数之和
	p_tax_tx->findex = 0x81; 	//帧号标识本帧的特征信息，帧号OFFH表示单帧命令;
	p_tax_tx->fport = port;
	p_tax_tx->fcmd = cmd;
	fparm = &send_buf[sizeof(tYTSFCommFrame_t)];
	memcpy(fparm, parm, size);
        //printf("======================port = %d\r\n",port);
	//caculate crc val;
	*p_crc = _crc16_get(&p_tax_tx->fhead, p_tax_tx->flen);//校验码为帧号、命令码和参数逐字节的逻辑和
	*p_crc = htons(*p_crc);
	send_size = p_tax_tx->flen + 2;
	_ytsf_data_code(send_buf, &send_size);	/* 编码发送 */

	memcpy(puser,p_tax_tx,send_size);

	return send_size;
}

//密文下发数据
int ytsf_send_cmd(uint8_t cmd, uint8_t info_type, uint8_t node, uint8_t port, uint8_t gun)
{
    int ret = -1;
    uint8_t para[16] = {0};
    uint8_t send_buf[64],send_len,taxType;
    int uart=0,gun_num=0,tax = 0;
    uint32_t seq_num = 0,id = 0;

    seq_num = nodeConf.taxconf[node].port[port].gun[gun].seq_no;
   // uart = nodeConf.taxconf[node].port[port].uart;
    gun_num = downlink_config.collect_conf[node].tax_conf[port].gunid[gun];
    tax = downlink_config.collect_conf[node].tax_conf[port].tax_id;
    //	id = nodeConf.taxconf[node].device_id;
    id = downlink_config.collect_conf[node].collect_no;
    taxType = nodeConf.taxconf[node].port[port].taxType;

    g_logCfigDa.curportno = tax;
    g_logCfigDa.curgunno = gun_num;
    switch(cmd)
    {
    case 0xA1:
        if(info_type == 0x11)//读当次加油信息
        {
            para[0] = 0x11;
            para[1] = gun_num-1;
            memset(&para[2], 0, 4);
           // memcpy(&para[6], gateway_read.collect_read[node].tax_read[port].monitor_serino, 5);
            memcpy(&para[6], downlink_config.collect_conf[node].tax_conf[port].monitor_serino, 5);
            send_len = ytsf_cmd_set(port,0xA1,para,11,send_buf);
            //gateway_collect_cmd_set(send_buf,send_len,uart,CIPHERTEXT,seq_num,id,gun);
            gateway_collect_cmd_set(send_buf,send_len,node,tax,uart,gun_num,taxType,seq_num,id);
        }
        else if(info_type == 0x14)//读总累计
        {
            para[0] = 0x14;
            para[1] = gun_num-1;
            memset(&para[2], 0, 4);
            //memcpy(&para[6], gateway_read.collect_read[node].tax_read[port].monitor_serino, 5);
            memcpy(&para[6], downlink_config.collect_conf[node].tax_conf[port].monitor_serino, 5);
            send_len = ytsf_cmd_set(port,0xA1,para,11,send_buf);
            //gateway_collect_cmd_set(send_buf,send_len,uart,CIPHERTEXT,seq_num,id,gun);
            gateway_collect_cmd_set(send_buf,send_len,node,tax,uart,gun_num,taxType,seq_num,id);
        }
    break;

    case 0xA2:
        if(info_type == 0x00) //读监控序列号
        {
            para[0] = 0;
            para[1] = 0;
            memset(para+2,0,6);
            send_len = ytsf_cmd_set(port,0xA2,para,8,send_buf);
            //gateway_collect_cmd_set(send_buf,send_len,uart,CIPHERTEXT,seq_num,id,gun);
            gateway_collect_cmd_set(send_buf,send_len,node,tax,uart,gun_num,taxType,seq_num,id);
        }
        break;
    }
    return ret;
}

extern int ytsf_0xa2_0x00_anaylse(void *puser, uint8_t *data, uint8_t data_len);
extern int ytsf_0xa1_0x11_anaylse(void *puser, uint8_t *data, uint8_t data_len);
extern int ytsf_0xa1_0x14_anaylse(void *puser, uint8_t *data, uint8_t data_len);
/*----------------------------------------------------------------------
 * 密文接收数据处理
 *  result:读取结果
 *  0x00:执行错误  0x01: 执行成功  0x02:数据模块忙，稍息再试 0x03:监控微处理器忙，稍后再试
 *  0x04:监控微处理器通讯超时，超时时间设定为10S
 *  0x05:查询的纪录不存在
 *  0x10: 监控微处理器序列号不存在
 *  0x11: 密文数据解密错误
 */
int ytsf_rcv_analyze(uint8_t *data,uint8_t len,void *puser, uint8_t *port)
{
    int ret = 1;
    uint8_t  *fparm;
    uint16_t *p_crc, crc;
    uint8_t result = 0x01;

    tYTSFCommFrame_t *p_tax_rx = (tYTSFCommFrame_t *)data;

    _ytsf_data_decode(data, &len);	/* 接收解码 */
    crc = _crc16_get(&p_tax_rx->fhead, p_tax_rx->flen);
    p_crc = (uint16_t *)&data[p_tax_rx->flen];
    *p_crc = ntohs(*p_crc);
    if(p_tax_rx->fhead == 0xBB && crc == *p_crc)
    {
        result = *(data+7); // 读取结果
        if(result != 0x01 ) return result;
        *port = p_tax_rx->fport;
        fparm = &data[sizeof(tYTSFCommFrame_t)];
        switch(p_tax_rx->fcmd)
        {
            case 0xA1:
                if(*fparm == 0x11)
                {
                    ret = ytsf_0xa1_0x11_anaylse(puser, fparm, p_tax_rx->flen-5);
                    if(ret == 0) ret = YTSF_0XA1_0X11;
                    else ret = 0;
                }
                else if(*fparm == 0x14)
                {
                    ret = ytsf_0xa1_0x14_anaylse(puser, fparm, p_tax_rx->flen-5);
                    if(ret == 0) ret = YTSF_0XA1_0X14;
                    else ret = 0;
                }
            break;
            case 0xA2:
                if(*fparm == 0x00)
                {
                    ytsf_0xa2_0x00_anaylse(puser, fparm, p_tax_rx->flen-5);
                    ret = YTSF_0XA2_0X00;
                }
            break;
        }
    }

	return ret;

}
/*-----------------------------------------------------------------------------
 *  错误日志上报
 * -----------------------------------------------------------------------------*/
void up_send_log_err(uint16_t sendcmd, uint8_t type,uint8_t node,uint8_t port,uint8_t gun,uint32_t id,uint8_t cmd,uint8_t err)
{
     //uint8_t send_buf[128] = {0};
    uint8_t send_len;

    // if((err&LOG_COLL_XSP_ERR) != LOG_COLL_XSP_ERR){
        if(timeout_isOut(&g_logCfigDa.time) == 1) return;
    // }

      memset(log_buff,0,256);
     uplink_tax_log_da(log_buff,&send_len,type,node,port,gun,id,cmd,err);
     tax_net_send_log(log_buff,send_len);
     return;

}
uint8_t *hex_to_ascii(uint8_t *str, uint32_t len)
{
//    uint8_t *hex_buf = str;
//    for (int i = 0; i < len; i++)
//    {
//        sprintf(&data[i * 2], "%02X", hex_buf[i]);
//    }
//    return (uint8_t *)data;
	return 0;
}
/*-----------------------------------------------------------------------------
 *  错误日志上报 （原始数据）
 * -----------------------------------------------------------------------------*/
void up_send_log_srcdata(uint8_t *data,uint16_t len)
{
     //uint8_t send_buf[256] = {0};
     uint8_t i=0;
     uint16_t temlen = 0,send_len;
    if(g_logCfigDa.bEnable == 0) return;
    if(timeout_isOut(&g_logCfigDa.time2) == 1) return;

    memset(log_buff,0,256);
    sprintf((char*)log_buff,"|%01d|%02x|%02x|",nodeConf.nodeIndex,g_logCfigDa.curportno<<4|g_logCfigDa.curgunno,g_curSendCmd); //采集器索引 报税号枪号  指令
    temlen = strlen((char*)log_buff);

    if(data[0] == 0xFE) {
        for(i=0;i<len;i++){
            sprintf((char*)(&log_buff[temlen+i*2]),"%02x",data[i]);
        }
        send_len = temlen +(len)*2;
    }
    else {
        memcpy(&log_buff[temlen],data,len);
        send_len = temlen + len;
    }
  //  printf("curgun = %d, curport = %d, cindex= %d statu = %x\r\n",g_logCfigDa.curgunno,g_logCfigDa.curportno,g_logCfigDa.collIndex,g_logCfigDa.status);
    switch (g_logCfigDa.status){
    case 0x80:
        tax_net_send_log(log_buff,send_len);
        break;
    case 0x81: // 指定的采集器
        if(g_logCfigDa.collIndex == nodeConf.nodeIndex)
            tax_net_send_log(log_buff,send_len);
        break;
    case 0x83: // 指定到某个采集器的某个报税口
        if(g_logCfigDa.collIndex == nodeConf.nodeIndex){
           if(g_logCfigDa.curportno == g_logCfigDa.taxInddex)
               tax_net_send_log(log_buff,send_len);
        }
        break;
    case 0x87: // 指定到某个采集器的某个报税口的某个枪
        if(g_logCfigDa.collIndex == nodeConf.nodeIndex && g_logCfigDa.curportno == g_logCfigDa.taxInddex){
           if(g_logCfigDa.gunIndex == g_logCfigDa.curgunno)
               tax_net_send_log(log_buff,send_len);
        }
        break;
    }

     return;

}
/////////////////////////////////////////////////////////////////
/*解析采集器的数据信息 0x67指令*/
////////////////////////////////////////////////////////////////////////////////
int collect_rcv_analyze0x67(uint8_t *data, uint8_t len)
{
    int ret = 1,tempret = 0;
    uint8_t send_buf[128],send_len;
    uint8_t taxType = 0;
    uint16_t fcrc, crc;
    uint8_t gun_buf[128];
    uint8_t node=0,port=0,gun=0;
    uint8_t port_temp = 0;
    int lorastatus;
//    int i=0;
    uint32_t sn = 0,seqno=0;
    uint64_t tempDa = 0xFFFFFFFFFFFFFFFF;
    gun_info_t *p_gun = NULL;
    tax_info_t *p_tax = NULL;



    gateway_collect_com_t *p_tax_tx = (gateway_collect_com_t *)data;//Lora接收数据
    memset(send_buf,0,sizeof(send_buf));

    up_send_log_srcdata(data,len-2);


    crc = _crc16_get((uint8_t*)data,p_tax_tx->len+GATE_COLL_HEAD_LEN-2);// len-2);
    fcrc = data[p_tax_tx->len+GATE_COLL_HEAD_LEN-1];
    fcrc = (fcrc<<8)|data[p_tax_tx->len+GATE_COLL_HEAD_LEN-2];

    if(p_tax_tx->frame_header!=0xfefe) { goto GATEWAY_COLLECT_END;} //数据头不对则返回
    node = read_collect_index(p_tax_tx->taxinfo.data.device_sn);
    if((node == 0xFF) || (node>=downlink_config.collect_num)) {goto GATEWAY_COLLECT_END;}
    g_loraCollMsg.lora_rcvCount++;
    g_loraCollMsg.info[node].rcvNum++;
   // printf("接收 loraRecv= %d,采集(%d)接收：%d\r\n",g_loraCollMsg.lora_rcvCount,node,g_loraCollMsg.info[node].rcvNum);
    lorastatus = (int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN+1);
    lorastatus = (lorastatus<<8) | ((int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN));
    g_runData.collrunMsg[node].lorastatus =lorastatus;
    g_runData.collrunMsg[node].checkNum = 0;
    if(fcrc != crc ){
        printf("cmd0x67: crc error\r\n");
       up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,0,0,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_CRC);
        goto GATEWAY_COLLECT_END;
    } //校验位不对则返回



    if(p_tax_tx->taxinfo.data.device_type == 0x02){ // 处理显示屏的数据
        up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,0,0,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_XSP);
        goto GATEWAY_COLLECT_END;
    }

    port = read_tax_index(node,p_tax_tx->taxinfo.data.tax_no); //查询报税口编号
    if(port == 0xFF) {
       up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,0,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_NOTAXID);
        goto GATEWAY_COLLECT_END;
    }


    gun = read_gun_index(node,port,p_tax_tx->taxinfo.data.gun_msgid);
    if(gun == 0xFF) {
        up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,p_tax_tx->taxinfo.data.gun_msgid,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_NOGUNID);
        goto GATEWAY_COLLECT_END;
    }

    downlink_config.collect_conf[node].collect_status = COLL_STATUS_ONLINE; // 采集器在线状态
    sn = downlink_config.collect_conf[node].collect_no;
    seqno = nodeConf.taxconf[node].port[port].gun[gun].seq_no;
    //prot_type = downlink_config.collect_conf[node].tax_type;
    taxType = nodeConf.taxconf[node].port[port].taxType;
    if(p_tax_tx->taxinfo.data.status==2){
        printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,0x02,seqno,taxType);
        downlink_config.collect_conf[node].tax_conf[port].status = 0;
        up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,p_tax_tx->taxinfo.data.gun_msgid,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_COLL_TIMOUT);
        if(nodeConf.taxconf[node].port[port].gun[gun].gLpState == TAX_GUN_LP_STATE_86){
            nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_CH;
        }
        goto GATEWAY_COLLECT_END;
    }
    else if(p_tax_tx->taxinfo.data.status==3){ //重新去读取83指令
        printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,0x03,seqno,taxType);
        up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,p_tax_tx->taxinfo.data.gun_msgid,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_COLL_ENCPYST);
        nodeConf.taxconf[node].port[port].taxType &= 0xF0;
        goto GATEWAY_COLLECT_END;
    }
    else if(p_tax_tx->taxinfo.data.status == 0x06) { //  采集器判断的加油机忙
        printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,0x06,seqno,taxType);
        up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,p_tax_tx->taxinfo.data.gun_msgid,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,LOG_COLL_BUSY);
        if(nodeConf.taxconf[node].port[port].gun[gun].gLpState == TAX_GUN_LP_STATE_86){
            nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_CH;
        }
        goto GATEWAY_COLLECT_END;
    }


    //prot_type = p_tax_tx->taxinfo.data.prot_type;
    downlink_config.collect_conf[node].tax_conf[port].status = 1; // 报税口在线

    if(((taxType&PLAINTEXT)   == PLAINTEXT)) {///明文
        ret = tax_rcv_analyze((uint8_t *)p_tax_tx->taxinfo.data.info,gun_buf);//解析Lora接收的税控口数据部分
        if(ret == 0x86 || ret == 0x89)
        {
            printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,ret,seqno,taxType);
            if(ret == 0x89){
                memset(&rcv_data_temp,0,sizeof(rcv_data_temp_t));
            }
            p_gun = (gun_info_t *)gun_buf;
            if(rcv_data_temp.rcv_no == 0)//接收的第一组数据
            {
                rcv_data_temp.prev_collect = node;
                rcv_data_temp.prev_tax = port;
                rcv_data_temp.prev_gun = gun;
                rcv_data_temp.rcv_no = 1;
                rcv_data_temp.prev_seq = p_tax_tx->seq_no;
                if(ret == 0x86)
                {
                    rcv_data_temp.unit_price = p_gun->last_unit_price;
                    rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                    rcv_data_temp.price = p_gun->last_price;
                    rcv_data_temp.time_day = p_gun->time_day;
                    rcv_data_temp.time_hour = p_gun->time_hour;
                    rcv_data_temp.time_minute = p_gun->time_minute;
                }
                else if(ret == 0x89)
                {
                    rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                    rcv_data_temp.total_price = p_gun->total_price;
                }
              //  printf("ming wen - step1\r\n");
            }
            else //接收的第二组数据
            {
                if(rcv_data_temp.prev_collect == node && rcv_data_temp.prev_tax == port && \
                rcv_data_temp.prev_gun == gun && rcv_data_temp.prev_seq == p_tax_tx->seq_no) //采集器、报税口、枪号、流水号全部相同，认为是同一组数据
                {
                  //  printf("ming wen - step2\r\n");
                    rcv_data_temp.rcv_no = 0;
                    if(ret == 0x86)
                    {
                        rcv_data_temp.unit_price = p_gun->last_unit_price;
                        rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                        rcv_data_temp.price = p_gun->last_price;
                        rcv_data_temp.time_day = p_gun->time_day;
                        rcv_data_temp.time_hour = p_gun->time_hour;
                        rcv_data_temp.time_minute = p_gun->time_minute;
                    }
                    else if(ret == 0x89)
                    {
                        rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                        rcv_data_temp.total_price = p_gun->total_price;
                    }
                    tempDa = rcv_data_temp.unit_price+rcv_data_temp.oil_volume+rcv_data_temp.price+rcv_data_temp.total_oil_volume + rcv_data_temp.total_price;
                    if((downlink_config.bInstallFinish==INSTALL_5A) ||((g_checkDa[node][port][gun]^tempDa) != 0) ){ // 去掉重复数据，重复的数据不上报服务器
                        g_checkDa[node][port][gun]=tempDa;
                        uplink_tax_comb(send_buf,&send_len,node,port,gun,p_tax_tx->seq_no);//向服务器上传数据的参数部分
                        rcv_data_temp.unit_price = 0;
                        rcv_data_temp.oil_volume = 0;
                        rcv_data_temp.price = 0;
                        rcv_data_temp.total_oil_volume = 0;
                        rcv_data_temp.total_price = 0;
                        tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,COLL_TAX_DA_CMD_UP); //向服务器上传数据的完整数据，并通过mqtt发送
                        g_runData.daStatus[node][port][gun] = 0;
                    }
                    else { // 重复数据2分钟上传一次
                        if(g_runData.daStatus[node][port][gun]>=TAX_REPEAD_DATA){
                            uplink_tax_comb(send_buf,&send_len,node,port,gun,p_tax_tx->seq_no);//向服务器上传数据的参数部分
                            rcv_data_temp.unit_price = 0;
                            rcv_data_temp.oil_volume = 0;
                            rcv_data_temp.price = 0;
                            rcv_data_temp.total_oil_volume = 0;
                            rcv_data_temp.total_price = 0;
                            tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,COLL_TAX_DA_CMD_UP); //向服务器上传数据的完整数据，并通过mqtt发送
                            g_runData.daStatus[node][port][gun] = 0;
                          //  printf("明文 ：重复数据2分钟 node = %d, port = %d, gun = %d\r\n",node,port,gun);
                        }
                    }

                }
                else//采集器、报税口、枪号、流水号不全部相同，认为是下一组数据的第一组
                {
                    rcv_data_temp.prev_collect = node;
                    rcv_data_temp.prev_tax = port;
                    rcv_data_temp.prev_gun = gun;
                    rcv_data_temp.rcv_no = 1;
                    rcv_data_temp.prev_seq = p_tax_tx->seq_no;
                    if(ret == 0x86)
                    {
                        rcv_data_temp.unit_price = p_gun->last_unit_price;
                        rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                        rcv_data_temp.price = p_gun->last_price;
                        rcv_data_temp.time_day = p_gun->time_day;
                        rcv_data_temp.time_hour = p_gun->time_hour;
                        rcv_data_temp.time_minute = p_gun->time_minute;
                    }
                    else if(ret == 0x89)
                    {
                        rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                        rcv_data_temp.total_price = p_gun->total_price;
                    }
                }

            }
        }
        else if(ret == 0x83)
        {
            printf("lora rcv 0x83\r\n");
            p_tax = (tax_info_t *)gun_buf;
           // gateway_read.collect_read[node].tax_read[port].alrd_sn = 1;

           // memcpy(gateway_read.collect_read[node].tax_read[port].monitor_serino,p_tax->monitor_serino,16);
            downlink_config.collect_conf[node].tax_num = 2;
            downlink_config.collect_conf[node].tax_conf[port].alrd_sn = 1;
            nodeConf.taxconf[node].port[port].alrd_sn = 1;
            if(p_tax->gun_num>8){
                printf("read gun num = %d\r\n",p_tax->gun_num);
                p_tax->gun_num = 8;
            }
            downlink_config.collect_conf[node].tax_conf[port].gun_num =p_tax->gun_num ; //枪的个数
            downlink_config.collect_conf[node].tax_conf[port].factory =p_tax->factory ; // 厂家信息
            downlink_config.collect_conf[node].tax_conf[port].status = 1; // 报税器口状态
            memcpy(downlink_config.collect_conf[node].tax_conf[port].monitor_serino,p_tax->monitor_serino,16); //序列号

            uplink_tax_systemcmd_0x2011(send_buf,&send_len,node,port,gun);
            tax_net_send(send_buf,send_len,FIRST_TYPE_SYST,COLL_UP_SYS_CMD2011);
            g_checkGun[node].gunSta.status[port] = pow(2,p_tax->gun_num)-1;
            fram_write_collect_msg();
            nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_89;
            printf("rcv----0x83:coll = %d port=%d  gunNUM=%d, factory=%d\r\n",node, port, p_tax->gun_num, p_tax->factory);

        }
        else {
            printf("明文数据错误\r\n");
            memset(&rcv_data_temp,0,sizeof(rcv_data_temp_t));
            if(nodeConf.taxconf[node].port[port].gun[gun].gLpState == TAX_GUN_LP_STATE_86){
                nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_CH;
            }
        }
    }
    else if(((taxType&CIPHERTEXT) == CIPHERTEXT) && ((taxType&0xF0)== 0x00)) { //密文
        ret = ytsf_rcv_analyze((uint8_t *)p_tax_tx->taxinfo.data.info,p_tax_tx->len-GATE_COLL_CMD5767_LEN,gun_buf,(uint8_t *)&port_temp);
        port = port_temp;
        if(ret == YTSF_0XA1_0X11 || ret == YTSF_0XA1_0X14)
        {
            tempret = ((ret==YTSF_0XA1_0X14) ? 0x89 : 0x86);
            printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,tempret,seqno,taxType);
            if(ret == YTSF_0XA1_0X14){
                memset(&rcv_data_temp,0,sizeof(rcv_data_temp_t));
            }
            p_gun = (gun_info_t *)gun_buf;
            if(rcv_data_temp.rcv_no == 0)//接收的第一组数据
            {
                rcv_data_temp.prev_collect = node;
                rcv_data_temp.prev_tax = port;
                rcv_data_temp.prev_gun = gun;
                rcv_data_temp.rcv_no = 1;
                rcv_data_temp.prev_seq = p_tax_tx->seq_no;
                if(ret == YTSF_0XA1_0X11)
                {
                    rcv_data_temp.unit_price = p_gun->last_unit_price;
                    rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                    rcv_data_temp.price = p_gun->last_price;
                    rcv_data_temp.time_day = p_gun->time_day;
                    rcv_data_temp.time_hour = p_gun->time_hour;
                    rcv_data_temp.time_minute = p_gun->time_minute;
                }
                else if(ret == YTSF_0XA1_0X14)
                {
                    rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                    rcv_data_temp.total_price = p_gun->total_price;
                }
             //   printf("\r\nmi wen - step1\r\n");
            }
            else //接收的第二组数据
            {
                if(rcv_data_temp.prev_collect == node && rcv_data_temp.prev_tax == port && \
                rcv_data_temp.prev_gun == gun && rcv_data_temp.prev_seq == p_tax_tx->seq_no) //采集器、报税口、枪号、流水号全部相同，认为是同一组数据
                {
                //    printf("\r\n mi wen - step2\r\n");
                    rcv_data_temp.rcv_no = 0;
                    if(ret == YTSF_0XA1_0X11)
                    {
                        rcv_data_temp.unit_price = p_gun->last_unit_price;
                        rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                        rcv_data_temp.price = p_gun->last_price;
                        rcv_data_temp.time_day = p_gun->time_day;
                        rcv_data_temp.time_hour = p_gun->time_hour;
                        rcv_data_temp.time_minute = p_gun->time_minute;
                    }
                    else if(ret == YTSF_0XA1_0X14)
                    {
                        rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                        rcv_data_temp.total_price = p_gun->total_price;
                    }

                    tempDa = rcv_data_temp.unit_price+rcv_data_temp.oil_volume+rcv_data_temp.price+\
                             rcv_data_temp.total_oil_volume + rcv_data_temp.total_price;
                    if((downlink_config.bInstallFinish==INSTALL_5A) ||((g_checkDa[node][port][gun]^tempDa) != 0) ){ //重复的数据不上报服务器
                        g_checkDa[node][port][gun]=tempDa;
                        uplink_tax_comb(send_buf,&send_len,node,port,gun,p_tax_tx->seq_no);//向服务器上传数据的参数部分
                        rcv_data_temp.unit_price = 0;
                        rcv_data_temp.oil_volume = 0;
                        rcv_data_temp.price = 0;
                        rcv_data_temp.total_oil_volume = 0;
                        rcv_data_temp.total_price = 0;
                        tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,COLL_TAX_DA_CMD_UP); //向服务器上传数据的完整数据，并通过mqtt发送
                        g_runData.daStatus[node][port][gun] = 0;
                    }
                    else { // 重复数据2分钟上传一次
                        if(g_runData.daStatus[node][port][gun]>=TAX_REPEAD_DATA){
                            uplink_tax_comb(send_buf,&send_len,node,port,gun,p_tax_tx->seq_no);//向服务器上传数据的参数部分
                            rcv_data_temp.unit_price = 0;
                            rcv_data_temp.oil_volume = 0;
                            rcv_data_temp.price = 0;
                            rcv_data_temp.total_oil_volume = 0;
                            rcv_data_temp.total_price = 0;
                            tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,COLL_TAX_DA_CMD_UP); //向服务器上传数据的完整数据，并通过mqtt发送
                            g_runData.daStatus[node][port][gun] = 0;
                     //       printf("密文 ：重复数据2分钟 node = %d, port = %d, gun = %d\r\n",node,port,gun);
                        }
                    }
                }
                else//采集器、报税口、枪号、流水号不全部相同，认为是下一组数据的第一组
                {
                    rcv_data_temp.prev_collect = node;
                    rcv_data_temp.prev_tax = port;
                    rcv_data_temp.prev_gun = gun;
                    rcv_data_temp.rcv_no = 1;
                    rcv_data_temp.prev_seq = p_tax_tx->seq_no;
                    if(ret == YTSF_0XA1_0X11)
                    {
                        rcv_data_temp.unit_price = p_gun->last_unit_price;
                        rcv_data_temp.oil_volume = p_gun->last_oil_volume;
                        rcv_data_temp.price = p_gun->last_price;
                        rcv_data_temp.time_day = p_gun->time_day;
                        rcv_data_temp.time_hour = p_gun->time_hour;
                        rcv_data_temp.time_minute = p_gun->time_minute;
                    }
                    else if(ret == YTSF_0XA1_0X14)
                    {
                        rcv_data_temp.total_oil_volume = p_gun->total_oil_volume;
                        rcv_data_temp.total_price = p_gun->total_price;
                    }
                }
            }
        }
        else if(ret == YTSF_0XA2_0X00)
        {
            p_tax = (tax_info_t *)gun_buf;
            downlink_config.collect_conf[node].tax_num = 2;
            downlink_config.collect_conf[node].tax_conf[port].alrd_sn = 1;
            nodeConf.taxconf[node].port[port].alrd_sn = 1;
            if(p_tax->gun_num>8){
                printf("read gun num = %d\r\n",p_tax->gun_num);
                p_tax->gun_num = 8;
            }
            downlink_config.collect_conf[node].tax_conf[port].gun_num =p_tax->gun_num ; //枪的个数
            downlink_config.collect_conf[node].tax_conf[port].factory =p_tax->factory ; // 厂家信息
            downlink_config.collect_conf[node].tax_conf[port].status = 1; // 报税器口状态
            memcpy(downlink_config.collect_conf[node].tax_conf[port].monitor_serino,p_tax->monitor_serino,16); //序列号
            uplink_tax_systemcmd_0x2011(send_buf,&send_len,node,port,gun);
            tax_net_send(send_buf,send_len,FIRST_TYPE_SYST,COLL_UP_SYS_CMD2011);
            fram_write_collect_msg();
            nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_89;
            printf("rcv------0x83:coll = %d port=%d  gunNUM=%d, factory=%d\r\n", node, port,p_tax->gun_num,p_tax->factory );
        }
        else { // 密文数据返回错误
            printf("\r\n 密文数据返回错误 错误代码: 0x%x\r\n",ret);
            up_send_log_err(GATEWAY_UP_LOG_CMD2001,LOG_TAX_DA,node,p_tax_tx->taxinfo.data.tax_no,p_tax_tx->taxinfo.data.gun_msgid,p_tax_tx->taxinfo.data.device_sn,g_curSendCmd,ret);
            port = read_tax_index(node,p_tax_tx->taxinfo.data.tax_no); //查询报税口编号
            if(port != 0xFF) {
               // printf("node=%d, port = %d, gun = %d,glpstate = %d\r\n",node,port,gun,nodeConf.taxconf[node].port[port].gun[gun].gLpState);
                if(nodeConf.taxconf[node].port[port].gun[gun].gLpState == TAX_GUN_LP_STATE_86){
                    nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_CH;
                }
                if(g_runData.daStatus[node][port][gun]>=TAX_REPEAD_DATA) {
                    uplink_tax_comb_2002(send_buf,&send_len,node,port,gun,ret);//向服务器上传数据的参数部分
                    tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,COLL_TAX_DAER_CMD_UP); //向服务器上传数据的完整数据，并通过mqtt发送
                    g_runData.daStatus[node][port][gun] = 0;
                }
            }
            memset(&rcv_data_temp,0,sizeof(rcv_data_temp_t));
        }
    }
    else if(((taxType&CIPHERTEXT) == CIPHERTEXT) && ((taxType&0x80)== 0x80)) { //密文指令解析8C
        ret = tax_rcv_analyze_0x8C((uint8_t*)(p_tax_tx->taxinfo.data.info+10),gun_buf,&send_len); // 前10个字节是税控序列号
        printf("recv : sn = %010d, coll=%d, port=%d, gun=%d, cmd = 0x%02x, seqNo = %010d, taxType = 0x%02x\n",sn,node,port,gun,ret,seqno,taxType);
        if((ret == 0x11) ||( ret == 0x14) || (ret == 0x91) || (ret == 0x94)){
            memcpy(g_tax8Cda.monitor_serino,p_tax_tx->taxinfo.data.info,10);
            if((ret == 0x11) || (ret == 0x91)) {
                if(rcv_data_temp.rcv_no == 1){
                    if(rcv_data_temp.prev_collect == node && rcv_data_temp.prev_tax == port && \
                    rcv_data_temp.prev_gun == gun && rcv_data_temp.prev_seq == p_tax_tx->seq_no) {
                        tempDa = ((g_tax8Cda.timer86<<16) |(g_tax8Cda.crc86<<8) | (g_tax8Cda.crc89));
                        if((downlink_config.bInstallFinish==INSTALL_5A) || (tempDa != g_checkDa[node][port][gun])){
                            memcpy(g_tax8Cda.data11,gun_buf,send_len);
                            g_tax8Cda.data11len = send_len;
                            //printf("timer = %x, crc86= %x, crc89 = %x\n",g_tax8Cda.timer86,g_tax8Cda.crc86,g_tax8Cda.crc89);
                            uplink_data_cmd_0x2071(send_buf,&send_len,p_tax_tx->seq_no,node,port,gun,&g_tax8Cda);
                            tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,NET_UP_DATA_CMD2071);
                            data_dump("上传数据到服务器",send_buf,send_len);
                            g_checkDa[node][port][gun] = tempDa;
                            g_runData.daStatus[node][port][gun] = 0;
                        }
                        else {
                            if(g_runData.daStatus[node][port][gun]>=TAX_REPEAD_DATA){
                                memcpy(g_tax8Cda.data11,gun_buf,send_len);
                                g_tax8Cda.data11len = send_len;
                                //printf("timer = %x, crc86= %x, crc89 = %x\n",g_tax8Cda.timer86,g_tax8Cda.crc86,g_tax8Cda.crc89);
                                uplink_data_cmd_0x2071(send_buf,&send_len,p_tax_tx->seq_no,node,port,gun,&g_tax8Cda);
                                tax_net_send(send_buf,send_len,FIRST_TYPE_DATA,NET_UP_DATA_CMD2071);
                                data_dump("重覆数据上传到服务器",send_buf,send_len);
                                g_checkDa[node][port][gun] = tempDa;
                                g_runData.daStatus[node][port][gun] = 0;
                            }
                        }

                    }
                    else {
                        printf("不是同一组数据\n");

                    }
                    rcv_data_temp.rcv_no = 0;
                    memset((char*)&g_tax8Cda,0,sizeof(rcv_data_0x8C_t));
                }
            }
            else if((ret == 0x14) || (ret == 0x94)) {
                rcv_data_temp.prev_collect = node;
                rcv_data_temp.prev_tax = port;
                rcv_data_temp.prev_gun = gun;
                rcv_data_temp.rcv_no = 1;
                rcv_data_temp.prev_seq = p_tax_tx->seq_no;

                memcpy(g_tax8Cda.data14,gun_buf,send_len);
                g_tax8Cda.data14len = send_len;
            }
        }
        else if((ret == 0x70) || (ret == 0xF0) ){
            if(ret == 0x70) {
                //printf("cccc ret = %x\n",ret);
                p_tax = (tax_info_t *)gun_buf;
                downlink_config.collect_conf[node].tax_num = 2;
                downlink_config.collect_conf[node].tax_conf[port].alrd_sn = 1;
                nodeConf.taxconf[node].port[port].alrd_sn = 1;
                if(p_tax->gun_num>8){
                    printf("read gun num = %d\r\n",p_tax->gun_num);
                    p_tax->gun_num = 8;
                }
                downlink_config.collect_conf[node].tax_conf[port].gun_num =p_tax->gun_num ; //枪的个数
                downlink_config.collect_conf[node].tax_conf[port].factory =p_tax->factory ; // 厂家信息
                downlink_config.collect_conf[node].tax_conf[port].status = 1; // 报税器口状态
                memcpy(downlink_config.collect_conf[node].tax_conf[port].monitor_serino,p_tax->monitor_serino,16); //序列号

                uplink_tax_systemcmd_0x2011(send_buf,&send_len,node,port,gun);
                tax_net_send(send_buf,send_len,FIRST_TYPE_SYST,COLL_UP_SYS_CMD2011);
                g_checkGun[node].gunSta.status[port] = pow(2,p_tax->gun_num)-1;
                fram_write_collect_msg();
                nodeConf.taxconf[node].port[port].gun[gun].gLpState = TAX_GUN_LP_STATE_89;
                printf("rcv----0x83:coll = %d port=%d  gunNUM=%d, factory=%d\r\n",node, port, p_tax->gun_num, p_tax->factory);

            }
        }
    }


    timeout_start(&g_taxDataTime);
GATEWAY_COLLECT_END:
    timeout_stop(&g_taxSendTime);
    return 0;
}

/*--------------------------------------------------------------
 *  解析采集器通过lora发的过的指令0x66指令
 *  心跳包指令
 *  只有当是拓盛密文时，才会主动下发心跳包，
 *
 * -------------------------------------------------------------*/
int collect_rcv_analyze0x66(uint8_t *data, uint8_t len)
{
//    uint8_t idIndex = 0;
    uint16_t p_crc = 0;
    uint8_t factory;
    uint16_t crc;
    uint8_t send_buff[160];
    uint8_t sendlen = 0;

    uint8_t node = 0;
    int lorastatus = 0;
    gateway_collect_com_t *p_tax_tx = (gateway_collect_com_t *)data;//Lora接收数据

    crc = _crc16_get((uint8_t*)data,p_tax_tx->len+GATE_COLL_HEAD_LEN -2 );// len-2);
    p_crc = data[p_tax_tx->len+GATE_COLL_HEAD_LEN-1];
    p_crc = (p_crc<<8)|data[p_tax_tx->len+GATE_COLL_HEAD_LEN-2];

    up_send_log_srcdata(data,len-2);
    if(p_tax_tx->frame_header!=0xfefe) {goto GATEWAY_COLL_0x66;} //数据头不对则返回

    if(g_runData.bchangelora == 1) {
        node = p_tax_tx->taxinfo.comdata.coll_no-1;
        g_loraCollMsg.info[node].loraindex = g_runData.nextlorIndex;
        printf("SN：%d 成功\r\n",g_loraCollMsg.info[node].coll_sn);
        uplink_update_systemcmd_0x2017(send_buff,&sendlen,p_tax_tx->taxinfo.comdata.device_sn,1,g_runData.nextlorIndex);
        tax_net_send(send_buff,sendlen,FIRST_TYPE_SYST,COLL_UP_SYS_CMD2017);

    }
    else {

        node = read_collect_index(p_tax_tx->taxinfo.comdata.device_sn);
        if((node == 0xFF) || (node>=downlink_config.collect_num)) {goto GATEWAY_COLL_0x66;}

        g_loraCollMsg.lora_rcvCount++;
        g_loraCollMsg.info[node].rcvNum++;
       // printf("接收 loraRecv= %d,采集(%d)接收：%d\r\n",g_loraCollMsg.lora_rcvCount,node,g_loraCollMsg.info[node].rcvNum);


        lorastatus = (int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN+1);
        lorastatus = (lorastatus<<8) | ((int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN));

        g_runData.collrunMsg[node].lorastatus = lorastatus;
        if(p_crc != crc ){
            printf("cmd0x66: crc error\r\n");
            goto GATEWAY_COLL_0x66;
        } //校验位不对则返回

        g_runData.collrunMsg[node].checkNum = 0;
        factory = p_tax_tx->taxinfo.taxEnStatus.factory;

        if((factory&0x80) == 0x80) {
            nodeConf.taxconf[node].port[0].taxType = factory&0xF3;
            nodeConf.taxconf[node].port[1].taxType = ((factory&0xF0)|((factory>>2)&0x03));
        }
        else {
            nodeConf.taxconf[node].port[0].taxType = factory;
            nodeConf.taxconf[node].port[1].taxType = factory;
        }

        downlink_config.collect_conf[node].collect_status = 1;
        downlink_config.collect_conf[node].tax_type = factory;
        if(factory !=0 )downlink_config.collect_conf[node].coll_send_num = 0;
        printf("rcv cmd 0x66 coll = %d, tax_type = %02x ,port1Type = %02x, port2Type = %02x\n",node,factory,nodeConf.taxconf[node].port[0].taxType,nodeConf.taxconf[node].port[1].taxType);
    }
    if(g_logCfigDa.bEnable)
        timeout_start(&g_taxDataTime);

GATEWAY_COLL_0x66:
    timeout_stop(&g_taxSendTime);
    return 0;
}

/*--------------------------------------------------------------
 *  解析采集器通过lora发的过的指令0x58指令
 *  固件包指令
 *  收到固件包信息后，要向服务器上传
 * -------------------------------------------------------------*/
int collect_rcv_analyze0x68(uint8_t *data, uint8_t len)
{

    uint8_t flag = 0;//i=0,idIndex = 0,
    uint16_t p_crc = 0;
    uint16_t crc;
    uint8_t index = 0;
    uint8_t send_buff[160];
    uint8_t sendlen = 0;//,num;
    int lorastatus = 0;
    static uint8_t collNum = 0;

    CollMsg *collMsg = NULL;
    gateway_collect_com_t *p_tax_tx = (gateway_collect_com_t *)data;//Lora接收数据


    crc = _crc16_get((uint8_t*)data,p_tax_tx->len+GATE_COLL_HEAD_LEN-2);// len-2);
    p_crc = data[p_tax_tx->len+GATE_COLL_HEAD_LEN-1];
    p_crc = (p_crc<<8)|data[p_tax_tx->len+GATE_COLL_HEAD_LEN-2];


    //data_dump("aaaaa:", (uint8_t *)data, len);

    if(p_tax_tx->frame_header!=0xfefe) {goto GATEWAY_COLL_0x68;} //数据头不对则返回
    if(p_crc != crc ){printf("cmd0x68: crc error\r\n"); goto GATEWAY_COLL_0x68;} //校验位不对则返回


    index = read_collect_index(p_tax_tx->taxinfo.firmMsg.device_sn);
    if((index == 0xFF) || (index >=downlink_config.collect_num)) goto GATEWAY_COLL_0x68;
    g_loraCollMsg.lora_rcvCount++;
    g_loraCollMsg.info[index].rcvNum++;
   // printf("接收 loraRecv= %d,采集(%d)接收：%d\r\n",g_loraCollMsg.lora_rcvCount,index,g_loraCollMsg.info[index].rcvNum);

    lorastatus = (int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN+1);
    lorastatus = (lorastatus<<8) | ((int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN));

    g_runData.collrunMsg[index].lorastatus = lorastatus;
    downlink_config.collect_conf[index].collect_status = COLL_STATUS_ONLINE; // 采集器在线状态


    collMsg = &(g_firmwareMsg.collMsg[index]);

   // collMsg->device_sn = p_tax_tx->taxinfo.firmMsg.device_sn; // 采集器的SN号; //

    if(g_runData.bServerRead58==0){
        if(collMsg->bootloaderVr!=p_tax_tx->taxinfo.firmMsg.bootloaderVr) flag = 1;
        else if(collMsg->appVr!=p_tax_tx->taxinfo.firmMsg.appVr) flag = 1;
        else if(collMsg->resetNum!=p_tax_tx->taxinfo.firmMsg.resetNum) flag = 1;
        else if(collMsg->resetType!= p_tax_tx->taxinfo.firmMsg.resetType) flag = 1;
        else if(collMsg->updateStatus!=p_tax_tx->taxinfo.firmMsg.updateStatus) flag = 1;
        else if(collMsg->voltage != p_tax_tx->taxinfo.firmMsg.voltage) flag = 1;
        else if(collMsg->temperature != p_tax_tx->taxinfo.firmMsg.temperature) flag = 0;
        else flag = 0;
    }
    else {
        flag = 1;
        g_runData.bServerRead58 = 0;
    }

    collMsg->bootloaderVr = p_tax_tx->taxinfo.firmMsg.bootloaderVr; // bootloader版本
    collMsg->appVr = p_tax_tx->taxinfo.firmMsg.appVr; // app版本号
    collMsg->resetNum = p_tax_tx->taxinfo.firmMsg.resetNum; // 复位次数
    collMsg->resetType = p_tax_tx->taxinfo.firmMsg.resetType; // 最后一次复位类型
    collMsg->runTime = p_tax_tx->taxinfo.firmMsg.runTime; //运行时长
    collMsg->voltage = p_tax_tx->taxinfo.firmMsg.voltage; // 电压
    collMsg->temperature = p_tax_tx->taxinfo.firmMsg.temperature; // 温度
    collMsg->updateStatus = p_tax_tx->taxinfo.firmMsg.updateStatus;// 升级状态码
    memcpy(collMsg->uuid,p_tax_tx->taxinfo.firmMsg.uuid,12); // 芯片ID号

    if(flag==1){
        memset(send_buff,0,sizeof(send_buff));
        uplink_tax_statusmcmd_0x2001(send_buff,&sendlen,DEVICE_COLLECT,index);
        tax_net_send(send_buff,sendlen,FIRST_TYPE_STATUS,COLL_UP_STATUS_CMD2001);
        printf("rcv 68: sn = %10u, status = %d\r\n",collMsg->device_sn, collMsg->updateStatus);
        printf("rcv cmd analyze finish 0x68\r\n");
    }
    else {
        printf("rcv 0x68 same last\r\n");
   }

    if(g_runData.bsendUpdateStatus==2){
        up_to_send_server_update_status(DEVICE_COLLECT,collMsg->device_sn,g_runData.task_no,collMsg->updateStatus);
        collNum++;
        if(collNum>=(downlink_config.collect_num)){
            g_runData.bsendUpdateStatus = 0;
            collNum = 0;
        }
    }
GATEWAY_COLL_0x68:
    timeout_stop(&g_taxSendTime);
    return 0;
}

/*----------------------------------------------------------------------------------
 *  解析编码器的数据
 * ---------------------------------------------------------------------------------*/
int collect_rcv_analyze0x6C(uint8_t *data, uint8_t len)
{

    uint8_t send_buf[128],sendlen=0;
    uint16_t fcrc, crc;
    //uint8_t rcv_buf[64],rcvlen=0;
    uint32_t sn = 0;
    uint8_t portNo = 0,gunNo = 0;
    uint8_t node=0,port=0;//,enindex = 0;
    int lorastatus;
  //  encoderDa_00 *msg = NULL;
    uint8_t bnewCode = 0; // 是否为新记录
    enMsgDa *msg = NULL;
    gateway_collect_com_t *p_tax_tx = (gateway_collect_com_t *)data;//Lora接收数据
    memset(send_buf,0,sizeof(send_buf));


    up_send_log_srcdata(data,len-2);

    crc = _crc16_get((uint8_t*)data,p_tax_tx->len+GATE_COLL_HEAD_LEN-2);// len-2);
    fcrc = data[p_tax_tx->len+GATE_COLL_HEAD_LEN-1];
    fcrc = (fcrc<<8)|data[p_tax_tx->len+GATE_COLL_HEAD_LEN-2];


    if(p_tax_tx->frame_header!=0xfefe) { goto GATEWAY_COLL_0x6C;} //数据头不对则返回
    node = read_collect_index(p_tax_tx->taxinfo.encoderda.device_sn);
    if( (0xFF == node) || (node>=downlink_config.collect_num)) {
        printf("coll index error coll = %d,sn = %010u\r\n",node,p_tax_tx->taxinfo.encoderda.device_sn);
        goto GATEWAY_COLL_0x6C;
    }
    g_loraCollMsg.lora_rcvCount++;
    g_loraCollMsg.info[node].rcvNum++;


    lorastatus = (int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN+1);
    lorastatus = (lorastatus<<8) | ((int)*(data+p_tax_tx->len+GATE_COLL_HEAD_LEN));
    g_runData.collrunMsg[node].lorastatus =lorastatus;
    g_runData.collrunMsg[node].checkNum = 0;
    if(fcrc != crc ){//校验位不对则返回
        printf("cmd0x6C: crc error\r\n");
        goto GATEWAY_COLL_0x6C;
    }

    if(p_tax_tx->taxinfo.encoderda.device_type != 0x0501){ // 处理编译器的数据
        goto GATEWAY_COLL_0x6C;
    }
    port = read_tax_index(node,p_tax_tx->taxinfo.encoderda.tax_no); //查询报税口编号
    if(port == 0xFF) {goto GATEWAY_COLL_0x6C;}


    if(p_tax_tx->taxinfo.encoderda.status==2){
        printf("recv 0x6C : sn = %010d, targetType = 0x%04x timeout_noreturn\r\n",p_tax_tx->taxinfo.encoderda.device_sn,p_tax_tx->taxinfo.encoderda.device_type);

        goto GATEWAY_COLL_0x6C;
    }
    else if(p_tax_tx->taxinfo.encoderda.status == 4) {
        printf("recv 0x6C : sn = %010d, error = %d\r\n",p_tax_tx->taxinfo.encoderda.device_sn,4);

        goto GATEWAY_COLL_0x6C;
    }
    else if(p_tax_tx->taxinfo.encoderda.status == 5) {
        printf("recv 0x6C : sn = %010d, error = %d\r\n",p_tax_tx->taxinfo.encoderda.device_sn,5);

        goto GATEWAY_COLL_0x6C;
    }
    sn = p_tax_tx->taxinfo.encoderda.device_sn;
    portNo = p_tax_tx->taxinfo.encoderda.tax_no;
    gunNo = p_tax_tx->taxinfo.encoderda.gun_msgid;
   // msg = (encoderDa_00*)p_tax_tx->taxinfo.encoderda.info;
    bnewCode = p_tax_tx->taxinfo.encoderda.info[3];// 有无新记录
    if((downlink_config.bInstallFinish==INSTALL_5A) || (bnewCode != 0)){
        memset(send_buf,0,sizeof(send_buf));
        uplink_encoder_data0x2051(send_buf,&sendlen,node,portNo,gunNo,p_tax_tx->taxinfo.encoderda.dataLen, (uint8_t*)p_tax_tx->taxinfo.encoderda.info);
        tax_net_send(send_buf,sendlen,FIRST_TYPE_DATA,COLL_ENCODER_DA_CMD_UP);
        printf(" send 0x6c data to server \r\n");
    }
    printf("recv 0x6C : sn = %010u, coll=%d, port=%d, bNewcode=%d,gunstatus01=%d, gunstatus02=%d \r\n",\
    sn,node,portNo,bnewCode,p_tax_tx->taxinfo.encoderda.info[1],p_tax_tx->taxinfo.encoderda.info[2] );

    node = nodeConf.nodeIndex;
    port = nodeConf.taxconf[node].portIndex;
    msg = &(nodeConf.taxconf[node].port[port].enMsg[g_encodeOpt.curIndex]);

    if(portNo==1){ // 报税口1
        if((msg->da.gunstatus&p_tax_tx->taxinfo.encoderda.info[1])==0){ //抬挂枪状态 1:抬枪状态，代表加油  0：挂枪状态，代表未加油
            nodeConf.taxconf[node].port[port].portRead += 1;
        }
        else nodeConf.taxconf[node].port[port].portRead = 0;
      //  printf("11,node = %d,port= %d,portread = %d\r\n",node,port,nodeConf.taxconf[node].port[port].portRead);

    }
    else if(portNo == 2) { // 报税口2
        if((msg->da.gunstatus&p_tax_tx->taxinfo.encoderda.info[2])==0){ //抬挂枪状态
            nodeConf.taxconf[node].port[port].portRead += 1;
        }
        else
            nodeConf.taxconf[node].port[port].portRead = 0;
      //  printf("22,node = %d,port= %d,portread = %d\r\n",node,port,nodeConf.taxconf[node].port[port].portRead);
    }
    if(g_logCfigDa.bEnable)
        timeout_start(&g_taxDataTime);

GATEWAY_COLL_0x6C:
    timeout_stop(&g_taxSendTime);
    return 0;
}
/*---------------------------------------------------------------------
 * 透传指令 0x01----0x2052,2053
 * -------------------------------------------------------------------*/
int collect_rcv_analyze0x01_0x2052(uint16_t cmd,uint8_t *data, uint8_t len)
{
    printf("收到指令:0x01---0x%04x\n",cmd);

    tax_net_send_0x01_0x1052(data,len);

    timeout_stop(&g_taxSendTime);
    return 0;
}

/*-----------------------------------
 *  向服务器发送网关的信息
 * ----------------------------------*/
void gateway_net_send_gatewayMsg(void)
{
    uint8_t sendBuff[160];
    uint8_t sendLen = 0;
    static uint8_t bfirstPowerup = 0;

    if((bfirstPowerup == 0) || (g_runData.bsendgatewayfirmMsg ==1) && (air.State.MQTT_State==1)){
        uplink_tax_statusmcmd_0x2001(sendBuff,&sendLen,DEVICE_GATEWAY,0);
        tax_net_send(sendBuff,sendLen,FIRST_TYPE_STATUS,COLL_UP_STATUS_CMD2001);
        bfirstPowerup = 1;
        g_runData.bsendgatewayfirmMsg = 0;
        printf("send gateway msg to server\r\n");
    }

    return;
}

