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<ExeRequest> 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;
|
}
|
}
|
|
}
|