|
|
@@ -1,578 +0,0 @@
|
|
|
-package cn.oleauto.iec104;
|
|
|
-
|
|
|
-import cn.hutool.core.convert.Convert;
|
|
|
-import cn.hutool.core.thread.ThreadUtil;
|
|
|
-import cn.oleauto.biz.domain.BizYkLog;
|
|
|
-import cn.oleauto.biz.domain.BizYtLog;
|
|
|
-import cn.oleauto.biz.service.IBizYkLogService;
|
|
|
-import cn.oleauto.biz.service.IBizYtLogService;
|
|
|
-import cn.oleauto.common.enums.ControlStepType;
|
|
|
-import cn.oleauto.common.enums.ControlType;
|
|
|
-import cn.oleauto.common.enums.MessageOwnerType;
|
|
|
-import cn.oleauto.common.enums.OperateStateType;
|
|
|
-import cn.oleauto.common.exception.ServiceException;
|
|
|
-import cn.oleauto.common.utils.StringUtils;
|
|
|
-import cn.oleauto.common.utils.spring.SpringUtils;
|
|
|
-import cn.oleauto.iec104.util.DataConverter;
|
|
|
-import cn.oleauto.iec60870.*;
|
|
|
-import cn.oleauto.iec60870.ie.*;
|
|
|
-import cn.oleauto.protocol.common.IChannel;
|
|
|
-import cn.oleauto.protocol.common.cache.DefaultMessageCache;
|
|
|
-import cn.oleauto.protocol.common.dto.ReportMessageDto;
|
|
|
-import cn.oleauto.protocol.common.dto.ReportValueDtoList;
|
|
|
-import cn.oleauto.protocol.common.event.DefaultEventArgs;
|
|
|
-import cn.oleauto.protocol.common.event.EventType;
|
|
|
-import cn.oleauto.protocol.common.event.TransmitMessageEventArgs;
|
|
|
-import cn.oleauto.protocol.common.mq.MQCenter;
|
|
|
-import cn.oleauto.protocol.common.protocol.AbstractProtocol;
|
|
|
-import cn.oleauto.protocol.common.transmit.TransmitState;
|
|
|
-import io.netty.buffer.ByteBufUtil;
|
|
|
-import lombok.AllArgsConstructor;
|
|
|
-import lombok.Data;
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.springframework.util.ConcurrentReferenceHashMap;
|
|
|
-
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.StringReader;
|
|
|
-import java.util.Arrays;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Objects;
|
|
|
-import java.util.Properties;
|
|
|
-import java.util.concurrent.BlockingDeque;
|
|
|
-import java.util.concurrent.ConcurrentMap;
|
|
|
-import java.util.concurrent.LinkedBlockingDeque;
|
|
|
-
|
|
|
-@Slf4j
|
|
|
-public class ProtocolImpl extends AbstractProtocol{
|
|
|
- private ConnectionSettings settings = new ConnectionSettings();
|
|
|
- private DefaultMessageCache messageCache = new DefaultMessageCache(1024 * 20);
|
|
|
- private Thread thParse;
|
|
|
- private Thread thTask;
|
|
|
- private volatile boolean isStop = false;
|
|
|
- private volatile short sendSq = 0;
|
|
|
- private volatile short recSq = 0;
|
|
|
- private byte[] packageBuffer = new byte[255];
|
|
|
- private static final int LAZY_AMOUNT = 256;
|
|
|
- private BlockingDeque<LazyRequest> waitSendApdus = new LinkedBlockingDeque<>(LAZY_AMOUNT);
|
|
|
- private ConcurrentMap<String, WaitResponseRequest> waitResponseMap = new ConcurrentReferenceHashMap<>();
|
|
|
- private long last100 = 0;
|
|
|
- private long last103 = 0;
|
|
|
- private int tm100 = 120_000;
|
|
|
- private int tm103 = 86400_000/2;
|
|
|
-
|
|
|
- public ProtocolImpl(IChannel channel){
|
|
|
- super(channel);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onTransmitConnected(DefaultEventArgs e) {
|
|
|
- sendSq = recSq = 0;
|
|
|
- messageCache.clear();
|
|
|
- notifyTransmitState(1);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onTransmitDisconnected(DefaultEventArgs e) {
|
|
|
- sendSq = recSq = 0;
|
|
|
- messageCache.clear();
|
|
|
- notifyTransmitState(0);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onTransmitSent(TransmitMessageEventArgs e) {
|
|
|
- notifyMessage(EventType.PROTOCOL_SENT, e.getData());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- protected void onTransmitReceived(TransmitMessageEventArgs e) {
|
|
|
- if(!messageCache.append(e.getData())){
|
|
|
- log.warn("message cache is full, lost={}", ByteBufUtil.hexDump(e.getData()));
|
|
|
- }
|
|
|
- synchronized (this) {
|
|
|
- notify();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int start(String config) {
|
|
|
- log.info("protocol start channel={}", channel.getName());
|
|
|
- if(thParse != null || thTask != null){
|
|
|
- return 0;
|
|
|
- }
|
|
|
- try {
|
|
|
- Properties properties = new Properties();
|
|
|
- properties.load(new StringReader(config));
|
|
|
- // 总召唤间隔
|
|
|
- tm100 = Convert.toInt(properties.get("ti1000Interval"), tm100);
|
|
|
- settings.setCotFieldLength(Convert.toInt(properties.get("cotFieldLength"), 2));
|
|
|
- settings.setCommonAddressFieldLength(Convert.toInt(properties.get("commonAddressFieldLength"), 2));
|
|
|
- settings.setIoaFieldLength(Convert.toInt(properties.get("ioaFieldLength"), 3));
|
|
|
- settings.setCommonAddress(Convert.toInt(properties.get("commonAddress"), 1));
|
|
|
- settings.setOriginAddress(Convert.toInt(properties.get("originAddress"), 0));
|
|
|
-
|
|
|
- buildPointRelation();
|
|
|
-
|
|
|
- thParse = new Thread(()->{
|
|
|
- this.parseMessageTask();
|
|
|
- });
|
|
|
- thParse.setName("ch-" + channel.getName() + "-protocol-parse");
|
|
|
- thParse.start();
|
|
|
-
|
|
|
- thTask = new Thread(()->{
|
|
|
- this.timerTask();
|
|
|
- });
|
|
|
- thTask.setName("ch-" + channel.getName() + "-protocol-task");
|
|
|
- thTask.start();
|
|
|
-
|
|
|
- messageCache.clear();
|
|
|
- } catch (Exception ex){
|
|
|
- log.error("start protocol failed, config={} ex={}",config, ex);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void stop() {
|
|
|
- isStop = true;
|
|
|
- thTask = null;
|
|
|
- thParse = null;
|
|
|
- messageCache.clear();
|
|
|
- synchronized (this) {
|
|
|
- notifyAll();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public List<Object> decode(byte[] data) {
|
|
|
- APdu apdu = APdu.decode(data, settings);
|
|
|
- if(apdu.getApciType() == APdu.ApciType.I_FORMAT){
|
|
|
- int theirSn = apdu.getSendSeqNumber();
|
|
|
- if(recSq == theirSn){
|
|
|
- decodeAsdu(apdu);
|
|
|
- // 发回一个s帧
|
|
|
- recSq = (short) (theirSn + 1);
|
|
|
- sendLazyRequest(new LazyRequest(APdu.ApciType.S_FORMAT, null, null, null, 0, 0));
|
|
|
- }
|
|
|
- if(theirSn < recSq || (theirSn > recSq && Math.abs(theirSn - recSq) > 32700)){
|
|
|
- // 重复的情况
|
|
|
- return List.of();
|
|
|
- }
|
|
|
- else {
|
|
|
- // 丢了报文
|
|
|
- }
|
|
|
- } else if(apdu.getApciType() == APdu.ApciType.S_FORMAT){
|
|
|
- // 监视帧
|
|
|
- } else {
|
|
|
- // U帧
|
|
|
- }
|
|
|
- return List.of();
|
|
|
- }
|
|
|
- public void notifyMessage(EventType eventType, byte[] data){
|
|
|
- String frame = switch (data[2] & 0x3){
|
|
|
- case 3->"U";
|
|
|
- case 1->"S";
|
|
|
- default -> "I";
|
|
|
- };
|
|
|
- log.info("channel={} frame={} ti={} action={} bytes ={}", channel.getName(), frame, (data.length > 6? data[6]: 0), eventType, ByteBufUtil.hexDump(data));
|
|
|
- String fun = data.length <= 6? frame : Byte.toString(data[6]);
|
|
|
- MessageOwnerType owner = (eventType == EventType.TRANSMIT_RECEIVED || eventType == EventType.PROTOCOL_RECEIVED)? MessageOwnerType.DEVICE : MessageOwnerType.SYSTEM;
|
|
|
- ReportMessageDto channelMessageDto = new ReportMessageDto(channel.getId(), null, owner, fun, data, System.currentTimeMillis());
|
|
|
- MQCenter.getInstance().send(ReportMessageDto.REPORT_MESSAGE, channelMessageDto);
|
|
|
- }
|
|
|
- private void decodeAsdu(APdu apdu){
|
|
|
- try {
|
|
|
- ASdu asdu = ASdu.decode(apdu.getASduBuffer(), settings);
|
|
|
- ASduType typeIdentification = asdu.getTypeIdentification();
|
|
|
- switch (typeIdentification){
|
|
|
- case C_SE_NC_1, C_SE_NA_1-> receiveYtResponse(asdu);
|
|
|
- case C_SC_NA_1, C_DC_NA_1-> receiveYkResponse(asdu);
|
|
|
- }
|
|
|
- ReportValueDtoList realData = DataConverter.toRealData(this, asdu);
|
|
|
- if(realData.size() > 0) {
|
|
|
- notifyRealValue(realData);
|
|
|
- }
|
|
|
- } catch (IOException e) {
|
|
|
- throw new RuntimeException(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void receiveYtResponse(ASdu asdu){
|
|
|
- String wrrId = getWaitResponseRequestId(asdu.getTypeIdentification().getId(), asdu.getInformationObjects()[0].getInformationObjectAddress(), "");
|
|
|
- WaitResponseRequest waitResponseRequest = waitResponseMap.remove(wrrId);
|
|
|
- if(waitResponseRequest != null && waitResponseRequest.extraObject instanceof BizYtLog bizYtLog){
|
|
|
- CauseOfTransmission causeOfTransmission = asdu.getCauseOfTransmission();
|
|
|
- bizYtLog.setState((CauseOfTransmission.ACTIVATION_CON == causeOfTransmission && !asdu.isNegativeConfirm())
|
|
|
- ? OperateStateType.ES.getType()
|
|
|
- : OperateStateType.EF.getType());
|
|
|
- IBizYtLogService bean = SpringUtils.getBean(IBizYtLogService.class);
|
|
|
- bean.updateBizYtLog(bizYtLog);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void receiveYkResponse(ASdu asdu) {
|
|
|
- String wrrId = getWaitResponseRequestId(asdu.getTypeIdentification().getId(), asdu.getInformationObjects()[0].getInformationObjectAddress(), "");
|
|
|
- WaitResponseRequest waitResponseRequest = waitResponseMap.remove(wrrId);
|
|
|
- if(waitResponseRequest != null && waitResponseRequest.extraObject instanceof BizYkLog bizYkLog){
|
|
|
- CauseOfTransmission causeOfTransmission = asdu.getCauseOfTransmission();
|
|
|
- if(causeOfTransmission == CauseOfTransmission.ACTIVATION_CON){
|
|
|
- if(asdu.isNegativeConfirm()){
|
|
|
- if(StringUtils.equals(bizYkLog.getState(), OperateStateType.SE.getType())){
|
|
|
- bizYkLog.setState(OperateStateType.SF.getType());
|
|
|
- } else {
|
|
|
- bizYkLog.setState(OperateStateType.EF.getType());
|
|
|
- }
|
|
|
- }
|
|
|
- else {
|
|
|
- if(StringUtils.equals(bizYkLog.getState(), OperateStateType.SE.getType())){
|
|
|
- bizYkLog.setState(OperateStateType.SS.getType());
|
|
|
- } else {
|
|
|
- bizYkLog.setState(OperateStateType.ES.getType());
|
|
|
- }
|
|
|
- }
|
|
|
- } else if(causeOfTransmission == CauseOfTransmission.DEACTIVATION_CON){
|
|
|
- if(asdu.isNegativeConfirm()){
|
|
|
- bizYkLog.setState(OperateStateType.CF.getType());
|
|
|
- } else {
|
|
|
- bizYkLog.setState(OperateStateType.CS.getType());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- IBizYkLogService bean = SpringUtils.getBean(IBizYkLogService.class);
|
|
|
- bean.updateBizYkLog(bizYkLog);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void write(Object obj) {
|
|
|
- if(null == transmit || transmit.state() != TransmitState.CONNECTED){
|
|
|
- throw new RuntimeException("没有连接上设备");
|
|
|
- }
|
|
|
- if(obj instanceof BizYtLog bizYtLog){
|
|
|
- addYtToLazy(bizYtLog);
|
|
|
- } else if(obj instanceof BizYkLog bizYkLog){
|
|
|
- addYkToLazy(bizYkLog);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void parseMessageTask(){
|
|
|
- log.info("start channel protocol paserTask, channel={}", channel.getName());
|
|
|
- byte[] head = new byte[APdu.APCI_LENGTH];
|
|
|
- while(!isStop){
|
|
|
- boolean noData = true;
|
|
|
- if(messageCache.pick(head)){
|
|
|
- int i = 0;
|
|
|
- for(; head[i] != APdu.START_FLAG && i < head.length; ++i){
|
|
|
- }
|
|
|
- if(i > 0){
|
|
|
- // 首字节不是0x68,
|
|
|
- messageCache.remove(i);
|
|
|
- continue;
|
|
|
- }
|
|
|
- int len = head[1] & 0xff;
|
|
|
- if(len < APdu.MIN_APDU_LENGTH || len > APdu.MAX_APDU_LENGTH){
|
|
|
- // 报文长度字节有错误了
|
|
|
- messageCache.remove(2);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if(len == APdu.MIN_APDU_LENGTH){
|
|
|
- // 如果是U或者S帧
|
|
|
- messageCache.remove(APdu.APCI_LENGTH);
|
|
|
- decode(head);
|
|
|
- }
|
|
|
- else if(len + 2 <= messageCache.size()){
|
|
|
- // I帧,并且数据够,则取出解析
|
|
|
- byte[] message = new byte[len + 2];
|
|
|
- messageCache.take(message);
|
|
|
- notifyMessage(EventType.PROTOCOL_RECEIVED, message);
|
|
|
- decode(message);
|
|
|
- noData = false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(noData){
|
|
|
- synchronized (this) {
|
|
|
- try {
|
|
|
- this.wait(1000);
|
|
|
- } catch (InterruptedException ex) {
|
|
|
- log.warn("wait exception={}", ex);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- log.info("end channel protocol paserTask, channel={}", channel.getName());
|
|
|
- }
|
|
|
-
|
|
|
- private void timerTask(){
|
|
|
- log.info("start channel protocol timerTask, channel={}", channel.getName());
|
|
|
- while(!isStop){
|
|
|
- try{
|
|
|
- TransmitState transmitState = transmit.state();
|
|
|
- if(transmitState == TransmitState.DISCONNECTED || transmitState == TransmitState.STARTED){
|
|
|
- if(transmit.connect() == 0){
|
|
|
- ThreadUtil.sleep(1000);
|
|
|
- waitSendApdus.push(new LazyRequest(APdu.ApciType.STARTDT_ACT, null, null, null, System.currentTimeMillis(), 0));
|
|
|
- }else{
|
|
|
- ThreadUtil.sleep(10000);
|
|
|
- }
|
|
|
- ThreadUtil.sleep(10000);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- LazyRequest lazyRequest = waitSendApdus.poll();
|
|
|
- if(lazyRequest != null){
|
|
|
- sendLazyRequest(lazyRequest);
|
|
|
- ThreadUtil.sleep(100);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Long curTm = System.currentTimeMillis();
|
|
|
- clearWaitResponseRequest();
|
|
|
- if(curTm - last100 > tm100){
|
|
|
- send100();
|
|
|
- last100 = curTm;
|
|
|
- }
|
|
|
- else if(curTm - last103 > tm103){
|
|
|
- send103();
|
|
|
- last103 = curTm;
|
|
|
- }
|
|
|
-
|
|
|
- ThreadUtil.sleep(1000);
|
|
|
- } catch (Exception ex)
|
|
|
- {
|
|
|
- log.error("protocol timerTask occur exception, channel={}, ex={}",channel.getName(), ex.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
- log.info("end channel protocol timerTask, channel={}", channel.getName());
|
|
|
- }
|
|
|
-
|
|
|
- private void sendLazyRequest(LazyRequest lazyRequest) {
|
|
|
- boolean exist = false;
|
|
|
- long nowTm = System.currentTimeMillis();
|
|
|
- if(StringUtils.isBlank(lazyRequest.wrpId) ) {
|
|
|
- sendApdu(lazyRequest.apciType, lazyRequest.getAsdu());
|
|
|
- return;
|
|
|
- } else if(!waitResponseMap.containsKey(lazyRequest.wrpId)){
|
|
|
- sendApdu(lazyRequest.apciType, lazyRequest.getAsdu());
|
|
|
- }else {
|
|
|
- if(nowTm - lazyRequest.beginTm > lazyRequest.tmOutMs){
|
|
|
- exist = true;
|
|
|
- }
|
|
|
- else {
|
|
|
- // 重新等发送
|
|
|
- waitSendApdus.push(lazyRequest);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if(lazyRequest.extraObject instanceof BizYtLog bizYtLog){
|
|
|
- if(exist){
|
|
|
- bizYtLog.setState(OperateStateType.AL.getType());
|
|
|
- }
|
|
|
- else if(bizYtLog.getTmOut() <= 0) {
|
|
|
- bizYtLog.setState(OperateStateType.ES.getType());
|
|
|
- } else {
|
|
|
- bizYtLog.setState(OperateStateType.EX.getType());
|
|
|
- waitResponseMap.put(lazyRequest.wrpId, new WaitResponseRequest(lazyRequest.wrpId, bizYtLog, nowTm));
|
|
|
- }
|
|
|
- IBizYtLogService bean = SpringUtils.getBean(IBizYtLogService.class);
|
|
|
- bean.updateBizYtLog(bizYtLog);
|
|
|
- } else if(lazyRequest.extraObject instanceof BizYkLog bizYkLog){
|
|
|
- if(exist){
|
|
|
- bizYkLog.setState(OperateStateType.AL.getType());
|
|
|
- }
|
|
|
- else if(Objects.equals(OperateStateType.SE.getType(), bizYkLog.getState())
|
|
|
- && Objects.equals(bizYkLog.getControlStep(), ControlStepType.TWO.getType())) {
|
|
|
- waitResponseMap.put(lazyRequest.wrpId, new WaitResponseRequest(lazyRequest.wrpId, bizYkLog, nowTm));
|
|
|
- } else {
|
|
|
- if(bizYkLog.getTmOut() <= 0){
|
|
|
- bizYkLog.setState(OperateStateType.ES.getType());
|
|
|
- } else {
|
|
|
- waitResponseMap.put(lazyRequest.wrpId, new WaitResponseRequest(lazyRequest.wrpId, bizYkLog, nowTm));
|
|
|
- }
|
|
|
- }
|
|
|
- IBizYkLogService bean = SpringUtils.getBean(IBizYkLogService.class);
|
|
|
- bean.updateBizYkLog(bizYkLog);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void clearWaitResponseRequest() {
|
|
|
- for(var val : waitResponseMap.values()){
|
|
|
- if(val.extraObject instanceof BizYtLog bizYtLog){
|
|
|
- if(System.currentTimeMillis() - val.tmMs > bizYtLog.getTmOut() * 1000){
|
|
|
- if(waitResponseMap.remove(val.id) != null) {
|
|
|
- bizYtLog.setState(OperateStateType.ET.getType());
|
|
|
- IBizYtLogService bean = SpringUtils.getBean(IBizYtLogService.class);
|
|
|
- bean.updateBizYtLog(bizYtLog);
|
|
|
- }
|
|
|
- }
|
|
|
- } else if(val.extraObject instanceof BizYkLog bizYkLog){
|
|
|
- if(System.currentTimeMillis() - val.tmMs > bizYkLog.getTmOut() * 1000) {
|
|
|
- if(waitResponseMap.remove(val.id)!=null) {
|
|
|
- if(StringUtils.equals(bizYkLog.getState(), OperateStateType.SE.getType())){
|
|
|
- bizYkLog.setState(OperateStateType.ST.getType());
|
|
|
- } else if(StringUtils.equals(bizYkLog.getState(), OperateStateType.CA.getType())){
|
|
|
- bizYkLog.setState(OperateStateType.CT.getType());
|
|
|
- } else {
|
|
|
- bizYkLog.setState(OperateStateType.ET.getType());
|
|
|
- }
|
|
|
- IBizYkLogService bean = SpringUtils.getBean(IBizYkLogService.class);
|
|
|
- bean.updateBizYkLog(bizYkLog);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void sendApdu(APdu.ApciType type, ASdu aSdu){
|
|
|
- byte[] sendBuf = null;
|
|
|
- synchronized (packageBuffer) {
|
|
|
- APdu apdu = null;
|
|
|
- if(type == APdu.ApciType.I_FORMAT){
|
|
|
- int asduLength = aSdu.encode(packageBuffer, 0, settings);
|
|
|
- byte[] asduBufferCut = Arrays.copyOf(packageBuffer, asduLength);
|
|
|
- apdu = new APdu(sendSq, recSq, type, asduBufferCut);
|
|
|
- sendSq = (short)(sendSq+1);
|
|
|
- } else {
|
|
|
- apdu = new APdu(sendSq, recSq, type);
|
|
|
- }
|
|
|
- int len = apdu.encode(packageBuffer, settings);
|
|
|
- sendBuf = Arrays.copyOf(packageBuffer, len);
|
|
|
- }
|
|
|
- if(sendBuf != null){
|
|
|
- transmit.send(sendBuf);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void send100(){
|
|
|
- ASdu aSdu = new ASdu(ASduType.C_IC_NA_1,
|
|
|
- false,
|
|
|
- CauseOfTransmission.ACTIVATION,
|
|
|
- false,
|
|
|
- false,
|
|
|
- 0,
|
|
|
- 1,
|
|
|
- new InformationObject(0, new IeQualifierOfInterrogation(20)));
|
|
|
- sendApdu(APdu.ApciType.I_FORMAT, aSdu);
|
|
|
- }
|
|
|
-
|
|
|
- private void send103() {
|
|
|
- IeTime56 time = new IeTime56(System.currentTimeMillis());
|
|
|
- InformationObject io = new InformationObject(0, time);
|
|
|
- ASdu asdu = new ASdu(ASduType.C_CS_NA_1,
|
|
|
- false,
|
|
|
- CauseOfTransmission.ACTIVATION,
|
|
|
- false,
|
|
|
- false,
|
|
|
- 0,
|
|
|
- settings.getCommonAddress(),
|
|
|
- io);
|
|
|
- sendApdu(APdu.ApciType.I_FORMAT, asdu);
|
|
|
- }
|
|
|
-
|
|
|
- private void addYtToLazy(BizYtLog bizYtLog){
|
|
|
- Integer iFunCode = Convert.toInt(bizYtLog.getFun());
|
|
|
- if(iFunCode == null){
|
|
|
- throw new ServiceException("fun value is invalid, val=" + bizYtLog.getFun());
|
|
|
- }
|
|
|
- Integer addr = Convert.toInt(bizYtLog.getAddrCode());
|
|
|
- if(addr == null){
|
|
|
- throw new ServiceException("addr code value is invalid, addrCode=" + bizYtLog.getAddrCode());
|
|
|
- }
|
|
|
- Float ytVal = Convert.toFloat(bizYtLog.getControlVal());
|
|
|
- if(ytVal == null){
|
|
|
- throw new ServiceException("yt value is invalid, val=" + bizYtLog.getControlVal());
|
|
|
- }
|
|
|
-
|
|
|
- IeQualifierOfSetPointCommand qualifier = new IeQualifierOfSetPointCommand(0, false);
|
|
|
- InformationObject io;
|
|
|
- ASduType aSduType = ASduType.typeFor(iFunCode);
|
|
|
- if(aSduType == ASduType.C_SE_NC_1) {
|
|
|
- IeShortFloat val = new IeShortFloat(ytVal);
|
|
|
- io = new InformationObject(addr.intValue(), val, qualifier);
|
|
|
- } else if(aSduType == ASduType.C_SE_NA_1) {
|
|
|
- IeNormalizedValue val = new IeNormalizedValue(ytVal.intValue());
|
|
|
- io = new InformationObject(addr.intValue(), val, qualifier);
|
|
|
- } else {
|
|
|
- throw new ServiceException("fun value is invalid, val=" + bizYtLog.getFun());
|
|
|
- }
|
|
|
- ASdu aSdu = new ASdu(aSduType,
|
|
|
- false,
|
|
|
- CauseOfTransmission.ACTIVATION,
|
|
|
- false,
|
|
|
- false,
|
|
|
- settings.getOriginAddress(),
|
|
|
- settings.getCommonAddress(),
|
|
|
- io);
|
|
|
- String wrqId = getWaitResponseRequestId(aSduType.getId(), addr.intValue(), "");
|
|
|
- waitSendApdus.push(new LazyRequest(APdu.ApciType.I_FORMAT, aSdu, bizYtLog, wrqId, System.currentTimeMillis(), bizYtLog.getTmOut() * 1000));
|
|
|
- }
|
|
|
-
|
|
|
- private void addYkToLazy(BizYkLog bizYkLog) {
|
|
|
- Integer ykVal = null;
|
|
|
- if(Objects.equals(bizYkLog.getControlVal(), ControlType.OPEN.getType())){
|
|
|
- ykVal = 0;
|
|
|
- } else if(Objects.equals(bizYkLog.getControlVal(), ControlType.CLOSE.getType())){
|
|
|
- ykVal = 1;
|
|
|
- }
|
|
|
- if(ykVal == null){
|
|
|
- log.error("yk value is invalid, val={}", bizYkLog.getControlVal());
|
|
|
- throw new ServiceException("yk value is invalid, val=" + bizYkLog.getControlVal());
|
|
|
- }
|
|
|
-
|
|
|
- Integer addr = Convert.toInt(bizYkLog.getAddrCode());
|
|
|
- if(addr == null){
|
|
|
- log.error("addr code value is invalid, addrCode={}", bizYkLog.getAddrCode());
|
|
|
- throw new ServiceException("addr code value is invalid, addrCode=" + bizYkLog.getAddrCode());
|
|
|
- }
|
|
|
- boolean isSelect = OperateStateType.SE.getType().equals(bizYkLog.getState());
|
|
|
-
|
|
|
- int fun = Convert.toInt(bizYkLog.getFun(), 45);
|
|
|
- InformationElement val;
|
|
|
- ASduType ti = ASduType.C_SC_NA_1;
|
|
|
- if(fun == ASduType.C_DC_NA_1.getId()){
|
|
|
- val = new IeDoubleCommand((ykVal.intValue()!=0? IeDoubleCommand.DoubleCommandState.ON: IeDoubleCommand.DoubleCommandState.OFF), 0, isSelect);
|
|
|
- ti = ASduType.C_DC_NA_1;
|
|
|
- } else {
|
|
|
- val = new IeSingleCommand(ykVal.intValue()!=0, 0, isSelect);
|
|
|
- }
|
|
|
- CauseOfTransmission cot = StringUtils.equals(OperateStateType.CA.getType(), bizYkLog.getState())? CauseOfTransmission.DEACTIVATION: CauseOfTransmission.ACTIVATION;
|
|
|
- InformationObject io = new InformationObject(addr, val);
|
|
|
- ASdu aSdu = new ASdu(ti,
|
|
|
- false,
|
|
|
- cot,
|
|
|
- false,
|
|
|
- false,
|
|
|
- settings.getOriginAddress(),
|
|
|
- settings.getCommonAddress(),
|
|
|
- io);
|
|
|
- String wrqId = getWaitResponseRequestId(ti.getId(), addr.intValue(), "");
|
|
|
- waitSendApdus.push(new LazyRequest(APdu.ApciType.I_FORMAT, aSdu, bizYkLog, wrqId, System.currentTimeMillis(), bizYkLog.getTmOut() * 1000));
|
|
|
- }
|
|
|
-
|
|
|
- static String getWaitResponseRequestId(int cmd, int ioa, String val){
|
|
|
- return "" + cmd + "-" + ioa;
|
|
|
- }
|
|
|
-
|
|
|
- @Data
|
|
|
- @AllArgsConstructor
|
|
|
- static class LazyRequest{
|
|
|
- private APdu.ApciType apciType;
|
|
|
- private ASdu asdu;
|
|
|
- private Object extraObject;
|
|
|
- private String wrpId;
|
|
|
- private long beginTm;
|
|
|
- private long tmOutMs;
|
|
|
- }
|
|
|
-
|
|
|
- @Data
|
|
|
- @AllArgsConstructor
|
|
|
- static class WaitResponseRequest{
|
|
|
- private String id;
|
|
|
- private Object extraObject;
|
|
|
- // 开始时间
|
|
|
- private long tmMs;
|
|
|
- }
|
|
|
-}
|