package com.ld.igds.protocol.zldz.analysis; import com.ld.igds.common.CoreSerService; import com.ld.igds.constant.BizType; import com.ld.igds.io.constant.OrderRespEnum; import com.ld.igds.io.notify.NotifyWebInvoker; import com.ld.igds.models.DeviceSer; import com.ld.igds.order.ExeOrderService; import com.ld.igds.order.data.ExeRequest; import com.ld.igds.protocol.zldz.analysis.builder.ReMessageBuilder; import com.ld.igds.protocol.zldz.analysis.message.ReMessage; import com.ld.igds.protocol.zldz.task.CommandReSendService; import com.ld.igds.protocol.zldz.util.CRC8; import com.ld.igds.protocol.zldz.util.ServerUtils; import com.ld.igds.util.BytesUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; /** * 协议解析入口 * * @author jiazx */ @Slf4j @Component(AnalysisService.BEAN_ID) public class AnalysisService { public static final String BEAN_ID = "zldz.analysisService"; @Autowired private CoreSerService coreSerService; @Autowired private AnalysisTH analysisTH; @Autowired private AnalysisGrain analysisGrain; @Autowired private AnalysisConf analysisConf; @Autowired private NotifyWebInvoker notifyWebInvoker; @Autowired private ExeOrderService exeOrderService; @Autowired private CommandReSendService commandReSendService; /** * @param sessionKey ip:port * @param strMsg */ public void analysis2(String sessionKey, String strMsg) { String[] attr = sessionKey.split(":"); String ip = attr[0]; Integer port = Integer.valueOf(attr[1]); ReMessage reMessage = ReMessageBuilder.getInstance().buildMessage(null, ip, port, strMsg); if (null == reMessage || null == reMessage.getCompanyId()) { log.error("分机----->>>平台:返回信息没有获取组织编码信息,无法继续解析----{}", sessionKey); return; } DeviceSer ser = coreSerService.getCacheSer(reMessage.getCompanyId(), reMessage.getSourceId()); if (null == ser) { String info = "分机=" + reMessage.getSourceId() + "返回信息没有匹配到分机,系统踢出离线。"; log.error("分机----->>>平台:" + info); notifyWebInvoker.notifyWeb(reMessage.getCompanyId(), OrderRespEnum.MSG_ERROR, BizType.SYS, info); // 清除缓存并销毁链接 commandReSendService.destoryAndDelCache(reMessage.getCompanyId(), ip, port, reMessage.getMessageType()); return; } log.debug("分机----->>>平台:所属组织-{},分机-{} 返回的命令信息={}", ser.getCompanyId(), ser.getName(), reMessage.toString()); String checkMsg = this.checkMsg(reMessage, ser); if (null != checkMsg) { // 系统拦截到了异常原因,不踢出连接 if (ServerUtils.MSG_TYPE_8815.equals(reMessage.getMessageType()) || ServerUtils.MSG_TYPE_8817.equals(reMessage.getMessageType())) { commandReSendService.cleanKey(ser.getCompanyId(), ser.getIp(), ser.getPort(), ServerUtils.MSG_TYPE_8817); List list = exeOrderService.getInProgressOrderBySerId(BizType.GRAIN.getCode(), ser.getId()); if (null != list && list.size() > 0) { exeOrderService.progressError(ser.getCompanyId(), BizType.GRAIN.getCode(), list.get(0).getDepotId(), checkMsg); } else { notifyWebInvoker.notifyWeb(ser.getCompanyId(), OrderRespEnum.MSG_ERROR, BizType.SYS, checkMsg); } } else { commandReSendService.cleanKey(ser.getCompanyId(), ser.getIp(), ser.getPort(), reMessage.getMessageType()); notifyWebInvoker.notifyWeb(ser.getCompanyId(), OrderRespEnum.MSG_ERROR, BizType.SYS, checkMsg); } log.error("分机----->>>平台:命令验证异常:所属组织-{},异常信息-{},报文信息-{}", ser.getCompanyId(), checkMsg, reMessage.getStrMsg()); return; } switch (reMessage.getMessageType()) { case ServerUtils.MSG_TYPE_8828:// 温湿度解析 analysisTH.analysis8828(reMessage, ser); break; case ServerUtils.MSG_TYPE_8815:// 终端应答粮情请求 analysisGrain.analysis8815(reMessage, ser); break; case ServerUtils.MSG_TYPE_1117:// 粮情数据信息 analysisGrain.analysis8817(reMessage, ser); break; case ServerUtils.MSG_TYPE_1129:// 终端发送通道电缆数据给后台 analysisConf.analysis1129(reMessage, ser); break; case ServerUtils.MSG_TYPE_8816:// 解析配置 analysisConf.analysis8816(reMessage, ser); break; case ServerUtils.MSG_TYPE_8822:// 电缆初始化成功 analysisConf.analysis8822(reMessage, ser); break; case ServerUtils.MSG_TYPE_8823:// 电缆汇总应答 analysisConf.analysis8823(reMessage, ser); break; case ServerUtils.MSG_TYPE_8825:// 读取通道电缆配置 analysisConf.analysis8825(reMessage, ser); break; case ServerUtils.MSG_TYPE_8826:// 修改电缆的返回 analysisConf.analysis8826(reMessage, ser); break; default: break; } } /** * 校验,正常返回NULL,异常返回异常原因,正常异常原因返回不踢掉重新连接 * * @param message * @param ser * @return * @throws Exception */ private String checkMsg(ReMessage message, DeviceSer ser) { String result; if (message.getResult() == 1) { result = "分机=" + ser.getName() + " 协议解析失败,原因:接收的应答校验异常"; return result; } if (message.getResult() == 2) { result = "分机=" + ser.getName() + " 协议解析失败,原因:发送的数据校验异常"; return result; } if (message.getResult() == 3) { result = "分机=" + ser.getName() + " 协议解析失败,原因:排队中"; return result; } if (message.getResult() == 4) { result = "分机=" + ser.getName() + " 协议解析失败,原因:发送超时错误"; return result; } if (message.getResult() == 9) { result = "分机=" + ser.getName() + " 协议解析失败,原因:Io模块不在线"; return result; } if (message.getResult() == 10) { result = "分机=" + ser.getName() + " 协议解析失败,原因:发送中"; return result; } if (message.getResult() == 11) { result = "分机=" + ser.getName() + " 协议解析失败,原因:无线模块故障"; return result; } if (message.getResult() == 12) { result = "分机=" + ser.getName() + " 协议解析失败,原因:主要是反馈坐标点交换命令或者是电缆修改命令的错误,或者粮情采集的参数不对"; return result; } if (message.getResult() == 13) { result = "分机=" + ser.getName() + " 协议解析失败,原因:网关未注册"; return result; } // 获取校验的报文信息 int end = 4 + 18 * 2 + message.getBody().getLength() * 2; String checkStr = message.getStrMsg().substring(4, end); byte[] byteCrc16 = BytesUtil.hexStrToBytes(checkStr); short crc16Hex2 = CRC8.calculateCrc16(byteCrc16, (short) 0, (short) (byteCrc16.length)); byte[] crc16Hex2Bytes = BytesUtil.shortToByte(crc16Hex2); int crc16 = BytesUtil.bytesToInt(crc16Hex2Bytes); String hexCrc16 = BytesUtil.intToHexStr(crc16); if (message.getHexCrc16().equals(hexCrc16)) { return null; } else { result = "分机=" + ser.getName() + " 协议解析失败,原因:CRC16校验异常"; return result; } } }