From 2f4a6b754fbee1525b65f99f6f1c00e515fa252a Mon Sep 17 00:00:00 2001 From: wei <493703217@qq.com> Date: Wed, 11 Dec 2024 10:51:50 +0800 Subject: [PATCH] feat: add device discover response Signed-off-by: wei <493703217@qq.com> --- .../protocol/mdtp/client/MdtpClient.java | 20 ++-- .../codec/DeviceDiscoveryReponseDecoder.java | 13 +++ .../mdtp/common/codec/MdtpDecoder.java | 3 +- .../common/codec/MessageDecoderFactory.java | 1 + .../DeviceDiscoveryRequestHandler.java | 36 +++++++ .../common/handler/MessageBodyHandler.java | 9 ++ .../common/handler/MessageHandlerFactory.java | 19 ++++ .../common/model/AbstractMessageBody.java | 11 ++- .../protocol/mdtp/common/model/Address.java | 36 +++++++ .../mdtp/common/model/Attributes.java | 7 ++ .../mdtp/common/model/CDATHeader.java | 19 +++- .../mdtp/common/model/CDATHeaderFactory.java | 29 ++++++ .../protocol/mdtp/common/model/Device.java | 96 +++++++++++++++++++ .../common/model/DeviceDiscoveryRequest.java | 6 +- .../common/model/DeviceDiscoveryResponse.java | 54 +++-------- .../mdtp/common/AbstractMessageBodyTest.java | 9 +- .../protocol/mdtp/common/CDATHeaderTest.java | 6 +- .../common/DeviceDiscoveryRequestTest.java | 1 - .../common/DeviceDiscoveryResponseTest.java | 70 ++++++-------- .../mdtp/examples/MdtpServerExample.java | 15 ++- .../protocol/mdtp/server/MdtpServer.java | 6 +- .../mdtp/server/MdtpServerConfig.java | 15 +-- .../mdtp/server/MdtpServerHandler.java | 7 +- .../protocol/mdtp/client/MdtpClientTest.java | 8 +- .../protocol/mdtp/server/MdtpConnectTest.java | 9 +- .../mdtp/server/MdtpServerHandlerTest.java | 21 +++- 26 files changed, 400 insertions(+), 126 deletions(-) create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryReponseDecoder.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/DeviceDiscoveryRequestHandler.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageBodyHandler.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageHandlerFactory.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Address.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Attributes.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeaderFactory.java create mode 100644 mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Device.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 e446805..15a1683 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,12 +1,14 @@ package io.github.protocol.mdtp.client; +import io.github.protocol.mdtp.common.codec.MdtpDecoder; import io.github.protocol.mdtp.common.model.CDATHeader; +import io.github.protocol.mdtp.common.model.CDATHeaderFactory; 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; +import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; @@ -42,6 +44,8 @@ public void start() throws Exception { .handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + pipeline.addLast(new MdtpDecoder()); } }); this.channelFuture = bootstrap.connect().sync(); @@ -66,8 +70,7 @@ public void close() throws IOException { 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()); + request.setRequestId(request.generateId()); if (deviceTypes == null) { request.setDeviceTypeCount((byte) 0); @@ -79,14 +82,7 @@ public void sendDeviceDiscoveryRequest(int[] deviceTypes) { 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); + CDATHeader cdatHeader = CDATHeaderFactory.createDeviceDiscoveryCDATHeader(); MdtpPacket packet = new MdtpPacket(); packet.setHeader(cdatHeader); @@ -95,6 +91,6 @@ public void sendDeviceDiscoveryRequest(int[] deviceTypes) { packet.setSignature(null); this.channelFuture.channel().writeAndFlush(packet.toByteBuf()); - log.info("send device discovery request success: " + packet); + log.info("send device discovery request success."); } } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryReponseDecoder.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryReponseDecoder.java new file mode 100644 index 0000000..f13f085 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryReponseDecoder.java @@ -0,0 +1,13 @@ +package io.github.protocol.mdtp.common.codec; + +import io.github.protocol.mdtp.common.model.AbstractMessageBody; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryResponse; +import io.netty.buffer.ByteBuf; + +public class DeviceDiscoveryReponseDecoder implements MessageBodyDecoder { + @Override + public AbstractMessageBody handle(ByteBuf in) { + return DeviceDiscoveryResponse.readFromBuffer(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 index 983aa4f..18b847a 100644 --- 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 @@ -24,11 +24,10 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) t 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); + log.info("decode packet success: {}", mdtpPacket); } } 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 index 4a1ff0b..2400cc8 100644 --- 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 @@ -11,6 +11,7 @@ public class MessageDecoderFactory { static { decoders.put(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort(), new DeviceDiscoveryRequestDecoder()); + decoders.put(MessageBodyHeader.DEVICE_DISCOVERY_RESPONSE.toShort(), new DeviceDiscoveryReponseDecoder()); } public static MessageBodyDecoder getDecoder(MessageBodyHeader header) { diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/DeviceDiscoveryRequestHandler.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/DeviceDiscoveryRequestHandler.java new file mode 100644 index 0000000..2ba1d1a --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/DeviceDiscoveryRequestHandler.java @@ -0,0 +1,36 @@ +package io.github.protocol.mdtp.common.handler; + +import io.github.protocol.mdtp.common.model.Attributes; +import io.github.protocol.mdtp.common.model.CDATHeader; +import io.github.protocol.mdtp.common.model.CDATHeaderFactory; +import io.github.protocol.mdtp.common.model.Device; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryRequest; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryResponse; +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.netty.channel.ChannelHandlerContext; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class DeviceDiscoveryRequestHandler implements MessageBodyHandler { + + @Override + public void handle (ChannelHandlerContext ctx, MdtpPacket requestPacket) { + log.info("start to send device discovery response."); + DeviceDiscoveryRequest deviceDiscoveryRequest = (DeviceDiscoveryRequest) requestPacket.getBody(); + DeviceDiscoveryResponse deviceDiscoveryResponse = new DeviceDiscoveryResponse(); + deviceDiscoveryResponse.setRequestId(deviceDiscoveryRequest.getRequestId()); + deviceDiscoveryResponse.setResponseId(deviceDiscoveryResponse.generateId()); + Device device = ctx.channel().attr(Attributes.DEVICE_KEY).get(); + deviceDiscoveryResponse.setDevice(device); + + CDATHeader cdatHeader = CDATHeaderFactory.createDeviceDiscoveryCDATHeader(); + + MdtpPacket packet = new MdtpPacket(); + packet.setHeader(cdatHeader); + packet.setSecurityHeader(null); + packet.setBody(deviceDiscoveryResponse); + packet.setSignature(null); + ctx.channel().writeAndFlush(packet.toByteBuf()); + log.info("send device discovery response success."); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageBodyHandler.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageBodyHandler.java new file mode 100644 index 0000000..072919e --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageBodyHandler.java @@ -0,0 +1,9 @@ +package io.github.protocol.mdtp.common.handler; + +import io.github.protocol.mdtp.common.model.MdtpPacket; +import io.netty.channel.ChannelHandlerContext; + +public interface MessageBodyHandler { + + void handle (ChannelHandlerContext ctx, MdtpPacket mdtpPacket); +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageHandlerFactory.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageHandlerFactory.java new file mode 100644 index 0000000..c4f91bc --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/handler/MessageHandlerFactory.java @@ -0,0 +1,19 @@ +package io.github.protocol.mdtp.common.handler; + + +import io.github.protocol.mdtp.common.model.MessageBodyHeader; + +import java.util.HashMap; +import java.util.Map; + +public class MessageHandlerFactory { + private static final Map handlers = new HashMap<>(); + + static { + handlers.put(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort(), new DeviceDiscoveryRequestHandler()); + } + + public static MessageBodyHandler getHandler(MessageBodyHeader header) { + return handlers.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 36c5fda..c84cd63 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 @@ -9,9 +9,16 @@ public abstract class AbstractMessageBody { private MessageBodyHeader messageBodyHeader; - public short generateRequestId() { + protected AbstractMessageBody () { + } + + protected AbstractMessageBody (MessageBodyHeader messageBodyHeader) { + this.messageBodyHeader = messageBodyHeader; + } + + public short generateId() { UUID uuid = UUID.randomUUID(); - return (short) (uuid.getLeastSignificantBits() & 0xFFFF); + return (short) (uuid.getLeastSignificantBits() & 0x7FFF); } public void writeByteBuf(ByteBuf buffer) { diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Address.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Address.java new file mode 100644 index 0000000..e971b5f --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Address.java @@ -0,0 +1,36 @@ +package io.github.protocol.mdtp.common.model; + +import io.netty.buffer.ByteBuf; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +public class Address { + public static final byte IPV4_TYPE = 4; + public static final byte IPV6_TYPE = 6; + + private final byte type; + private final byte[] value; + + public Address(byte type, byte[] value) { + this.type = type; + this.value = value; + } + + public String getIpString() throws UnknownHostException { + return InetAddress.getByAddress(value).getHostAddress(); + } + + public void writeByteBuf(ByteBuf buffer) { + buffer.writeByte(type); + buffer.writeBytes(value); + } + + public static Address readByteBuf(ByteBuf buffer) { + byte type = buffer.readByte(); + int length = (type == IPV4_TYPE) ? 4 : 16; + byte[] value = new byte[length]; + buffer.readBytes(value); + return new Address(type, value); + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Attributes.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Attributes.java new file mode 100644 index 0000000..23be284 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Attributes.java @@ -0,0 +1,7 @@ +package io.github.protocol.mdtp.common.model; + +import io.netty.util.AttributeKey; + +public class Attributes { + public static final AttributeKey DEVICE_KEY = AttributeKey.valueOf("device"); +} 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 6a8651f..55197c6 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 @@ -31,8 +31,12 @@ public void writeByteBuf(ByteBuf buffer) { buffer.writeShort(messageLength); buffer.writeLong(timestamp); buffer.writeByte(flags); - buffer.writeInt(sequenceNumber); - buffer.writeInt(logicalChannelId); + if (sequenceNumber != null) { + buffer.writeInt(sequenceNumber); + } + if (logicalChannelId != null) { + buffer.writeInt(logicalChannelId); + } } public static CDATHeader readByteBuf(ByteBuf buffer) { @@ -43,8 +47,15 @@ public static CDATHeader readByteBuf(ByteBuf buffer) { header.setMessageLength(buffer.readShort()); header.setTimestamp(buffer.readLong()); header.setFlags(buffer.readByte()); - header.setSequenceNumber(buffer.readInt()); - header.setLogicalChannelId(buffer.readInt()); + byte formatType = header.getFormatType(); + + if (formatType == 0x00) { + header.setSequenceNumber(buffer.readInt()); + header.setLogicalChannelId(buffer.readInt()); + } else if (formatType == 0x02) { + header.setSequenceNumber(null); + header.setLogicalChannelId(null); + } return header; } diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeaderFactory.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeaderFactory.java new file mode 100644 index 0000000..64b4507 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeaderFactory.java @@ -0,0 +1,29 @@ +package io.github.protocol.mdtp.common.model; + +public class CDATHeaderFactory { + public static CDATHeader createMessageTransferCDATHeader() { + return initializeDefault(new CDATHeader(), (byte) 0x00); + } + + public static CDATHeader createDeviceDiscoveryCDATHeader() { + return initializeDefault(new CDATHeader(), (byte) 0x02); + } + + private static CDATHeader initializeDefault(CDATHeader header, byte formatType) { + header.setFormatType(formatType); + header.setProtocolVersion((byte) 1); + header.setMessageLength((short) 0); + header.setTimestamp(System.currentTimeMillis()); + header.setFlags((byte) 0b01100000); + + if (formatType == 0x00) { + header.setSequenceNumber(0); + header.setLogicalChannelId(0); + } else { + header.setSequenceNumber(null); + header.setLogicalChannelId(null); + } + + return header; + } +} diff --git a/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Device.java b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Device.java new file mode 100644 index 0000000..094b881 --- /dev/null +++ b/mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/Device.java @@ -0,0 +1,96 @@ +package io.github.protocol.mdtp.common.model; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class Device { + private byte mask; + + private byte deviceStatus; + + private byte addressCount; + + private List
addresses; + + private short port; + + private int deviceType; + + private byte[] uniqueId; + + private String deviceName; + + public void writeByteBuf(ByteBuf buffer) { + buffer.writeByte(mask); + buffer.writeByte(deviceStatus); + buffer.writeByte(addressCount); + + for (Address address : addresses) { + address.writeByteBuf(buffer); + } + + buffer.writeShort(port); + buffer.writeInt(deviceType); + + if (uniqueId != null) { + buffer.writeShort(uniqueId.length); + buffer.writeBytes(uniqueId); + } else { + buffer.writeShort(0); + } + + if (deviceName != null) { + byte[] nameBytes = deviceName.getBytes(StandardCharsets.UTF_8); + buffer.writeShort(nameBytes.length); + buffer.writeBytes(nameBytes); + } else { + buffer.writeShort(0); + } + } + + public static Device readByteBuf(ByteBuf buffer) { + Device device = new Device(); + + device.mask = buffer.readByte(); + device.deviceStatus = buffer.readByte(); + device.addressCount = buffer.readByte(); + + device.addresses = new ArrayList<>(); + for (int i = 0; i < device.addressCount; i++) { + device.addresses.add(Address.readByteBuf(buffer)); + } + + device.port = buffer.readShort(); + device.deviceType = buffer.readInt(); + + int uniqueIdLength = buffer.readShort(); + if (uniqueIdLength > 0) { + device.uniqueId = new byte[uniqueIdLength]; + buffer.readBytes(device.uniqueId); + } else { + device.uniqueId = null; + } + + int deviceNameLength = buffer.readShort(); + if (deviceNameLength > 0) { + byte[] nameBytes = new byte[deviceNameLength]; + buffer.readBytes(nameBytes); + device.deviceName = new String(nameBytes, StandardCharsets.UTF_8); + } else { + device.deviceName = null; + } + + return device; + } +} 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 03fc78a..e06e6e3 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,7 @@ @Data -public class DeviceDiscoveryRequest extends AbstractMessageBody{ +public class DeviceDiscoveryRequest extends AbstractMessageBody { private short requestId; @@ -15,6 +15,10 @@ public class DeviceDiscoveryRequest extends AbstractMessageBody{ private int[] deviceTypes; + public DeviceDiscoveryRequest() { + super(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST); + } + public void writeByteBuf(ByteBuf buffer) { super.writeByteBuf(buffer); buffer.writeShort(requestId); 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 199ddce..9dda91c 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 @@ -3,55 +3,31 @@ import io.netty.buffer.ByteBuf; import lombok.Data; -import java.nio.charset.StandardCharsets; @Data -public class DeviceDiscoveryResponse { - private short messageHeader; - +public class DeviceDiscoveryResponse extends AbstractMessageBody { private short requestId; private short responseId; - private byte mask; - - private byte deviceStatus; - - private byte addressCount; - - private String[] addresses; - - private short port; + private Device device; - private int deviceType; - - private byte[] uniqueId; - - private String deviceName; + public DeviceDiscoveryResponse() { + super(MessageBodyHeader.DEVICE_DISCOVERY_RESPONSE); + } public void writeByteBuf(ByteBuf buffer) { - buffer.writeShort(messageHeader); + super.writeByteBuf(buffer); buffer.writeShort(requestId); buffer.writeShort(responseId); - buffer.writeByte(mask); - buffer.writeByte(deviceStatus); - buffer.writeByte(addressCount); - - for (String address : addresses) { - byte[] addressBytes = address.getBytes(StandardCharsets.UTF_8); - buffer.writeBytes(addressBytes); - } - - buffer.writeShort(port); - buffer.writeInt(deviceType); - - if (uniqueId != null) { - buffer.writeBytes(uniqueId); - } - - if (deviceName != null) { - byte[] nameBytes = deviceName.getBytes(StandardCharsets.UTF_8); - buffer.writeBytes(nameBytes); - } + device.writeByteBuf(buffer); + } + + public static DeviceDiscoveryResponse readFromBuffer(ByteBuf buffer) { + DeviceDiscoveryResponse response = new DeviceDiscoveryResponse(); + response.setRequestId(buffer.readShort()); + response.setResponseId(buffer.readShort()); + response.setDevice(Device.readByteBuf(buffer)); + return response; } } 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 07d0470..98eb63f 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,6 +1,7 @@ package io.github.protocol.mdtp.common; import io.github.protocol.mdtp.common.model.AbstractMessageBody; +import io.github.protocol.mdtp.common.model.MessageBodyHeader; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -13,15 +14,15 @@ public class AbstractMessageBodyTest { @BeforeEach void setUp() { - messageBody = new AbstractMessageBody(){}; + MessageBodyHeader messageBodyHeader = new MessageBodyHeader(); + messageBody = new AbstractMessageBody(messageBodyHeader){}; } @Test void testGenerateRequestId() { - short requestId1 = messageBody.generateRequestId(); - short requestId2 = messageBody.generateRequestId(); - + short requestId1 = messageBody.generateId(); + short requestId2 = messageBody.generateId(); assertEquals(Short.class, ((Object) requestId1).getClass()); assertEquals(Short.class, ((Object) requestId2).getClass()); assertNotEquals(requestId1, requestId2); 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 d7f7ed2..1f9b890 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 @@ -14,7 +14,7 @@ public class CDATHeaderTest { @BeforeEach void setUp() { cdatHeader = new CDATHeader( - (byte) 1, + (byte) 0, (byte) 2, (short) 100, 123456789L, @@ -30,7 +30,7 @@ void testToByteBuf() { cdatHeader.writeByteBuf(buffer); - assertEquals(1, buffer.readByte()); + assertEquals(0, buffer.readByte()); assertEquals(2, buffer.readByte()); assertEquals(100, buffer.readShort()); assertEquals(123456789L, buffer.readLong()); @@ -44,7 +44,7 @@ void testToByteBuf() { @Test void testFromByteBuf() { ByteBuf buffer = Unpooled.buffer(); - buffer.writeByte(1); + buffer.writeByte(0); buffer.writeByte(2); buffer.writeShort(100); buffer.writeLong(123456789L); 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 e6b31f1..20a6016 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 @@ -16,7 +16,6 @@ public class DeviceDiscoveryRequestTest { @BeforeEach void setUp() { request = new DeviceDiscoveryRequest(); - request.setMessageBodyHeader(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST); request.setRequestId((short) 123); request.setMask((byte) 0x1F); request.setDeviceTypeCount((byte) 3); 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 2f950b1..f5feb9e 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 @@ -1,14 +1,16 @@ package io.github.protocol.mdtp.common; +import io.github.protocol.mdtp.common.model.Address; +import io.github.protocol.mdtp.common.model.Device; import io.github.protocol.mdtp.common.model.DeviceDiscoveryResponse; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; public class DeviceDiscoveryResponseTest { @@ -18,51 +20,41 @@ public class DeviceDiscoveryResponseTest { @BeforeEach void setUp() { response = new DeviceDiscoveryResponse(); - response.setMessageHeader((short) 100); response.setRequestId((short) 200); response.setResponseId((short) 300); - response.setMask((byte) 0x1F); - response.setDeviceStatus((byte) 0x01); - response.setAddressCount((byte) 2); - response.setAddresses(new String[]{"192.168.1.1", "192.168.1.2"}); - response.setPort((short) 8080); - response.setDeviceType(12345); - response.setUniqueId(new byte[]{0x01, 0x02, 0x03, 0x04}); - response.setDeviceName("TestDevice"); + List
addresses = new ArrayList<>(); + addresses.add(new Address(Address.IPV4_TYPE, new byte[]{(byte) 192,(byte) 168,1,2} )); + addresses.add(new Address(Address.IPV4_TYPE, new byte[]{(byte) 192,(byte) 168,1,1} )); + Device device = Device.builder() + .mask((byte) 0x1F) + .deviceStatus((byte) 0x01) + .addressCount((byte) 2) + .addresses(addresses) + .port((short) 8080) + .deviceType(1) + .uniqueId(new byte[]{0x01, 0x02, 0x03, 0x04}) + .deviceName("TestDevice").build(); + response.setDevice(device); } @Test - void testToByteBuf() { + void testWriteByteBuf() { ByteBuf buffer = Unpooled.buffer(); - response.writeByteBuf(buffer); - assertEquals(100, buffer.readShort()); - assertEquals(200, buffer.readShort()); - assertEquals(300, buffer.readShort()); - assertEquals(0x1F, buffer.readByte()); - assertEquals(0x01, buffer.readByte()); - assertEquals(2, buffer.readByte()); - - byte[] addressBytes1 = new byte[11]; - buffer.readBytes(addressBytes1); - assertEquals("192.168.1.1", new String(addressBytes1, StandardCharsets.UTF_8)); - - byte[] addressBytes2 = new byte[11]; - buffer.readBytes(addressBytes2); - assertEquals("192.168.1.2", new String(addressBytes2, StandardCharsets.UTF_8)); - - assertEquals(8080, buffer.readShort()); - assertEquals(12345, buffer.readInt()); - - byte[] uniqueId = new byte[4]; - buffer.readBytes(uniqueId); - assertArrayEquals(new byte[]{0x01, 0x02, 0x03, 0x04}, uniqueId); - - byte[] nameBytes = new byte[10]; - buffer.readBytes(nameBytes); - assertEquals("TestDevice", new String(nameBytes, StandardCharsets.UTF_8)); + assertEquals((short) 1033, buffer.readShort()); + assertEquals((short) 200, buffer.readShort()); + assertEquals((short) 300, buffer.readShort()); + } - buffer.release(); + @Test + void testReadFromBuffer() { + ByteBuf buffer = Unpooled.buffer(); + response.writeByteBuf(buffer); + buffer.readShort(); + DeviceDiscoveryResponse readResponse = DeviceDiscoveryResponse.readFromBuffer(buffer); + assertEquals(response.getRequestId(), readResponse.getRequestId()); + assertEquals(response.getResponseId(), readResponse.getResponseId()); + assertEquals(response.getDevice().getDeviceName(), readResponse.getDevice().getDeviceName()); } } diff --git a/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpServerExample.java b/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpServerExample.java index 409bbe7..3030de3 100644 --- a/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpServerExample.java +++ b/mdtp-examples/src/main/java/io/github/protocol/mdtp/examples/MdtpServerExample.java @@ -1,11 +1,24 @@ package io.github.protocol.mdtp.examples; +import io.github.protocol.mdtp.common.model.Address; +import io.github.protocol.mdtp.common.model.Device; import io.github.protocol.mdtp.server.MdtpServer; import io.github.protocol.mdtp.server.MdtpServerConfig; +import java.util.List; + public class MdtpServerExample { public static void main(String[] args) throws Exception { - MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().host("localhost").port(4146); + Device device = Device.builder() + .mask((byte) 1) + .deviceStatus((byte) 0x01) + .addressCount((byte) 1) + .addresses(List.of(new Address(Address.IPV4_TYPE, new byte[]{127, 0, 0, 1}))) + .port((short) 4146) + .deviceType(1) + .uniqueId(new byte[]{0x01, 0x02, 0x03, 0x04}) + .deviceName("discovered endpoint").build(); + MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().device(device); MdtpServer mdtpServer = new MdtpServer(mdtpServerConfig); mdtpServer.start(); } 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 e142a6c..883b9bd 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,6 +1,8 @@ package io.github.protocol.mdtp.server; import io.github.protocol.mdtp.common.codec.MdtpDecoder; +import io.github.protocol.mdtp.common.model.Attributes; +import io.github.protocol.mdtp.common.model.Device; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -40,11 +42,13 @@ public void start() throws Exception { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(this.acceptorGroup, this.ioGroup); serverBootstrap.channel(NioServerSocketChannel.class); - serverBootstrap.localAddress(new InetSocketAddress(this.config.host, this.config.port)); + serverBootstrap.localAddress(this.config.device.getAddresses().get(0).getIpString(), this.config.device.getPort()); serverBootstrap.childHandler(new ChannelInitializer() { + private final Device device = MdtpServer.this.config.device; @Override protected void initChannel(SocketChannel socketChannel) throws Exception { log.info("init channel for remote address: {}", socketChannel.remoteAddress()); + socketChannel.attr(Attributes.DEVICE_KEY).set(device); ChannelPipeline pipeline = socketChannel.pipeline(); pipeline.addLast(new MdtpDecoder()); pipeline.addLast(new MdtpServerHandler()); diff --git a/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerConfig.java b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerConfig.java index 93d43d8..4865a07 100644 --- a/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerConfig.java +++ b/mdtp-server/src/main/java/io/github/protocol/mdtp/server/MdtpServerConfig.java @@ -1,17 +1,12 @@ package io.github.protocol.mdtp.server; -public class MdtpServerConfig { - public String host; - - public int port; +import io.github.protocol.mdtp.common.model.Device; - public MdtpServerConfig host(String host) { - this.host = host; - return this; - } +public class MdtpServerConfig { + public Device device; - public MdtpServerConfig port(int port) { - this.port = port; + public MdtpServerConfig device(Device device) { + this.device = device; return this; } } 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 index 838192b..e0a48e6 100644 --- 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 @@ -1,5 +1,8 @@ package io.github.protocol.mdtp.server; +import io.github.protocol.mdtp.common.handler.MessageBodyHandler; +import io.github.protocol.mdtp.common.handler.MessageHandlerFactory; +import io.github.protocol.mdtp.common.model.AbstractMessageBody; import io.github.protocol.mdtp.common.model.MdtpPacket; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; @@ -10,7 +13,9 @@ public class MdtpServerHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0(ChannelHandlerContext ctx, MdtpPacket packet) throws Exception { - log.info("receive packet:" + packet.toString()); + AbstractMessageBody messageBody = packet.getBody(); + MessageBodyHandler handler = MessageHandlerFactory.getHandler(messageBody.getMessageBodyHeader()); + handler.handle(ctx, packet); } @Override 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 index 7ba40a3..e5e05ef 100644 --- 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 @@ -1,5 +1,7 @@ package io.github.protocol.mdtp.client; +import io.github.protocol.mdtp.common.model.Address; +import io.github.protocol.mdtp.common.model.Device; import io.github.protocol.mdtp.server.MdtpServer; import io.github.protocol.mdtp.server.MdtpServerConfig; import org.junit.jupiter.api.AfterEach; @@ -7,6 +9,7 @@ import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.List; public class MdtpClientTest { @@ -17,7 +20,10 @@ public class MdtpClientTest { @BeforeEach public void setUp() throws Exception { - MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().host("localhost").port(4146); + Device device = Device.builder() + .addresses(List.of(new Address(Address.IPV4_TYPE, new byte[]{127,0,0,1}))) + .port((short) 4146).build(); + MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().device(device); mdtpServer = new MdtpServer(mdtpServerConfig); mdtpServer.start(); 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 e5441a6..955c37c 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,11 +1,18 @@ package io.github.protocol.mdtp.server; +import io.github.protocol.mdtp.common.model.Address; +import io.github.protocol.mdtp.common.model.Device; import org.junit.jupiter.api.Test; +import java.util.List; + public class MdtpConnectTest { @Test public void mdtpConnect() throws Exception { - MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().host("localhost").port(0); + Device device = Device.builder() + .addresses(List.of(new Address(Address.IPV4_TYPE, new byte[]{127,0,0,1}))) + .port((short) 4146).build(); + MdtpServerConfig mdtpServerConfig = new MdtpServerConfig().device(device); MdtpServer mdtpServer = new MdtpServer(mdtpServerConfig); mdtpServer.start(); 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 index cb0a4ff..7d30adb 100644 --- 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 @@ -1,16 +1,22 @@ package io.github.protocol.mdtp.server; +import io.github.protocol.mdtp.common.handler.MessageBodyHandler; +import io.github.protocol.mdtp.common.handler.MessageHandlerFactory; +import io.github.protocol.mdtp.common.model.DeviceDiscoveryRequest; 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.MockedStatic; import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; public class MdtpServerHandlerTest extends MdtpServerHandler { + private MdtpServerHandler handler; private ChannelHandlerContext ctx; private EmbeddedChannel channel; @@ -18,19 +24,26 @@ public class MdtpServerHandlerTest extends MdtpServerHandler { public void setUp() { ctx = Mockito.mock(ChannelHandlerContext.class); channel = new EmbeddedChannel(); + handler = new MdtpServerHandler(); } @Test public void testChannelRead0() throws Exception { MdtpPacket packet = Mockito.mock(MdtpPacket.class); - Mockito.when(packet.toString()).thenReturn("Mocked MdtpPacket"); - channelRead0(ctx, packet); + Mockito.when(packet.getBody()).thenReturn(new DeviceDiscoveryRequest()); + + MessageBodyHandler messageBodyHandler = Mockito.mock(MessageBodyHandler.class); + try (MockedStatic mockedStatic = Mockito.mockStatic(MessageHandlerFactory.class)) { + mockedStatic.when(() -> MessageHandlerFactory.getHandler(any())).thenReturn(messageBodyHandler); + handler.channelRead0(ctx, packet); + verify(messageBodyHandler).handle(ctx, packet); + } } @Test public void testExceptionCaught() throws Exception { - Throwable cause = new Throwable(); - exceptionCaught(ctx, cause); + Throwable cause = new RuntimeException("Test exception"); + handler.exceptionCaught(ctx, cause); verify(ctx).close(); } }