diff options
Diffstat (limited to 'src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java')
-rw-r--r-- | src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java index d03f7648d..411e2b9d7 100644 --- a/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/DualcamProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 - 2022 Anton Tananaev (anton@traccar.org) + * Copyright 2021 - 2023 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,13 +42,24 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMPLETE = 5; public static final int MSG_FILE_REQUEST = 8; public static final int MSG_INIT_REQUEST = 9; + public static final int MSG_PATH_REQUEST = 0x000C; + public static final int MSG_PATH_RESPONSE = 0x000D; + private String model; private String uniqueId; - private int packetCount; - private int currentPacket; + private int dataSize; + private int dataCurrent; private boolean video; private ByteBuf media; + private boolean isPacketData() { + if (model == null) { + return dataSize < 8192; + } else { + return !"DSM".equals(model); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -57,15 +68,21 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedShort(); + DeviceSession deviceSession; switch (type) { case MSG_INIT: buf.readUnsignedShort(); // protocol id uniqueId = String.valueOf(buf.readLong()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); + deviceSession = getDeviceSession(channel, remoteAddress, uniqueId); long settings = buf.readUnsignedInt(); if (channel != null && deviceSession != null) { + model = getDeviceModel(deviceSession); ByteBuf response = Unpooled.buffer(); - if (BitUtil.between(settings, 26, 30) > 0) { + if (BitUtil.check(settings, 25)) { + response.writeShort(MSG_PATH_REQUEST); + response.writeShort(2); + response.writeShort(0); + } else if (BitUtil.between(settings, 26, 30) > 0) { response.writeShort(MSG_FILE_REQUEST); String file; if (BitUtil.check(settings, 26)) { @@ -91,21 +108,29 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { break; case MSG_START: buf.readUnsignedShort(); // length - packetCount = buf.readInt(); - currentPacket = 1; + dataSize = buf.readInt(); + dataCurrent = isPacketData() ? 1 : 0; media = Unpooled.buffer(); if (channel != null) { ByteBuf response = Unpooled.buffer(); response.writeShort(MSG_RESUME); response.writeShort(4); - response.writeInt(currentPacket); + response.writeInt(dataCurrent); channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } break; case MSG_DATA: - buf.readUnsignedShort(); // length - media.writeBytes(buf, buf.readableBytes() - 2); - if (currentPacket == packetCount) { + int length = buf.readUnsignedShort() - 2; + media.writeBytes(buf, length); + boolean finished; + if (isPacketData()) { + finished = dataCurrent == dataSize; + dataCurrent += 1; + } else { + finished = dataCurrent + length == dataSize; + dataCurrent += length; + } + if (finished) { deviceSession = getDeviceSession(channel, remoteAddress); Position position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); @@ -126,8 +151,16 @@ public class DualcamProtocolDecoder extends BaseProtocolDecoder { channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } return position; - } else { - currentPacket += 1; + } + break; + case MSG_PATH_RESPONSE: + String file = buf.readCharSequence(buf.readUnsignedShort(), StandardCharsets.US_ASCII).toString(); + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeShort(MSG_FILE_REQUEST); + response.writeShort(file.length()); + response.writeCharSequence(file, StandardCharsets.US_ASCII); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } break; default: |