SendAndReceiveNumUtil.java 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package wei.yigulu.iec104.util;
  2. import io.netty.buffer.Unpooled;
  3. import io.netty.channel.Channel;
  4. import io.netty.channel.ChannelId;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import wei.yigulu.iec104.apdumodel.Apdu;
  8. import wei.yigulu.iec104.container.Iec104Link;
  9. import wei.yigulu.iec104.container.LinkContainer;
  10. import wei.yigulu.utils.DataConvertor;
  11. /**
  12. * 用以处理接收和发送序列号的处理类
  13. *
  14. * @author 修唯xiuwei
  15. * @version 3.0
  16. */
  17. public class SendAndReceiveNumUtil {
  18. private static Logger log = LoggerFactory.getLogger(SendAndReceiveNumUtil.class);
  19. private static final String INTERVALPROPNAME = "sFrameInterval";
  20. private static final int INTERVALDEFVAL = 5;
  21. private static final int INTERVAL = PropertiesReader.getInstance().getIntProp(INTERVALPROPNAME, INTERVALDEFVAL);
  22. /**
  23. * 为发送的i帧组装接收和发送序号
  24. *
  25. * @param apdu apdu
  26. * @param channelId channel id
  27. */
  28. public static void setSendAndReceiveNum(Apdu apdu, ChannelId channelId) {
  29. Iec104Link link = LinkContainer.getInstance().getLink(channelId);
  30. int send = link.getISend();
  31. int receive = link.getIReceive();
  32. apdu.setSendSeqNum(send++);
  33. apdu.setReceiveSeqNum(receive);
  34. link.setISend(send);
  35. LinkContainer.getInstance().getLinks().put(channelId, link);
  36. }
  37. /**
  38. * 组装i帧的发送和接收序号 后发出
  39. *
  40. * @param apdu apdu
  41. * @param channel channel
  42. * @throws Exception exception
  43. */
  44. public static void sendIFrame(Apdu apdu, Channel channel) throws Exception {
  45. setSendAndReceiveNum(apdu, channel.id());
  46. byte[] bb = apdu.encode();
  47. //TODO 改变日志模式
  48. log.debug("向104对端发出数据帧:" + DataConvertor.Byte2String(bb));
  49. channel.writeAndFlush(Unpooled.copiedBuffer(bb));
  50. }
  51. /**
  52. * 组装i帧的发送和接收序号 后发出
  53. *
  54. * @param apdu apdu
  55. * @param channel channel
  56. * @throws Exception exception
  57. */
  58. public static void sendIFrame(Apdu apdu, Channel channel, Logger log) throws Exception {
  59. setSendAndReceiveNum(apdu, channel.id());
  60. byte[] bb = apdu.encode();
  61. //TODO 改变日志模式
  62. if (log != null) {
  63. log.debug("向104对端发出数据帧:" + DataConvertor.Byte2String(bb));
  64. } else {
  65. SendAndReceiveNumUtil.log.debug("向104对端发出数据帧:" + DataConvertor.Byte2String(bb));
  66. }
  67. channel.writeAndFlush(Unpooled.copiedBuffer(bb));
  68. }
  69. /**
  70. * 接收到i帧,处理接收和发送序号
  71. *
  72. * @param apdu apdu
  73. * @param channelId channel id
  74. */
  75. public static void receiveIFrame(Apdu apdu, ChannelId channelId) {
  76. Iec104Link link = LinkContainer.getInstance().getLink(channelId);
  77. int send = link.getISend();
  78. int receive = link.getIReceive();
  79. int send1 = apdu.getSendSeqNum();
  80. int receive1 = apdu.getReceiveSeqNum();
  81. link.setLinkState(Iec104Link.LinkState.NORMAL);
  82. if (receive < send1) {
  83. /**
  84. * 我方丢失 通道对方放出的 i帧
  85. */
  86. apdu.loseReceive();
  87. link.setLinkState(Iec104Link.LinkState.LOSEREC);
  88. }
  89. if (send < receive1) {
  90. /**
  91. * 通道对方丢失 我方发出的i帧
  92. */
  93. apdu.loseSend();
  94. link.setLinkState(Iec104Link.LinkState.LOSESEND);
  95. }
  96. link.setIReceive(++send1);
  97. link.setISend(receive1);
  98. sendSFrame(link);
  99. LinkContainer.getInstance().getLinks().put(channelId, link);
  100. }
  101. /**
  102. * 向通道内发送s帧
  103. *
  104. * @param link link
  105. */
  106. public static void sendSFrame(Iec104Link link) {
  107. if (link.getIReceive() != 0 && link.getIReceive() % INTERVAL == 0) {
  108. Apdu apdu1 = new Apdu();
  109. apdu1.setReceiveSeqNum(link.getIReceive());
  110. apdu1.setApciType(Apdu.ApciType.S_FORMAT);
  111. try {
  112. byte[] bs = apdu1.encode();
  113. //TODO 改变日志模式
  114. link.getLog().debug("发送s帧:" + DataConvertor.Byte2String(bs));
  115. link.getChannel().writeAndFlush(Unpooled.copiedBuffer(bs));
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. }
  119. }
  120. }
  121. }