From 81d2bdab9d91b2faa4824fbced4db2bc0edc821d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 11 Sep 2020 21:59:53 -0700 Subject: Support batched locations --- .../protocol/Minifinder2ProtocolDecoder.java | 25 ++++++++++++++++++++-- .../protocol/Minifinder2ProtocolDecoderTest.java | 11 ++++++---- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java index 08f49c9ee..7475ba4d9 100644 --- a/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/Minifinder2ProtocolDecoder.java @@ -34,6 +34,10 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { @@ -100,11 +104,26 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_DATA) { + List positions = new LinkedList<>(); + Set keys = new HashSet<>(); + boolean hasLocation = false; Position position = new Position(getProtocolName()); while (buf.isReadable()) { int endIndex = buf.readUnsignedByte() + buf.readerIndex(); int key = buf.readUnsignedByte(); + + if (keys.contains(key)) { + if (!hasLocation) { + getLastLocation(position, null); + } + positions.add(position); + keys.clear(); + hasLocation = false; + position = new Position(getProtocolName()); + } + keys.add(key); + switch (key) { case 0x01: DeviceSession deviceSession = getDeviceSession( @@ -122,6 +141,7 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShortLE() * 0.001); break; case 0x20: + hasLocation = true; position.setLatitude(buf.readIntLE() * 0.0000001); position.setLongitude(buf.readIntLE() * 0.0000001); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShortLE())); @@ -186,11 +206,12 @@ public class Minifinder2ProtocolDecoder extends BaseProtocolDecoder { buf.readerIndex(endIndex); } - if (!position.getAttributes().containsKey(Position.KEY_SATELLITES)) { + if (!hasLocation) { getLastLocation(position, null); } + positions.add(position); - return position.getDeviceId() > 0 ? position : null; + return positions; } diff --git a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java index f6a2afe62..00c33ec82 100644 --- a/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/Minifinder2ProtocolDecoderTest.java @@ -13,19 +13,22 @@ public class Minifinder2ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "ab10150076f1320003100133353534363530373130323933303602105a")); - verifyAttributes(decoder, binary( + verifyPositions(decoder, binary( + "ab10cf0382171a0c0110013836353036383034303030303132380924d2a85b5f010296411620d8d9cf13283b5fc601000000e4065500ac4001000b0924dca85b5f0102964116205fd4cf13c53d5fc6010099009f074300ac4001000b0924e6a85b5f010296411620dbd0cf13b83b5fc60d00df00d0074300ac4001000b0924f0a85b5f010296411620a0cccf1339195fc61c000a01fd074000ac4001000b0924faa85b5f010296411620efd9cf135f0b5fc61f00a600b0074200124101000b092404a95b5f010296411620c1eecf13de235fc627005400d3074300124101000b09240ea95b5f010296411620b6f0cf139d505fc628005400280846007d4101000b092418a95b5f01029641162041f2cf13d5835fc62b0056006a084600514201000b092422a95b5f0102964116204ee6cf137ea25fc62100a00091084000514201000b09242ca95b5f01029641162042d6cf130a9a5fc62100fd0085074300b74201000b092436a95b5f010296411620a6d4cf132b6a5fc628000a01250841001e4301000b092440a95b5f01029641162039d1cf1336445fc61200100127084000894301000b09244aa95b5f010296411620bad5cf13eb3d5fc601004e001d084c00894301000b092454a95b5f01029641162042d6cf13163e5fc6000004006e084500894301000b09245ea95b5f01029641162008d9cf1322395fc60100000032084000894301000b092468a95b5f010296411620bfd5cf1345395fc60000080069084c00894301000b092472a95b5f01029641162001d7cf13e8375fc6000000003e085200894301000b09247ca95b5f0102964116204fd7cf136c3a5fc60000000055085400894301000b092486a95b5f010296411620d2d7cf1364395fc600000000a8076c00894301000b092490a95b5f010296411620fdd6cf13383a5fc6000000003c084d00894301000b09249aa95b5f01029641162049d7cf13d9395fc600000000be076c00894301000b0924a4a95b5f010296411620e8d5cf133f375fc6000000001a085900894301000b0924aea95b5f01029641162080d9cf13e3395fc60000000080076c00894301000b0924b8a95b5f010296411620a1d9cf13ac395fc6000000006f075b00894301000b0924c2a95b5f010296411620f3d9cf13b53a5fc60000000090074f00894301000b0924cca95b5f010296411620a1d7cf13aa385fc6000000001d084d00894301000b0924d6a95b5f0102964116208fd8cf1393385fc600000000fc074d00894301000b0924e0a95b5f0102964116206dd7cf13ae395fc600000000ef074d00894301000b0924eaa95b5f01029641162044d8cf1388395fc600000000a5075200894301000b")); + + verifyNotNull(decoder, binary( "ab10ba034461360201100138363339323130333135313139363009245b364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda092464364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda09246e364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda09246f364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda092478364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda092482364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda09248c364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda092496364f5f3200ae646a22a76ce873a3ee50b8547595374807b2fad027610438b504d3b5b7819cb2943bb04351a3b094bf8087b878b8502b7306cb11aec85ba0a15044a7dcfe18bdcdf8ac1226a6964e1ab00c8447c13e5dbf480eecf0e436a1c486e987b794a5b8f88340d7b5ad9ca615c91cda")); verifyNotNull(decoder, binary( "ab1024009b3f9742011001383635323039303336333430303235113154cfc95d0a00000080d0c95d0a000000")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "ab103f007e2533000110013335353436353037313032393330360930e09d245d210100000924b49e245d01025b201620e6c03b1ef367420400000000aa026d00c90e0000100110")); - verifyAttributes(decoder, binary( + verifyNotNull(decoder, binary( "ab1845005d39370301100133353836383830303030303338303209245b92b55c84004b610502001000002221ca00050b4a005cc30f4a0056c80f4a003ba90e4a0055c8074a005dc3034a0057c8")); - verifyAttributes(decoder, binary( + verifyNotNull(decoder, binary( "ab185c001db78b03011001333538363838303030303033383032092448bd8a5c82003b130502010000003922ca923bad10f794bd30b5c2cb0595b2944a0c49a4f9b6a4b1e9991e79ba0026bb78c08fb4581faae7ee3fb0e091f5778e96b074a78ed46528")); verifyNotNull(decoder, binary( -- cgit v1.2.3