From 3771dbab43715a5b04a37ae51a4d416bd0cd6430 Mon Sep 17 00:00:00 2001 From: wei <493703217@qq.com> Date: Tue, 19 Nov 2024 20:45:55 +0800 Subject: [PATCH] feat: add device discover request Signed-off-by: wei <493703217@qq.com> --- .../protocol/mdtp/client/MdtpClient.java | 44 +++++++++++++++- .../codec/DeviceDiscoveryRequestDecoder.java | 12 +++++ .../mdtp/common/codec/MdtpDecoder.java | 34 ++++++++++++ .../mdtp/common/codec/MessageBodyDecoder.java | 8 +++ .../common/codec/MessageDecoderFactory.java | 19 +++++++ .../common/model/AbstractMessageBody.java | 14 ++--- .../mdtp/common/model/CDATHeader.java | 17 +++++- .../common/model/DeviceDiscoveryRequest.java | 14 ++--- .../common/model/DeviceDiscoveryResponse.java | 4 +- .../common/model/DiscoveryServiceCode.java | 8 +++ .../mdtp/common/model/MdtpPacket.java | 10 ++-- .../mdtp/common/model/MessageBodyHeader.java | 46 ++++++++++++++++ .../mdtp/common/model/MessageType.java | 9 ++++ .../mdtp/common/model/SecurityHeader.java | 3 +- .../mdtp/common/model/ServiceGroup.java | 9 ++++ .../mdtp/common/AbstractMessageBodyTest.java | 44 ---------------- .../protocol/mdtp/common/CDATHeaderTest.java | 26 +++++++++- .../common/DeviceDiscoveryRequestTest.java | 7 +-- .../common/DeviceDiscoveryResponseTest.java | 2 +- .../mdtp/common/DiscoveryServiceCodeTest.java | 26 ++++++++++ .../protocol/mdtp/common/MdtpDecoderTest.java | 46 ++++++++++++++++ .../protocol/mdtp/common/MdtpPacketTest.java | 10 ++-- .../common/MessageDecoderFactoryTest.java | 22 ++++++++ .../mdtp/common/SecurityHeaderTest.java | 2 +- .../mdtp/common/ServiceGroupTest.java | 37 +++++++++++++ .../mdtp/examples/MdtpClientExample.java | 1 + .../protocol/mdtp/server/MdtpServer.java | 5 ++ .../mdtp/server/MdtpServerHandler.java | 21 ++++++++ .../protocol/mdtp/client/MdtpClientTest.java | 52 +++++++++++++++++++ .../protocol/mdtp/server/MdtpConnectTest.java | 6 --- .../mdtp/server/MdtpServerHandlerTest.java | 36 +++++++++++++ pom.xml | 1 + 32 files changed, 504 insertions(+), 91 deletions(-) create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageBodyDecoder.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java create mode 100644 mdtp-common/src/test/java/io/github/protocol/mdtp/common/DiscoveryServiceCodeTest.java create mode 100644 mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpDecoderTest.java create mode 100644 mdtp-common/src/test/java/io/github/protocol/mdtp/common/MessageDecoderFactoryTest.java create mode 100644 mdtp-common/src/test/java/io/github/protocol/mdtp/common/ServiceGroupTest.java create mode 100644 mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerHandler.java create mode 100644 mdtp-server/src/test/java/io/github/protocol/mdtp/client/MdtpClientTest.java create mode 100644 mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpServerHandlerTest.java diff --git a/mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java b/mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java index bfee0ce..e446805 100644 --- a/mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java +++ b/mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java @@ -1,5 +1,9 @@ package io.github.protocol.mdtp.client; +import io.github.protocol.mdtp.common.model.CDATHeader; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryRequest; +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; @@ -18,6 +22,9 @@ public class MdtpClient implements Closeable { private EventLoopGroup group; + private ChannelFuture channelFuture; + + public MdtpClient(MdtpClientConfig config) { this.config = config; } @@ -37,7 +44,7 @@ public void start() throws Exception { protected void initChannel(SocketChannel ch) throws Exception { } }); - ChannelFuture channelFuture = bootstrap.connect().sync(); + this.channelFuture = bootstrap.connect().sync(); if (channelFuture.isSuccess()) { log.info("mdtp client started"); } else { @@ -55,4 +62,39 @@ public void close() throws IOException { this.group.shutdownGracefully(); log.info("mdtp client closed"); } + + public void sendDeviceDiscoveryRequest(int[] deviceTypes) { + log.info("start to send device discovery request."); + DeviceDiscoveryRequest request = new DeviceDiscoveryRequest(); + request.setMessageBodyHeader(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST); + request.setRequestId(request.generateRequestId()); + + if (deviceTypes == null) { + request.setDeviceTypeCount((byte) 0); + } + + if (deviceTypes != null && deviceTypes.length > 0) { + request.setMask((byte) 1); + request.setDeviceTypeCount((byte) deviceTypes.length); + request.setDeviceTypes(deviceTypes); + } + + CDATHeader cdatHeader = new CDATHeader(); + cdatHeader.setFormatType((byte) 0x02); + cdatHeader.setProtocolVersion((byte) 1); + cdatHeader.setMessageLength((short) 0); + cdatHeader.setTimestamp(System.currentTimeMillis()); + cdatHeader.setFlags((byte) 0b01100000); + cdatHeader.setSequenceNumber(0); + cdatHeader.setLogicalChannelId(0); + + MdtpPacket packet = new MdtpPacket(); + packet.setHeader(cdatHeader); + packet.setSecurityHeader(null); + packet.setBody(request); + packet.setSignature(null); + + this.channelFuture.channel().writeAndFlush(packet.toByteBuf()); + log.info("send device discovery request success: " + packet); + } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java new file mode 100644 index 0000000..dd88666 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java @@ -0,0 +1,12 @@ +package io.github.protocol.mdtp.common.codec; + +import io.github.protocol.mdtp.common.model.AbstractMessageBody; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryRequest; +import io.netty.buffer.ByteBuf; + +public class DeviceDiscoveryRequestDecoder implements MessageBodyDecoder { + @Override + public AbstractMessageBody handle(ByteBuf in) { + return DeviceDiscoveryRequest.fromByteBuf(in); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java new file mode 100644 index 0000000..983aa4f --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java @@ -0,0 +1,34 @@ +package io.github.protocol.mdtp.common.codec; + + +import io.github.protocol.mdtp.common.model.AbstractMessageBody; +import io.github.protocol.mdtp.common.model.CDATHeader; +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +@Slf4j +public class MdtpDecoder extends ByteToMessageDecoder { + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { + + MdtpPacket mdtpPacket = new MdtpPacket(); + CDATHeader header = CDATHeader.readByteBuf(in); + + MessageBodyHeader messageBodyHeader = MessageBodyHeader.readByteBuf(in); + MessageBodyDecoder messageDecode = MessageDecoderFactory.getDecoder(messageBodyHeader); + AbstractMessageBody messageBody = messageDecode.handle(in); + messageBody.setMessageBodyHeader(messageBodyHeader); + + mdtpPacket.setHeader(header); + mdtpPacket.setBody(messageBody); + + out.add(mdtpPacket); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageBodyDecoder.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageBodyDecoder.java new file mode 100644 index 0000000..ababb50 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageBodyDecoder.java @@ -0,0 +1,8 @@ +package io.github.protocol.mdtp.common.codec; + +import io.github.protocol.mdtp.common.model.AbstractMessageBody; +import io.netty.buffer.ByteBuf; + +public interface MessageBodyDecoder { + AbstractMessageBody handle(ByteBuf in); +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java new file mode 100644 index 0000000..4a1ff0b --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java @@ -0,0 +1,19 @@ +package io.github.protocol.mdtp.common.codec; + +import io.github.protocol.mdtp.common.model.MessageBodyHeader; + +import java.util.HashMap; +import java.util.Map; + +public class MessageDecoderFactory { + + private static final Map decoders = new HashMap<>(); + + static { + decoders.put(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort(), new DeviceDiscoveryRequestDecoder()); + } + + public static MessageBodyDecoder getDecoder(MessageBodyHeader header) { + return decoders.get(header.toShort()); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/AbstractMessageBody.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/AbstractMessageBody.java index c808204..36c5fda 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/AbstractMessageBody.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/AbstractMessageBody.java @@ -7,22 +7,14 @@ @Data public abstract class AbstractMessageBody { - private short messageBodyHeader; - - public void setMessageBodyHeader(MessageType messageType, ServiceGroup serviceGroup, DiscoveryServiceCode serviceCode) { - this.messageBodyHeader = 0; - this.messageBodyHeader |= (short) (messageType.getCode() & 0b111); - this.messageBodyHeader |= (short) ((serviceGroup.getCode() & 0b1111111) << 3); - this.messageBodyHeader |= (short) ((serviceCode.getCode() & 0b111111) << 10); - } + private MessageBodyHeader messageBodyHeader; public short generateRequestId() { UUID uuid = UUID.randomUUID(); return (short) (uuid.getLeastSignificantBits() & 0xFFFF); } - public ByteBuf toByteBuf(ByteBuf buffer) { - buffer.writeShort(messageBodyHeader); - return buffer; + public void writeByteBuf(ByteBuf buffer) { + messageBodyHeader.writeByteBuf(buffer); } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java index 495c8a6..6a8651f 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java @@ -25,7 +25,7 @@ public class CDATHeader { private Integer logicalChannelId; - public ByteBuf toByteBuf(ByteBuf buffer) { + public void writeByteBuf(ByteBuf buffer) { buffer.writeByte(formatType); buffer.writeByte(protocolVersion); buffer.writeShort(messageLength); @@ -33,6 +33,19 @@ public ByteBuf toByteBuf(ByteBuf buffer) { buffer.writeByte(flags); buffer.writeInt(sequenceNumber); buffer.writeInt(logicalChannelId); - return buffer; + } + + public static CDATHeader readByteBuf(ByteBuf buffer) { + CDATHeader header = new CDATHeader(); + + header.setFormatType(buffer.readByte()); + header.setProtocolVersion(buffer.readByte()); + header.setMessageLength(buffer.readShort()); + header.setTimestamp(buffer.readLong()); + header.setFlags(buffer.readByte()); + header.setSequenceNumber(buffer.readInt()); + header.setLogicalChannelId(buffer.readInt()); + + return header; } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryRequest.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryRequest.java index c9f5bc6..03fc78a 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryRequest.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryRequest.java @@ -5,7 +5,8 @@ @Data -public class DeviceDiscoveryRequest extends AbstractMessageBody { +public class DeviceDiscoveryRequest extends AbstractMessageBody{ + private short requestId; private byte mask; @@ -14,15 +15,16 @@ public class DeviceDiscoveryRequest extends AbstractMessageBody { private int[] deviceTypes; - public ByteBuf toByteBuf(ByteBuf buffer) { - super.toByteBuf(buffer); + public void writeByteBuf(ByteBuf buffer) { + super.writeByteBuf(buffer); buffer.writeShort(requestId); buffer.writeByte(mask); buffer.writeByte(deviceTypeCount); - for (int deviceType : deviceTypes) { - buffer.writeInt(deviceType); + if (deviceTypeCount > 0) { + for (int deviceType : deviceTypes) { + buffer.writeInt(deviceType); + } } - return buffer; } public static DeviceDiscoveryRequest fromByteBuf(ByteBuf data) { diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryResponse.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryResponse.java index 37eb5cf..199ddce 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryResponse.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DeviceDiscoveryResponse.java @@ -29,7 +29,7 @@ public class DeviceDiscoveryResponse { private String deviceName; - public ByteBuf toByteBuf(ByteBuf buffer) { + public void writeByteBuf(ByteBuf buffer) { buffer.writeShort(messageHeader); buffer.writeShort(requestId); buffer.writeShort(responseId); @@ -53,7 +53,5 @@ public ByteBuf toByteBuf(ByteBuf buffer) { byte[] nameBytes = deviceName.getBytes(StandardCharsets.UTF_8); buffer.writeBytes(nameBytes); } - - return buffer; } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java index 0f4b504..2557521 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java @@ -16,4 +16,12 @@ public enum DiscoveryServiceCode { this.description = description; } + public static DiscoveryServiceCode fromCode(int value) { + for (DiscoveryServiceCode serviceCode : DiscoveryServiceCode.values()) { + if (serviceCode.getCode() == value) { + return serviceCode; + } + } + throw new IllegalArgumentException("Invalid DiscoveryServiceCode: " + value); + } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MdtpPacket.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MdtpPacket.java index b75b7b3..1b56ce1 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MdtpPacket.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MdtpPacket.java @@ -1,6 +1,7 @@ package io.github.protocol.mdtp.common.model; import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import lombok.Data; @Data @@ -14,13 +15,14 @@ public class MdtpPacket { private Signature signature; - public ByteBuf toByteBuf(ByteBuf buffer) { - header.toByteBuf(buffer); + public ByteBuf toByteBuf() { + ByteBuf buffer = Unpooled.buffer(); + header.writeByteBuf(buffer); if (securityHeader != null) { - securityHeader.toByteBuf(buffer); + securityHeader.writeByteBuf(buffer); } if (body != null) { - body.toByteBuf(buffer); + body.writeByteBuf(buffer); } return buffer; } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java new file mode 100644 index 0000000..f01e20c --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java @@ -0,0 +1,46 @@ +package io.github.protocol.mdtp.common.model; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Slf4j +public class MessageBodyHeader { + private MessageType messageType; + + private ServiceGroup serviceGroup; + + private DiscoveryServiceCode serviceCode; + + public static final MessageBodyHeader DEVICE_DISCOVERY_REQUEST = + new MessageBodyHeader(MessageType.REQUEST, ServiceGroup.DISCOVERY_SERVICE, DiscoveryServiceCode.DEVICE_DISCOVERY); + + public static final MessageBodyHeader DEVICE_DISCOVERY_RESPONSE = + new MessageBodyHeader(MessageType.RESPONSE, ServiceGroup.DISCOVERY_SERVICE, DiscoveryServiceCode.DEVICE_DISCOVERY); + + public short toShort() { + short messageBodyHeader = 0; + messageBodyHeader |= (short) (this.messageType.getCode() & 0b111); + messageBodyHeader |= (short) ((this.serviceGroup.getCode() & 0b1111111) << 3); + messageBodyHeader |= (short) ((this.serviceCode.getCode() & 0b111111) << 10); + return messageBodyHeader; + } + + public void writeByteBuf(ByteBuf buffer) { + buffer.writeShort(toShort()); + } + + public static MessageBodyHeader readByteBuf(ByteBuf buffer) { + short messageBodyHeader = buffer.readShort(); + MessageType messageType = MessageType.fromCode((short) (messageBodyHeader & 0b111)); + ServiceGroup serviceGroup = ServiceGroup.fromCode((short) ((messageBodyHeader >> 3) & 0b1111111)); + DiscoveryServiceCode serviceCode = DiscoveryServiceCode.fromCode((short) ((messageBodyHeader >> 10) & 0b111111)); + return new MessageBodyHeader(messageType, serviceGroup, serviceCode); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java index 7a05693..c784cc0 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java @@ -16,4 +16,13 @@ public enum MessageType { public int getCode() { return code; } + + public static MessageType fromCode(int value) { + for (MessageType type : MessageType.values()) { + if (type.getCode() == value) { + return type; + } + } + throw new IllegalArgumentException("Invalid MessageType code: " + value); + } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/SecurityHeader.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/SecurityHeader.java index 000ddb4..6d6faee 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/SecurityHeader.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/SecurityHeader.java @@ -7,11 +7,10 @@ public class SecurityHeader { private byte[] encryptionData; - public ByteBuf toByteBuf(ByteBuf buffer) { + public void writeByteBuf(ByteBuf buffer) { for (int data : encryptionData) { buffer.writeInt(data); } - return buffer; } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java index 7855c5f..060276e 100644 --- a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java @@ -25,4 +25,13 @@ public enum ServiceGroup { this.code = code; this.description = description; } + + public static ServiceGroup fromCode(int value) { + for (ServiceGroup group : ServiceGroup.values()) { + if (group.getCode() == value) { + return group; + } + } + throw new IllegalArgumentException("Invalid ServiceGroup code: " + value); + } } diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/AbstractMessageBodyTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/AbstractMessageBodyTest.java index 9e44892..07d0470 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/AbstractMessageBodyTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/AbstractMessageBodyTest.java @@ -1,18 +1,11 @@ package io.github.protocol.mdtp.common; import io.github.protocol.mdtp.common.model.AbstractMessageBody; -import io.github.protocol.mdtp.common.model.DiscoveryServiceCode; -import io.github.protocol.mdtp.common.model.MessageType; -import io.github.protocol.mdtp.common.model.ServiceGroup; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; public class AbstractMessageBodyTest { @@ -23,22 +16,6 @@ void setUp() { messageBody = new AbstractMessageBody(){}; } - @Test - void testSetMessageBodyHeader() { - MessageType messageType = mock(MessageType.class); - ServiceGroup serviceGroup = mock(ServiceGroup.class); - DiscoveryServiceCode serviceCode = mock(DiscoveryServiceCode.class); - - when(messageType.getCode()).thenReturn(1); - when(serviceGroup.getCode()).thenReturn(2); - when(serviceCode.getCode()).thenReturn( 3); - - messageBody.setMessageBodyHeader(messageType, serviceGroup, serviceCode); - - short expectedHeader = (short) ((1 & 0b111) | ((2 & 0b1111111) << 3) | ((3 & 0b111111) << 10)); - - assertEquals(expectedHeader, messageBody.getMessageBodyHeader()); - } @Test void testGenerateRequestId() { @@ -49,25 +26,4 @@ void testGenerateRequestId() { assertEquals(Short.class, ((Object) requestId2).getClass()); assertNotEquals(requestId1, requestId2); } - - @Test - void testToByteBuf() { - ByteBuf buffer = Unpooled.buffer(); - - MessageType messageType = mock(MessageType.class); - ServiceGroup serviceGroup = mock(ServiceGroup.class); - DiscoveryServiceCode serviceCode = mock(DiscoveryServiceCode.class); - - when(messageType.getCode()).thenReturn(1); - when(serviceGroup.getCode()).thenReturn(2); - when(serviceCode.getCode()).thenReturn( 3); - - messageBody.setMessageBodyHeader(messageType, serviceGroup, serviceCode); - - messageBody.toByteBuf(buffer); - - assertEquals(messageBody.getMessageBodyHeader(), buffer.readShort()); - - buffer.release(); - } } diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/CDATHeaderTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/CDATHeaderTest.java index f535cad..d7f7ed2 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/CDATHeaderTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/CDATHeaderTest.java @@ -28,7 +28,7 @@ void setUp() { void testToByteBuf() { ByteBuf buffer = Unpooled.buffer(); - cdatHeader.toByteBuf(buffer); + cdatHeader.writeByteBuf(buffer); assertEquals(1, buffer.readByte()); assertEquals(2, buffer.readByte()); @@ -40,4 +40,28 @@ void testToByteBuf() { buffer.release(); } + + @Test + void testFromByteBuf() { + ByteBuf buffer = Unpooled.buffer(); + buffer.writeByte(1); + buffer.writeByte(2); + buffer.writeShort(100); + buffer.writeLong(123456789L); + buffer.writeByte((byte) 0x1F); + buffer.writeInt(42); + buffer.writeInt(7); + + CDATHeader headerFromBuffer = CDATHeader.readByteBuf(buffer); + + assertEquals(cdatHeader.getFormatType(), headerFromBuffer.getFormatType()); + assertEquals(cdatHeader.getProtocolVersion(), headerFromBuffer.getProtocolVersion()); + assertEquals(cdatHeader.getMessageLength(), headerFromBuffer.getMessageLength()); + assertEquals(cdatHeader.getTimestamp(), headerFromBuffer.getTimestamp()); + assertEquals(cdatHeader.getFlags(), headerFromBuffer.getFlags()); + assertEquals(cdatHeader.getSequenceNumber(), headerFromBuffer.getSequenceNumber()); + assertEquals(cdatHeader.getLogicalChannelId(), headerFromBuffer.getLogicalChannelId()); + + buffer.release(); + } } diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryRequestTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryRequestTest.java index 0b7ff8b..e6b31f1 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryRequestTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryRequestTest.java @@ -1,6 +1,7 @@ package io.github.protocol.mdtp.common; import io.github.protocol.mdtp.common.model.DeviceDiscoveryRequest; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.junit.jupiter.api.BeforeEach; @@ -15,7 +16,7 @@ public class DeviceDiscoveryRequestTest { @BeforeEach void setUp() { request = new DeviceDiscoveryRequest(); - request.setMessageBodyHeader((short) 0); + request.setMessageBodyHeader(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST); request.setRequestId((short) 123); request.setMask((byte) 0x1F); request.setDeviceTypeCount((byte) 3); @@ -26,8 +27,8 @@ void setUp() { void testToByteBuf() { ByteBuf buffer = Unpooled.buffer(); - request.toByteBuf(buffer); - assertEquals(0, buffer.readShort()); + request.writeByteBuf(buffer); + assertEquals(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort(), buffer.readShort()); assertEquals( 123, buffer.readShort()); assertEquals(0x1F, buffer.readByte()); assertEquals(3, buffer.readByte()); diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryResponseTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryResponseTest.java index 868a9d3..2f950b1 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryResponseTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DeviceDiscoveryResponseTest.java @@ -35,7 +35,7 @@ void setUp() { void testToByteBuf() { ByteBuf buffer = Unpooled.buffer(); - response.toByteBuf(buffer); + response.writeByteBuf(buffer); assertEquals(100, buffer.readShort()); assertEquals(200, buffer.readShort()); diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DiscoveryServiceCodeTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DiscoveryServiceCodeTest.java new file mode 100644 index 0000000..3040009 --- /dev/null +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/DiscoveryServiceCodeTest.java @@ -0,0 +1,26 @@ +package io.github.protocol.mdtp.common; + +import io.github.protocol.mdtp.common.model.DiscoveryServiceCode; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class DiscoveryServiceCodeTest { + + @Test + public void testFromCode_ValidCode() { + DiscoveryServiceCode code = DiscoveryServiceCode.fromCode(1); + assertEquals(DiscoveryServiceCode.DEVICE_DISCOVERY, code); + + code = DiscoveryServiceCode.fromCode(2); + assertEquals(DiscoveryServiceCode.DEVICE_INFO_QUERY, code); + } + + @Test + public void testFromCode_InvalidCode() { + assertThrows(IllegalArgumentException.class, () -> { + DiscoveryServiceCode.fromCode(999); + }); + } +} diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpDecoderTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpDecoderTest.java new file mode 100644 index 0000000..84d3bf9 --- /dev/null +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpDecoderTest.java @@ -0,0 +1,46 @@ +package io.github.protocol.mdtp.common; + +import io.github.protocol.mdtp.common.codec.MdtpDecoder; +import io.github.protocol.mdtp.common.model.CDATHeader; +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MdtpDecoderTest extends MdtpDecoder { + + private ChannelHandlerContext ctx; + private ByteBuf in; + private List out; + + @BeforeEach + public void setUp() { + ctx = mock(ChannelHandlerContext.class); + in = mock(ByteBuf.class); + out = new ArrayList<>(); + when(in.readShort()).thenReturn(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort()); + } + + @Test + public void testDecode() throws Exception { + CDATHeader mockHeader = mock(CDATHeader.class); + try (MockedStatic mockedCDATHeader = Mockito.mockStatic(CDATHeader.class)) { + mockedCDATHeader.when(() -> CDATHeader.readByteBuf(in)).thenReturn(mockHeader); + decode(ctx, in, out); + assertEquals(1, out.size()); + MdtpPacket mdtpPacket = (MdtpPacket) out.get(0); + assertEquals(mockHeader, mdtpPacket.getHeader()); + } + } +} diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpPacketTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpPacketTest.java index d2d3b83..c13dd65 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpPacketTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MdtpPacketTest.java @@ -6,7 +6,6 @@ import io.github.protocol.mdtp.common.model.SecurityHeader; import io.github.protocol.mdtp.common.model.Signature; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -36,13 +35,12 @@ void setUp() { @Test void testToByteBuf() { - ByteBuf buffer = Unpooled.buffer(); - mdtpPacket.toByteBuf(buffer); + ByteBuf buffer = mdtpPacket.toByteBuf(); - verify(mockHeader).toByteBuf(buffer); - verify(mockSecurityHeader).toByteBuf(buffer); - verify(mockBody).toByteBuf(buffer); + verify(mockHeader).writeByteBuf(buffer); + verify(mockSecurityHeader).writeByteBuf(buffer); + verify(mockBody).writeByteBuf(buffer); buffer.release(); } diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MessageDecoderFactoryTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MessageDecoderFactoryTest.java new file mode 100644 index 0000000..a51edfc --- /dev/null +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/MessageDecoderFactoryTest.java @@ -0,0 +1,22 @@ +package io.github.protocol.mdtp.common; + +import io.github.protocol.mdtp.common.codec.DeviceDiscoveryRequestDecoder; +import io.github.protocol.mdtp.common.codec.MessageBodyDecoder; +import io.github.protocol.mdtp.common.codec.MessageDecoderFactory; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class MessageDecoderFactoryTest { + @Test + public void testGetDecoder_ValidHeader() { + MessageBodyHeader header = MessageBodyHeader.DEVICE_DISCOVERY_REQUEST; + + MessageBodyDecoder decoder = MessageDecoderFactory.getDecoder(header); + + assertNotNull(decoder); + assertTrue(decoder instanceof DeviceDiscoveryRequestDecoder); + } +} diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/SecurityHeaderTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/SecurityHeaderTest.java index df77a35..63860af 100644 --- a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/SecurityHeaderTest.java +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/SecurityHeaderTest.java @@ -21,7 +21,7 @@ void setUp() { void testToByteBuf() { ByteBuf buffer = Unpooled.buffer(); - securityHeader.toByteBuf(buffer); + securityHeader.writeByteBuf(buffer); assertEquals(1, buffer.readInt()); assertEquals(2, buffer.readInt()); diff --git a/mdtp-common/src/test/java/io/github/protocol/mdtp/common/ServiceGroupTest.java b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/ServiceGroupTest.java new file mode 100644 index 0000000..0f9af28 --- /dev/null +++ b/mdtp-common/src/test/java/io/github/protocol/mdtp/common/ServiceGroupTest.java @@ -0,0 +1,37 @@ +package io.github.protocol.mdtp.common; + +import io.github.protocol.mdtp.common.model.ServiceGroup; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class ServiceGroupTest { + @Test + public void testFromCode_ValidCode() { + ServiceGroup group = ServiceGroup.fromCode(1); + assertEquals(ServiceGroup.DISCOVERY_SERVICE, group); + + group = ServiceGroup.fromCode(2); + assertEquals(ServiceGroup.SECURITY_SERVICE, group); + + group = ServiceGroup.fromCode(3); + assertEquals(ServiceGroup.CONNECTION_SERVICE, group); + + group = ServiceGroup.fromCode(4); + assertEquals(ServiceGroup.BILLING_SERVICE, group); + + group = ServiceGroup.fromCode(5); + assertEquals(ServiceGroup.SETTING_SERVICE, group); + + group = ServiceGroup.fromCode(6); + assertEquals(ServiceGroup.METHOD_SERVICE, group); + } + + @Test + public void testFromCode_InvalidCode() { + assertThrows(IllegalArgumentException.class, () -> { + ServiceGroup.fromCode(999); + }); + } +} diff --git a/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpClientExample.java b/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpClientExample.java index 58fbd58..9421cb1 100644 --- a/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpClientExample.java +++ b/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpClientExample.java @@ -8,5 +8,6 @@ public static void main(String[] args) throws Exception { MdtpClientConfig mdtpClientConfig = new MdtpClientConfig().host("localhost").port(4146); MdtpClient mdtpClient = new MdtpClient(mdtpClientConfig); mdtpClient.start(); + mdtpClient.sendDeviceDiscoveryRequest(null); } } diff --git a/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServer.java b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServer.java index 29e2554..e142a6c 100644 --- a/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServer.java +++ b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServer.java @@ -1,9 +1,11 @@ package io.github.protocol.mdtp.server; +import io.github.protocol.mdtp.common.codec.MdtpDecoder; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; @@ -43,6 +45,9 @@ public void start() throws Exception { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { log.info("init channel for remote address: {}", socketChannel.remoteAddress()); + ChannelPipeline pipeline = socketChannel.pipeline(); + pipeline.addLast(new MdtpDecoder()); + pipeline.addLast(new MdtpServerHandler()); } }); ChannelFuture channelFuture = serverBootstrap.bind().sync(); diff --git a/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerHandler.java b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerHandler.java new file mode 100644 index 0000000..838192b --- /dev/null +++ b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerHandler.java @@ -0,0 +1,21 @@ +package io.github.protocol.mdtp.server; + +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MdtpServerHandler extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext ctx, MdtpPacket packet) throws Exception { + log.info("receive packet:" + packet.toString()); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/mdtp-server/src/test/java/io/github/protocol/mdtp/client/MdtpClientTest.java b/mdtp-server/src/test/java/io/github/protocol/mdtp/client/MdtpClientTest.java new file mode 100644 index 0000000..7ba40a3 --- /dev/null +++ b/mdtp-server/src/test/java/io/github/protocol/mdtp/client/MdtpClientTest.java @@ -0,0 +1,52 @@ +package io.github.protocol.mdtp.client; + +import io.github.protocol.mdtp.server.MdtpServer; +import io.github.protocol.mdtp.server.MdtpServerConfig; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + + +public class MdtpClientTest { + + private MdtpServer mdtpServer; + private MdtpClient mdtpClient; + + + @BeforeEach + public void setUp() throws Exception { + MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().host("localhost").port(4146); + mdtpServer = new MdtpServer(mdtpServerConfig); + mdtpServer.start(); + + MdtpClientConfig config = new MdtpClientConfig().host("localhost").port(4146); + mdtpClient = new MdtpClient(config); + + } + + @AfterEach + public void close() throws IOException { + mdtpServer.close(); + } + + @Test + public void testStartConnection() throws Exception { + mdtpClient.start(); + } + + @Test + public void testSendDeviceDiscoveryRequest() throws Exception { + mdtpClient.start(); + int[] deviceTypes = {1, 2, 3}; + mdtpClient.sendDeviceDiscoveryRequest(deviceTypes); + } + + @Test + public void testSendDeviceDiscoveryRequestWithNullDeviceTypes() throws Exception { + mdtpClient.start(); + mdtpClient.sendDeviceDiscoveryRequest(null); + } + +} diff --git a/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpConnectTest.java b/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpConnectTest.java index 0d55c7a..e5441a6 100644 --- a/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpConnectTest.java +++ b/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpConnectTest.java @@ -1,7 +1,5 @@ package io.github.protocol.mdtp.server; -import io.github.protocol.mdtp.client.MdtpClient; -import io.github.protocol.mdtp.client.MdtpClientConfig; import org.junit.jupiter.api.Test; public class MdtpConnectTest { @@ -10,10 +8,6 @@ public void mdtpConnect() throws Exception { MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().host("localhost").port(0); MdtpServer mdtpServer = new MdtpServer(mdtpServerConfig); mdtpServer.start(); - MdtpClientConfig mdtpClientConfig = new MdtpClientConfig().host("localhost").port(mdtpServer.listenPort()); - MdtpClient mdtpClient = new MdtpClient(mdtpClientConfig); - mdtpClient.start(); - mdtpClient.close(); mdtpServer.close(); } } diff --git a/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpServerHandlerTest.java b/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpServerHandlerTest.java new file mode 100644 index 0000000..cb0a4ff --- /dev/null +++ b/mdtp-server/src/test/java/io/github/protocol/mdtp/server/MdtpServerHandlerTest.java @@ -0,0 +1,36 @@ +package io.github.protocol.mdtp.server; + +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.embedded.EmbeddedChannel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import static org.mockito.Mockito.verify; + +public class MdtpServerHandlerTest extends MdtpServerHandler { + + private ChannelHandlerContext ctx; + private EmbeddedChannel channel; + + @BeforeEach + public void setUp() { + ctx = Mockito.mock(ChannelHandlerContext.class); + channel = new EmbeddedChannel(); + } + + @Test + public void testChannelRead0() throws Exception { + MdtpPacket packet = Mockito.mock(MdtpPacket.class); + Mockito.when(packet.toString()).thenReturn("Mocked MdtpPacket"); + channelRead0(ctx, packet); + } + + @Test + public void testExceptionCaught() throws Exception { + Throwable cause = new Throwable(); + exceptionCaught(ctx, cause); + verify(ctx).close(); + } +} diff --git a/pom.xml b/pom.xml index 7770e7a..3e33d29 100644 --- a/pom.xml +++ b/pom.xml @@ -30,6 +30,7 @@ 5.11.0 4.1.112.Final 2.0.16 + 5.11.0 1.18.20.0 0.8.12