Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add device discover request #11

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,6 +22,9 @@ public class MdtpClient implements Closeable {

private EventLoopGroup group;

private ChannelFuture channelFuture;


public MdtpClient(MdtpClientConfig config) {
this.config = config;
}
Expand All @@ -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 {
Expand All @@ -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);
}
}
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 {
@Override
public AbstractMessageBody handle(ByteBuf in) {
return DeviceDiscoveryRequest.fromByteBuf(in);
}
}
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.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);
}
}
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<>();

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

public static MessageBodyDecoder getDecoder(MessageBodyHeader header) {
return decoders.get(header.toShort());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,27 @@ 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);
buffer.writeLong(timestamp);
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;
}
}
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 @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -53,7 +53,5 @@ public ByteBuf toByteBuf(ByteBuf buffer) {
byte[] nameBytes = deviceName.getBytes(StandardCharsets.UTF_8);
buffer.writeBytes(nameBytes);
}

return buffer;
}
}
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;
}
}
throw new IllegalArgumentException("Invalid DiscoveryServiceCode: " + value);
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,13 @@
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);

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 @@ -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;
}

}
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;
}
}
throw new IllegalArgumentException("Invalid ServiceGroup code: " + value);
}
}
Loading
Loading