Skip to content

Commit

Permalink
feat: add device discover request
Browse files Browse the repository at this point in the history
Signed-off-by: wei <[email protected]>
  • Loading branch information
instpe committed Nov 20, 2024
1 parent cf32c2c commit 571cda1
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
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.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
Expand All @@ -16,6 +21,8 @@
public class MdtpClient implements Closeable {
private final MdtpClientConfig config;

private ChannelFuture channelFuture;

private EventLoopGroup group;

public MdtpClient(MdtpClientConfig config) {
Expand All @@ -35,9 +42,13 @@ public void start() throws Exception {
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// ChannelPipeline pipeline = ch.pipeline();
// pipeline.addLast(new MdtpDecoder());
// pipeline.addLast(new MdtpEncoder());
// pipeline.addLast(new MdtpClientHandler());
}
});
ChannelFuture channelFuture = bootstrap.connect().sync();
this.channelFuture = bootstrap.connect().sync();
if (channelFuture.isSuccess()) {
log.info("mdtp client started");
} else {
Expand All @@ -55,4 +66,40 @@ 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);
log.info("" + request.getMessageBodyHeader().toShort());
request.setRequestId(request.generateRequestId());

Check warning on line 75 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L71-L75

Added lines #L71 - L75 were not covered by tests

if (deviceTypes == null) {
request.setDeviceTypeCount((byte) 0);

Check warning on line 78 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L78

Added line #L78 was not covered by tests
}

if (deviceTypes != null && deviceTypes.length > 0) {
request.setMask((byte) 1);
request.setDeviceTypeCount((byte) deviceTypes.length);
request.setDeviceTypes(deviceTypes);

Check warning on line 84 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L82-L84

Added lines #L82 - L84 were not covered by tests
}

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);

Check warning on line 94 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L87-L94

Added lines #L87 - L94 were not covered by tests

MdtpPacket packet = new MdtpPacket();
packet.setHeader(cdatHeader);
packet.setSecurityHeader(null);
packet.setBody(request);
packet.setSignature(null);

Check warning on line 100 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L96-L100

Added lines #L96 - L100 were not covered by tests

this.channelFuture.channel().writeAndFlush(packet.toByteBuf(Unpooled.buffer()));
log.info("send device discovery request success: " + packet);
}

Check warning on line 104 in mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java

View check run for this annotation

Codecov / codecov/patch

mdtp-client/src/main/java/io/github/protocol/mdtp/client/MdtpClient.java#L102-L104

Added lines #L102 - L104 were not covered by tests
}
Original file line number Diff line number Diff line change
@@ -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 {

Check warning on line 7 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java#L7

Added line #L7 was not covered by tests
@Override
public AbstractMessageBody handle(ByteBuf in) {
return DeviceDiscoveryRequest.fromByteBuf(in);

Check warning on line 10 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/DeviceDiscoveryRequestDecoder.java#L10

Added line #L10 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -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<Object> out) throws Exception {

MdtpPacket mdtpPacket = new MdtpPacket();
CDATHeader header = CDATHeader.fromByteBuf(in);

Check warning on line 22 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java#L21-L22

Added lines #L21 - L22 were not covered by tests

MessageBodyHeader messageBodyHeader = MessageBodyHeader.fromByteBuf(in);
MessageBodyDecoder messageDecode = MessageDecoderFactory.getDecoder(messageBodyHeader);
AbstractMessageBody messageBody = messageDecode.handle(in);
messageBody.setMessageBodyHeader(messageBodyHeader);

Check warning on line 27 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java#L24-L27

Added lines #L24 - L27 were not covered by tests

mdtpPacket.setHeader(header);
mdtpPacket.setBody(messageBody);

Check warning on line 30 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java#L29-L30

Added lines #L29 - L30 were not covered by tests

out.add(mdtpPacket);
}

Check warning on line 33 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MdtpDecoder.java#L32-L33

Added lines #L32 - L33 were not covered by tests
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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 {

Check warning on line 8 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java#L8

Added line #L8 was not covered by tests

private static final Map<Short, MessageBodyDecoder> decoders = new HashMap<>();

Check warning on line 10 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java#L10

Added line #L10 was not covered by tests

static {
decoders.put(MessageBodyHeader.DEVICE_DISCOVERY_REQUEST.toShort(), new DeviceDiscoveryRequestDecoder());
}

Check warning on line 14 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java#L13-L14

Added lines #L13 - L14 were not covered by tests

public static MessageBodyDecoder getDecoder(MessageBodyHeader header) {
return decoders.get(header.toShort());

Check warning on line 17 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/codec/MessageDecoderFactory.java#L17

Added line #L17 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,15 @@

@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);
messageBodyHeader.toByteBuf(buffer);
return buffer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,18 @@ public ByteBuf toByteBuf(ByteBuf buffer) {
buffer.writeInt(logicalChannelId);
return buffer;
}

public static CDATHeader fromByteBuf(ByteBuf buffer) {
CDATHeader header = new CDATHeader();

Check warning on line 40 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java#L40

Added line #L40 was not covered by tests

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());

Check warning on line 48 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java#L42-L48

Added lines #L42 - L48 were not covered by tests

return header;

Check warning on line 50 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/CDATHeader.java#L50

Added line #L50 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@


@Data
public class DeviceDiscoveryRequest extends AbstractMessageBody {
public class DeviceDiscoveryRequest extends AbstractMessageBody{

private short requestId;

private byte mask;
Expand All @@ -19,8 +20,10 @@ public ByteBuf toByteBuf(ByteBuf 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Check warning on line 22 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java#L22

Added line #L22 was not covered by tests
}
}
throw new IllegalArgumentException("Invalid DiscoveryServiceCode: " + value);

Check warning on line 25 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/DiscoveryServiceCode.java#L25

Added line #L25 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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 ByteBuf toByteBuf(ByteBuf buffer) {
buffer.writeShort(toShort());
return buffer;
}

public static MessageBodyHeader fromByteBuf(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);

Check warning on line 45 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageBodyHeader.java#L41-L45

Added lines #L41 - L45 were not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Check warning on line 23 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java#L23

Added line #L23 was not covered by tests
}
}
throw new IllegalArgumentException("Invalid MessageType code: " + value);

Check warning on line 26 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/MessageType.java#L26

Added line #L26 was not covered by tests
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Check warning on line 32 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java#L32

Added line #L32 was not covered by tests
}
}
throw new IllegalArgumentException("Invalid ServiceGroup code: " + value);

Check warning on line 35 in mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java

View check run for this annotation

Codecov / codecov/patch

mdtp-common/src/main/java/io/github/protocol/mdtp/common/model/ServiceGroup.java#L35

Added line #L35 was not covered by tests
}
}
Original file line number Diff line number Diff line change
@@ -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 {

Expand All @@ -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() {
Expand All @@ -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();
}
}
Loading

0 comments on commit 571cda1

Please sign in to comment.