diff options
-rw-r--r-- | src/org/traccar/protocol/GalileoProtocolDecoder.java | 60 | ||||
-rw-r--r-- | test/org/traccar/protocol/GalileoProtocolDecoderTest.java | 3 |
2 files changed, 59 insertions, 4 deletions
diff --git a/src/org/traccar/protocol/GalileoProtocolDecoder.java b/src/org/traccar/protocol/GalileoProtocolDecoder.java index 7e17ebd93..8ed4840a5 100644 --- a/src/org/traccar/protocol/GalileoProtocolDecoder.java +++ b/src/org/traccar/protocol/GalileoProtocolDecoder.java @@ -20,6 +20,7 @@ import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.helper.UnitsConverter; @@ -41,6 +42,8 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private ByteBuf photo; + private static final Map<Integer, Integer> TAG_LENGTH_MAP = new HashMap<>(); static { @@ -92,10 +95,10 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return length; } - private void sendReply(Channel channel, int checksum) { + private void sendReply(Channel channel, int header, int checksum) { if (channel != null) { ByteBuf reply = Unpooled.buffer(3); - reply.writeByte(0x02); + reply.writeByte(header); reply.writeShortLE((short) checksum); channel.writeAndFlush(new NetworkMessage(reply, channel.remoteAddress())); } @@ -243,7 +246,19 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { ByteBuf buf = (ByteBuf) msg; - buf.readUnsignedByte(); // header + int header = buf.readUnsignedByte(); + if (header == 0x01) { + return decodePositions(channel, remoteAddress, buf); + } else if (header == 0x07) { + return decodePhoto(channel, remoteAddress, buf); + } + + return null; + } + + private Object decodePositions( + Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + int length = (buf.readUnsignedShortLE() & 0x7fff) + 3; List<Position> positions = new LinkedList<>(); @@ -295,7 +310,7 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { positions.add(position); } - sendReply(channel, buf.readUnsignedShortLE()); + sendReply(channel, 0x02, buf.readUnsignedShortLE()); for (Position p : positions) { p.setDeviceId(deviceSession.getDeviceId()); @@ -304,4 +319,41 @@ public class GalileoProtocolDecoder extends BaseProtocolDecoder { return positions.isEmpty() ? null : positions; } + private Object decodePhoto( + Channel channel, SocketAddress remoteAddress, ByteBuf buf) throws Exception { + + int length = buf.readUnsignedShortLE(); + + Position position = null; + + if (length > 1) { + + if (photo == null) { + photo = Unpooled.buffer(); + } + + buf.readUnsignedByte(); // part number + photo.writeBytes(buf, length - 1); + + } else { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); + + position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + photo.release(); + photo = null; + + } + + sendReply(channel, 0x07, buf.readUnsignedShortLE()); + + return position; + } + } diff --git a/test/org/traccar/protocol/GalileoProtocolDecoderTest.java b/test/org/traccar/protocol/GalileoProtocolDecoderTest.java index d6563453a..9e80d2aad 100644 --- a/test/org/traccar/protocol/GalileoProtocolDecoderTest.java +++ b/test/org/traccar/protocol/GalileoProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class GalileoProtocolDecoderTest extends ProtocolTest { GalileoProtocolDecoder decoder = new GalileoProtocolDecoder(new GalileoProtocol()); + verifyNull(decoder, binary( + "07e10300ffd8ffe000114a464946000101010000000000000affe1011445786966000049492a000800000005000e010200140000004a0000000f0102000a0000005e000000100102000a0000006800000032010200130000007200000025880400010000008600000000000000494d45492033353336313230383730353035393247616c696c656f536b7971717a6d202020202020323031383a30383a30392030363a35393a303100060001000200020000004e0000000200050003000000d40000000300020002000000450000000400050003000000ec000000050001000100000000000000060005000100000004010000000000008e7f930240420f0000000000010000000000000001000000a11aaa0140420f00000000000100000000000000010000003300000001000000ffdb0084000d09090b09080d0b0a0b0e0d0d0f131f1413111113261b1d171f2d28302f2d282c2b3238483d323544362b2c3f553f444a4d505150303c585f584e5e484f504d010d0e0e131013251414254d342c344d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4d4dffc000110801e0028003012100021101031101ffdd0004000affc401a20000010501010101010100000000000000000102030405060708090a0b100002010303020403050504040000017d01020300041105122131410613516107227114328191a1082342b1c11552d1f02433627282090a161718191a25262728292a3435363738393a434445464748494a535455565758595a636465666768696a737475767778797a838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae1e2e3e4e5e6e7e8e9eaf1f2f3f4f5f6f7f8f9fa0100030101010101010101010000000000000102030405060708090a0b1100020102040403040705040400010277000102031104052131061241510761711322328108144291a1b1c109233352f0156272d10a162434e125f11718191a262728292a35363738393a434445464748494a535455565758595a636465666768696a737475767778797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f3f4f5f6f7f8f9faffda000c03010002110311003f00f41237526768c119a0811803c8e29a7eb40075151ba9e2801436060d0df779ef408685c50092db6801e63c9c83834c772a3140c818163522924fa5310367b9a8f3ce2806382734e2bc7340c68031c52ab1e86811ffd0edcf0335170fd7b5333023151c83d4ba")); + verifyPositions(decoder, false, binary( "01560003383636303530303338343337353836044701e000000000e13c494e414c4c3a696e303d31313230362c696e313d302c696e323d302c696e333d302c696e343d302c696e353d302c4163633d3536363932343732353bfdef")); |