From 5516c939bfc85a8c29a58da21d5e4d9a1ae66219 Mon Sep 17 00:00:00 2001 From: kenta-shimizu Date: Sat, 27 Jan 2024 20:16:58 +0900 Subject: [PATCH] 2024-01-27T20:16 --- .../AbstractHsmsGsActiveCommunicator.java | 15 +- .../AbstractHsmsGsPassiveCommunicator.java | 15 +- .../AbstractHsmsSsActiveCommunicator.java | 15 +- .../AbstractHsmsSsPassiveCommunicator.java | 15 +- .../secs/impl/AbstractSecsMessageBuilder.java | 61 +++ .../secs/impl/SecsMessageBuilder.java | 24 ++ .../secs1/impl/AbstractSecs1Communicator.java | 6 +- .../impl/AbstractSecs1MessageBuilder.java | 86 +--- .../secs/secs1/impl/Secs1MessageBuilder.java | 14 +- .../secs/SecsCommunicatorTest.java | 2 +- .../secs/secs1/Secs1MessageTest.java | 234 ++++++++++- .../secs1/impl/Secs1MessageBuilderTest.java | 394 ++++++++++++++++++ 12 files changed, 776 insertions(+), 105 deletions(-) create mode 100644 src/main/java/com/shimizukenta/secs/impl/AbstractSecsMessageBuilder.java create mode 100644 src/main/java/com/shimizukenta/secs/impl/SecsMessageBuilder.java create mode 100644 src/test/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilderTest.java diff --git a/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsActiveCommunicator.java b/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsActiveCommunicator.java index b9ea06c8..b0b68a3c 100644 --- a/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsActiveCommunicator.java +++ b/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsActiveCommunicator.java @@ -9,22 +9,27 @@ import com.shimizukenta.secs.UnsetSocketAddressException; import com.shimizukenta.secs.hsms.HsmsCommunicateState; import com.shimizukenta.secs.hsms.HsmsConnectionMode; -import com.shimizukenta.secs.hsms.HsmsConnectionModeIllegalStateException; import com.shimizukenta.secs.hsmsgs.HsmsGsCommunicatorConfig; public abstract class AbstractHsmsGsActiveCommunicator extends AbstractHsmsGsCommunicator { public AbstractHsmsGsActiveCommunicator(HsmsGsCommunicatorConfig config) { super(config); + + config.connectionMode().addChangeListener(mode -> { + if (mode != HsmsConnectionMode.ACTIVE) { + try { + this.close(); + } + catch (IOException giveup) { + } + } + }); } @Override public void open() throws IOException { - if ( this.config().connectionMode().get() != HsmsConnectionMode.ACTIVE ) { - throw new HsmsConnectionModeIllegalStateException("NOT ACTIVE"); - } - super.open(); this.executorService().execute(() -> { diff --git a/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsPassiveCommunicator.java b/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsPassiveCommunicator.java index d0f465d8..44c1423a 100644 --- a/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsPassiveCommunicator.java +++ b/src/main/java/com/shimizukenta/secs/hsmsgs/impl/AbstractHsmsGsPassiveCommunicator.java @@ -10,7 +10,6 @@ import com.shimizukenta.secs.UnsetSocketAddressException; import com.shimizukenta.secs.hsms.HsmsCommunicateState; import com.shimizukenta.secs.hsms.HsmsConnectionMode; -import com.shimizukenta.secs.hsms.HsmsConnectionModeIllegalStateException; import com.shimizukenta.secs.hsmsgs.HsmsGsCommunicatorConfig; import com.shimizukenta.secs.local.property.TimeoutProperty; @@ -18,15 +17,21 @@ public abstract class AbstractHsmsGsPassiveCommunicator extends AbstractHsmsGsCo public AbstractHsmsGsPassiveCommunicator(HsmsGsCommunicatorConfig config) { super(config); + + config.connectionMode().addChangeListener(mode -> { + if (mode != HsmsConnectionMode.PASSIVE) { + try { + this.close(); + } + catch (IOException giveup) { + } + } + }); } @Override public void open() throws IOException { - if ( this.config().connectionMode().get() != HsmsConnectionMode.PASSIVE ) { - throw new HsmsConnectionModeIllegalStateException("NOT PASSIVE"); - } - super.open(); this.executorService().execute(() -> { diff --git a/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsActiveCommunicator.java b/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsActiveCommunicator.java index e244110e..42014512 100644 --- a/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsActiveCommunicator.java +++ b/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsActiveCommunicator.java @@ -16,7 +16,6 @@ import com.shimizukenta.secs.UnsetSocketAddressException; import com.shimizukenta.secs.hsms.HsmsCommunicateState; import com.shimizukenta.secs.hsms.HsmsConnectionMode; -import com.shimizukenta.secs.hsms.HsmsConnectionModeIllegalStateException; import com.shimizukenta.secs.hsms.HsmsException; import com.shimizukenta.secs.hsms.HsmsMessage; import com.shimizukenta.secs.hsms.HsmsMessageRejectReason; @@ -30,15 +29,21 @@ public abstract class AbstractHsmsSsActiveCommunicator extends AbstractHsmsSsCom public AbstractHsmsSsActiveCommunicator(HsmsSsCommunicatorConfig config) { super(Objects.requireNonNull(config)); + + config.connectionMode().addChangeListener(mode -> { + if (mode != HsmsConnectionMode.ACTIVE) { + try { + this.close(); + } + catch (IOException giveup) { + } + } + }); } @Override public void open() throws IOException { - if ( this.config().connectionMode().get() != HsmsConnectionMode.ACTIVE ) { - throw new HsmsConnectionModeIllegalStateException("NOT ACTIVE"); - } - super.open(); this.executorService().execute(() -> { diff --git a/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsPassiveCommunicator.java b/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsPassiveCommunicator.java index 787915c9..df8f16ab 100644 --- a/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsPassiveCommunicator.java +++ b/src/main/java/com/shimizukenta/secs/hsmsss/impl/AbstractHsmsSsPassiveCommunicator.java @@ -17,7 +17,6 @@ import com.shimizukenta.secs.UnsetSocketAddressException; import com.shimizukenta.secs.hsms.HsmsCommunicateState; import com.shimizukenta.secs.hsms.HsmsConnectionMode; -import com.shimizukenta.secs.hsms.HsmsConnectionModeIllegalStateException; import com.shimizukenta.secs.hsms.HsmsException; import com.shimizukenta.secs.hsms.HsmsMessage; import com.shimizukenta.secs.hsms.HsmsMessageRejectReason; @@ -45,15 +44,21 @@ public abstract class AbstractHsmsSsPassiveCommunicator extends AbstractHsmsSsCo public AbstractHsmsSsPassiveCommunicator(HsmsSsCommunicatorConfig config) { super(Objects.requireNonNull(config)); + + config.connectionMode().addChangeListener(mode -> { + if (mode != HsmsConnectionMode.PASSIVE) { + try { + this.close(); + } + catch (IOException giveup) { + } + } + }); } @Override public void open() throws IOException { - if ( this.config().connectionMode().get() != HsmsConnectionMode.PASSIVE ) { - throw new HsmsConnectionModeIllegalStateException("NOT PASSIVE"); - } - super.open(); this.executorService().execute(() -> { diff --git a/src/main/java/com/shimizukenta/secs/impl/AbstractSecsMessageBuilder.java b/src/main/java/com/shimizukenta/secs/impl/AbstractSecsMessageBuilder.java new file mode 100644 index 00000000..afb45f9d --- /dev/null +++ b/src/main/java/com/shimizukenta/secs/impl/AbstractSecsMessageBuilder.java @@ -0,0 +1,61 @@ +package com.shimizukenta.secs.impl; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.shimizukenta.secs.SecsCommunicator; +import com.shimizukenta.secs.SecsMessage; +import com.shimizukenta.secs.secs2.Secs2; + +public abstract class AbstractSecsMessageBuilder implements SecsMessageBuilder { + + private final AtomicInteger autoNum; + + public AbstractSecsMessageBuilder() { + this.autoNum = new AtomicInteger(0); + } + +// abstract protected boolean isEquip(); +// +// abstract protected byte[] device2Bytes(); + + abstract protected boolean isEquip(C communicator); + + abstract protected byte[] device2Bytes(C communicator); + + protected byte[] system4Bytes(C communicator) { + + final int num = autoNum.incrementAndGet(); + + if (isEquip(communicator)) { + + byte[] dev2bs = this.device2Bytes(communicator); + + return new byte[] { + dev2bs[0], + dev2bs[1], + (byte)(num >> 8), + (byte)num + }; + + } else { + + return new byte[] { + (byte)0x00, + (byte)0x00, + (byte)(num >> 8), + (byte)num + }; + } + } + + @Override + public M build(C communicator, int strm, int func, boolean wbit) { + return this.build(communicator, strm, func, wbit, Secs2.empty()); + } + + @Override + public M build(C communicator, SecsMessage primaryMsg, int strm, int func, boolean wbit) { + return this.build(communicator, primaryMsg, strm, func, wbit, Secs2.empty()); + } + +} diff --git a/src/main/java/com/shimizukenta/secs/impl/SecsMessageBuilder.java b/src/main/java/com/shimizukenta/secs/impl/SecsMessageBuilder.java new file mode 100644 index 00000000..04666a6c --- /dev/null +++ b/src/main/java/com/shimizukenta/secs/impl/SecsMessageBuilder.java @@ -0,0 +1,24 @@ +package com.shimizukenta.secs.impl; + +import com.shimizukenta.secs.SecsCommunicator; +import com.shimizukenta.secs.SecsMessage; +import com.shimizukenta.secs.secs2.Secs2; + +/** + * SsecsMeessageBuilder. + * + * @author kenta-shimizu + * + * @param the Secs-Message extends + * @param the SecsCommunicator extends + */ +public interface SecsMessageBuilder { + + public M build(C communicator, int strm, int func, boolean wbit); + + public M build(C communicator, int strm, int func, boolean wbit, Secs2 body); + + public M build(C communicator, SecsMessage primaryMsg, int strm, int func, boolean wbit); + + public M build(C communicator, SecsMessage primaryMsg, int strm, int func, boolean wbit, Secs2 body); +} diff --git a/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1Communicator.java b/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1Communicator.java index b6ad1a41..08a89fbf 100644 --- a/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1Communicator.java +++ b/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1Communicator.java @@ -45,7 +45,7 @@ public abstract class AbstractSecs1Communicator extends AbstractSecsCommunicator public AbstractSecs1Communicator(AbstractSecs1CommunicatorConfig config) { super(config); this.config = config; - this.msgBuilder = new AbstractSecs1MessageBuilder(this) {}; + this.msgBuilder = new AbstractSecs1MessageBuilder() {}; this.circuit = new AbstractSecs1Circuit(this) {}; this.secs1MsgRecvQueueBiObserver = new Secs1MessageReceiveQueueBiObserver(this); @@ -91,7 +91,7 @@ public Optional templateSend(int strm, int func, boolean wbit, Secs try { - return this.circuit.send(this.messageBuilder().build(strm, func, wbit, secs2)) + return this.circuit.send(this.messageBuilder().build(this, strm, func, wbit, secs2)) .map(m -> (SecsMessage)m); } catch (Secs1TooBigMessageBodyException e) { @@ -104,7 +104,7 @@ public Optional templateSend(SecsMessage primaryMsg, int strm, int throws SecsSendMessageException, SecsWaitReplyMessageException, SecsException, InterruptedException { try { - return this.circuit.send(this.messageBuilder().build(primaryMsg, strm, func, wbit, secs2)) + return this.circuit.send(this.messageBuilder().build(this, primaryMsg, strm, func, wbit, secs2)) .map(m -> (SecsMessage)m); } catch (Secs1TooBigMessageBodyException e) { diff --git a/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1MessageBuilder.java b/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1MessageBuilder.java index 37fec6a1..3590494a 100644 --- a/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1MessageBuilder.java +++ b/src/main/java/com/shimizukenta/secs/secs1/impl/AbstractSecs1MessageBuilder.java @@ -4,85 +4,46 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.concurrent.atomic.AtomicInteger; import com.shimizukenta.secs.SecsMessage; +import com.shimizukenta.secs.impl.AbstractSecsMessageBuilder; +import com.shimizukenta.secs.secs1.Secs1Communicator; import com.shimizukenta.secs.secs1.Secs1MessageBlock; import com.shimizukenta.secs.secs1.Secs1TooBigMessageBodyException; import com.shimizukenta.secs.secs2.Secs2; import com.shimizukenta.secs.secs2.Secs2BytesParseException; import com.shimizukenta.secs.secs2.impl.Secs2BytesParsers; -public abstract class AbstractSecs1MessageBuilder implements Secs1MessageBuilder { +public abstract class AbstractSecs1MessageBuilder extends AbstractSecsMessageBuilder implements Secs1MessageBuilder { - private final AbstractSecs1Communicator comm; - - public AbstractSecs1MessageBuilder(AbstractSecs1Communicator communicator) { - this.comm = communicator; + public AbstractSecs1MessageBuilder() { + /* Nothing */ } - private final AtomicInteger autoNumber = new AtomicInteger(0); - - protected byte[] getAutoNumber2Bytes() { - int n = autoNumber.incrementAndGet(); - return new byte[] { - (byte)(n >> 8), - (byte)n - }; + @Override + protected boolean isEquip(Secs1Communicator communicator) { + return communicator.isEquip(); } - protected byte[] getDeviceId2Bytes() { - int n = this.comm.deviceId(); + @Override + protected byte[] device2Bytes(Secs1Communicator communicator) { + int n = communicator.deviceId(); return new byte[] { (byte)((n >> 8) & 0x7F), (byte)n }; } - protected byte[] getSystem4Bytes() { - - byte[] aa = this.getAutoNumber2Bytes(); - - if ( this.comm.isEquip() ) { - - byte[] ss = this.getDeviceId2Bytes(); - - return new byte[] { - ss[0], - ss[1], - aa[0], - aa[1] - }; - - } else { - - return new byte[] { - (byte)0x0, - (byte)0x0, - aa[0], - aa[1] - }; - } - } - - @Override - public AbstractSecs1Message build( - int strm, - int func, - boolean wbit) { - - return this.build(strm, func, wbit, Secs2.empty()); - } - @Override public AbstractSecs1Message build( + Secs1Communicator communicator, int strm, int func, boolean wbit, Secs2 body) { - byte[] dd = this.getDeviceId2Bytes(); - byte[] ssss = this.getSystem4Bytes(); + byte[] dd = this.device2Bytes(communicator); + byte[] ssss = this.system4Bytes(communicator); byte[] header = new byte[] { dd[0], @@ -97,7 +58,7 @@ public AbstractSecs1Message build( ssss[3] }; - if ( this.comm.isEquip() ) { + if ( this.isEquip(communicator) ) { header[0] |= (byte)0x80; } @@ -107,26 +68,17 @@ public AbstractSecs1Message build( return build(header, body); } - - @Override - public AbstractSecs1Message build( - SecsMessage primaryMsg, - int strm, - int func, - boolean wbit) { - - return this.build(primaryMsg, strm, func, wbit, Secs2.empty()); - } - + @Override public AbstractSecs1Message build( + Secs1Communicator communicator, SecsMessage primaryMsg, int strm, int func, boolean wbit, Secs2 body) { - byte[] dd = this.getDeviceId2Bytes(); + byte[] dd = this.device2Bytes(communicator); byte[] ppbb = primaryMsg.header10Bytes(); byte[] header = new byte[] { @@ -142,7 +94,7 @@ public AbstractSecs1Message build( ppbb[9] }; - if ( this.comm.isEquip() ) { + if ( this.isEquip(communicator) ) { header[0] |= (byte)0x80; } diff --git a/src/main/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilder.java b/src/main/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilder.java index 5eebc7cf..f3e8f4c2 100644 --- a/src/main/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilder.java +++ b/src/main/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilder.java @@ -2,24 +2,18 @@ import java.util.List; -import com.shimizukenta.secs.SecsMessage; +import com.shimizukenta.secs.impl.SecsMessageBuilder; +import com.shimizukenta.secs.secs1.Secs1Communicator; import com.shimizukenta.secs.secs1.Secs1MessageBlock; import com.shimizukenta.secs.secs2.Secs2; /** + * SECS-I-Message builder. * * @author kenta-shimizu * */ -public interface Secs1MessageBuilder { - - public AbstractSecs1Message build(int strm, int func, boolean wbit); - - public AbstractSecs1Message build(int strm, int func, boolean wbit, Secs2 body); - - public AbstractSecs1Message build(SecsMessage primaryMsg, int strm, int func, boolean wbit); - - public AbstractSecs1Message build(SecsMessage primaryMsg, int strm, int func, boolean wbit, Secs2 body); +public interface Secs1MessageBuilder extends SecsMessageBuilder { public static AbstractSecs1Message build(byte[] header) { return AbstractSecs1MessageBuilder.build(header); diff --git a/src/test/java/com/shimizukenta/secs/SecsCommunicatorTest.java b/src/test/java/com/shimizukenta/secs/SecsCommunicatorTest.java index 926dceda..a539c06f 100644 --- a/src/test/java/com/shimizukenta/secs/SecsCommunicatorTest.java +++ b/src/test/java/com/shimizukenta/secs/SecsCommunicatorTest.java @@ -328,7 +328,7 @@ void testRun() { assertEquals(tiack, TIACK.OK); } { - SmlMessage smlMsg = SmlMessage.of(" op = host.send(smlMsg); assertEquals(op.map(SecsMessage::getStream) diff --git a/src/test/java/com/shimizukenta/secs/secs1/Secs1MessageTest.java b/src/test/java/com/shimizukenta/secs/secs1/Secs1MessageTest.java index 2e811a07..d0632553 100644 --- a/src/test/java/com/shimizukenta/secs/secs1/Secs1MessageTest.java +++ b/src/test/java/com/shimizukenta/secs/secs1/Secs1MessageTest.java @@ -1,14 +1,240 @@ package com.shimizukenta.secs.secs1; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import com.shimizukenta.secs.secs2.Secs2; +import com.shimizukenta.secs.secs2.Secs2Item; + class Secs1MessageTest { @Test - void test() { - fail("Not yet implemented"); + @DisplayName("Secs1Message#of empty") + void testOfEmpty() { + + final byte[] header10Bytes = new byte[] { + (byte)0x00, (byte)0x0A, + (byte)0x81, (byte)0x01, + (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 + }; + + Secs1Message msg = Secs1Message.of(header10Bytes); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 1); + assertEquals(wbit, true); + + assertEquals(body.isEmpty(), true); + + assertEquals(rbit, false); + assertEquals(deviceId, 10); + + final List blocks = msg.toBlocks(); + { + assertEquals(blocks.isEmpty(), false); + assertEquals(blocks.size(), 1); + + { + Secs1MessageBlock block = blocks.get(0); + byte[] bs = block.getBytes(); + + assertEquals(bs[0], (byte)0xA); + assertEquals(bs[1], header10Bytes[0]); + assertEquals(bs[2], header10Bytes[1]); + assertEquals(bs[3], header10Bytes[2]); + assertEquals(bs[4], header10Bytes[3]); + assertEquals(bs[5], (byte)0x80); + assertEquals(bs[6], (byte)0x01); + assertEquals(bs[7], header10Bytes[6]); + assertEquals(bs[8], header10Bytes[7]); + assertEquals(bs[9], header10Bytes[8]); + assertEquals(bs[10], header10Bytes[9]); + + assertEquals(block.isValid(), true); + assertEquals(block.isFirstBlock(), true); + assertEquals(block.ebit(), true); + } + + } } - + + @Test + @DisplayName("Secs1Message#of list") + void testOfList() { + + final byte[] header10Bytes = new byte[] { + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 + }; + + Secs1Message msg = Secs1Message.of(header10Bytes, Secs2.list()); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 2); + assertEquals(wbit, false); + + assertEquals(body.isEmpty(), false); + assertEquals(body.secs2Item(), Secs2Item.LIST); + assertEquals(body.size(), 0); + + assertEquals(rbit, true); + assertEquals(deviceId, 10); + + final List blocks = msg.toBlocks(); + { + assertEquals(blocks.isEmpty(), false); + assertEquals(blocks.size(), 1); + + { + Secs1MessageBlock block = blocks.get(0); + byte[] bs = block.getBytes(); + + assertEquals(bs[0], (byte)0xC); + assertEquals(bs[1], header10Bytes[0]); + assertEquals(bs[2], header10Bytes[1]); + assertEquals(bs[3], header10Bytes[2]); + assertEquals(bs[4], header10Bytes[3]); + assertEquals(bs[5], (byte)0x80); + assertEquals(bs[6], (byte)0x01); + assertEquals(bs[7], header10Bytes[6]); + assertEquals(bs[8], header10Bytes[7]); + assertEquals(bs[9], header10Bytes[8]); + assertEquals(bs[10], header10Bytes[9]); + assertEquals(bs[11], (byte)0x01); + assertEquals(bs[12], (byte)0x00); + + assertEquals(block.isValid(), true); + assertEquals(block.isFirstBlock(), true); + assertEquals(block.ebit(), true); + } + + } + } + + @Test + @DisplayName("Secs1Message#of Single-blocks") + void testOfSingleBlocks() { + + Secs1MessageBlock block = Secs1MessageBlock.of(new byte[] { + (byte)0x0A, + (byte)0x00, (byte)0x0A, + (byte)0x81, (byte)0x01, + (byte)0x80, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x01, (byte)0x0E + }); + + assertEquals(block.isValid(), true); + + Secs1Message msg = Secs1Message.of(Arrays.asList(block)); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 1); + assertEquals(wbit, true); + + assertEquals(body.isEmpty(), true); + + assertEquals(rbit, false); + assertEquals(deviceId, 10); + + assertEquals(msg.toBlocks().size(), 1); + } + + @Test + @DisplayName("Secs1Message#of Multi-blocks") + void testOfMultiBlocks() { + + Secs1MessageBlock block1 = Secs1MessageBlock.of(new byte[] { + (byte)0x0B, + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x01, + (byte)0x00, (byte)0x90 + }); + + Secs1MessageBlock block2 = Secs1MessageBlock.of(new byte[] { + (byte)0x0B, + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x80, (byte)0x02, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x00, + (byte)0x01, (byte)0x10 + }); + + assertEquals(block1.isValid(), true); + assertEquals(block1.ebit(), false); + assertEquals(block1.isFirstBlock(), true); + assertEquals(block2.isValid(), true); + assertEquals(block2.ebit(), true); + assertEquals(block2.isFirstBlock(), false); + + Secs1Message msg = Secs1Message.of(Arrays.asList(block1, block2)); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 2); + assertEquals(wbit, false); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(body.isEmpty(), false); + assertEquals(body.secs2Item(), Secs2Item.LIST); + assertEquals(body.size(), 0); + + assertEquals(rbit, true); + assertEquals(deviceId, 10); + + assertEquals(msg.toBlocks().size(), 2); + } + } diff --git a/src/test/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilderTest.java b/src/test/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilderTest.java new file mode 100644 index 00000000..46fa93ce --- /dev/null +++ b/src/test/java/com/shimizukenta/secs/secs1/impl/Secs1MessageBuilderTest.java @@ -0,0 +1,394 @@ +package com.shimizukenta.secs.secs1.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.net.InetSocketAddress; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.shimizukenta.secs.secs1.Secs1Communicator; +import com.shimizukenta.secs.secs1.Secs1Message; +import com.shimizukenta.secs.secs1.Secs1MessageBlock; +import com.shimizukenta.secs.secs1ontcpip.Secs1OnTcpIpCommunicatorConfig; +import com.shimizukenta.secs.secs1ontcpip.impl.AbstractSecs1OnTcpIpCommunicator; +import com.shimizukenta.secs.secs2.Secs2; +import com.shimizukenta.secs.secs2.Secs2Item; + +class Secs1MessageBuilderTest { + + private static Secs1OnTcpIpCommunicatorConfig buildConfig(int deviceId, boolean isEquip) { + Secs1OnTcpIpCommunicatorConfig config = new Secs1OnTcpIpCommunicatorConfig(); + config.socketAddress(new InetSocketAddress("127.0.0.1", 0)); + config.deviceId(deviceId); + config.isEquip(isEquip); + return config; + } + + private static AbstractSecs1OnTcpIpCommunicator buildCommunicator(Secs1OnTcpIpCommunicatorConfig config) { + return new AbstractSecs1OnTcpIpCommunicator(config) {}; + } + + private static Secs1MessageBuilder getBuilder() { + return new AbstractSecs1MessageBuilder() {}; + } + + @Test + @DisplayName("EquipPrimaryMessage") + void testEquipPrimaryMessage() { + final int deviceId = 10; + final boolean isEquip = true; + final int strm = 1; + final int func = 1; + final boolean wbit = true; + + final Secs1Communicator equipComm = buildCommunicator(buildConfig(deviceId, isEquip)); + final Secs1MessageBuilder builder = getBuilder(); + + Secs1Message msg = builder.build(equipComm, strm, func, wbit); + + assertEquals(msg.getStream(), strm); + assertEquals(msg.getFunction(), func); + assertEquals(msg.wbit(), wbit); + assertEquals(msg.secs2().isEmpty(), true); + assertEquals(msg.rbit(), isEquip); + assertEquals(msg.deviceId(), deviceId); + + { + byte[] header10Bytes = msg.header10Bytes(); + assertEquals((byte)((deviceId >> 8) & 0x7F), header10Bytes[6]); + assertEquals((byte)deviceId, header10Bytes[7]); + } + } + + @Test + @DisplayName("HostPrimaryMessage") + void testHostPrimaryMessage() { + final int deviceId = 200; + final boolean isEquip = false; + final int strm = 55; + final int func = 99; + final boolean wbit = false; + final Secs2 body = Secs2.list(); + + final Secs1Communicator hostComm = buildCommunicator(buildConfig(deviceId, isEquip)); + final Secs1MessageBuilder builder = getBuilder(); + + Secs1Message msg = builder.build(hostComm, strm, func, wbit, body); + + assertEquals(msg.getStream(), strm); + assertEquals(msg.getFunction(), func); + assertEquals(msg.wbit(), wbit); + assertEquals(msg.secs2().isEmpty(), false); + assertEquals(msg.rbit(), isEquip); + assertEquals(msg.deviceId(), deviceId); + + { + byte[] header10Bytes = msg.header10Bytes(); + assertEquals((byte)0x00, header10Bytes[6]); + assertEquals((byte)0x00, header10Bytes[7]); + } + } + + @Test + @DisplayName("EquipRepryMessage") + void testEquipReplyMessage() { + final int deviceId = 2000; + final int strm = 99; + final int func = 111; + + final Secs1Communicator hostComm = buildCommunicator(buildConfig(deviceId, false)); + final Secs1MessageBuilder hostBuilder = getBuilder(); + + final Secs1Communicator equipComm = buildCommunicator(buildConfig(deviceId, true)); + final Secs1MessageBuilder equipBuilder = getBuilder(); + + final Secs1Message primaryMsg = hostBuilder.build(hostComm, strm, func, true); + + final int replyFunc = func + 1; + + final Secs1Message replyMsg = equipBuilder.build(equipComm, primaryMsg, strm, replyFunc, false); + + assertEquals(replyMsg.getStream(), strm); + assertEquals(replyMsg.getFunction(), replyFunc); + assertEquals(replyMsg.wbit(), false); + assertEquals(replyMsg.secs2().isEmpty(), true); + assertEquals(replyMsg.rbit(), true); + + { + byte[] hostHeader10Bytes = primaryMsg.header10Bytes(); + byte[] equipHeader10Bytes = replyMsg.header10Bytes(); + + assertEquals(hostHeader10Bytes[6], equipHeader10Bytes[6]); + assertEquals(hostHeader10Bytes[7], equipHeader10Bytes[7]); + assertEquals(hostHeader10Bytes[8], equipHeader10Bytes[8]); + assertEquals(hostHeader10Bytes[9], equipHeader10Bytes[9]); + } + } + + @Test + @DisplayName("HostRepryMessage") + void testHostReplyMessage() { + final int deviceId = 30000; + final int strm = 111; + final int func = 199; + + final Secs1Communicator equipComm = buildCommunicator(buildConfig(deviceId, true)); + final Secs1MessageBuilder equipBuilder = getBuilder(); + + final Secs1Communicator hostComm = buildCommunicator(buildConfig(deviceId, false)); + final Secs1MessageBuilder hostBuilder = getBuilder(); + + final Secs1Message primaryMsg = equipBuilder.build(equipComm, strm, func, true); + + final int replyFunc = func + 1; + final Secs2 body = Secs2.list(); + + final Secs1Message replyMsg = hostBuilder.build(hostComm, primaryMsg, strm, replyFunc, false, body); + + assertEquals(replyMsg.getStream(), strm); + assertEquals(replyMsg.getFunction(), replyFunc); + assertEquals(replyMsg.wbit(), false); + assertEquals(replyMsg.secs2().isEmpty(), false); + assertEquals(replyMsg.secs2().secs2Item(), Secs2Item.LIST); + assertEquals(replyMsg.rbit(), false); + + { + byte[] hostHeader10Bytes = primaryMsg.header10Bytes(); + byte[] equipHeader10Bytes = replyMsg.header10Bytes(); + + assertEquals(hostHeader10Bytes[6], equipHeader10Bytes[6]); + assertEquals(hostHeader10Bytes[7], equipHeader10Bytes[7]); + assertEquals(hostHeader10Bytes[8], equipHeader10Bytes[8]); + assertEquals(hostHeader10Bytes[9], equipHeader10Bytes[9]); + } + } + + + @Test + @DisplayName("Secs1MessageBuilder#build empty") + void testStaticBuildEmpty() { + + final byte[] header10Bytes = new byte[] { + (byte)0x00, (byte)0x0A, + (byte)0x81, (byte)0x01, + (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 + }; + + Secs1Message msg = Secs1MessageBuilder.build(header10Bytes); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 1); + assertEquals(wbit, true); + + assertEquals(body.isEmpty(), true); + + assertEquals(rbit, false); + assertEquals(deviceId, 10); + + final List blocks = msg.toBlocks(); + { + assertEquals(blocks.isEmpty(), false); + assertEquals(blocks.size(), 1); + + { + Secs1MessageBlock block = blocks.get(0); + byte[] bs = block.getBytes(); + + assertEquals(bs[0], (byte)0xA); + assertEquals(bs[1], header10Bytes[0]); + assertEquals(bs[2], header10Bytes[1]); + assertEquals(bs[3], header10Bytes[2]); + assertEquals(bs[4], header10Bytes[3]); + assertEquals(bs[5], (byte)0x80); + assertEquals(bs[6], (byte)0x01); + assertEquals(bs[7], header10Bytes[6]); + assertEquals(bs[8], header10Bytes[7]); + assertEquals(bs[9], header10Bytes[8]); + assertEquals(bs[10], header10Bytes[9]); + + assertEquals(block.isValid(), true); + assertEquals(block.isFirstBlock(), true); + assertEquals(block.ebit(), true); + } + + } + } + + @Test + @DisplayName("Secs1MessageBuilder#build list") + void testStaticBuildList() { + + final byte[] header10Bytes = new byte[] { + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x00, (byte)0x00, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01 + }; + + Secs1Message msg = Secs1MessageBuilder.build(header10Bytes, Secs2.list()); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 2); + assertEquals(wbit, false); + + assertEquals(body.isEmpty(), false); + assertEquals(body.secs2Item(), Secs2Item.LIST); + assertEquals(body.size(), 0); + + assertEquals(rbit, true); + assertEquals(deviceId, 10); + + final List blocks = msg.toBlocks(); + { + assertEquals(blocks.isEmpty(), false); + assertEquals(blocks.size(), 1); + + { + Secs1MessageBlock block = blocks.get(0); + byte[] bs = block.getBytes(); + + assertEquals(bs[0], (byte)0xC); + assertEquals(bs[1], header10Bytes[0]); + assertEquals(bs[2], header10Bytes[1]); + assertEquals(bs[3], header10Bytes[2]); + assertEquals(bs[4], header10Bytes[3]); + assertEquals(bs[5], (byte)0x80); + assertEquals(bs[6], (byte)0x01); + assertEquals(bs[7], header10Bytes[6]); + assertEquals(bs[8], header10Bytes[7]); + assertEquals(bs[9], header10Bytes[8]); + assertEquals(bs[10], header10Bytes[9]); + assertEquals(bs[11], (byte)0x01); + assertEquals(bs[12], (byte)0x00); + + assertEquals(block.isValid(), true); + assertEquals(block.isFirstBlock(), true); + assertEquals(block.ebit(), true); + } + + } + } + + @Test + @DisplayName("Secs1MessageBuilder#fromBlocks Single-blocks") + void testStaticFromSingleBlocks() { + + Secs1MessageBlock block = Secs1MessageBlock.of(new byte[] { + (byte)0x0A, + (byte)0x00, (byte)0x0A, + (byte)0x81, (byte)0x01, + (byte)0x80, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x01, (byte)0x0E + }); + + assertEquals(block.isValid(), true); + + Secs1Message msg = Secs1MessageBuilder.fromBlocks(Arrays.asList(block)); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 1); + assertEquals(wbit, true); + + assertEquals(body.isEmpty(), true); + + assertEquals(rbit, false); + assertEquals(deviceId, 10); + + assertEquals(msg.toBlocks().size(), 1); + } + + @Test + @DisplayName("Secs1MessageBuilder#fromBlocks Multi-blocks") + void testStaticromMultiBlocks() { + + Secs1MessageBlock block1 = Secs1MessageBlock.of(new byte[] { + (byte)0x0B, + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x00, (byte)0x01, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x01, + (byte)0x00, (byte)0x90 + }); + + Secs1MessageBlock block2 = Secs1MessageBlock.of(new byte[] { + (byte)0x0B, + (byte)0x80, (byte)0x0A, + (byte)0x01, (byte)0x02, + (byte)0x80, (byte)0x02, + (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, + (byte)0x00, + (byte)0x01, (byte)0x10 + }); + + assertEquals(block1.isValid(), true); + assertEquals(block1.ebit(), false); + assertEquals(block1.isFirstBlock(), true); + assertEquals(block2.isValid(), true); + assertEquals(block2.ebit(), true); + assertEquals(block2.isFirstBlock(), false); + + Secs1Message msg = Secs1MessageBuilder.fromBlocks(Arrays.asList(block1, block2)); + + int strm = msg.getStream(); + int func = msg.getFunction(); + boolean wbit = msg.wbit(); + Secs2 body = msg.secs2(); + + boolean rbit = msg.rbit(); + int deviceId = msg.deviceId(); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(strm, 1); + assertEquals(func, 2); + assertEquals(wbit, false); + + assertEquals(msg.isValidBlocks(), true); + + assertEquals(body.isEmpty(), false); + assertEquals(body.secs2Item(), Secs2Item.LIST); + assertEquals(body.size(), 0); + + assertEquals(rbit, true); + assertEquals(deviceId, 10); + + assertEquals(msg.toBlocks().size(), 2); + } + +}