From b19f1a505f7088ff48f467b32b5f1c207aa3be01 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 12 Jul 2017 14:22:03 +0500 Subject: - Handle rfid attributes and populate driverUniqueId - Add Driver Name to Trip report --- src/org/traccar/protocol/AplicomProtocolDecoder.java | 3 ++- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 2 +- src/org/traccar/protocol/OsmAndProtocolDecoder.java | 3 +++ src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index eb8d77011..448cd94fc 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -263,7 +263,8 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0200) != 0) { - position.set(Position.KEY_RFID, (((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); + position.set(Position.KEY_RFID, + String.valueOf(((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); } if ((selector & 0x0400) != 0) { diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 44e01d5e0..77e117262 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -253,7 +253,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - position.set(Position.KEY_RFID, parser.nextHexInt(0)); + position.set(Position.KEY_RFID, String.valueOf(parser.nextHexInt(0))); } return position; diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 15f6f40b8..20cd54b2f 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -128,6 +128,9 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { case "batt": position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); break; + case "rfid": + position.set(Position.KEY_RFID, value); + break; default: try { position.set(entry.getKey(), Double.parseDouble(value)); diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 3f5b68f67..f1fd55d98 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -114,7 +114,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; case 78: - position.set(Position.KEY_RFID, readValue(buf, length, false)); + position.set(Position.KEY_RFID, String.valueOf(readValue(buf, length, false))); break; case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); -- cgit v1.2.3 From beffaa1bcb14965e34d533cf7c771886c5832391 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jul 2017 05:57:21 +1200 Subject: Add Teltonika UDP tests --- src/org/traccar/protocol/TeltonikaProtocol.java | 4 ++-- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 11 +++++++---- .../org/traccar/protocol/TeltonikaProtocolDecoderTest.java | 14 +++++++++++++- 3 files changed, 22 insertions(+), 7 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocol.java b/src/org/traccar/protocol/TeltonikaProtocol.java index 524e6d5b5..d0177da97 100644 --- a/src/org/traccar/protocol/TeltonikaProtocol.java +++ b/src/org/traccar/protocol/TeltonikaProtocol.java @@ -39,14 +39,14 @@ public class TeltonikaProtocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new TeltonikaFrameDecoder()); pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); - pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); + pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, false)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("objectEncoder", new TeltonikaProtocolEncoder()); - pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this)); + pipeline.addLast("objectDecoder", new TeltonikaProtocolDecoder(TeltonikaProtocol.this, true)); } }); } diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 3f5b68f67..d8a7b0bc0 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -35,8 +35,11 @@ import java.util.List; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { - public TeltonikaProtocolDecoder(TeltonikaProtocol protocol) { + boolean connectionless; + + public TeltonikaProtocolDecoder(TeltonikaProtocol protocol, boolean connectionless) { super(protocol); + this.connectionless = connectionless; } private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { @@ -249,7 +252,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int locationPacketId, String... imei) { List positions = new LinkedList<>(); - if (!(channel instanceof DatagramChannel)) { + if (!connectionless) { buf.readUnsignedInt(); // data length } @@ -278,7 +281,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - if (channel instanceof DatagramChannel) { + if (connectionless) { ChannelBuffer response = ChannelBuffers.dynamicBuffer(); response.writeShort(5); response.writeShort(0); @@ -301,7 +304,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; - if (channel instanceof DatagramChannel) { + if (connectionless) { return decodeUdp(channel, remoteAddress, buf); } else { return decodeTcp(channel, remoteAddress, buf); diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index dd484cad7..2eb5271d1 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -1,5 +1,6 @@ package org.traccar.protocol; +import org.junit.Ignore; import org.junit.Test; import org.traccar.ProtocolTest; @@ -8,7 +9,7 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { @Test public void testDecode() throws Exception { - TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol()); + TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol(), false); verifyNull(decoder, binary( "000F313233343536373839303132333435")); @@ -60,4 +61,15 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { } + @Ignore + @Test + public void testDecodeConnectionless() throws Exception { + + TeltonikaProtocolDecoder decoder = new TeltonikaProtocolDecoder(new TeltonikaProtocol(), true); + + verifyPositions(decoder, false, binary( + "0049cafe0122000f33353734353430373237313339373508010000015d3766f6a800003eef961ec6215e0063006d09003100070401000200f001c8000242381c18003201c7000000e10001")); + + } + } -- cgit v1.2.3 From 408f34e20d8673acb6064cb7d62f754effe8a204 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jul 2017 06:02:43 +1200 Subject: Fix build issue --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index d8a7b0bc0..bf9a19bc7 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; -- cgit v1.2.3 From 9962c5ee58f4f5be82e9d2aae434aa2e619d4c85 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 13 Jul 2017 06:04:02 +1200 Subject: Fix another build issue --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index bf9a19bc7..8c4d6f72e 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -34,7 +34,7 @@ import java.util.List; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { - boolean connectionless; + private boolean connectionless; public TeltonikaProtocolDecoder(TeltonikaProtocol protocol, boolean connectionless) { super(protocol); -- cgit v1.2.3 From a2e1f56adf50746425565557dd38f0e2c81a0222 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 14 Jul 2017 06:59:47 +1200 Subject: Implement extended Teltonika protocol --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 15 +++++++++++++++ .../traccar/protocol/TeltonikaProtocolDecoderTest.java | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 8c4d6f72e..c8c2e4002 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; @@ -35,10 +36,16 @@ import java.util.List; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { private boolean connectionless; + private boolean extended; + + public void setExtended(boolean extended) { + this.extended = extended; + } public TeltonikaProtocolDecoder(TeltonikaProtocol protocol, boolean connectionless) { super(protocol); this.connectionless = connectionless; + this.extended = Context.getConfig().getBoolean(getProtocolName() + ".extended"); } private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { @@ -245,6 +252,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + // Read 16 byte data + if (extended) { + int cnt = buf.readUnsignedByte(); + for (int j = 0; j < cnt; j++) { + position.set(Position.PREFIX_IO + buf.readUnsignedByte(), ChannelBuffers.hexDump(buf.readBytes(16))); + } + } + } private List parseData( diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index 2eb5271d1..50e8600cf 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -58,7 +58,12 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "00000000000000a608010000013f14a1d1ce000f0eb790209a778000ab010c0500000000000000000100003390")); - + + decoder.setExtended(true); + + verifyPositions(decoder, false, binary( + "00000000000003b5080b0000015ab5642a8800d5db1769ec01d70a020a00e3040004000e0501010200030004006000060900100a00010b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab5642e7000d5db178aec01d6d6020a0070040003000e0501010200030004006000060900100a00000b0000130000422f1318000302c700000000f7000000000001cb000000000000000000000000000000000000015ab567050000d5db1805ec01da3c02060101040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000046f7000000000001cb000000000000000000000000000000000000015ab56708e800d5db1723ec01d9ec020600e5040006000e05010102000300040060000609000f0a00010b0000130000422f1018000502c700000003f7000000000001cb000000000000000000000000000000000000015ab5685cc000d5db20f7ec01d8fa02080033050007000e05010102000300040060000609000f0a00010b0000130000422f0a18000502c700000030f7000000000001cb000000000000000000000000000000000000015ab5693b6800d5db2367ec01d9430211011b040006000e05010102000300040060000609000f0a00010b0000130000422f0c18000302c700000027f7000000000001cb000000000000000000000000000000000000015ab569433800d5db1fb2ec01d9310211008b040006000e0501010200030004006000060900110a00000b0000130000422f1318000402c700000009f7000000000001cb000000000000000000000000000000000000015ab56a0e5800d5db22a2ec01da5502100041050007000e05010102000300040060000609000f0a00000b0000130000422f1118000602c70000000ef7000000000001cb000000000000000000000000000000000000015ab56a700000d5db2afcec01ddb2020a0012050008000e05010102000300040060000609000e0a00000b0000130000422f0918000502c700000026f7000000000001cb000000000000000000000000000000000000015ab56a73e800d5db2ad8ec01de65020a014e050008000e05010102000300040060000609000f0a00010b0000130000422f0818000702c700000002f7000000000001cb000000000000000000000000000000000000015ab56a7bb800d5db2971ec01e00e020a013f040008000e0501010200030004006000060900100a00020b0000130000422f0b18000802c700000004f7000000000001cb000000000000000000000000000000000b00007c5f")); + } @Ignore -- cgit v1.2.3 From 9949cadcdf3f07a4590742e2f0303d82efb653f9 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 14 Jul 2017 11:34:58 +0500 Subject: Save driver identification (rfid/ibutton etc.) as driverUniqueId attribute --- src/org/traccar/model/Position.java | 1 - src/org/traccar/protocol/AplicomProtocolDecoder.java | 2 +- src/org/traccar/protocol/AstraProtocolDecoder.java | 2 +- src/org/traccar/protocol/AtrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/FifotrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 2 +- src/org/traccar/protocol/GnxProtocolDecoder.java | 2 +- src/org/traccar/protocol/Gps103ProtocolDecoder.java | 2 +- src/org/traccar/protocol/MegastekProtocolDecoder.java | 2 +- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 4 ++-- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- src/org/traccar/protocol/MxtProtocolDecoder.java | 2 +- src/org/traccar/protocol/OsmAndProtocolDecoder.java | 2 +- src/org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- src/org/traccar/protocol/StarLinkProtocolDecoder.java | 2 +- src/org/traccar/protocol/Stl060ProtocolDecoder.java | 2 +- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- src/org/traccar/protocol/TmgProtocolDecoder.java | 2 +- src/org/traccar/protocol/UlbotechProtocolDecoder.java | 3 ++- src/org/traccar/protocol/VisiontekProtocolDecoder.java | 2 +- src/org/traccar/protocol/WialonProtocolDecoder.java | 2 +- test/org/traccar/ProtocolTest.java | 4 ++-- 22 files changed, 24 insertions(+), 24 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 97b3f365f..9e7bac932 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -49,7 +49,6 @@ public class Position extends Message { public static final String KEY_FUEL_LEVEL = "fuel"; // liters public static final String KEY_FUEL_CONSUMPTION = "fuelConsumption"; // liters/hour - public static final String KEY_RFID = "rfid"; public static final String KEY_VERSION_FW = "versionFw"; public static final String KEY_VERSION_HW = "versionHw"; public static final String KEY_TYPE = "type"; diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 448cd94fc..6f63d0c17 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -263,7 +263,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { } if ((selector & 0x0200) != 0) { - position.set(Position.KEY_RFID, + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(((long) buf.readUnsignedShort()) << 32) + buf.readUnsignedInt()); } diff --git a/src/org/traccar/protocol/AstraProtocolDecoder.java b/src/org/traccar/protocol/AstraProtocolDecoder.java index ea6aa7b30..8d86cd2be 100644 --- a/src/org/traccar/protocol/AstraProtocolDecoder.java +++ b/src/org/traccar/protocol/AstraProtocolDecoder.java @@ -105,7 +105,7 @@ public class AstraProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // geofence events if (BitUtil.check(status, 8)) { - position.set(Position.KEY_RFID, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, buf.readBytes(7).toString(StandardCharsets.US_ASCII)); position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 1000); position.set(Position.KEY_HOURS, buf.readUnsignedShort()); } diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 79b3c36cc..23cb67e15 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -327,7 +327,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OUTPUT, buf.readUnsignedByte()); position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort() * 0.001); - position.set("driver", readString(buf)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, readString(buf)); position.set(Position.PREFIX_TEMP + 1, buf.readShort() * 0.1); position.set(Position.PREFIX_TEMP + 2, buf.readShort() * 0.1); diff --git a/src/org/traccar/protocol/FifotrackProtocolDecoder.java b/src/org/traccar/protocol/FifotrackProtocolDecoder.java index f8f4fb078..304f6a2c3 100644 --- a/src/org/traccar/protocol/FifotrackProtocolDecoder.java +++ b/src/org/traccar/protocol/FifotrackProtocolDecoder.java @@ -110,7 +110,7 @@ public class FifotrackProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + (i + 1), Integer.parseInt(adc[i], 16)); } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { String[] sensors = parser.next().split("\\|"); diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java index a3062c942..140d3300a 100644 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -644,7 +644,7 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder { return null; } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); decodeLocation(position, parser); diff --git a/src/org/traccar/protocol/GnxProtocolDecoder.java b/src/org/traccar/protocol/GnxProtocolDecoder.java index 070d394e8..2274ec164 100644 --- a/src/org/traccar/protocol/GnxProtocolDecoder.java +++ b/src/org/traccar/protocol/GnxProtocolDecoder.java @@ -102,7 +102,7 @@ public class GnxProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); if (type.equals("MIF")) { - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); } return position; diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index f5ba3cff7..a9a72b110 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -258,7 +258,7 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { String rfid = parser.next(); if (alarm.equals("rfid")) { - position.set(Position.KEY_RFID, rfid); + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); } String utcHours = parser.next(); diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 15a384cc0..994e2d983 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -327,7 +327,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { } } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); String battery = parser.next(); if (battery != null) { diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 77e117262..dbbf61f71 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -253,7 +253,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - position.set(Position.KEY_RFID, String.valueOf(parser.nextHexInt(0))); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(parser.nextHexInt(0))); } return position; @@ -370,7 +370,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { if (rfid != 0) { String card = String.format("%010d", rfid); position.set("card" + (i + 1), card); - position.set(Position.KEY_RFID, card); + position.set(Position.KEY_DRIVER_UNIQUE_ID, card); } } } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 38ecde519..711697fc4 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -201,7 +201,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (eventData != null && !eventData.isEmpty()) { switch (event) { case 37: - position.set(Position.KEY_RFID, eventData); + position.set(Position.KEY_DRIVER_UNIQUE_ID, eventData); break; default: position.set("eventData", eventData); diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java index 49987ce57..6d82e4a4b 100644 --- a/src/org/traccar/protocol/MxtProtocolDecoder.java +++ b/src/org/traccar/protocol/MxtProtocolDecoder.java @@ -159,7 +159,7 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder { } if (BitUtil.check(infoGroups, 7)) { - position.set(Position.KEY_RFID, buf.readUnsignedInt()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(buf.readUnsignedInt())); } buf.readerIndex(buf.writerIndex() - 3); diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 20cd54b2f..cb324aa86 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -129,7 +129,7 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); break; case "rfid": - position.set(Position.KEY_RFID, value); + position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; default: try { diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java index b1851f8ca..e12bbdf28 100644 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -129,7 +129,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { } position.set(Position.KEY_ODOMETER, parser.nextInt(0)); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { int value = parser.nextHexInt(0); diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java index e90dde455..38f6980f6 100644 --- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -196,7 +196,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { if (rfid.matches("0+")) { rfid = data[data.length - 2]; } - position.set(Position.KEY_RFID, rfid); + position.set(Position.KEY_DRIVER_UNIQUE_ID, rfid); } return position; diff --git a/src/org/traccar/protocol/Stl060ProtocolDecoder.java b/src/org/traccar/protocol/Stl060ProtocolDecoder.java index c81e83aab..26817a5c8 100644 --- a/src/org/traccar/protocol/Stl060ProtocolDecoder.java +++ b/src/org/traccar/protocol/Stl060ProtocolDecoder.java @@ -104,7 +104,7 @@ public class Stl060ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); position.set(Position.KEY_IGNITION, parser.nextInt(0) == 1); position.set(Position.KEY_INPUT, parser.nextInt(0)); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); position.set(Position.KEY_ODOMETER, parser.nextInt(0)); position.set(Position.PREFIX_TEMP + 1, parser.nextInt(0)); position.set(Position.KEY_FUEL_LEVEL, parser.nextInt(0)); diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index f1fd55d98..72e06c083 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -114,7 +114,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; case 78: - position.set(Position.KEY_RFID, String.valueOf(readValue(buf, length, false))); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false))); break; case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); diff --git a/src/org/traccar/protocol/TmgProtocolDecoder.java b/src/org/traccar/protocol/TmgProtocolDecoder.java index c10523117..b8458dd52 100644 --- a/src/org/traccar/protocol/TmgProtocolDecoder.java +++ b/src/org/traccar/protocol/TmgProtocolDecoder.java @@ -144,7 +144,7 @@ public class TmgProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_ADC + 1, parser.nextDouble(0)); position.set(Position.PREFIX_ADC + 2, parser.nextDouble(0)); position.set(Position.KEY_VERSION_FW, parser.next()); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); return position; } diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java index 1b22eeb75..31a3d2cfe 100644 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -308,7 +308,8 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { break; case DATA_RFID: - position.set(Position.KEY_RFID, buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_DRIVER_UNIQUE_ID, + buf.readBytes(length - 1).toString(StandardCharsets.US_ASCII)); position.set("authorized", buf.readUnsignedByte() != 0); break; diff --git a/src/org/traccar/protocol/VisiontekProtocolDecoder.java b/src/org/traccar/protocol/VisiontekProtocolDecoder.java index 636a3d640..f32c9fbfe 100644 --- a/src/org/traccar/protocol/VisiontekProtocolDecoder.java +++ b/src/org/traccar/protocol/VisiontekProtocolDecoder.java @@ -130,7 +130,7 @@ public class VisiontekProtocolDecoder extends BaseProtocolDecoder { position.setValid(parser.next().equals("A")); - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); return position; } diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java index 82098413b..4eb3b9b8e 100644 --- a/src/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/org/traccar/protocol/WialonProtocolDecoder.java @@ -109,7 +109,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } } - position.set(Position.KEY_RFID, parser.next()); + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); if (parser.hasNext()) { String[] values = parser.next().split(","); diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index dc4f70981..cb9cdf759 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -245,8 +245,8 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_ARCHIVE) instanceof Boolean); } - if (attributes.containsKey(Position.KEY_RFID)) { - Assert.assertTrue(attributes.get(Position.KEY_RFID) instanceof String); + if (attributes.containsKey(Position.KEY_DRIVER_UNIQUE_ID)) { + Assert.assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String); } if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { -- cgit v1.2.3 From b6a318daabbaf485e327cab77adba98413462516 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Fri, 14 Jul 2017 14:06:06 +0500 Subject: Use driverUniqueId instead of rfid in test script and OsmAnd protocol --- src/org/traccar/protocol/OsmAndProtocolDecoder.java | 2 +- tools/test-generator.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index cb324aa86..6f8513c41 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -128,7 +128,7 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { case "batt": position.set(Position.KEY_BATTERY_LEVEL, Double.parseDouble(value)); break; - case "rfid": + case "driverUniqueId": position.set(Position.KEY_DRIVER_UNIQUE_ID, value); break; default: diff --git a/tools/test-generator.py b/tools/test-generator.py index 47c1c478f..41ec5a2fa 100755 --- a/tools/test-generator.py +++ b/tools/test-generator.py @@ -35,7 +35,7 @@ for i in range(0, len(waypoints)): lon = lon1 + (lon2 - lon1) * j / count points.append((lat, lon)) -def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel, rfid): +def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId): params = (('id', id), ('timestamp', int(time.time())), ('lat', lat), ('lon', lon), ('bearing', course), ('speed', speed)) if alarm: params = params + (('alarm', 'sos'),) @@ -47,8 +47,8 @@ def send(conn, lat, lon, course, speed, alarm, ignition, accuracy, rpm, fuel, rf params = params + (('rpm', rpm),) if fuel: params = params + (('fuel', fuel),) - if rfid: - params = params + (('rfid', rfid),) + if driverUniqueId: + params = params + (('driverUniqueId', driverUniqueId),) conn.request('GET', '?' + urllib.urlencode(params)) conn.getresponse().read() @@ -74,7 +74,7 @@ while True: accuracy = 100 if (index % 10) == 0 else 0 rpm = random.randint(500, 4000) fuel = random.randint(0, 80) - rfid = driver_id if (index % len(points)) == 0 else False - send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, alarm, ignition, accuracy, rpm, fuel, rfid) + driverUniqueId = driver_id if (index % len(points)) == 0 else False + send(conn, lat1, lon1, course(lat1, lon1, lat2, lon2), speed, alarm, ignition, accuracy, rpm, fuel, driverUniqueId) time.sleep(period) index += 1 -- cgit v1.2.3 From 1b4bcb2cef3f4e3907ed0820478f2f3cae245c7f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 11:41:44 +1200 Subject: Fix TK103 identification issue --- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 16 +++++----------- test/org/traccar/protocol/Tk103ProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 4c7da12e0..0106e5bf3 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -200,17 +200,11 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { String id = sentence.substring(0, 12); String type = sentence.substring(12, 16); - if (type.equals("BP00") || type.equals("BP05")) { - String content = sentence.substring(16); - if (content.length() >= 15) { - getDeviceSession(channel, remoteAddress, content.substring(0, 15)); - } - if (type.equals("BP00")) { - channel.write("(" + id + "AP01HSO)"); - return null; - } else if (type.equals("BP05")) { - channel.write("(" + id + "AP05)"); - } + if (type.equals("BP00")) { + channel.write("(" + id + "AP01HSO)"); + return null; + } else if (type.equals("BP05")) { + channel.write("(" + id + "AP05)"); } } diff --git a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java index 4d872b082..f2ee8ffe5 100644 --- a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { Tk103ProtocolDecoder decoder = new Tk103ProtocolDecoder(new Tk103Protocol()); + verifyNull(decoder, text( + "(027044702512BP00027044702512HSO01A4)")); + verifyPosition(decoder, text( "(864768011069660,ZC11,250517,V,0000.0000N,00000.0000E,000.0,114725,000.0,0.00,11)")); -- cgit v1.2.3 From 7a17135f9b0b1ae127b9cb5ea4f29e0af98a813b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 12:05:36 +1200 Subject: Extend eelink protocol decoder --- .../traccar/protocol/EelinkProtocolDecoder.java | 41 +++++++++++++++++----- .../protocol/EelinkProtocolDecoderTest.java | 14 +++++++- 2 files changed, 45 insertions(+), 10 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 0f6551cc3..e16866977 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -96,6 +96,22 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeStatus(Position position, int status) { + if (BitUtil.check(status, 1)) { + position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); + } + if (BitUtil.check(status, 3)) { + position.set(Position.KEY_ARMED, BitUtil.check(status, 4)); + } + if (BitUtil.check(status, 5)) { + position.set(Position.KEY_BLOCKED, !BitUtil.check(status, 6)); + } + if (BitUtil.check(status, 7)) { + position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); + } + position.set(Position.KEY_STATUS, status); + } + private Position decodeOld(DeviceSession deviceSession, ChannelBuffer buf, int type, int index) { Position position = new Position(); @@ -119,16 +135,11 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); } - if (buf.readableBytes() >= 2 * 5) { + if (buf.readableBytes() >= 2) { + decodeStatus(position, buf.readUnsignedShort()); + } - int status = buf.readUnsignedShort(); - if (BitUtil.check(status, 1)) { - position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); - } - if (BitUtil.check(status, 7)) { - position.set(Position.KEY_CHARGE, BitUtil.check(status, 8)); - } - position.set(Position.KEY_STATUS, status); + if (buf.readableBytes() >= 2 * 4) { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); @@ -221,6 +232,18 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return decodeOld(deviceSession, buf, type, index); } else if (type >= MSG_NORMAL && type <= MSG_OBD_CODE) { return decodeNew(deviceSession, buf, index); + } else if (type == MSG_HEARTBEAT && buf.readableBytes() >= 2) { + + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); + + getLastLocation(position, null); + + decodeStatus(position, buf.readUnsignedShort()); + + return position; + } } diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index 8aabf8375..46c85d89a 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,18 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "6767050022001F59643640000000000000000000000001CC0000249500142000015964A6C0006E")); + + verifyAttributes(decoder, binary( + "67670300040021006E")); + + verifyPosition(decoder, binary( + "676705002200255964369D000000000000000000000001CC0000249500142000025964A71D006A")); + + verifyAttributes(decoder, binary( + "67670300040028006A")); + verifyPosition(decoder, binary( "676712002d066c592cca6803002631a60b22127700240046005c08020d000301af000da0fd12007f11ce05820000001899c0")); @@ -46,7 +58,7 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000b001b035418804661834901")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "6767030004001A0001")); verifyNull(decoder, binary( -- cgit v1.2.3 From 7c3351939eca27d349417f053ef98a7e4e2668fd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 13:17:05 +1200 Subject: Implement GL200 frame decoder --- src/org/traccar/protocol/Gl200FrameDecoder.java | 96 ++++++++++++++++++++++ src/org/traccar/protocol/Gl200Protocol.java | 5 +- .../traccar/protocol/Gl200FrameDecoderTest.java | 28 +++++++ 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/org/traccar/protocol/Gl200FrameDecoder.java create mode 100644 test/org/traccar/protocol/Gl200FrameDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200FrameDecoder.java b/src/org/traccar/protocol/Gl200FrameDecoder.java new file mode 100644 index 000000000..960c3779a --- /dev/null +++ b/src/org/traccar/protocol/Gl200FrameDecoder.java @@ -0,0 +1,96 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class Gl200FrameDecoder extends FrameDecoder { + + private static final int MINIMUM_LENGTH = 11; + + private static final Set BINARY_HEADERS = new HashSet<>( + Arrays.asList("+RSP", "+BSP", "+EVT", "+BVT", "+INF", "+BNF", "+HBD", "+CRD", "+BRD")); + + public static boolean isBinary(ChannelBuffer buf) { + String header = buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII); + if (header.equals("+ACK")) { + return buf.getByte(buf.readerIndex() + header.length()) != (byte) ':'; + } else { + return BINARY_HEADERS.contains(header); + } + } + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + + if (buf.readableBytes() < MINIMUM_LENGTH) { + return null; + } + + if (isBinary(buf)) { + + int length; + switch (buf.toString(buf.readerIndex(), 4, StandardCharsets.US_ASCII)) { + case "+ACK": + length = buf.getUnsignedByte(buf.readerIndex() + 6); + break; + case "+INF": + case "+BNF": + length = buf.getUnsignedShort(buf.readerIndex() + 7); + break; + case "+HBD": + length = buf.getUnsignedByte(buf.readerIndex() + 5); + break; + case "+CRD": + case "+BRD": + length = buf.getUnsignedShort(buf.readerIndex() + 6); + break; + default: + length = buf.getUnsignedShort(buf.readerIndex() + 9); + break; + } + + if (buf.readableBytes() >= length) { + return buf.readBytes(length); + } + + } else { + + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '$'); + if (endIndex < 0) { + endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0); + } + if (endIndex > 0) { + ChannelBuffer frame = buf.readBytes(endIndex - buf.readerIndex()); + buf.readByte(); // delimiter + return frame; + } + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index b3743042c..3ea371085 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -21,7 +21,6 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -44,7 +43,7 @@ public class Gl200Protocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(4096, "$", "\0")); + pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); diff --git a/test/org/traccar/protocol/Gl200FrameDecoderTest.java b/test/org/traccar/protocol/Gl200FrameDecoderTest.java new file mode 100644 index 000000000..54c35f084 --- /dev/null +++ b/test/org/traccar/protocol/Gl200FrameDecoderTest.java @@ -0,0 +1,28 @@ +package org.traccar.protocol; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200FrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200FrameDecoder decoder = new Gl200FrameDecoder(); + + Assert.assertEquals( + binary("2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a"), + decoder.decode(null, null, binary("2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a"))); + + Assert.assertEquals( + binary("2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a"), + decoder.decode(null, null, binary("2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a"))); + + Assert.assertEquals( + binary("2b524553503a47545354522c3430303330302c3836323336353033303134323238392c474c3530302c302c302c302c33392e342c39332c312c302e332c31372c3130352e382c32352e3934343234302c34342e3430333733362c32303137303532393134303533302c303232362c303030312c353643322c373038342c2c2c2c32303137303532393136303533302c30324441"), + decoder.decode(null, null, binary("2b524553503a47545354522c3430303330302c3836323336353033303134323238392c474c3530302c302c302c302c33392e342c39332c312c302e332c31372c3130352e382c32352e3934343234302c34342e3430333733362c32303137303532393134303533302c303232362c303030312c353643322c373038342c2c2c2c32303137303532393136303533302c3032444124"))); + + } + +} -- cgit v1.2.3 From 8bb68423f9a1e3c30f900e89f2016bfcc26a324b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 13:29:32 +1200 Subject: Rename GL200 text protocol decoder --- src/org/traccar/protocol/Gl200Protocol.java | 6 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 878 -------------------- .../traccar/protocol/Gl200TextProtocolDecoder.java | 880 +++++++++++++++++++++ .../traccar/protocol/Gl200ProtocolDecoderTest.java | 291 ------- .../protocol/Gl200TextProtocolDecoderTest.java | 291 +++++++ 5 files changed, 1173 insertions(+), 1173 deletions(-) delete mode 100644 src/org/traccar/protocol/Gl200ProtocolDecoder.java create mode 100644 src/org/traccar/protocol/Gl200TextProtocolDecoder.java delete mode 100644 test/org/traccar/protocol/Gl200ProtocolDecoderTest.java create mode 100644 test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index 3ea371085..dbcbf61c0 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -45,18 +45,16 @@ public class Gl200Protocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java deleted file mode 100644 index 140d3300a..000000000 --- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java +++ /dev/null @@ -1,878 +0,0 @@ -/* - * Copyright 2012 - 2017 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.protocol; - -import org.jboss.netty.channel.Channel; -import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; -import org.traccar.DeviceSession; -import org.traccar.helper.BitUtil; -import org.traccar.helper.Parser; -import org.traccar.helper.PatternBuilder; -import org.traccar.helper.UnitsConverter; -import org.traccar.model.CellTower; -import org.traccar.model.Network; -import org.traccar.model.Position; -import org.traccar.model.WifiAccessPoint; - -import java.net.SocketAddress; -import java.util.LinkedList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Gl200ProtocolDecoder extends BaseProtocolDecoder { - - private boolean ignoreFixTime; - - public Gl200ProtocolDecoder(Gl200Protocol protocol) { - super(protocol); - - ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime"); - } - - private static final Pattern PATTERN_ACK = new PatternBuilder() - .text("+ACK:GT") - .expression("...,") // type - .number("([0-9A-Z]{2}xxxx),") // protocol version - .number("(d{15}|x{14}),") // imei - .any().text(",") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_INF = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTINF,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17},)?") // vin - .expression("(?:[^,]+)?,") // device name - .number("(xx),") // state - .expression("(?:[0-9F]{20})?,") // iccid - .number("d{1,2},") - .number("d{1,2},") - .expression("[01],") // external power - .number("([d.]+)?,") // odometer or external power - .number("d*,") // backup battery or lightness - .number("(d+.d+),") // battery - .expression("([01]),") // charging - .number("(?:d),") // led - .number("(?:d)?,") // gps on need - .number("(?:d)?,") // gps antenna type - .number("(?:d),").optional() // gps antenna state - .number("d{14},") // last fix time - .groupBegin() - .number("(d+),") // battery percentage - .expression("[01]?,") // flash type - .number("(-?[d.]+)?,,,") // temperature - .or() - .expression("(?:[01])?,").optional() // pin15 mode - .number("(d+)?,") // adc1 - .number("(d+)?,").optional() // adc2 - .number("(xx)?,") // digital input - .number("(xx)?,") // digital output - .number("[-+]dddd,") // timezone - .expression("[01],") // daylight saving - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_VER = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTVER,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .expression("([^,]*),") // device type - .number("(xxxx),") // firmware version - .number("(xxxx),") // hardware version - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd),") // time (hhmmss) - .number("(xxxx)") // counter - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_LOCATION = new PatternBuilder() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+)?,") // mcc - .number("(d+)?,") // mnc - .groupBegin() - .number("(d+),") // lac - .number("(d+),") // cid - .or() - .number("(x+)?,") // lac - .number("(x+)?,") // cid - .groupEnd() - .number("(?:d+|(d+.d))?,") // odometer - .compile(); - - private static final Pattern PATTERN_OBD = new PatternBuilder() - .text("+RESP:GTOBD,") - .number("[0-9A-Z]{2}xxxx,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:[0-9A-Z]{17})?,") // vin - .expression("[^,]{0,20},") // device name - .expression("[01],") // report type - .number("x{1,8},") // report mask - .expression("(?:[0-9A-Z]{17})?,") // vin - .number("[01],") // obd connect - .number("(?:d{1,5})?,") // obd voltage - .number("(?:x{8})?,") // support pids - .number("(d{1,5})?,") // engine rpm - .number("(d{1,3})?,") // speed - .number("(-?d{1,3})?,") // coolant temp - .number("(d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d{1,5})?,") // dtcs cleared distance - .number("(?:d{1,5})?,") - .expression("([01])?,") // obd connect - .number("(d{1,3})?,") // number of dtcs - .number("(x*),") // dtcs - .number("(d{1,3})?,") // throttle - .number("(?:d{1,3})?,") // engine load - .number("(d{1,3})?,") // fuel level - .expression("(?:[0-9A],)?") // obd protocol - .number("(d+),") // odometer - .expression(PATTERN_LOCATION.pattern()) - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_FRI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTFRI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:([0-9A-Z]{17}),)?") // vin - .expression("[^,]*,") // device name - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .number("(d+)?,") // rpm - .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption - .number("(d+)?,") // fuel level - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_ERI = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTERI,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("x{8},") // mask - .number("(d+)?,") // power - .number("d{1,2},") // report type - .number("d{1,2},") // count - .expression("((?:") - .expression(PATTERN_LOCATION.pattern()) - .expression(")+)") - .number("(d{1,7}.d)?,") // odometer - .number("(d{5}:dd:dd)?,") // hour meter - .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 - .number("(d{1,3})?,") // battery - .number("(?:(xx)(xx)(xx))?,") // device status - .expression("(.*)") // additional data - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IGN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GTIG[NF],") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d+,") // ignition off duration - .expression(PATTERN_LOCATION.pattern()) - .number("(d{5}:dd:dd)?,") // hour meter - .number("(d{1,7}.d)?,") // odometer - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_IDA = new PatternBuilder() - .text("+RESP:GTIDA,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,,") // device name - .number("([^,]+),") // rfid - .expression("[01],") // report type - .number("1,") // count - .expression(PATTERN_LOCATION.pattern()) - .number("(d+.d),") // odometer - .text(",,,,") - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_WIF = new PatternBuilder() - .text("+RESP:GTWIF,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("(d+),") // count - .number("((?:x{12},-?d+,,,,)+),,,,") // wifi - .number("(d{1,3}),") // battery - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_GSM = new PatternBuilder() - .text("+RESP:GTGSM,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("(?:STR|CTN|NMR|RTL),") // fix type - .expression("(.*)") // cells - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF):GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version - .number("(d{15}|x{14}),") // imei - .expression("[^,]*,") // device name - .number("d*,") - .number("(d{1,2}),") // report type - .number("d{1,2},") // count - .expression(PATTERN_LOCATION.pattern()) - .groupBegin() - .number("(d{1,7}.d)?,").optional() // odometer - .number("(d{1,3})?,") // battery - .or() - .number("(d{1,7}.d)?,") // odometer - .groupEnd() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)") // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private static final Pattern PATTERN_BASIC = new PatternBuilder() - .text("+").expression("(?:RESP|BUFF)").text(":") - .expression("GT...,") - .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version - .number("(d{15}|x{14}),") // imei - .any() - .number("(d{1,2})?,") // hdop - .number("(d{1,3}.d)?,") // speed - .number("(d{1,3})?,") // course - .number("(-?d{1,5}.d)?,") // altitude - .number("(-?d{1,3}.d{6})?,") // longitude - .number("(-?d{1,2}.d{6})?,") // latitude - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(d+),") // mcc - .number("(d+),") // mnc - .number("(x+),") // lac - .number("(x+),").optional(4) // cell - .any() - .number("(dddd)(dd)(dd)") // date (yyyymmdd) - .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) - .text(",") - .number("(xxxx)") // count number - .text("$").optional() - .compile(); - - private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_ACK, sentence); - if (parser.matches()) { - String protocolVersion = parser.next(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - if (type.equals("HBD")) { - if (channel != null) { - parser.skip(6); - channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress); - } - } else { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, parser.nextDateTime()); - position.setValid(false); - position.set(Position.KEY_RESULT, "Command " + type + " accepted"); - return position; - } - } - return null; - } - - private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) { - if (parser.matches()) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession != null) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - return position; - } - } - return null; - } - - private void decodeDeviceTime(Position position, Parser parser) { - if (parser.hasNext(6)) { - if (ignoreFixTime) { - position.setTime(parser.nextDateTime()); - } else { - position.setDeviceTime(parser.nextDateTime()); - } - } - } - - private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_INF, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_STATUS, parser.next()); - - parser.next(); // odometer or external power - - position.set(Position.KEY_BATTERY, parser.nextDouble(0)); - position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - position.set(Position.PREFIX_TEMP + 1, parser.next()); - - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - - position.set(Position.KEY_INPUT, parser.next()); - position.set(Position.KEY_OUTPUT, parser.next()); - - getLastLocation(position, parser.nextDateTime()); - - position.set(Position.KEY_INDEX, parser.nextHexInt(0)); - - return position; - } - - private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_VER, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set("deviceType", parser.next()); - position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0)); - position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0)); - - getLastLocation(position, parser.nextDateTime()); - - return position; - } - - private void decodeLocation(Position position, Parser parser) { - int hdop = parser.nextInt(0); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(8)) { - position.setValid(true); - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - position.setTime(parser.nextDateTime()); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - int mcc = parser.nextInt(0); - int mnc = parser.nextInt(0); - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0)))); - } - if (parser.hasNext(2)) { - position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0)))); - } - } - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - } - - private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_OBD, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_OBD_SPEED, parser.nextInt()); - position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); - position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); - position.set("dtcsClearedDistance", parser.nextInt()); - position.set("odbConnect", parser.nextInt(0) == 1); - position.set("dtcsNumber", parser.nextInt()); - position.set("dtcsCodes", parser.next()); - position.set(Position.KEY_THROTTLE, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000); - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private void decodeStatus(Position position, Parser parser) { - if (parser.hasNext(3)) { - int ignition = parser.nextHexInt(0); - if (BitUtil.check(ignition, 4)) { - position.set(Position.KEY_IGNITION, false); - } else if (BitUtil.check(ignition, 5)) { - position.set(Position.KEY_IGNITION, true); - } - position.set(Position.KEY_INPUT, parser.nextHexInt(0)); - position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); - } - } - - private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_FRI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - LinkedList positions = new LinkedList<>(); - - String vin = parser.next(); - int power = parser.nextInt(0); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - position.set(Position.KEY_VIN, vin); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - decodeLocation(position, parser); - - // power value only on some devices - if (power > 10) { - position.set(Position.KEY_POWER, power); - } - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - decodeStatus(position, parser); - - position.set(Position.KEY_RPM, parser.nextInt()); - position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); - - decodeDeviceTime(position, parser); - - return positions; - } - - private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_ERI, sentence); - if (!parser.matches()) { - return null; - } - - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - - LinkedList positions = new LinkedList<>(); - - int power = parser.nextInt(0); - - Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); - while (itemParser.find()) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - - decodeLocation(position, itemParser); - - positions.add(position); - } - - Position position = positions.getLast(); - - decodeLocation(position, parser); - - position.set(Position.KEY_POWER, power); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.PREFIX_ADC + 1, parser.next()); - position.set(Position.PREFIX_ADC + 2, parser.next()); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - - decodeStatus(position, parser); - - int index = 0; - String[] data = parser.next().split(","); - if (data.length > 1) { - int deviceType = Integer.parseInt(data[index++]); - if (deviceType == 2) { - int deviceCount = Integer.parseInt(data[index++]); - for (int i = 1; i <= deviceCount; i++) { - index++; // id - index++; // type - position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); - } - } - } - - decodeDeviceTime(position, parser); - - return positions; - } - - private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IGN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - decodeLocation(position, parser); - - position.set(Position.KEY_HOURS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_IDA, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - return position; - } - - private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_WIF, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - parser.nextInt(0); // count - Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); - while (matcher.find()) { - String mac = matcher.group(1).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2)))); - } - - position.setNetwork(network); - - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - return position; - } - - private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { - Parser parser = new Parser(PATTERN_GSM, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - getLastLocation(position, null); - - Network network = new Network(); - - String[] data = parser.next().split(","); - for (int i = 0; i < 6; i++) { - if (!data[i * 6].isEmpty()) { - network.addCellTower(CellTower.from( - Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]), - Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16), - Integer.parseInt(data[i * 6 + 4]))); - } - } - - position.setNetwork(network); - - return position; - } - - private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - int reportType = parser.nextInt(0); - if (type.equals("NMR")) { - position.set(Position.KEY_MOTION, reportType == 1); - } else if (type.equals("SOS")) { - position.set(Position.KEY_ALARM, Position.ALARM_SOS); - } - - decodeLocation(position, parser); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - - position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); - - decodeDeviceTime(position, parser); - - if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { - channel.write("+SACK:" + parser.next() + "$", remoteAddress); - } - - return position; - } - - private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { - Parser parser = new Parser(PATTERN_BASIC, sentence); - Position position = initPosition(parser, channel, remoteAddress); - if (position == null) { - return null; - } - - int hdop = parser.nextInt(0); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); - - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - position.setCourse(parser.nextDouble(0)); - position.setAltitude(parser.nextDouble(0)); - - if (parser.hasNext(2)) { - position.setLongitude(parser.nextDouble(0)); - position.setLatitude(parser.nextDouble(0)); - } else { - getLastLocation(position, null); - } - - if (parser.hasNext(6)) { - position.setTime(parser.nextDateTime()); - } - - if (parser.hasNext(4)) { - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - } - - decodeDeviceTime(position, parser); - - switch (type) { - case "PNA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); - break; - case "PFA": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); - break; - case "EPN": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); - break; - case "EPF": - position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); - break; - case "BPL": - position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); - break; - case "STT": - position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); - break; - case "SWG": - position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); - break; - case "TMP": - case "TEM": - position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); - break; - case "JDR": - case "JDS": - position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); - break; - default: - break; - } - - return position; - } - - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - String sentence = (String) msg; - - int typeIndex = sentence.indexOf(":GT"); - if (typeIndex < 0) { - return null; - } - - Object result; - String type = sentence.substring(typeIndex + 3, typeIndex + 6); - if (sentence.startsWith("+ACK")) { - result = decodeAck(channel, remoteAddress, sentence, type); - } else { - switch (type) { - case "INF": - result = decodeInf(channel, remoteAddress, sentence); - break; - case "OBD": - result = decodeObd(channel, remoteAddress, sentence); - break; - case "FRI": - result = decodeFri(channel, remoteAddress, sentence); - break; - case "ERI": - result = decodeEri(channel, remoteAddress, sentence); - break; - case "IGN": - case "IGF": - result = decodeIgn(channel, remoteAddress, sentence); - break; - case "IDA": - result = decodeIda(channel, remoteAddress, sentence); - break; - case "WIF": - result = decodeWif(channel, remoteAddress, sentence); - break; - case "GSM": - result = decodeGsm(channel, remoteAddress, sentence); - break; - case "VER": - result = decodeVer(channel, remoteAddress, sentence); - break; - default: - result = decodeOther(channel, remoteAddress, sentence, type); - break; - } - - if (result == null) { - result = decodeBasic(channel, remoteAddress, sentence, type); - } - - if (result != null) { - if (result instanceof Position) { - ((Position) result).set(Position.KEY_TYPE, type); - } else { - for (Position p : (List) result) { - p.set(Position.KEY_TYPE, type); - } - } - } - } - - return result; - } - -} diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java new file mode 100644 index 000000000..57fecc3fe --- /dev/null +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -0,0 +1,880 @@ +/* + * Copyright 2012 - 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { + + private boolean ignoreFixTime; + + public Gl200TextProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + + ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime"); + } + + private static final Pattern PATTERN_ACK = new PatternBuilder() + .text("+ACK:GT") + .expression("...,") // type + .number("([0-9A-Z]{2}xxxx),") // protocol version + .number("(d{15}|x{14}),") // imei + .any().text(",") + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_INF = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTINF,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17},)?") // vin + .expression("(?:[^,]+)?,") // device name + .number("(xx),") // state + .expression("(?:[0-9F]{20})?,") // iccid + .number("d{1,2},") + .number("d{1,2},") + .expression("[01],") // external power + .number("([d.]+)?,") // odometer or external power + .number("d*,") // backup battery or lightness + .number("(d+.d+),") // battery + .expression("([01]),") // charging + .number("(?:d),") // led + .number("(?:d)?,") // gps on need + .number("(?:d)?,") // gps antenna type + .number("(?:d),").optional() // gps antenna state + .number("d{14},") // last fix time + .groupBegin() + .number("(d+),") // battery percentage + .expression("[01]?,") // flash type + .number("(-?[d.]+)?,,,") // temperature + .or() + .expression("(?:[01])?,").optional() // pin15 mode + .number("(d+)?,") // adc1 + .number("(d+)?,").optional() // adc2 + .number("(xx)?,") // digital input + .number("(xx)?,") // digital output + .number("[-+]dddd,") // timezone + .expression("[01],") // daylight saving + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_VER = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTVER,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .expression("([^,]*),") // device type + .number("(xxxx),") // firmware version + .number("(xxxx),") // hardware version + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(xxxx)") // counter + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_LOCATION = new PatternBuilder() + .number("(d{1,2})?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+)?,") // mcc + .number("(d+)?,") // mnc + .groupBegin() + .number("(d+),") // lac + .number("(d+),") // cid + .or() + .number("(x+)?,") // lac + .number("(x+)?,") // cid + .groupEnd() + .number("(?:d+|(d+.d))?,") // odometer + .compile(); + + private static final Pattern PATTERN_OBD = new PatternBuilder() + .text("+RESP:GTOBD,") + .number("[0-9A-Z]{2}xxxx,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:[0-9A-Z]{17})?,") // vin + .expression("[^,]{0,20},") // device name + .expression("[01],") // report type + .number("x{1,8},") // report mask + .expression("(?:[0-9A-Z]{17})?,") // vin + .number("[01],") // obd connect + .number("(?:d{1,5})?,") // obd voltage + .number("(?:x{8})?,") // support pids + .number("(d{1,5})?,") // engine rpm + .number("(d{1,3})?,") // speed + .number("(-?d{1,3})?,") // coolant temp + .number("(d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d{1,5})?,") // dtcs cleared distance + .number("(?:d{1,5})?,") + .expression("([01])?,") // obd connect + .number("(d{1,3})?,") // number of dtcs + .number("(x*),") // dtcs + .number("(d{1,3})?,") // throttle + .number("(?:d{1,3})?,") // engine load + .number("(d{1,3})?,") // fuel level + .expression("(?:[0-9A],)?") // obd protocol + .number("(d+),") // odometer + .expression(PATTERN_LOCATION.pattern()) + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_FRI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTFRI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:([0-9A-Z]{17}),)?") // vin + .expression("[^,]*,") // device name + .number("(d+)?,") // power + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .number("(d+)?,") // rpm + .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption + .number("(d+)?,") // fuel level + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_ERI = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTERI,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("x{8},") // mask + .number("(d+)?,") // power + .number("d{1,2},") // report type + .number("d{1,2},") // count + .expression("((?:") + .expression(PATTERN_LOCATION.pattern()) + .expression(")+)") + .number("(d{1,7}.d)?,") // odometer + .number("(d{5}:dd:dd)?,") // hour meter + .number("(x+)?,") // adc 1 + .number("(x+)?,") // adc 2 + .number("(d{1,3})?,") // battery + .number("(?:(xx)(xx)(xx))?,") // device status + .expression("(.*)") // additional data + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_IGN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GTIG[NF],") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d+,") // ignition off duration + .expression(PATTERN_LOCATION.pattern()) + .number("(d{5}:dd:dd)?,") // hour meter + .number("(d{1,7}.d)?,") // odometer + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_IDA = new PatternBuilder() + .text("+RESP:GTIDA,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,,") // device name + .number("([^,]+),") // rfid + .expression("[01],") // report type + .number("1,") // count + .expression(PATTERN_LOCATION.pattern()) + .number("(d+.d),") // odometer + .text(",,,,") + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_WIF = new PatternBuilder() + .text("+RESP:GTWIF,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("(d+),") // count + .number("((?:x{12},-?d+,,,,)+),,,,") // wifi + .number("(d{1,3}),") // battery + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_GSM = new PatternBuilder() + .text("+RESP:GTGSM,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("(?:STR|CTN|NMR|RTL),") // fix type + .expression("(.*)") // cells + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF):GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .number("d*,") + .number("(d{1,2}),") // report type + .number("d{1,2},") // count + .expression(PATTERN_LOCATION.pattern()) + .groupBegin() + .number("(d{1,7}.d)?,").optional() // odometer + .number("(d{1,3})?,") // battery + .or() + .number("(d{1,7}.d)?,") // odometer + .groupEnd() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)") // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private static final Pattern PATTERN_BASIC = new PatternBuilder() + .text("+").expression("(?:RESP|BUFF)").text(":") + .expression("GT...,") + .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version + .number("(d{15}|x{14}),") // imei + .any() + .number("(d{1,2})?,") // hdop + .number("(d{1,3}.d)?,") // speed + .number("(d{1,3})?,") // course + .number("(-?d{1,5}.d)?,") // altitude + .number("(-?d{1,3}.d{6})?,") // longitude + .number("(-?d{1,2}.d{6})?,") // latitude + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(x+),") // lac + .number("(x+),").optional(4) // cell + .any() + .number("(dddd)(dd)(dd)") // date (yyyymmdd) + .number("(dd)(dd)(dd)").optional(2) // time (hhmmss) + .text(",") + .number("(xxxx)") // count number + .text("$").optional() + .compile(); + + private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN_ACK, sentence); + if (parser.matches()) { + String protocolVersion = parser.next(); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + if (type.equals("HBD")) { + if (channel != null) { + parser.skip(6); + channel.write("+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress); + } + } else { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, parser.nextDateTime()); + position.setValid(false); + position.set(Position.KEY_RESULT, "Command " + type + " accepted"); + return position; + } + } + return null; + } + + private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) { + if (parser.matches()) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession != null) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } + } + return null; + } + + private void decodeDeviceTime(Position position, Parser parser) { + if (parser.hasNext(6)) { + if (ignoreFixTime) { + position.setTime(parser.nextDateTime()); + } else { + position.setDeviceTime(parser.nextDateTime()); + } + } + } + + private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_INF, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_STATUS, parser.next()); + + parser.next(); // odometer or external power + + position.set(Position.KEY_BATTERY, parser.nextDouble(0)); + position.set(Position.KEY_CHARGE, parser.nextInt(0) == 1); + + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + position.set(Position.PREFIX_TEMP + 1, parser.next()); + + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + + position.set(Position.KEY_INPUT, parser.next()); + position.set(Position.KEY_OUTPUT, parser.next()); + + getLastLocation(position, parser.nextDateTime()); + + position.set(Position.KEY_INDEX, parser.nextHexInt(0)); + + return position; + } + + private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_VER, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set("deviceType", parser.next()); + position.set(Position.KEY_VERSION_FW, parser.nextHexInt(0)); + position.set(Position.KEY_VERSION_HW, parser.nextHexInt(0)); + + getLastLocation(position, parser.nextDateTime()); + + return position; + } + + private void decodeLocation(Position position, Parser parser) { + int hdop = parser.nextInt(0); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + if (parser.hasNext(8)) { + position.setValid(true); + position.setLongitude(parser.nextDouble(0)); + position.setLatitude(parser.nextDouble(0)); + position.setTime(parser.nextDateTime()); + } else { + getLastLocation(position, null); + } + + if (parser.hasNext(6)) { + int mcc = parser.nextInt(0); + int mnc = parser.nextInt(0); + if (parser.hasNext(2)) { + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(0), parser.nextInt(0)))); + } + if (parser.hasNext(2)) { + position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(0), parser.nextHexInt(0)))); + } + } + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + } + + private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_OBD, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_OBD_SPEED, parser.nextInt()); + position.set(Position.PREFIX_TEMP + 1, parser.nextInt()); + position.set(Position.KEY_FUEL_CONSUMPTION, parser.next()); + position.set("dtcsClearedDistance", parser.nextInt()); + position.set("odbConnect", parser.nextInt(0) == 1); + position.set("dtcsNumber", parser.nextInt()); + position.set("dtcsCodes", parser.next()); + position.set(Position.KEY_THROTTLE, parser.nextInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + position.set(Position.KEY_OBD_ODOMETER, parser.nextInt(0) * 1000); + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private void decodeStatus(Position position, Parser parser) { + if (parser.hasNext(3)) { + int ignition = parser.nextHexInt(0); + if (BitUtil.check(ignition, 4)) { + position.set(Position.KEY_IGNITION, false); + } else if (BitUtil.check(ignition, 5)) { + position.set(Position.KEY_IGNITION, true); + } + position.set(Position.KEY_INPUT, parser.nextHexInt(0)); + position.set(Position.KEY_OUTPUT, parser.nextHexInt(0)); + } + } + + private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_FRI, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + LinkedList positions = new LinkedList<>(); + + String vin = parser.next(); + int power = parser.nextInt(0); + + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); + while (itemParser.find()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_VIN, vin); + + decodeLocation(position, itemParser); + + positions.add(position); + } + + Position position = positions.getLast(); + + decodeLocation(position, parser); + + // power value only on some devices + if (power > 10) { + position.set(Position.KEY_POWER, power); + } + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + decodeStatus(position, parser); + + position.set(Position.KEY_RPM, parser.nextInt()); + position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); + + decodeDeviceTime(position, parser); + + return positions; + } + + private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_ERI, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + LinkedList positions = new LinkedList<>(); + + int power = parser.nextInt(0); + + Parser itemParser = new Parser(PATTERN_LOCATION, parser.next()); + while (itemParser.find()) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + decodeLocation(position, itemParser); + + positions.add(position); + } + + Position position = positions.getLast(); + + decodeLocation(position, parser); + + position.set(Position.KEY_POWER, power); + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.PREFIX_ADC + 1, parser.next()); + position.set(Position.PREFIX_ADC + 2, parser.next()); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); + + decodeStatus(position, parser); + + int index = 0; + String[] data = parser.next().split(","); + if (data.length > 1) { + int deviceType = Integer.parseInt(data[index++]); + if (deviceType == 2) { + int deviceCount = Integer.parseInt(data[index++]); + for (int i = 1; i <= deviceCount; i++) { + index++; // id + index++; // type + position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); + } + } + } + + decodeDeviceTime(position, parser); + + return positions; + } + + private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_IGN, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + decodeLocation(position, parser); + + position.set(Position.KEY_HOURS, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_IDA, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + return position; + } + + private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_WIF, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + Network network = new Network(); + + parser.nextInt(0); // count + Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next()); + while (matcher.find()) { + String mac = matcher.group(1).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2)))); + } + + position.setNetwork(network); + + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + + return position; + } + + private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_GSM, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + Network network = new Network(); + + String[] data = parser.next().split(","); + for (int i = 0; i < 6; i++) { + if (!data[i * 6].isEmpty()) { + network.addCellTower(CellTower.from( + Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]), + Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16), + Integer.parseInt(data[i * 6 + 4]))); + } + } + + position.setNetwork(network); + + return position; + } + + private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int reportType = parser.nextInt(0); + if (type.equals("NMR")) { + position.set(Position.KEY_MOTION, reportType == 1); + } else if (type.equals("SOS")) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + + decodeLocation(position, parser); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); + + position.set(Position.KEY_ODOMETER, parser.nextDouble(0) * 1000); + + decodeDeviceTime(position, parser); + + if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) { + channel.write("+SACK:" + parser.next() + "$", remoteAddress); + } + + return position; + } + + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) { + Parser parser = new Parser(PATTERN_BASIC, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + int hdop = parser.nextInt(0); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setCourse(parser.nextDouble(0)); + position.setAltitude(parser.nextDouble(0)); + + if (parser.hasNext(2)) { + position.setLongitude(parser.nextDouble(0)); + position.setLatitude(parser.nextDouble(0)); + } else { + getLastLocation(position, null); + } + + if (parser.hasNext(6)) { + position.setTime(parser.nextDateTime()); + } + + if (parser.hasNext(4)) { + position.setNetwork(new Network(CellTower.from( + parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); + } + + decodeDeviceTime(position, parser); + + switch (type) { + case "PNA": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON); + break; + case "PFA": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF); + break; + case "EPN": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED); + break; + case "EPF": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case "BPL": + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case "STT": + position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + break; + case "SWG": + position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE); + break; + case "TMP": + case "TEM": + position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE); + break; + case "JDR": + case "JDS": + position.set(Position.KEY_ALARM, Position.ALARM_JAMMING); + break; + default: + break; + } + + return position; + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String sentence = ((ChannelBuffer) msg).toString(StandardCharsets.US_ASCII); + + int typeIndex = sentence.indexOf(":GT"); + if (typeIndex < 0) { + return null; + } + + Object result; + String type = sentence.substring(typeIndex + 3, typeIndex + 6); + if (sentence.startsWith("+ACK")) { + result = decodeAck(channel, remoteAddress, sentence, type); + } else { + switch (type) { + case "INF": + result = decodeInf(channel, remoteAddress, sentence); + break; + case "OBD": + result = decodeObd(channel, remoteAddress, sentence); + break; + case "FRI": + result = decodeFri(channel, remoteAddress, sentence); + break; + case "ERI": + result = decodeEri(channel, remoteAddress, sentence); + break; + case "IGN": + case "IGF": + result = decodeIgn(channel, remoteAddress, sentence); + break; + case "IDA": + result = decodeIda(channel, remoteAddress, sentence); + break; + case "WIF": + result = decodeWif(channel, remoteAddress, sentence); + break; + case "GSM": + result = decodeGsm(channel, remoteAddress, sentence); + break; + case "VER": + result = decodeVer(channel, remoteAddress, sentence); + break; + default: + result = decodeOther(channel, remoteAddress, sentence, type); + break; + } + + if (result == null) { + result = decodeBasic(channel, remoteAddress, sentence, type); + } + + if (result != null) { + if (result instanceof Position) { + ((Position) result).set(Position.KEY_TYPE, type); + } else { + for (Position p : (List) result) { + p.set(Position.KEY_TYPE, type); + } + } + } + } + + return result; + } + +} diff --git a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java deleted file mode 100644 index 2fd15a5f6..000000000 --- a/test/org/traccar/protocol/Gl200ProtocolDecoderTest.java +++ /dev/null @@ -1,291 +0,0 @@ -package org.traccar.protocol; - -import org.junit.Test; -import org.traccar.ProtocolTest; - -public class Gl200ProtocolDecoderTest extends ProtocolTest { - - @Test - public void testDecode() throws Exception { - - Gl200ProtocolDecoder decoder = new Gl200ProtocolDecoder(new Gl200Protocol()); - - verifyPosition(decoder, text( - "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); - - verifyPosition(decoder, text( - "+RESP:GTTRI,862370030005908,1,0,99,1,0.0,354,18.5,18.821100,-34.084002,20170607152024,0655,0001,00DD,1CAE,00,0103010100,20170607172115,3E7D$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060800,861074023677175,,00000002,12351,10,1,1,0.0,0,2862.4,-78.467273,-0.164998,20170529181717,,,,,,0.0,00259:11:50,,,0,210104,2,1,28E17436060000E2,1,015F,0,20170529181723,2824$")); - - verifyPosition(decoder, text( - "+RESP:GTSWG,110100,358688000000158,,1,0,2.1,0,27.1,121.390717,31.164424,20110901073917,0460,0000,1878,0873,,20110901154653,0015$")); - - verifyPosition(decoder, text( - "+RESP:GTTMP,110100,358688000000158,,2,60,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214093254,000F$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,110100,358688000000158,,41,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,0022$")); - - verifyPosition(decoder, text( - "+RESP:GTBPL,110100,358688000000158,,3.53,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,001F$")); - - verifyNotNull(decoder, text( - "+BUFF:GTIGL,060228,862894020180553,,,00,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,20170407081824,9606$")); - - verifyNotNull(decoder, text( - "+RESP:GTFRI,060228,862894020180553,,14827,10,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,01070:43:13,13,180,0,220101,,,,20170407081824,9607$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060502,861074023376992,,00000002,27239,10,1,1,0.2,312,183.3,-79.320820,-2.499110,20170401212005,0740,0000,EE4E,C98F,00,0.0,02114:36:35,,,90,220504,2,0,0,20170401212007,9E3D$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060502,861074023689626,,25202,10,1,1,0.0,0,2744.1,-78.261047,0.023452,20170401211940,,,,,,0.0,00079:19:15,,,51,110000,,,,20170401212003,4DA7$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,06020B,862170010196747,,00000000,,10,1,2,1.8,0,-2.5,117.198440,31.845219,20120802061037,0460,0000,5663,0358,00,0.0,,,,0,410000,20120802061040,0012$")); - - verifyPositions(decoder, text( - "+RESP:GTERI,060502,861074023692562,,00000002,14197,10,1,1,0.2,220,491.8,-79.064212,-2.159754,20170401212007,0740,0000,EE49,CE25,00,0.0,01509:10:58,,,87,220104,2,0,0,20170401212010,D14D$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,210102,354524044925825,,1,1,1,29,2.8,0,133.7,-90.203063,32.265473,20170318005208,,,,,10800,4,20170318005208,0002$")); - - verifyPositions(decoder, false, text( - "+RESP:GTFRI,210102,354524044925825,,1,1,1,,,,,,,,310,410,51bc,ca1dae6,10800,1,20170318214333,0002$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,62a2,16,,0234,0015,003a,56a2,14,,0234,0015,003a,062a,13,,0234,0015,003a,32d9,11,,0234,0015,003a,56a0,11,,,,,,,,0234,0015,003a,7489,17,,20170219200048,0033$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,56a2,18,,0234,0015,003a,77bc,14,,0234,0015,003a,32d9,12,,0234,0015,003a,062a,12,,0234,0015,003a,62a2,11,,0234,0015,003a,56a0,10,,0234,0015,003a,7489,15,,20170219080049,0030$")); - - verifyAttributes(decoder, text( - "+RESP:GTGSM,400201,862365030034940,STR,0234,0030,0870,2469,19,,0234,0030,0870,35ee,18,,0234,0030,0870,16ac,12,,0234,0030,0870,16b2,11,,0234,0030,0870,360f,6,,0234,0030,0870,165d,6,,0234,0030,0870,35ef,17,,20170215220049,008D$")); - - verifyPosition(decoder, text( - "+RESP:GTSTR,400201,862365030034940,GL500,0,0,2,21.1,86,0,1.6,0,5.8,0.622831,51.582688,20170215090422,0234,0030,0870,35EF,,,,20170215220049,008C$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,2C0402,867162020000816,,0,0,1,2,0.3,337,245.7,-82.373387,34.634011,20170215003054,,,,,,63,20170215003241,3EAB$")); - - verifyNotNull(decoder, text( - "+RESP:GTWIF,210102,354524044608058,,4,c413e200ff14,-39,,,,c413e2010e55,-39,,,,c8d3ff04a837,-43,,,,42490f997c6d,-57,,,,,,,,100,20170201020055,0001$")); - - verifyNotNull(decoder, text( - "+RESP:GTWIF,210102,354524044484948,,1,08626693fb98,-36,,,,,,,,97,20170119071300,05E3$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,210102,A100004D9EF2AE,,41,,8,99,0,17.7,21,3.58,0,1,1,0,0,20161216135038,4,,,,,20161216135038,00AB$")); - - verifyAttributes(decoder, text( - "+RESP:GTSTR,400201,862365030034957,GL500,0,0,2,23.1,5,2,0.2,0,36.0,0.623089,51.582744,20161129174625,0234,0015,03C3,3550,,,,20161129174625,0026$")); - - verifyNotNull(decoder, text( - "+RESP:GTSTR,400201,862365030034957,GL500,0,1,2,21.8,100,0,,,,,,,0234,0015,03C3,3550,,,,20161129174009,0023$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,210102,A10000499AEF9B,,41,,0,0,0,15.0,9,3.87,0,1,1,0,0,20161101140211,72,,,,,20161101140211,00A3$")); - - verifyAttributes(decoder, text( - "+RESP:GTNMR,210102,A10000499AEF9B,,0,0,1,9,0.0,0,288.0,-76.902364,39.578828,20161101134145,,,,,00,73,20161101134145,009F$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$")); - - verifyAttributes(decoder, text( - "+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,110100,358688000000158,,41,898600810906F8048812,18,99,0,33.23,1,4.19,1,1,1,0,0,20110714104934,100,,,,,20110714104934,0014$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,080100,135790246811220,,16,898600810906F8048812,16,0,1,11870,,4.1,0,0,0,,20090214013254,,12340,,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,040100,135790246811220,,16,898600810906F8048812,16,0,1,,0,4.4,0,0,0,0,20090214013254,13000,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,060100,135790246811220,,16,898600810906F8048812,16,0,1,12000,,4.4,0,0,0,0,20090214013254,0,1300,2000,00,00,+0800,0,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,17,0,1,26.6,,3.90,1,1,0,0,0,20161003184043,69,1,44,,,20161004040811,022C$")); - - verifyAttributes(decoder, text( - "+BUFF:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,23,0,1,204.7,,3.84,1,1,0,0,0,20161006072548,62,1,38,,,20161006082343,0C98$")); - - verifyPosition(decoder, text( - "+RESP:GTFRI,360100,864251020141408,3VWGW6AJ0FM237324,gv500,,10,1,1,0.0,0,2258.4,-99.256948,19.555800,20160929214743,0334,0020,0084,65AC,00,0.0,,,,100,410000,0,nan,,20160929214743,13BA$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,360201,864251020186064,4T1BE46KX7U018210,,0,19FFFF,4T1BE46KX7U018210,1,14283,983901C0,799,36,18,,33792,0,0,0,,,38,,6,53557,0,0.0,0,219.5,-76.661456,39.832588,20160507132153,20160507132154,0230$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,360201,864251020186064,1G1JC5444R7252367,,12802,10,1,0,0.0,0,219.5,-76.661456,39.832588,20160507132235,,,,,,20460.9,00080:03:37,,,100,210000,791,,56,20160507132239,0233$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,50,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,92,80,210100,,,50,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,060228,862894020178276,,21,0,0.0,0,411.3,-63.169745,-17.776330,20160319132220,0736,0003,6AD4,5BAA,00,20160319092223,1FBD$")); - - verifyPosition(decoder, text( - "+RESP:GTNMR,210102,A10000458356CE,,0,1,1,9,0.0,8,190.7,-85.765865,42.894837,20160316123202,,,,,60,30,20160316123202,0137$")); - - verifyPosition(decoder, text( - "+RESP:GTIDA,060228,862894020178276,,,01C68011010000C7,1,1,0,0.0,0,413.0,-63.169675,-17.776349,20160317222129,0736,0003,6AD4,32CF,00,34.9,,,,,20160317182130,1626$")); - - verifyPosition(decoder, text( - "+RESP:GTIGN,060228,862894020180553,,9860,0,0.2,189,420.0,-63.158195,-17.800608,20160309022951,0736,0003,6AD4,3471,00,,881.2,20160308222956,129A$")); - - verifyPosition(decoder, text( - "+BUFF:GTIGF,060228,862894020180553,,1958,0,0.0,240,390.3,-63.089213,-17.764712,20160309122854,0736,0003,6AB8,5A23,00,,936.8,20160309082858,1368$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060228,862894020180553,,,10,1,1,20.0,147,329.7,-62.899703,-17.720434,20160309113548,0736,0003,6AAE,3381,00,913.3,,,,0,220101,,,,20160309073554,132B$")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,2C0204,867162020003125,GL300W,0,0,2,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210433,0740,0000,7596,5891C,0.0,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210503,0740,0000,7596,5891C,0.0,88,20160215210506,1E78$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); - - verifyNotNull(decoder, text( - "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); - - verifyPosition(decoder, text( - "+RESP:GTIDA,06020A,862170013895931,,,D2C4FBC5,1,1,1,0.8,0,22.2,117.198630,31.845229,20120802121626,0460,0000,5663,2BB9,00,0.0,,,,,20120802121627,008E$")); - - verifyAttributes(decoder, text( - "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); - - verifyPositions(decoder, false, text( - "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,1F0109,864251020135483,,gv500,0,78FFFF,,1,12613,,,,,,,,,,,,,,1286,0,0.0,0,17.1,3.379630,6.529701,20150813074639,0621,0030,51C0,A2B3,00,0.0,20150813074641,A7E6$")); - - verifyPosition(decoder, text( - "+RESP:GTOBD,1F0109,864251020135483,4T1BE46KX7U018210,gv500,0,78FFFF,4T1BE46KX7U018210,1,13411,981B81C0,787,3,43,,921,463,1,10,0300030103030304001200310351035203530354,20,55,,1286,0,6.5,74,21.6,3.379710,6.529714,20150813074824,0621,0030,51C0,A2B3,00,0.0,20150813074828,A7E9$")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010D,867844001675407,,0,0,1,2,0.0,0,28.9,8.591011,56.476397,20140915213209,0238,0001,03CB,2871,,97,20140915213459,009A")); - - verifyNull(decoder, text( - "+RESP:GTINF,359464030073766,8938003990320469804f,18,99,100,1,0,+2.00,0,20131018084015,00EE,0103090402")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,04040C,359231038939904,,,10,1,2,0.0,117,346.0,8.924243,50.798077,20130618122040,0262,0002,0299,109C,00,0.0,,,,,,,,,20130618122045,00F6")); - - verifyPosition(decoder, text( - "+RESP:GTSTT,04040C,359231038939904,,42,0,0.0,117,346.0,8.924243,50.798077,20130618125152,0262,0002,0299,109C,00,20130618125154,017A")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,000035988863964,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,020102,135790246811220,,0,0,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTDOG,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTLBC,020102,135790246811220,,+8613800000000,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); - - verifyPosition(decoder, text( - "+RESP:GTGCR,020102,135790246811220,,3,50,180,2,0.4,296,-5.4,121.391055,31.164473,20100714104934,0460,0000,1878,0873,00,,20100714104934,000C")); - - verifyPosition(decoder, text( - "+RESP:GTFRI,07000D,868487001005941,,0,0,1,1,0.0,0,46.3,-77.039627,38.907573,20120731175232,0310,0260,B44B,EBC9,0015e96913a7,-58,,100,20120731175244,0114")); - - verifyPosition(decoder, text( - "+RESP:GTHBM,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPosition(decoder, text( - "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,02010C,867844001274649,,0,0,1,1,0.0,0,122.5,7.684216,51.524512,20140106233722,0262,0007,79EE,1D22,,93,20140107003805,03C4$")); - - verifyPositions(decoder, text( - "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); - - verifyPositions(decoder, text( - "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,20090214093254,11F0$")); - - verifyNotNull(decoder, text( - "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); - - verifyNotNull(decoder, text( - "+RESP:GTRTL,280100,A1000043D20139,,0,0,1,1,0.1,321,239.1,-76.661047,39.832501,20150615114455,0310,0484,00600019,0A52,,87,20150615074456,031E$")); - - verifyAttributes(decoder, text( - "+BUFF:GTBPL,1A0800,860599000773978,GL300,3.55,0,0.0,0,257.1,60.565437,56.818277,20161006070553,,,,,204.7,20161006071028,0C75$")); - - verifyAttributes(decoder, text( - "+RESP:GTTEM,1A0102,860599000000448,,3,33,0,5.8,0,33.4,117.201191,31.832502,20130109061410,0460,0000,5678,2079,,20130109061517,0091$")); - - verifyAttributes(decoder, text( - "+RESP:GTJDR,0A0102,135790246811220,,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTJDS,0A0102,135790246811220,,2,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTSOS,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0$")); - - verifyAttributes(decoder, text( - "+RESP:GTVER,1A0800,860599000773978,GL300,GL300,0A03,0103,20161007041531,10F8$")); - - verifyNull(decoder, text( - "+ACK:GTHBD,1A0401,135790246811220,,20100214093254,11F0")); - - verifyAttributes(decoder, text( - "+ACK:GTRTO,1A0800,860599000773978,GL300,VER,FFFF,20161006053520,0C19")); - - verifyAttributes(decoder, text( - "+ACK:GTJDC,0A0102,135790246811220,,0016,20090214093254,11F0")); - - verifyAttributes(decoder, text( - "+ACK:GTGEO,1A0102,135790246811220,,0,0008,20100310172830,11F0")); - - } - -} diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java new file mode 100644 index 000000000..e694022f2 --- /dev/null +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -0,0 +1,291 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200TextProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + + verifyPosition(decoder, buffer( + "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); + + verifyPosition(decoder, buffer( + "+RESP:GTTRI,862370030005908,1,0,99,1,0.0,354,18.5,18.821100,-34.084002,20170607152024,0655,0001,00DD,1CAE,00,0103010100,20170607172115,3E7D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060800,861074023677175,,00000002,12351,10,1,1,0.0,0,2862.4,-78.467273,-0.164998,20170529181717,,,,,,0.0,00259:11:50,,,0,210104,2,1,28E17436060000E2,1,015F,0,20170529181723,2824$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSWG,110100,358688000000158,,1,0,2.1,0,27.1,121.390717,31.164424,20110901073917,0460,0000,1878,0873,,20110901154653,0015$")); + + verifyPosition(decoder, buffer( + "+RESP:GTTMP,110100,358688000000158,,2,60,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214093254,000F$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,110100,358688000000158,,41,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,0022$")); + + verifyPosition(decoder, buffer( + "+RESP:GTBPL,110100,358688000000158,,3.53,0,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,,20110214093254,001F$")); + + verifyNotNull(decoder, buffer( + "+BUFF:GTIGL,060228,862894020180553,,,00,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,20170407081824,9606$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTFRI,060228,862894020180553,,14827,10,1,1,3.4,199,409.6,-63.174466,-17.739317,20170407121823,0000,0000,0000,0000,00,15989.5,01070:43:13,13,180,0,220101,,,,20170407081824,9607$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023376992,,00000002,27239,10,1,1,0.2,312,183.3,-79.320820,-2.499110,20170401212005,0740,0000,EE4E,C98F,00,0.0,02114:36:35,,,90,220504,2,0,0,20170401212007,9E3D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060502,861074023689626,,25202,10,1,1,0.0,0,2744.1,-78.261047,0.023452,20170401211940,,,,,,0.0,00079:19:15,,,51,110000,,,,20170401212003,4DA7$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060100,135790246811220,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,06020B,862170010196747,,00000000,,10,1,2,1.8,0,-2.5,117.198440,31.845219,20120802061037,0460,0000,5663,0358,00,0.0,,,,0,410000,20120802061040,0012$")); + + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023692562,,00000002,14197,10,1,1,0.2,220,491.8,-79.064212,-2.159754,20170401212007,0740,0000,EE49,CE25,00,0.0,01509:10:58,,,87,220104,2,0,0,20170401212010,D14D$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,210102,354524044925825,,1,1,1,29,2.8,0,133.7,-90.203063,32.265473,20170318005208,,,,,10800,4,20170318005208,0002$")); + + verifyPositions(decoder, false, buffer( + "+RESP:GTFRI,210102,354524044925825,,1,1,1,,,,,,,,310,410,51bc,ca1dae6,10800,1,20170318214333,0002$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,62a2,16,,0234,0015,003a,56a2,14,,0234,0015,003a,062a,13,,0234,0015,003a,32d9,11,,0234,0015,003a,56a0,11,,,,,,,,0234,0015,003a,7489,17,,20170219200048,0033$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030025161,STR,0234,0015,003a,56a2,18,,0234,0015,003a,77bc,14,,0234,0015,003a,32d9,12,,0234,0015,003a,062a,12,,0234,0015,003a,62a2,11,,0234,0015,003a,56a0,10,,0234,0015,003a,7489,15,,20170219080049,0030$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTGSM,400201,862365030034940,STR,0234,0030,0870,2469,19,,0234,0030,0870,35ee,18,,0234,0030,0870,16ac,12,,0234,0030,0870,16b2,11,,0234,0030,0870,360f,6,,0234,0030,0870,165d,6,,0234,0030,0870,35ef,17,,20170215220049,008D$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTR,400201,862365030034940,GL500,0,0,2,21.1,86,0,1.6,0,5.8,0.622831,51.582688,20170215090422,0234,0030,0870,35EF,,,,20170215220049,008C$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,2C0402,867162020000816,,0,0,1,2,0.3,337,245.7,-82.373387,34.634011,20170215003054,,,,,,63,20170215003241,3EAB$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTWIF,210102,354524044608058,,4,c413e200ff14,-39,,,,c413e2010e55,-39,,,,c8d3ff04a837,-43,,,,42490f997c6d,-57,,,,,,,,100,20170201020055,0001$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTWIF,210102,354524044484948,,1,08626693fb98,-36,,,,,,,,97,20170119071300,05E3$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,A100004D9EF2AE,,41,,8,99,0,17.7,21,3.58,0,1,1,0,0,20161216135038,4,,,,,20161216135038,00AB$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTSTR,400201,862365030034957,GL500,0,0,2,23.1,5,2,0.2,0,36.0,0.623089,51.582744,20161129174625,0234,0015,03C3,3550,,,,20161129174625,0026$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTSTR,400201,862365030034957,GL500,0,1,2,21.8,100,0,,,,,,,0234,0015,03C3,3550,,,,20161129174009,0023$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,A10000499AEF9B,,41,,0,0,0,15.0,9,3.87,0,1,1,0,0,20161101140211,72,,,,,20161101140211,00A3$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTNMR,210102,A10000499AEF9B,,0,0,1,9,0.0,0,288.0,-76.902364,39.578828,20161101134145,,,,,00,73,20161101134145,009F$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,210102,A10000499AEF9B,,0,1,1,9,0.5,0,288.0,-76.902364,39.578828,20161101134124,,,,,00,73,20161101134123,009D$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTRTL,210102,A10000499AEF9B,,0,0,1,10,0.2,0,305.4,-76.902274,39.578517,20161101155001,,,,,00,73,20161101155001,00A6$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,110100,358688000000158,,41,898600810906F8048812,18,99,0,33.23,1,4.19,1,1,1,0,0,20110714104934,100,,,,,20110714104934,0014$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,080100,135790246811220,,16,898600810906F8048812,16,0,1,11870,,4.1,0,0,0,,20090214013254,,12340,,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,040100,135790246811220,,16,898600810906F8048812,16,0,1,,0,4.4,0,0,0,0,20090214013254,13000,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,060100,135790246811220,,16,898600810906F8048812,16,0,1,12000,,4.4,0,0,0,0,20090214013254,0,1300,2000,00,00,+0800,0,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,17,0,1,26.6,,3.90,1,1,0,0,0,20161003184043,69,1,44,,,20161004040811,022C$")); + + verifyAttributes(decoder, buffer( + "+BUFF:GTINF,1A0800,860599000773978,GL300,41,89701016426133851978,23,0,1,204.7,,3.84,1,1,0,0,0,20161006072548,62,1,38,,,20161006082343,0C98$")); + + verifyPosition(decoder, buffer( + "+RESP:GTFRI,360100,864251020141408,3VWGW6AJ0FM237324,gv500,,10,1,1,0.0,0,2258.4,-99.256948,19.555800,20160929214743,0334,0020,0084,65AC,00,0.0,,,,100,410000,0,nan,,20160929214743,13BA$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,360201,864251020186064,4T1BE46KX7U018210,,0,19FFFF,4T1BE46KX7U018210,1,14283,983901C0,799,36,18,,33792,0,0,0,,,38,,6,53557,0,0.0,0,219.5,-76.661456,39.832588,20160507132153,20160507132154,0230$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,360201,864251020186064,1G1JC5444R7252367,,12802,10,1,0,0.0,0,219.5,-76.661456,39.832588,20160507132235,,,,,,20460.9,00080:03:37,,,100,210000,791,,56,20160507132239,0233$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,210100,,,50,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1F0101,135790246811220,1G1JC5444R7252367,,,00,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,92,80,210100,,,50,20090214093254,11F0$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,060228,862894020178276,,21,0,0.0,0,411.3,-63.169745,-17.776330,20160319132220,0736,0003,6AD4,5BAA,00,20160319092223,1FBD$")); + + verifyPosition(decoder, buffer( + "+RESP:GTNMR,210102,A10000458356CE,,0,1,1,9,0.0,8,190.7,-85.765865,42.894837,20160316123202,,,,,60,30,20160316123202,0137$")); + + verifyPosition(decoder, buffer( + "+RESP:GTIDA,060228,862894020178276,,,01C68011010000C7,1,1,0,0.0,0,413.0,-63.169675,-17.776349,20160317222129,0736,0003,6AD4,32CF,00,34.9,,,,,20160317182130,1626$")); + + verifyPosition(decoder, buffer( + "+RESP:GTIGN,060228,862894020180553,,9860,0,0.2,189,420.0,-63.158195,-17.800608,20160309022951,0736,0003,6AD4,3471,00,,881.2,20160308222956,129A$")); + + verifyPosition(decoder, buffer( + "+BUFF:GTIGF,060228,862894020180553,,1958,0,0.0,240,390.3,-63.089213,-17.764712,20160309122854,0736,0003,6AB8,5A23,00,,936.8,20160309082858,1368$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060228,862894020180553,,,10,1,1,20.0,147,329.7,-62.899703,-17.720434,20160309113548,0736,0003,6AAE,3381,00,913.3,,,,0,220101,,,,20160309073554,132B$")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,2C0204,867162020003125,GL300W,0,0,2,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210433,0740,0000,7596,5891C,0.0,1,1.7,205,2867.0,-78.481127,-0.206828,20160215210503,0740,0000,7596,5891C,0.0,88,20160215210506,1E78$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,060228,862894020178276,,15153,10,1,1,0.0,0,431.7,-63.169571,-17.776235,20160210153458,0736,0003,6AD4,80EF,00,34.9,00117:31:26,13442,15163,0,210101,,,,20160210113503,38EE$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,110100,A5868800000015,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20110214013254,0460,0000,18d8,6141,00,80,20110214013254,000C")); + + verifyNotNull(decoder, buffer( + "+RESP:GTFRI,210102,A10000458356CE,,0,1,1,15,1.4,0,190.6,-85.765763,42.894896,20160208164505,4126,210,0,18673,00,92,20160208164507,00A6")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,060402,862894021808798,,,10,1,1,0.0,349,394.3,-63.287717,-17.662410,20160116234031,0736,0003,6ABA,8305,00,3326.8,,,,94,220100,,,,20160116194035,4D83")); + + verifyPosition(decoder, buffer( + "+RESP:GTIDA,06020A,862170013895931,,,D2C4FBC5,1,1,1,0.8,0,22.2,117.198630,31.845229,20120802121626,0460,0000,5663,2BB9,00,0.0,,,,,20120802121627,008E$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,1F0101,135790246811220,1G1JC5444R7252367,,16,898600810906F8048812,16,0,1,12000,,4.2,0,0,,,20090214013254,,,,,,+0800,0,20090214093254,11F0$")); + + verifyPositions(decoder, false, buffer( + "+RESP:GTFRI,120113,555564055560555,,1,1,1,,,,,,,,0282,0380,f080,cabf,6900,79,20140824165629,0001$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,0F0106,862193020451183,,,10,1,1,0.0,163,,-57.513617,-25.368191,20150918182145,,,,,,21235.0,,,,0,210100,,,,20150918182149,00B8$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,1F0109,864251020135483,,gv500,0,78FFFF,,1,12613,,,,,,,,,,,,,,1286,0,0.0,0,17.1,3.379630,6.529701,20150813074639,0621,0030,51C0,A2B3,00,0.0,20150813074641,A7E6$")); + + verifyPosition(decoder, buffer( + "+RESP:GTOBD,1F0109,864251020135483,4T1BE46KX7U018210,gv500,0,78FFFF,4T1BE46KX7U018210,1,13411,981B81C0,787,3,43,,921,463,1,10,0300030103030304001200310351035203530354,20,55,,1286,0,6.5,74,21.6,3.379710,6.529714,20150813074824,0621,0030,51C0,A2B3,00,0.0,20150813074828,A7E9$")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,1A0401,860599000508846,,41,0,0.0,84,107.5,-76.657998,39.497203,20150623160622,0310,0260,B435,3B81,,20150623160622,0F54$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1A0401,860599000508846,,0,0,1,1,134.8,154,278.7,-76.671089,39.778885,20150623154301,0310,0260,043F,7761,,99,20150623154314,0F24$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,1A0200,860599000165464,CRI001,0,0,1,2,,41,,-71.153137,42.301634,20150328020301,,,,,280.3,55,20150327220351,320C")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010D,867844001675407,,0,0,1,2,0.0,0,28.9,8.591011,56.476397,20140915213209,0238,0001,03CB,2871,,97,20140915213459,009A")); + + verifyNull(decoder, buffer( + "+RESP:GTINF,359464030073766,8938003990320469804f,18,99,100,1,0,+2.00,0,20131018084015,00EE,0103090402")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,04040C,359231038939904,,,10,1,2,0.0,117,346.0,8.924243,50.798077,20130618122040,0262,0002,0299,109C,00,0.0,,,,,,,,,20130618122045,00F6")); + + verifyPosition(decoder, buffer( + "+RESP:GTSTT,04040C,359231038939904,,42,0,0.0,117,346.0,8.924243,50.798077,20130618125152,0262,0002,0299,109C,00,20130618125154,017A")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,000035988863964,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,020102,135790246811220,,0,0,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTDOG,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTLBC,020102,135790246811220,,+8613800000000,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0")); + + verifyPosition(decoder, buffer( + "+RESP:GTGCR,020102,135790246811220,,3,50,180,2,0.4,296,-5.4,121.391055,31.164473,20100714104934,0460,0000,1878,0873,00,,20100714104934,000C")); + + verifyPosition(decoder, buffer( + "+RESP:GTFRI,07000D,868487001005941,,0,0,1,1,0.0,0,46.3,-77.039627,38.907573,20120731175232,0310,0260,B44B,EBC9,0015e96913a7,-58,,100,20120731175244,0114")); + + verifyPosition(decoder, buffer( + "+RESP:GTHBM,0F0100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); + + verifyPosition(decoder, buffer( + "+RESP:GTHBM,0F0100,135790246811220,,,11,1,1,24.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010C,867844001274144,,0,0,1,1,18.0,233,118.1,7.615551,51.515600,20140106130516,0262,0007,79E6,B956,,72,20140106140524,09CE$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,02010C,867844001274649,,0,0,1,1,0.0,0,122.5,7.684216,51.524512,20140106233722,0262,0007,79EE,1D22,,93,20140107003805,03C4$")); + + verifyPositions(decoder, buffer( + "+BUFF:GTFRI,210101,863286020016706,,,10,1,1,,,,49.903915,40.391669,20140818105815,,,,,,,,,,,210100,,,,,000C$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,240100,135790246811220,,,10,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,2000.0,12345:12:34,,80,,,,,,20090214093254,11F0$")); + + verifyPositions(decoder, buffer( + "+RESP:GTFRI,240100,135790246811220,,,10,2,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,0,4.3,92,70.0,121.354335,31.222073,20090101000000,0460,0000,18d8,6141,00,2000.0,12345:12:34,,,80,,,,,20090214093254,11F0$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTSTT,280100,A1000043D20139,,42,0,0.1,321,228.6,-76.660884,39.832552,20150615120628,0310,0484,00600019,0A52,,20150615085741,0320$")); + + verifyNotNull(decoder, buffer( + "+RESP:GTRTL,280100,A1000043D20139,,0,0,1,1,0.1,321,239.1,-76.661047,39.832501,20150615114455,0310,0484,00600019,0A52,,87,20150615074456,031E$")); + + verifyAttributes(decoder, buffer( + "+BUFF:GTBPL,1A0800,860599000773978,GL300,3.55,0,0.0,0,257.1,60.565437,56.818277,20161006070553,,,,,204.7,20161006071028,0C75$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTTEM,1A0102,860599000000448,,3,33,0,5.8,0,33.4,117.201191,31.832502,20130109061410,0460,0000,5678,2079,,20130109061517,0091$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTJDR,0A0102,135790246811220,,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTJDS,0A0102,135790246811220,,2,0,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTSOS,020102,135790246811220,,0,0,1,1,4.3,92,70.0,121.354335,31.222073,20090214013254,0460,0000,18d8,6141,00,,20090214093254,11F0$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTVER,1A0800,860599000773978,GL300,GL300,0A03,0103,20161007041531,10F8$")); + + verifyNull(decoder, buffer( + "+ACK:GTHBD,1A0401,135790246811220,,20100214093254,11F0")); + + verifyAttributes(decoder, buffer( + "+ACK:GTRTO,1A0800,860599000773978,GL300,VER,FFFF,20161006053520,0C19")); + + verifyAttributes(decoder, buffer( + "+ACK:GTJDC,0A0102,135790246811220,,0016,20090214093254,11F0")); + + verifyAttributes(decoder, buffer( + "+ACK:GTGEO,1A0102,135790246811220,,0,0008,20100310172830,11F0")); + + } + +} -- cgit v1.2.3 From 08cc944644cee5ce745a9faae0866b206c575407 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 15 Jul 2017 14:01:52 +1200 Subject: Implement binary GL200 protocol --- .../protocol/Gl200BinaryProtocolDecoder.java | 103 +++++++++++++++++++++ src/org/traccar/protocol/Gl200Protocol.java | 5 +- src/org/traccar/protocol/Gl200ProtocolDecoder.java | 48 ++++++++++ .../protocol/Gl200BinaryProtocolDecoderTest.java | 21 +++++ 4 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java create mode 100644 src/org/traccar/protocol/Gl200ProtocolDecoder.java create mode 100644 test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java new file mode 100644 index 000000000..cb0417528 --- /dev/null +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -0,0 +1,103 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.CellTower; +import org.traccar.model.Network; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; + +public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { + + public Gl200BinaryProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + String header = buf.readBytes(4).toString(StandardCharsets.US_ASCII); + + if (header.equals("+EVT")) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + buf.readUnsignedByte(); // message type + + buf.readUnsignedInt(); // mask + + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version + + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); + + DeviceSession deviceSession = getDeviceSession( + channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); + + buf.readUnsignedByte(); // motion status + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + position.setTime(dateBuilder.getDate()); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + return position; + + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/Gl200Protocol.java b/src/org/traccar/protocol/Gl200Protocol.java index dbcbf61c0..799d7fe36 100644 --- a/src/org/traccar/protocol/Gl200Protocol.java +++ b/src/org/traccar/protocol/Gl200Protocol.java @@ -18,7 +18,6 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; @@ -46,7 +45,7 @@ public class Gl200Protocol extends BaseProtocol { pipeline.addLast("frameDecoder", new Gl200FrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { @@ -54,7 +53,7 @@ public class Gl200Protocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new Gl200ProtocolEncoder()); - pipeline.addLast("objectDecoder", new Gl200TextProtocolDecoder(Gl200Protocol.this)); + pipeline.addLast("objectDecoder", new Gl200ProtocolDecoder(Gl200Protocol.this)); } }); } diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java new file mode 100644 index 000000000..0de7bb926 --- /dev/null +++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; + +import java.net.SocketAddress; + +public class Gl200ProtocolDecoder extends BaseProtocolDecoder { + + private final Gl200TextProtocolDecoder textProtocolDecoder; + private final Gl200BinaryProtocolDecoder binaryProtocolDecoder; + + public Gl200ProtocolDecoder(Gl200Protocol protocol) { + super(protocol); + textProtocolDecoder = new Gl200TextProtocolDecoder(protocol); + binaryProtocolDecoder = new Gl200BinaryProtocolDecoder(protocol); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + if (Gl200FrameDecoder.isBinary(buf)) { + return binaryProtocolDecoder.decode(channel, remoteAddress, msg); + } else { + return textProtocolDecoder.decode(channel, remoteAddress, msg); + } + } + +} diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java new file mode 100644 index 000000000..42ccd4690 --- /dev/null +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + + verifyPosition(decoder, binary( + "2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a")); + + verifyNull(decoder, binary( + "2b41434b017f244501010108676231303000000000ffff07e1070b03112d054dfe030d0a")); + + } + +} -- cgit v1.2.3 From d62797376e7dc1d5810c1b8728da1e5443cc8e14 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Jul 2017 06:56:03 +1200 Subject: Refactor TAIP decoder --- src/org/traccar/protocol/TaipProtocolDecoder.java | 16 ++++++++++++++-- test/org/traccar/protocol/TaipProtocolDecoderTest.java | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 7702a89fb..a08bb6f2b 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -104,15 +104,21 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(); position.setProtocol(getProtocolName()); + Integer event = null; + if (parser.hasNext(3)) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); position.setTime(getTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0))); } else if (parser.hasNext()) { position.setTime(getTime(parser.nextInt(0))); } if (parser.hasNext()) { - position.set(Position.KEY_EVENT, parser.nextInt(0)); + event = parser.nextInt(); + } + + if (event != null) { + position.set(Position.KEY_EVENT, event); } if (parser.hasNext(6)) { @@ -150,6 +156,12 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { attributes = sentence.substring(beginIndex, endIndex).split(";"); } + return decodeAttributes(channel, remoteAddress, position, attributes); + } + + private Position decodeAttributes( + Channel channel, SocketAddress remoteAddress, Position position, String[] attributes) { + String uniqueId = null; DeviceSession deviceSession = null; String messageIndex = null; diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index 2251763cc..6d24a504f 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">REV011958000369+0307185+1016144400000032;IO=200;SV=9;BL=4158;CF=0,0,0;AD=12347;IX=10213040;FF=0,0,0,0;VO=338572;ID=357042063052352<")); + verifyPosition(decoder, text( ">REV421942237017+1170957-0701880200000032;ID=356612022463055<")); -- cgit v1.2.3 From a7c2aa4a3faddb007a82523b2119134eaa45bea7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 18 Jul 2017 07:28:00 +1200 Subject: Implement additional Syrus data --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/TaipProtocolDecoder.java | 40 +++++++++++++++++----- .../traccar/protocol/TaipProtocolDecoderTest.java | 3 ++ 3 files changed, 36 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 9e7bac932..4412b012c 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -111,6 +111,7 @@ public class Position extends Message { public static final String ALARM_TOW = "tow"; public static final String ALARM_ACCELERATION = "hardAcceleration"; public static final String ALARM_BREAKING = "hardBreaking"; + public static final String ALARM_CORNERING = "hardCornering"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; public static final String ALARM_POWER_RESTORED = "powerRestored"; diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index a08bb6f2b..6edf4a93e 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.Checksum; import org.traccar.helper.DateBuilder; import org.traccar.helper.DateUtil; @@ -118,7 +119,24 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { } if (event != null) { - position.set(Position.KEY_EVENT, event); + switch (event) { + case 22: + position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); + break; + case 23: + position.set(Position.KEY_ALARM, Position.ALARM_BREAKING); + break; + case 24: + position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); + break; + case 26: + case 28: + position.set(Position.KEY_ALARM, Position.ALARM_CORNERING); + break; + default: + position.set(Position.KEY_EVENT, event); + break; + } } if (parser.hasNext(6)) { @@ -173,7 +191,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { String key = attribute.substring(0, index).toLowerCase(); String value = attribute.substring(index + 1); switch (key) { - case "id": uniqueId = value; deviceSession = getDeviceSession(channel, remoteAddress, value); @@ -181,23 +198,30 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); } break; - + case "io": + position.set(Position.KEY_IGNITION, BitUtil.check(value.charAt(0) - '0', 0)); + position.set(Position.KEY_CHARGE, BitUtil.check(value.charAt(0) - '0', 1)); + position.set(Position.KEY_OUTPUT, value.charAt(1) - '0'); + position.set(Position.KEY_INPUT, value.charAt(2) - '0'); + break; + case "ix": + position.set(Position.PREFIX_IO + 1, value); + break; + case "ad": + position.set(Position.PREFIX_ADC + 1, Integer.parseInt(value)); + break; case "sv": position.set(Position.KEY_SATELLITES, Integer.parseInt(value)); break; - case "bl": - position.set(Position.KEY_BATTERY, Integer.parseInt(value)); + position.set(Position.KEY_BATTERY, Integer.parseInt(value) * 0.001); break; - case "vo": position.set(Position.KEY_ODOMETER, Long.parseLong(value)); break; - default: position.set(key, value); break; - } } else if (attribute.startsWith("#")) { messageIndex = attribute; diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index 6d24a504f..e2de26ec0 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<")); + verifyPosition(decoder, text( ">REV011958000369+0307185+1016144400000032;IO=200;SV=9;BL=4158;CF=0,0,0;AD=12347;IX=10213040;FF=0,0,0,0;VO=338572;ID=357042063052352<")); -- cgit v1.2.3 From 4f773f445e8d6e6fcc4ec030ca9c8b6b1e7c521d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2017 01:14:39 +1200 Subject: Save GPS103 unhandled events --- src/org/traccar/protocol/Gps103ProtocolDecoder.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index a9a72b110..099047aa0 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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. @@ -248,6 +248,8 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 1, alarm.substring(2)); } else if (alarm.startsWith("oil ")) { position.set("oil", alarm.substring(4)); + } else if (!position.getAttributes().containsKey(Position.KEY_ALARM) && !alarm.equals("tracker")) { + position.set(Position.KEY_EVENT, alarm); } DateBuilder dateBuilder = new DateBuilder() -- cgit v1.2.3 From 73fb44dfb7dea5cdddcb3ab939e9b7a64ae49abb Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2017 04:09:19 +1200 Subject: Support Sinocastel version 3 protocol --- src/org/traccar/protocol/CastelProtocolDecoder.java | 2 +- test/org/traccar/protocol/CastelProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CastelProtocolDecoder.java b/src/org/traccar/protocol/CastelProtocolDecoder.java index 83664fa5a..3a0ccea78 100644 --- a/src/org/traccar/protocol/CastelProtocolDecoder.java +++ b/src/org/traccar/protocol/CastelProtocolDecoder.java @@ -440,7 +440,7 @@ public class CastelProtocolDecoder extends BaseProtocolDecoder { } - } else if (version == 4) { + } else if (version == 3 || version == 4) { return decodeSc(channel, remoteAddress, buf, version, id, type, deviceSession); diff --git a/test/org/traccar/protocol/CastelProtocolDecoderTest.java b/test/org/traccar/protocol/CastelProtocolDecoderTest.java index bbc5f1f37..6b52373e1 100644 --- a/test/org/traccar/protocol/CastelProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CastelProtocolDecoderTest.java @@ -12,6 +12,9 @@ public class CastelProtocolDecoderTest extends ProtocolTest { CastelProtocolDecoder decoder = new CastelProtocolDecoder(new CastelProtocol()); + verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN, + "40408200033231334c323031373030303131370000000000001001000c6759a10d67590a9e1200000000000e3e0000000000020000000e4e791c000004010d0711060515083017086cd1181f000040067d4944442d3231334c2056312e312e3120323031372d30352d3038004944442d3231334c2056312e312e3000000066e30d0a")); + verifyAttributes(decoder, binary(ByteOrder.LITTLE_ENDIAN, "404043000432313345503230313630303035383500000000004006a2021d5810031d58ae940400da050000f6040000070000000400076401680000000001001bd20d0a")); -- cgit v1.2.3 From 5b56c2cc17fa23251b1985aa4d8f56dd6552b970 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 19 Jul 2017 21:23:48 +1200 Subject: Implement JV200 ignition support --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 10 +++++++--- test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 24bedcabf..aea3a29f4 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -336,7 +336,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); buf.readUnsignedShort(); // type - // Timezone offset if (dataLength > 10) { int extensionBits = buf.readUnsignedShort(); int hours = (extensionBits >> 4) / 100; @@ -405,7 +404,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mcc = buf.readUnsignedShort(); int mnc = buf.readUnsignedByte(); - Network network = new Network(); for (int i = 0; i < 7; i++) { network.addCellTower(CellTower.from( @@ -441,10 +439,16 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { decodeStatus(position, buf); } - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { + if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); } + if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + } else { buf.skipBytes(dataLength); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 0ac51f4b2..2e6a53b06 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyPosition(decoder, binary( + "787822221106160a1016c60278019407c7783800040001940504700046fc01030100065f570d0a")); + verifyAttributes(decoder, binary( "797900143311070609020b00000000a0030046000109e4610d0a")); -- cgit v1.2.3 From d7d66e3b724cde1a681e5e7f24e930d2bddfe703 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 20 Jul 2017 07:35:52 +1200 Subject: Fix Aplicom E driver decoding --- .../traccar/protocol/AplicomProtocolDecoder.java | 25 ++++++++++++++++------ .../protocol/AplicomProtocolDecoderTest.java | 3 +++ 2 files changed, 22 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 6f63d0c17..ef02cda7e 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -352,15 +352,28 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_VIN, buf.readBytes(18).toString(StandardCharsets.US_ASCII).trim()); } + if ((selector & 0x2000) != 0) { + buf.readUnsignedByte(); // card 1 type + buf.readUnsignedByte(); // card 1 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card1", card); + } + } + + if ((selector & 0x4000) != 0) { + buf.readUnsignedByte(); // card 2 type + buf.readUnsignedByte(); // card 2 country code + String card = buf.readBytes(20).toString(StandardCharsets.US_ASCII).trim(); + if (!card.isEmpty()) { + position.set("card2", card); + } + } + if ((selector & 0x10000) != 0) { int count = buf.readUnsignedByte(); for (int i = 1; i <= count; i++) { - ChannelBuffer driver = buf.readBytes(22); - int endIndex = driver.indexOf(0, driver.writerIndex(), (byte) 0); - if (endIndex < 0) { - endIndex = driver.writerIndex(); - } - position.set("driver" + i, driver.toString(0, endIndex, StandardCharsets.US_ASCII).trim()); + position.set("driver" + i, buf.readBytes(22).toString(StandardCharsets.US_ASCII).trim()); position.set("driverTime" + i, buf.readUnsignedInt()); } } diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 3c71e86b3..2498d94b3 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyAttributes(decoder, binary( + "45c20144f667c06ff9005d0161ef17000104596da2dc4b10c0c01d99020d6c04004cba7a010d44463030303235333731363238303030000000000000000000000000000000000000000000000000000001010d44463030303235333731363238303030000000000000031c")); + verifyAttributes(decoder, binary( "45c20144f667c07287008c01ffff6d01000059368963d0340a0616207d7f4b10c0c019e6000039d7000039d71f40ffff5001574442393036363035533132333435363700014142432d33343520202020202000011231303331373139343039303030303031000000000000000000000000000000000000000000000000000001011231303331373139343039303030303031000000000000005a")); -- cgit v1.2.3 From 2e157393d036f765687d5ff38797e6e600d986e5 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 12:24:55 +1200 Subject: Add binary INF support --- .../protocol/Gl200BinaryProtocolDecoder.java | 170 ++++++++++++++++----- .../protocol/Gl200BinaryProtocolDecoderTest.java | 3 + 2 files changed, 132 insertions(+), 41 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index cb0417528..a7ecf40d5 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -27,6 +27,7 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.Date; public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { @@ -34,70 +35,157 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + private Date decodeTime(ChannelBuffer buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return dateBuilder.getDate(); + } - ChannelBuffer buf = (ChannelBuffer) msg; + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { - String header = buf.readBytes(4).toString(StandardCharsets.US_ASCII); + Position position = new Position(); + position.setProtocol(getProtocolName()); - if (header.equals("+EVT")) { + buf.readUnsignedByte(); // message type + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - Position position = new Position(); - position.setProtocol(getProtocolName()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - buf.readUnsignedByte(); // message type + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); - buf.readUnsignedInt(); // mask + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedShort()); - buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // device type - buf.readUnsignedShort(); // protocol version + buf.readUnsignedByte(); // motion status - position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_INDEX, buf.readUnsignedByte()); - DeviceSession deviceSession = getDeviceSession( - channel, remoteAddress, String.format("%015d", buf.readLong())); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); - position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + position.setTime(decodeTime(buf)); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + return position; + } + + public static final int MSG_INF_GPS = 2; + public static final int MSG_INF_CID = 4; + public static final int MSG_INF_CSQ = 5; + public static final int MSG_INF_VER = 6; + public static final int MSG_INF_BAT = 7; + public static final int MSG_INF_TMZ = 9; + public static final int MSG_INF_GIR = 10; + + private Position decodeInformation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + + int type = buf.readUnsignedByte(); + + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length - buf.readUnsignedByte(); // motion status + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + position.setDeviceId(deviceSession.getDeviceId()); + + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_VERSION_FW, String.valueOf(buf.readUnsignedShort())); - int hdop = buf.readUnsignedByte(); - position.setValid(hdop > 0); - position.set(Position.KEY_HDOP, hdop); + if (type == MSG_INF_VER) { + buf.readUnsignedShort(); // hardware version + buf.readUnsignedShort(); // mcu version + buf.readUnsignedShort(); // reserved + } - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); - position.setCourse(buf.readUnsignedShort()); - position.setAltitude(buf.readShort()); - position.setLongitude(buf.readInt() * 0.000001); - position.setLatitude(buf.readInt() * 0.000001); + buf.readUnsignedByte(); // motion status + buf.readUnsignedByte(); // reserved + + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + + buf.readUnsignedByte(); // mode + buf.skipBytes(7); // last fix time + buf.readUnsignedByte(); // reserved + buf.readUnsignedByte(); + buf.readUnsignedShort(); // response report mask + buf.readUnsignedShort(); // ign interval + buf.readUnsignedShort(); // igf interval + buf.readUnsignedInt(); // reserved + buf.readUnsignedByte(); // reserved + + if (type == MSG_INF_BAT) { + position.set(Position.KEY_CHARGE, buf.readUnsignedByte() != 0); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY_LEVEL, buf.readUnsignedByte()); + } - DateBuilder dateBuilder = new DateBuilder() - .setDate(buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - position.setTime(dateBuilder.getDate()); + buf.skipBytes(10); // iccid + if (type == MSG_INF_CSQ) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + buf.readUnsignedByte(); + } + + buf.readUnsignedByte(); // time zone flags + buf.readUnsignedShort(); // time zone offset + + if (type == MSG_INF_GIR) { + buf.readUnsignedByte(); // gir trigger + buf.readUnsignedByte(); // cell number position.setNetwork(new Network(CellTower.from( buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort(), buf.readUnsignedShort()))); + buf.readUnsignedByte(); // ta + buf.readUnsignedByte(); // rx level + } - buf.readUnsignedByte(); // reserved + getLastLocation(position, decodeTime(buf)); - return position; + return position; + } - } + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - return null; + ChannelBuffer buf = (ChannelBuffer) msg; + + switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + case "+INF": + return decodeInformation(channel, remoteAddress, buf); + case "+EVT": + return decodeEvent(channel, remoteAddress, buf); + default: + return null; + } } } diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index 42ccd4690..24830a953 100644 --- a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, binary( + "2b494e4601fd7f0076676231303000000045010202090104020500004100054007e107150b061d0000003f010e02580000000000d0312a1013648935103226313921591f1200000000000302680003189c1ac3001b02680003189c1ac4000d02680003189c1ac5001207e107150b0d3704f658060d0a")); + verifyPosition(decoder, binary( "2b4556540c00fc1fbf005c4501010108563254030003430564312a41090100000000003f007dff75a11a025c6a7807e1070a14041202680003189c1ac500000000000000000000000000000000000007e1070b041134054e5c6e0d0a")); -- cgit v1.2.3 From 8b74b160890b9dbdd4a2d660d74d2879df6ceced Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 17:45:51 +1200 Subject: Another GT06 LBS and WiFi message type --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 122 ++++++++++++--------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 9 ++ 2 files changed, 79 insertions(+), 52 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index aea3a29f4..36358b6e5 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -31,6 +31,7 @@ import org.traccar.model.CellTower; import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; +import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; @@ -68,6 +69,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; + public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_PHONE = 0x17; public static final int MSG_LBS_EXTEND = 0x18; public static final int MSG_LBS_STATUS = 0x19; @@ -390,82 +392,98 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else { - Position position = new Position(); - position.setDeviceId(deviceSession.getDeviceId()); - position.setProtocol(getProtocolName()); + return decodeBasicOther(channel, buf, deviceSession, type, dataLength); - if (type == MSG_LBS_EXTEND) { + } - DateBuilder dateBuilder = new DateBuilder(timeZone) - .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) - .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); + return null; + } - getLastLocation(position, dateBuilder.getDate()); + private Object decodeBasicOther(Channel channel, ChannelBuffer buf, + DeviceSession deviceSession, int type, int dataLength) throws Exception { - int mcc = buf.readUnsignedShort(); - int mnc = buf.readUnsignedByte(); - Network network = new Network(); - for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); - } - position.setNetwork(network); + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); - } else if (type == MSG_STRING) { + if (type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { - getLastLocation(position, null); + DateBuilder dateBuilder = new DateBuilder(timeZone) + .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) + .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); - int commandLength = buf.readUnsignedByte(); + getLastLocation(position, dateBuilder.getDate()); - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set(Position.KEY_RESULT, - buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } + int mcc = buf.readUnsignedShort(); + int mnc = buf.readUnsignedByte(); + Network network = new Network(); + for (int i = 0; i < 7; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); + } - } else if (isSupported(type)) { + buf.readUnsignedByte(); // time leads - if (hasGps(type)) { - decodeGps(position, buf, false); - } else { - getLastLocation(position, null); - } + int wifiCount = buf.readUnsignedByte(); + for (int i = 0; i < wifiCount; i++) { + String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } + position.setNetwork(network); - if (hasStatus(type)) { - decodeStatus(position, buf); - } + } else if (type == MSG_STRING) { - if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + getLastLocation(position, null); - if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { - position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); - position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason - position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); - } + int commandLength = buf.readUnsignedByte(); + if (commandLength > 0) { + buf.readUnsignedByte(); // server flag (reserved) + position.set(Position.KEY_RESULT, + buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); + } + + } else if (isSupported(type)) { + + if (hasGps(type)) { + decodeGps(position, buf, false); } else { + getLastLocation(position, null); + } - buf.skipBytes(dataLength); - if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, false, type); - } - return null; + if (hasLbs(type)) { + decodeLbs(position, buf, hasStatus(type)); + } + if (hasStatus(type)) { + decodeStatus(position, buf); } - sendResponse(channel, false, type); + if (type == MSG_GPS_LBS_1 && buf.readableBytes() >= 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } - return position; + if (type == MSG_GPS_LBS_2 && buf.readableBytes() >= 3 + 6) { + position.set(Position.KEY_IGNITION, buf.readUnsignedByte() > 0); + position.set(Position.KEY_EVENT, buf.readUnsignedByte()); // reason + position.set(Position.KEY_ARCHIVE, buf.readUnsignedByte() > 0); + } + + } else { + + buf.skipBytes(dataLength); + if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { + sendResponse(channel, false, type); + } + return null; } - return null; + sendResponse(channel, false, type); + + return position; } private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 2e6a53b06..3c767c908 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,12 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "7878412c11030b011c1f013604cb8a00b17754cb8a00bef357cb8a00b73f5fcb8900b0e25fcb8900b6655fcb8a00b74960cb8a00b178620701001801eb40393800bbbde10d0a")); + + verifyNotNull(decoder, binary( + "7878412c11030b012629013604cb8a00b17757cb8a00b73f5bcb8a00b7495ecb8900b0e25fcb8a00b1b9620000000000ff0000000000ffff01001801eb40393e00c0e6340d0a")); + verifyPosition(decoder, binary( "787822221106160a1016c60278019407c7783800040001940504700046fc01030100065f570d0a")); @@ -149,6 +155,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "787811010123456789012345100B3201000171930D0A")); + verifyNull(decoder, binary( + "78780d1f000000000000000200b196a20d0a")); + } } -- cgit v1.2.3 From abe8232585103b9e4856a4eabb0df122c17db052 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 19:32:35 +1200 Subject: Support GP6000 packed messages --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 141 +++++++++++---------- .../traccar/protocol/Jt600ProtocolDecoderTest.java | 20 ++- 2 files changed, 87 insertions(+), 74 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 2bd02d3f1..3b68cd82a 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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. @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; @@ -31,6 +32,8 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.LinkedList; +import java.util.List; import java.util.regex.Pattern; public class Jt600ProtocolDecoder extends BaseProtocolDecoder { @@ -45,10 +48,9 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes / 60; } - private Position decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { + private List decodeBinary(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) { - Position position = new Position(); - position.setProtocol(getProtocolName()); + List positions = new LinkedList<>(); buf.readByte(); // header @@ -59,97 +61,102 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } - position.setDeviceId(deviceSession.getDeviceId()); if (longFormat) { buf.readUnsignedByte(); // protocol } - int version = buf.readUnsignedByte() >> 4; + int version = BitUtil.from(buf.readUnsignedByte(), 4); buf.readUnsignedShort(); // length - DateBuilder dateBuilder = new DateBuilder() - .setDay(BcdUtil.readInteger(buf, 2)) - .setMonth(BcdUtil.readInteger(buf, 2)) - .setYear(BcdUtil.readInteger(buf, 2)) - .setHour(BcdUtil.readInteger(buf, 2)) - .setMinute(BcdUtil.readInteger(buf, 2)) - .setSecond(BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); - - double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); - double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - - byte flags = buf.readByte(); - position.setValid((flags & 0x1) == 0x1); - if ((flags & 0x2) == 0) { - latitude = -latitude; - } - position.setLatitude(latitude); - if ((flags & 0x4) == 0) { - longitude = -longitude; - } - position.setLongitude(longitude); + while (buf.readableBytes() > 1) { - position.setSpeed(BcdUtil.readInteger(buf, 2)); - position.setCourse(buf.readUnsignedByte() * 2.0); + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); - if (longFormat) { + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) + .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); + position.setTime(dateBuilder.getDate()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); + double longitude = convertCoordinate(BcdUtil.readInteger(buf, 9)); - buf.readUnsignedInt(); // vehicle id combined + byte flags = buf.readByte(); + position.setValid((flags & 0x1) == 0x1); + if ((flags & 0x2) == 0) { + latitude = -latitude; + } + position.setLatitude(latitude); + if ((flags & 0x4) == 0) { + longitude = -longitude; + } + position.setLongitude(longitude); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + position.setSpeed(BcdUtil.readInteger(buf, 2)); + position.setCourse(buf.readUnsignedByte() * 2.0); - int battery = buf.readUnsignedByte(); - if (battery == 0xff) { - position.set(Position.KEY_CHARGE, true); - } else { - position.set(Position.KEY_BATTERY_LEVEL, battery); - } + if (longFormat) { + + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); - cellTower.setSignalStrength((int) buf.readUnsignedByte()); - position.setNetwork(new Network(cellTower)); + buf.readUnsignedInt(); // vehicle id combined - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + position.set(Position.KEY_STATUS, buf.readUnsignedShort()); - } else if (version == 1) { + int battery = buf.readUnsignedByte(); + if (battery == 0xff) { + position.set(Position.KEY_CHARGE, true); + } else { + position.set(Position.KEY_BATTERY_LEVEL, battery); + } - position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_POWER, buf.readUnsignedByte()); + CellTower cellTower = CellTower.fromCidLac(buf.readUnsignedShort(), buf.readUnsignedShort()); + cellTower.setSignalStrength((int) buf.readUnsignedByte()); + position.setNetwork(new Network(cellTower)); - buf.readByte(); // other flags and sensors + } else if (version == 1) { - position.setAltitude(buf.readUnsignedShort()); + position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); + position.set(Position.KEY_POWER, buf.readUnsignedByte()); - int cid = buf.readUnsignedShort(); - int lac = buf.readUnsignedShort(); - int rssi = buf.readUnsignedByte(); + buf.readByte(); // other flags and sensors - if (cid != 0 && lac != 0) { - CellTower cellTower = CellTower.fromCidLac(cid, lac); - cellTower.setSignalStrength(rssi); - position.setNetwork(new Network(cellTower)); - } else { - position.set(Position.KEY_RSSI, rssi); - } + position.setAltitude(buf.readUnsignedShort()); + + int cid = buf.readUnsignedShort(); + int lac = buf.readUnsignedShort(); + int rssi = buf.readUnsignedByte(); + + if (cid != 0 && lac != 0) { + CellTower cellTower = CellTower.fromCidLac(cid, lac); + cellTower.setSignalStrength(rssi); + position.setNetwork(new Network(cellTower)); + } else { + position.set(Position.KEY_RSSI, rssi); + } - } else if (version == 2) { + } else if (version == 2) { - int fuel = buf.readUnsignedByte() << 8; + int fuel = buf.readUnsignedByte() << 8; - position.set(Position.KEY_STATUS, buf.readUnsignedInt()); - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); + position.set(Position.KEY_STATUS, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 1000); - fuel += buf.readUnsignedByte(); - position.set(Position.KEY_FUEL_LEVEL, fuel); + fuel += buf.readUnsignedByte(); + position.set(Position.KEY_FUEL_LEVEL, fuel); + + } + + positions.add(position); } - return position; + buf.readUnsignedByte(); // index + + return positions; } private static final Pattern PATTERN_W01 = new PatternBuilder() diff --git a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java index 3b040297d..eb82d8c23 100644 --- a/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolDecoderTest.java @@ -11,13 +11,19 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { Jt600ProtocolDecoder decoder = new Jt600ProtocolDecoder(new Jt600Protocol()); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( + "24624090196121001b19071703493631277203074235752f295800005308010000768b0822")); + + verifyPositions(decoder, binary( + "24624090196123019519071703412131285623074214252f10560000130801000076850819071703420631282832074215165f172c0000030801000076850919071703422131282792074216635f222e0000130801000076850919071703423631282808074218261f212a0000130801000076860819071703435131283678074222928f08350000930801000076860919071703440631283003074223174f19500000930801000076870819071703445131279872074224584f07380000930801000076870819071703453631280643074227091f1b220000530801000076880919071703455131281043074228216f0a260000530801000076880819071703460631281229074228988f0c260000530801000076880819071703462131281551074229954f1f220000530801000076880919071703463631281289074230503f114e0000530801000076880819071703465131281186074230884f094f0000530801000076880819071703470631280308074231240f17500000530801000076880619071703472131280358074231636f0b1d0000530801000076890821")); + + verifyPositions(decoder, binary( "2475604055531611002311111600311326144436028210791d016c0000001f070000000020c03c4f6d07d80ccf")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475201509260111002313101503464722331560113555309F00000000002D0500CB206800F064109326381A03")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "2475605035891613002328091601152806086750106533350c00000000000a000000000000e1ff4f97007f1607")); verifyPosition(decoder, buffer( @@ -50,17 +56,17 @@ public class Jt600ProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, buffer( "(3460311327,U06,10,220916,140619,T,9.552495,N,13.658227,W,0.43,0,7,0%,00101001000000,11012,10,0,0,0,126,0,30)")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24311021600111001B16021105591022329862114046227B0598095080012327951435161F"), position("2011-02-16 05:59:10.000", true, 22.54977, -114.07705)); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B171012052831243810120255336425001907190003FD2B91044D1FA0")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24312082002911001B1710120533052438099702553358450004061E0003EE000000000C00")); - verifyPosition(decoder, binary( + verifyPositions(decoder, binary( "24608111888821001B09060908045322564025113242329F0598000001003F0000002D00AB")); verifyPosition(decoder, buffer( -- cgit v1.2.3 From ba82047a492be54545961716814584d8880d28ae Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 22 Jul 2017 19:41:14 +1200 Subject: Fix code style issue --- src/org/traccar/protocol/Jt600ProtocolDecoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index 3b68cd82a..f76fd8069 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -76,8 +76,12 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() - .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) - .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); + .setDay(BcdUtil.readInteger(buf, 2)) + .setMonth(BcdUtil.readInteger(buf, 2)) + .setYear(BcdUtil.readInteger(buf, 2)) + .setHour(BcdUtil.readInteger(buf, 2)) + .setMinute(BcdUtil.readInteger(buf, 2)) + .setSecond(BcdUtil.readInteger(buf, 2)); position.setTime(dateBuilder.getDate()); double latitude = convertCoordinate(BcdUtil.readInteger(buf, 8)); -- cgit v1.2.3 From c8e5c5e3da63646fd7c84d4f522bc8d7e5109982 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 25 Jul 2017 04:31:13 +1200 Subject: Implement missing XT2400 parameters --- src/org/traccar/protocol/Xt2400ProtocolDecoder.java | 15 +++++++++++++-- test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java | 5 +++++ 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java index a42c6175f..15e8558be 100644 --- a/src/org/traccar/protocol/Xt2400ProtocolDecoder.java +++ b/src/org/traccar/protocol/Xt2400ProtocolDecoder.java @@ -25,6 +25,7 @@ import org.traccar.model.Position; import javax.xml.bind.DatatypeConverter; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -77,8 +78,6 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { for (int i : l4) { TAG_LENGTH_MAP.put(i, 4); } - TAG_LENGTH_MAP.put(0x65, 17); - TAG_LENGTH_MAP.put(0x73, 16); TAG_LENGTH_MAP.put(0x95, 24); } @@ -163,12 +162,24 @@ public class Xt2400ProtocolDecoder extends BaseProtocolDecoder { case 0x13: position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); break; + case 0x14: + position.set(Position.KEY_RSSI, buf.readShort()); + break; case 0x16: position.set(Position.KEY_BATTERY, buf.readUnsignedByte() * 0.1); break; case 0x17: position.set(Position.KEY_POWER, buf.readUnsignedByte() * 0.1); break; + case 0x57: + position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(buf.readUnsignedShort())); + break; + case 0x65: + position.set(Position.KEY_VIN, buf.readBytes(17).toString(StandardCharsets.US_ASCII)); + break; + case 0x73: + position.set(Position.KEY_VERSION_FW, buf.readBytes(16).toString(StandardCharsets.US_ASCII).trim()); + break; default: buf.skipBytes(getTagLength(tag)); break; diff --git a/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java b/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java index 3cc0c22ec..35ca282b2 100644 --- a/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Xt2400ProtocolDecoderTest.java @@ -10,6 +10,11 @@ public class Xt2400ProtocolDecoderTest extends ProtocolTest { Xt2400ProtocolDecoder decoder = new Xt2400ProtocolDecoder(new Xt2400Protocol()); + decoder.setConfig("\n:wycfg pcr[0] 001001030406070809570a13121714100565\n"); + + verifyPosition(decoder, binary( + "000a344f1f0259766ae002074289f8f1c4b200e80000026712068000130000029300883559464255524845364650323433343235")); + decoder.setConfig("\n:wycfg pcr[0] 000f01030406070809570a131217141005\n"); verifyPosition(decoder, binary( -- cgit v1.2.3 From d31f68d80a8e3ae75fa0c2f02b9ca258486a3cad Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 26 Jul 2017 17:52:27 +0500 Subject: - Implement base manager classes as generics - Remame getDeviceById and getDeviceByUniqueId functions --- src/org/traccar/BaseProtocolDecoder.java | 2 +- src/org/traccar/BaseProtocolEncoder.java | 4 +-- src/org/traccar/FilterHandler.java | 2 +- src/org/traccar/MainEventHandler.java | 2 +- src/org/traccar/WebDataHandler.java | 2 +- .../traccar/api/resource/AttributeResource.java | 2 +- src/org/traccar/api/resource/CalendarResource.java | 9 ++++-- src/org/traccar/api/resource/DeviceResource.java | 4 +-- src/org/traccar/api/resource/DriverResource.java | 2 +- src/org/traccar/api/resource/GeofenceResource.java | 2 +- src/org/traccar/api/resource/GroupResource.java | 2 +- src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/api/resource/UserResource.java | 2 +- src/org/traccar/database/AttributesManager.java | 13 ++------- src/org/traccar/database/BaseObjectManager.java | 28 +++++++++--------- src/org/traccar/database/CalendarManager.java | 7 +---- src/org/traccar/database/ConnectionManager.java | 2 +- src/org/traccar/database/DeviceManager.java | 34 +++++++++------------- src/org/traccar/database/DriversManager.java | 25 ++++++---------- .../traccar/database/ExtendedObjectManager.java | 4 +-- src/org/traccar/database/GeofenceManager.java | 7 +---- src/org/traccar/database/GroupsManager.java | 19 +++++------- src/org/traccar/database/IdentityManager.java | 4 +-- src/org/traccar/database/PermissionsManager.java | 5 ++-- src/org/traccar/database/SimpleObjectManager.java | 5 ++-- src/org/traccar/database/UsersManager.java | 21 +++++-------- src/org/traccar/events/FuelDropEventHandler.java | 2 +- src/org/traccar/events/GeofenceEventHandler.java | 11 ++++--- src/org/traccar/events/IgnitionEventHandler.java | 2 +- .../traccar/events/MaintenanceEventHandler.java | 2 +- src/org/traccar/events/MotionEventHandler.java | 2 +- src/org/traccar/events/OverspeedEventHandler.java | 2 +- src/org/traccar/notification/EventForwarder.java | 2 +- .../notification/NotificationFormatter.java | 2 +- .../processing/ComputedAttributesHandler.java | 4 +-- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 4 +-- src/org/traccar/reports/Events.java | 2 +- src/org/traccar/reports/ReportUtils.java | 4 +-- src/org/traccar/reports/Route.java | 2 +- src/org/traccar/reports/Stops.java | 2 +- src/org/traccar/reports/Summary.java | 2 +- src/org/traccar/reports/Trips.java | 2 +- test/org/traccar/BaseTest.java | 4 +-- 44 files changed, 112 insertions(+), 152 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index b7ceabb5c..cc16000f4 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -75,7 +75,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { try { for (String uniqueId : uniqueIds) { if (uniqueId != null) { - Device device = Context.getIdentityManager().getDeviceByUniqueId(uniqueId); + Device device = Context.getIdentityManager().getByUniqueId(uniqueId); if (device != null) { deviceId = device.getId(); break; diff --git a/src/org/traccar/BaseProtocolEncoder.java b/src/org/traccar/BaseProtocolEncoder.java index 3c2d08471..2c8a81868 100644 --- a/src/org/traccar/BaseProtocolEncoder.java +++ b/src/org/traccar/BaseProtocolEncoder.java @@ -25,12 +25,12 @@ import org.traccar.model.Device; public abstract class BaseProtocolEncoder extends OneToOneEncoder { protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getDeviceById(deviceId).getUniqueId(); + return Context.getIdentityManager().getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - Device device = Context.getIdentityManager().getDeviceById(command.getDeviceId()); + Device device = Context.getIdentityManager().getById(command.getDeviceId()); String password = device.getString(Command.KEY_DEVICE_PASSWORD); if (password != null) { command.set(Command.KEY_DEVICE_PASSWORD, password); diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 71c0a1cf5..1f5fffc86 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -184,7 +184,7 @@ public class FilterHandler extends BaseDataHandler { message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId()); + message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); message.append(" with id: "); message.append(position.getDeviceId()); diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index a005ee44b..8e88e15b9 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -55,7 +55,7 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { Log.warning(error); } - String uniqueId = Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId(); + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); // Log position StringBuilder s = new StringBuilder(); diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java index eaf0978ef..c64dcc81b 100644 --- a/src/org/traccar/WebDataHandler.java +++ b/src/org/traccar/WebDataHandler.java @@ -75,7 +75,7 @@ public class WebDataHandler extends BaseDataHandler { public String formatRequest(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); String request = url .replace("{name}", device.getName()) diff --git a/src/org/traccar/api/resource/AttributeResource.java b/src/org/traccar/api/resource/AttributeResource.java index 7b81d3ffb..c12fcd9e6 100644 --- a/src/org/traccar/api/resource/AttributeResource.java +++ b/src/org/traccar/api/resource/AttributeResource.java @@ -81,7 +81,7 @@ public class AttributeResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(attributesManager.getDeviceItems(deviceId)); } - return attributesManager.getItems(Attribute.class, result); + return attributesManager.getItems(result); } diff --git a/src/org/traccar/api/resource/CalendarResource.java b/src/org/traccar/api/resource/CalendarResource.java index a0f8656af..f8d78a847 100644 --- a/src/org/traccar/api/resource/CalendarResource.java +++ b/src/org/traccar/api/resource/CalendarResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import java.sql.SQLException; import java.util.Collection; +import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -47,20 +48,22 @@ public class CalendarResource extends BaseResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { CalendarManager calendarManager = Context.getCalendarManager(); + Set result = null; if (all) { if (Context.getPermissionsManager().isAdmin(getUserId())) { - return calendarManager.getItems(Calendar.class, calendarManager.getAllItems()); + result = calendarManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - return calendarManager.getItems(Calendar.class, calendarManager.getManagedItems(getUserId())); + result = calendarManager.getManagedItems(getUserId()); } } else { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return calendarManager.getItems(Calendar.class, calendarManager.getUserItems(userId)); + result = calendarManager.getUserItems(userId); } + return calendarManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index c621d4304..a473b7bde 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -68,7 +68,7 @@ public class DeviceResource extends BaseResource { } else { result = new HashSet(); for (String uniqueId : uniqueIds) { - Device device = deviceManager.getDeviceByUniqueId(uniqueId); + Device device = deviceManager.getByUniqueId(uniqueId); Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); result.add(device.getId()); } @@ -77,7 +77,7 @@ public class DeviceResource extends BaseResource { result.add(deviceId); } } - return deviceManager.getItems(Device.class, result); + return deviceManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DriverResource.java b/src/org/traccar/api/resource/DriverResource.java index 72eadb711..d44979998 100644 --- a/src/org/traccar/api/resource/DriverResource.java +++ b/src/org/traccar/api/resource/DriverResource.java @@ -79,7 +79,7 @@ public class DriverResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(driversManager.getDeviceItems(deviceId)); } - return driversManager.getItems(Driver.class, result); + return driversManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GeofenceResource.java b/src/org/traccar/api/resource/GeofenceResource.java index 47f889e9c..9a110fbcf 100644 --- a/src/org/traccar/api/resource/GeofenceResource.java +++ b/src/org/traccar/api/resource/GeofenceResource.java @@ -78,7 +78,7 @@ public class GeofenceResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(geofenceManager.getDeviceItems(deviceId)); } - return geofenceManager.getItems(Geofence.class, result); + return geofenceManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java index f832660b2..4482f06c0 100644 --- a/src/org/traccar/api/resource/GroupResource.java +++ b/src/org/traccar/api/resource/GroupResource.java @@ -60,7 +60,7 @@ public class GroupResource extends BaseResource { Context.getPermissionsManager().checkUser(getUserId(), userId); result = groupsManager.getUserItems(userId); } - return groupsManager.getItems(Group.class, result); + return groupsManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index 9d3cd9ae6..6dab51744 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -87,7 +87,7 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getDeviceById(deviceId).getName()); + GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getById(deviceId).getName()); gpx.addPositions(Context.getDataManager().getPositions( deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to))); return Response.ok(gpx.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_GPX).build(); diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index 9998ed346..deb2dd2b4 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -58,7 +58,7 @@ public class UserResource extends BaseResource { } else { throw new SecurityException("Admin or manager access required"); } - return usersManager.getItems(User.class, result); + return usersManager.getItems(result); } @PermitAll diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java index e80d57c4e..28816645a 100644 --- a/src/org/traccar/database/AttributesManager.java +++ b/src/org/traccar/database/AttributesManager.java @@ -17,23 +17,16 @@ package org.traccar.database; import org.traccar.model.Attribute; -import org.traccar.model.BaseModel; -public class AttributesManager extends ExtendedObjectManager { +public class AttributesManager extends ExtendedObjectManager { public AttributesManager(DataManager dataManager) { super(dataManager, Attribute.class); } @Override - public Attribute getById(long calendarId) { - return (Attribute) super.getById(calendarId); - } - - @Override - public void updateCachedItem(BaseModel item) { - Attribute attribute = (Attribute) item; - Attribute cachedAttribute = getById(item.getId()); + public void updateCachedItem(Attribute attribute) { + Attribute cachedAttribute = getById(attribute.getId()); cachedAttribute.setDescription(attribute.getDescription()); cachedAttribute.setAttribute(attribute.getAttribute()); cachedAttribute.setExpression(attribute.getExpression()); diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java index 92cfd9b6b..cc1dbde5f 100644 --- a/src/org/traccar/database/BaseObjectManager.java +++ b/src/org/traccar/database/BaseObjectManager.java @@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap; import org.traccar.helper.Log; import org.traccar.model.BaseModel; -public class BaseObjectManager { +public class BaseObjectManager { private final DataManager dataManager; - private Map items; - private Class baseClass; + private Map items; + private Class baseClass; - protected BaseObjectManager(DataManager dataManager, Class baseClass) { + protected BaseObjectManager(DataManager dataManager, Class baseClass) { this.dataManager = dataManager; this.baseClass = baseClass; refreshItems(); @@ -44,23 +44,23 @@ public class BaseObjectManager { return dataManager; } - protected final Class getBaseClass() { + protected final Class getBaseClass() { return baseClass; } - public BaseModel getById(long itemId) { + public T getById(long itemId) { return items.get(itemId); } public void refreshItems() { if (dataManager != null) { try { - Collection databaseItems = dataManager.getObjects(baseClass); + Collection databaseItems = dataManager.getObjects(baseClass); if (items == null) { items = new ConcurrentHashMap<>(databaseItems.size()); } Set databaseItemIds = new HashSet<>(); - for (BaseModel item : databaseItems) { + for (T item : databaseItems) { databaseItemIds.add(item.getId()); if (items.containsKey(item.getId())) { updateCachedItem(item); @@ -79,20 +79,20 @@ public class BaseObjectManager { } } - protected void addNewItem(BaseModel item) { + protected void addNewItem(T item) { items.put(item.getId(), item); } - public void addItem(BaseModel item) throws SQLException { + public void addItem(T item) throws SQLException { dataManager.addObject(item); addNewItem(item); } - protected void updateCachedItem(BaseModel item) { + protected void updateCachedItem(T item) { items.put(item.getId(), item); } - public void updateItem(BaseModel item) throws SQLException { + public void updateItem(T item) throws SQLException { dataManager.updateObject(item); updateCachedItem(item); } @@ -109,10 +109,10 @@ public class BaseObjectManager { } } - public final Collection getItems(Class clazz, Set itemIds) { + public final Collection getItems(Set itemIds) { Collection result = new LinkedList<>(); for (long itemId : itemIds) { - result.add((T) getById(itemId)); + result.add(getById(itemId)); } return result; } diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java index b8d0914ee..44ced1082 100644 --- a/src/org/traccar/database/CalendarManager.java +++ b/src/org/traccar/database/CalendarManager.java @@ -18,15 +18,10 @@ package org.traccar.database; import org.traccar.model.Calendar; -public class CalendarManager extends SimpleObjectManager { +public class CalendarManager extends SimpleObjectManager { public CalendarManager(DataManager dataManager) { super(dataManager, Calendar.class); } - @Override - public Calendar getById(long calendarId) { - return (Calendar) super.getById(calendarId); - } - } diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 0baafb578..1445fb785 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -70,7 +70,7 @@ public class ConnectionManager { } public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return; } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 1fe7ddfa5..4aafe6631 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -30,7 +30,6 @@ import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; -import org.traccar.model.BaseModel; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; @@ -39,7 +38,7 @@ import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; -public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { +public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { public static final long DEFAULT_REFRESH_DELAY = 300; @@ -73,12 +72,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - public Device getDeviceById(long id) { - return (Device) getById(id); - } - - @Override - public Device getDeviceByUniqueId(String uniqueId) throws SQLException { + public Device getByUniqueId(String uniqueId) throws SQLException { boolean forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); updateDeviceCache(forceUpdate); @@ -105,7 +99,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } public Collection getAllDevices() { - return getItems(Device.class, getAllItems()); + return getItems(getAllItems()); } @Override @@ -142,9 +136,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - Device device = (Device) item; + protected void addNewItem(Device device) { + super.addNewItem(device); putUniqueDeviceId(device); if (device.getPhone() != null && !device.getPhone().isEmpty()) { putPhone(device); @@ -158,9 +151,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void updateCachedItem(BaseModel item) { - Device device = (Device) item; - Device cachedDevice = getDeviceById(device.getId()); + protected void updateCachedItem(Device device) { + Device cachedDevice = getById(device.getId()); cachedDevice.setName(device.getName()); cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); @@ -182,7 +174,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void removeCachedItem(long deviceId) { - Device cachedDevice = getDeviceById(deviceId); + Device cachedDevice = getById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); String phone = cachedDevice.getPhone(); @@ -197,7 +189,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, public void updateDeviceStatus(Device device) throws SQLException { getDataManager().updateDeviceStatus(device); - Device cachedDevice = getDeviceById(device.getId()); + Device cachedDevice = getById(device.getId()); if (cachedDevice != null) { cachedDevice.setStatus(device.getStatus()); } @@ -226,7 +218,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, getDataManager().updateLatestPosition(position); - Device device = getDeviceById(position.getDeviceId()); + Device device = getById(position.getDeviceId()); if (device != null) { device.setPositionId(position.getId()); } @@ -305,7 +297,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { String result = null; - Device device = getDeviceById(deviceId); + Device device = getById(deviceId); if (device != null) { result = device.getString(attributeName); if (result == null && lookupGroupsAttribute) { @@ -352,9 +344,9 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(getDeviceById(deviceId).getPhone(), command); + protocol.sendTextCommand(getById(deviceId).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(((Device) getById(deviceId)).getPhone(), + Context.getSmppManager().sendMessageSync(getById(deviceId).getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java index 420824dbb..d3866a5f0 100644 --- a/src/org/traccar/database/DriversManager.java +++ b/src/org/traccar/database/DriversManager.java @@ -20,37 +20,30 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.traccar.model.Driver; -import org.traccar.model.BaseModel; -public class DriversManager extends ExtendedObjectManager { +public class DriversManager extends ExtendedObjectManager { - private Map driversByUniqueId; + private Map driversByUniqueId; public DriversManager(DataManager dataManager) { super(dataManager, Driver.class); } - @Override - public Driver getById(long driverId) { - return (Driver) super.getById(driverId); - } - private void putUniqueDriverId(Driver driver) { if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); + driversByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); } - driversByUniqueId.put(driver.getUniqueId(), driver); + driversByUniqueId.put(driver.getUniqueId(), driver.getId()); } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putUniqueDriverId((Driver) item); + protected void addNewItem(Driver driver) { + super.addNewItem(driver); + putUniqueDriverId(driver); } @Override - protected void updateCachedItem(BaseModel item) { - Driver driver = (Driver) item; + protected void updateCachedItem(Driver driver) { Driver cachedDriver = getById(driver.getId()); cachedDriver.setName(driver.getName()); if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { @@ -72,6 +65,6 @@ public class DriversManager extends ExtendedObjectManager { } public Driver getDriverByUniqueId(String uniqueId) { - return driversByUniqueId.get(uniqueId); + return getById(driversByUniqueId.get(uniqueId)); } } diff --git a/src/org/traccar/database/ExtendedObjectManager.java b/src/org/traccar/database/ExtendedObjectManager.java index 19c9ca5b2..16785cb37 100644 --- a/src/org/traccar/database/ExtendedObjectManager.java +++ b/src/org/traccar/database/ExtendedObjectManager.java @@ -30,13 +30,13 @@ import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.BaseModel; -public abstract class ExtendedObjectManager extends SimpleObjectManager { +public abstract class ExtendedObjectManager extends SimpleObjectManager { private final Map> deviceItems = new ConcurrentHashMap<>(); private final Map> deviceItemsWithGroups = new ConcurrentHashMap<>(); private final Map> groupItems = new ConcurrentHashMap<>(); - protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { + protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); refreshExtendedPermissions(); } diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java index 4bc3909cd..a32847cf9 100644 --- a/src/org/traccar/database/GeofenceManager.java +++ b/src/org/traccar/database/GeofenceManager.java @@ -23,17 +23,12 @@ import org.traccar.model.Device; import org.traccar.model.Geofence; import org.traccar.model.Position; -public class GeofenceManager extends ExtendedObjectManager { +public class GeofenceManager extends ExtendedObjectManager { public GeofenceManager(DataManager dataManager) { super(dataManager, Geofence.class); } - @Override - public Geofence getById(long geofenceId) { - return (Geofence) super.getById(geofenceId); - } - @Override public final void refreshExtendedPermissions() { super.refreshExtendedPermissions(); diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java index 095e7a22c..20b403d55 100644 --- a/src/org/traccar/database/GroupsManager.java +++ b/src/org/traccar/database/GroupsManager.java @@ -26,7 +26,7 @@ import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Group; -public class GroupsManager extends BaseObjectManager implements ManagableObjects { +public class GroupsManager extends BaseObjectManager implements ManagableObjects { private AtomicLong groupsLastUpdate = new AtomicLong(); private final long dataRefreshDelay; @@ -37,11 +37,6 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; } - @Override - public Group getById(long groupId) { - return (Group) super.getById(groupId); - } - private void checkGroupCycles(BaseModel group) { Set groups = new HashSet<>(); while (group != null) { @@ -76,15 +71,15 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects } @Override - protected void addNewItem(BaseModel item) { - checkGroupCycles(item); - super.addNewItem(item); + protected void addNewItem(Group group) { + checkGroupCycles(group); + super.addNewItem(group); } @Override - protected void updateCachedItem(BaseModel item) { - checkGroupCycles(item); - super.updateCachedItem(item); + protected void updateCachedItem(Group group) { + checkGroupCycles(group); + super.updateCachedItem(group); } @Override diff --git a/src/org/traccar/database/IdentityManager.java b/src/org/traccar/database/IdentityManager.java index c8c593a54..82d905963 100644 --- a/src/org/traccar/database/IdentityManager.java +++ b/src/org/traccar/database/IdentityManager.java @@ -20,9 +20,9 @@ import org.traccar.model.Position; public interface IdentityManager { - Device getDeviceById(long id); + Device getById(long id); - Device getDeviceByUniqueId(String uniqueId) throws Exception; + Device getByUniqueId(String uniqueId) throws Exception; Position getLastPosition(long deviceId); diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 54e5ed979..3b03c1900 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -18,6 +18,7 @@ package org.traccar.database; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Attribute; +import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; @@ -99,7 +100,7 @@ public class PermissionsManager { devicePermissions.clear(); try { GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Group.class, Context.getGroupsManager().getAllItems()), + Context.getGroupsManager().getAllItems()), Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); @@ -284,7 +285,7 @@ public class PermissionsManager { public void checkPermission(Class object, long userId, long objectId) throws SecurityException { - SimpleObjectManager manager = null; + SimpleObjectManager manager = null; if (object.equals(Device.class)) { checkDevice(userId, objectId); diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java index fa41f30b6..0b4d11378 100644 --- a/src/org/traccar/database/SimpleObjectManager.java +++ b/src/org/traccar/database/SimpleObjectManager.java @@ -28,11 +28,12 @@ import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.model.User; -public abstract class SimpleObjectManager extends BaseObjectManager implements ManagableObjects { +public abstract class SimpleObjectManager extends BaseObjectManager + implements ManagableObjects { private Map> userItems; - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { + protected SimpleObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); } diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index e53409b4f..28e6a31b2 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -21,10 +21,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.traccar.model.BaseModel; import org.traccar.model.User; -public class UsersManager extends SimpleObjectManager { +public class UsersManager extends SimpleObjectManager { private Map usersTokens; @@ -32,11 +31,6 @@ public class UsersManager extends SimpleObjectManager { super(dataManager, User.class); } - @Override - public User getById(long userId) { - return (User) super.getById(userId); - } - private void putToken(User user) { if (usersTokens == null) { usersTokens = new ConcurrentHashMap<>(); @@ -47,16 +41,15 @@ public class UsersManager extends SimpleObjectManager { } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putToken((User) item); + protected void addNewItem(User user) { + super.addNewItem(user); + putToken(user); } @Override - protected void updateCachedItem(BaseModel item) { - User user = (User) item; - User cachedUser = getById(item.getId()); - super.updateCachedItem(item); + protected void updateCachedItem(User user) { + User cachedUser = getById(user.getId()); + super.updateCachedItem(user); if (user.getToken() != null) { usersTokens.put(user.getToken(), user.getId()); } diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index e9a261aea..4e09bd4fa 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -31,7 +31,7 @@ public class FuelDropEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 516df9d69..79e5d0f8e 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -25,7 +25,6 @@ import org.traccar.database.GeofenceManager; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; -import org.traccar.model.Geofence; import org.traccar.model.Position; public class GeofenceEventHandler extends BaseEventHandler { @@ -38,7 +37,7 @@ public class GeofenceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } @@ -59,8 +58,8 @@ public class GeofenceEventHandler extends BaseEventHandler { Collection events = new ArrayList<>(); for (long geofenceId : newGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId()); event.setGeofenceId(geofenceId); @@ -68,8 +67,8 @@ public class GeofenceEventHandler extends BaseEventHandler { } } for (long geofenceId : oldGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId()); event.setGeofenceId(geofenceId); diff --git a/src/org/traccar/events/IgnitionEventHandler.java b/src/org/traccar/events/IgnitionEventHandler.java index c628cc107..5519135bf 100644 --- a/src/org/traccar/events/IgnitionEventHandler.java +++ b/src/org/traccar/events/IgnitionEventHandler.java @@ -29,7 +29,7 @@ public class IgnitionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MaintenanceEventHandler.java b/src/org/traccar/events/MaintenanceEventHandler.java index 86836f6af..ffeefc8c5 100644 --- a/src/org/traccar/events/MaintenanceEventHandler.java +++ b/src/org/traccar/events/MaintenanceEventHandler.java @@ -32,7 +32,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index e6fd10f3e..ed81176a8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -29,7 +29,7 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 00c3845d2..795892f40 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -37,7 +37,7 @@ public class OverspeedEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index 08f55df75..ac37f980c 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -69,7 +69,7 @@ public final class EventForwarder { data.put(KEY_POSITION, position); } if (event.getDeviceId() != 0) { - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); if (device != null) { data.put(KEY_DEVICE, device); } diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java index cd9959671..33fd2cdc7 100644 --- a/src/org/traccar/notification/NotificationFormatter.java +++ b/src/org/traccar/notification/NotificationFormatter.java @@ -40,7 +40,7 @@ public final class NotificationFormatter { public static VelocityContext prepareContext(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("user", user); diff --git a/src/org/traccar/processing/ComputedAttributesHandler.java b/src/org/traccar/processing/ComputedAttributesHandler.java index d6a762535..f1f371475 100644 --- a/src/org/traccar/processing/ComputedAttributesHandler.java +++ b/src/org/traccar/processing/ComputedAttributesHandler.java @@ -51,7 +51,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private MapContext prepareContext(Position position) { MapContext result = new MapContext(); if (mapDeviceAttributes) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device != null) { for (Object key : device.getAttributes().keySet()) { result.set((String) key, device.getAttributes().get(key)); @@ -86,7 +86,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection attributes = Context.getAttributesManager().getItems(Attribute.class, + Collection attributes = Context.getAttributesManager().getItems( Context.getAttributesManager().getAllDeviceItems(position.getDeviceId())); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 36358b6e5..186867b9d 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -555,7 +555,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getDeviceById(deviceSession.getDeviceId()); + Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg"); photos.remove(pictureId); } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 711697fc4..469ef3f76 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -160,7 +160,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } - String deviceModel = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getModel(); + String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } @@ -316,7 +316,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "D03": if (channel != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String imei = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getUniqueId(); + String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n"); } return null; diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 348e6077f..63077de32 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -88,7 +88,7 @@ public final class Events { } } DeviceReport deviceEvents = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index bc58d28df..cf94030ab 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -176,7 +176,7 @@ public final class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -210,7 +210,7 @@ public final class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index 69be55155..1c53a15cc 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -57,7 +57,7 @@ public final class Route { Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); DeviceReport deviceRoutes = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 20a6c1ce3..886fd7915 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -74,7 +74,7 @@ public final class Stops { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReport deviceStops = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 5aaf33fae..dd9877cd7 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -38,7 +38,7 @@ public final class Summary { private static SummaryReport calculateSummaryResult(long deviceId, Date from, Date to) throws SQLException { SummaryReport result = new SummaryReport(); result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); Collection positions = Context.getDataManager().getPositions(deviceId, from, to); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 7b5df0248..68b03a819 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -73,7 +73,7 @@ public final class Trips { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReport deviceTrips = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/test/org/traccar/BaseTest.java b/test/org/traccar/BaseTest.java index 6af8610cd..37956f11d 100644 --- a/test/org/traccar/BaseTest.java +++ b/test/org/traccar/BaseTest.java @@ -18,12 +18,12 @@ public class BaseTest { } @Override - public Device getDeviceById(long id) { + public Device getById(long id) { return createDevice(); } @Override - public Device getDeviceByUniqueId(String uniqueId) { + public Device getByUniqueId(String uniqueId) { return createDevice(); } -- cgit v1.2.3 From 194263a9dc8040ebcbf62c80733aca5097eb3e36 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 27 Jul 2017 01:32:21 +1200 Subject: Extend VT200 protocol decoder --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- test/org/traccar/protocol/Vt200ProtocolDecoderTest.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index b9af11b43..f9683f12f 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -57,7 +57,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // length - if (type == 0x2084) { + if (type == 0x2084 || type == 0x2082) { Position position = new Position(); position.setProtocol(getProtocolName()); diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index e61c5f9f2..d63bf0062 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -10,6 +10,21 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { Vt200ProtocolDecoder decoder = new Vt200ProtocolDecoder(new Vt200Protocol()); + verifyNull(decoder, binary( + "28631037309456008e000801042307171804584229")); + + verifyNull(decoder, binary( + "28631037309456108800002e29")); + + verifyPosition(decoder, binary( + "28631037309456208200210103302307171805444417097301147188170198090f0000073a002000007e00074429")); + + verifyNull(decoder, binary( + "286310373094563089001200032f2107171740144417075001147188872c29")); + + verifyNull(decoder, binary( + "2863103730945630880062032f862631037309456f222014604362936f21071717373221071717401400a100000cd700000004020d3c8e0000000000000000000000000000000000000000000000000000000000000000000a000000040000000e009700000cc9000000000000e929")); + verifyPosition(decoder, binary( "28631037309456208400340102dc0906171616454415760201144494473f920a0c0000030500200100417c1f383a9d1090510000006a00007000000e00180ee129")); -- cgit v1.2.3 From 566f6b0dda38da75ed1fc89c9f5d29769fc1fbe9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Aug 2017 06:53:55 +1200 Subject: Update GB100 binary decoder --- src/org/traccar/helper/BitBuffer.java | 12 +- .../protocol/Gl200BinaryProtocolDecoder.java | 221 ++++++++++++++++++++- test/org/traccar/ProtocolTest.java | 2 +- .../protocol/Gl200BinaryProtocolDecoderTest.java | 12 ++ 4 files changed, 241 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/helper/BitBuffer.java b/src/org/traccar/helper/BitBuffer.java index 7626988cc..ac307efdf 100644 --- a/src/org/traccar/helper/BitBuffer.java +++ b/src/org/traccar/helper/BitBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -20,7 +20,7 @@ import org.jboss.netty.buffer.ChannelBuffers; public class BitBuffer { - private ChannelBuffer buffer = ChannelBuffers.dynamicBuffer(); + private final ChannelBuffer buffer; private int writeByte; private int writeCount; @@ -28,6 +28,14 @@ public class BitBuffer { private int readByte; private int readCount; + public BitBuffer() { + buffer = ChannelBuffers.dynamicBuffer(); + } + + public BitBuffer(ChannelBuffer buffer) { + this.buffer = buffer; + } + public void writeEncoded(byte[] bytes) { for (byte b : bytes) { b -= 48; diff --git a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java index a7ecf40d5..071960e49 100644 --- a/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200BinaryProtocolDecoder.java @@ -19,6 +19,8 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.BitBuffer; +import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; @@ -28,6 +30,8 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.LinkedList; +import java.util.List; public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { @@ -42,12 +46,171 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { return dateBuilder.getDate(); } + public static final int MSG_RSP_LCB = 3; + public static final int MSG_RSP_GEO = 8; + public static final int MSG_RSP_COMPRESSED = 100; + + private List decodeLocation(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + + List positions = new LinkedList<>(); + + int type = buf.readUnsignedByte(); + + buf.readUnsignedInt(); // mask + buf.readUnsignedShort(); // length + buf.readUnsignedByte(); // device type + buf.readUnsignedShort(); // protocol version + buf.readUnsignedShort(); // firmware version + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, String.format("%015d", buf.readLong())); + if (deviceSession == null) { + return null; + } + + int battery = buf.readUnsignedByte(); + int power = buf.readUnsignedShort(); + + if (type == MSG_RSP_GEO) { + buf.readUnsignedByte(); // reserved + buf.readUnsignedByte(); // reserved + } + + buf.readUnsignedByte(); // motion status + int satellites = buf.readUnsignedByte(); + + if (type != MSG_RSP_COMPRESSED) { + buf.readUnsignedByte(); // index + } + + if (type == MSG_RSP_LCB) { + buf.readUnsignedByte(); // phone length + for (int b = buf.readUnsignedByte();; b = buf.readUnsignedByte()) { + if ((b & 0xf) == 0xf || (b & 0xf0) == 0xf0) { + break; + } + } + } + + if (type == MSG_RSP_COMPRESSED) { + + int count = buf.readUnsignedShort(); + + BitBuffer bits; + int speed = 0; + int heading = 0; + int latitude = 0; + int longitude = 0; + long time = 0; + + for (int i = 0; i < count; i++) { + + if (time > 0) { + time += 1; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + switch (BitUtil.from(buf.getUnsignedByte(buf.readerIndex()), 8 - 2)) { + case 1: + bits = new BitBuffer(buf.readBytes(3)); + bits.readUnsigned(2); // point attribute + bits.readUnsigned(1); // fix type + speed = bits.readUnsigned(12); + heading = bits.readUnsigned(9); + longitude = buf.readInt(); + latitude = buf.readInt(); + if (time == 0) { + time = buf.readUnsignedInt(); + } + break; + case 2: + bits = new BitBuffer(buf.readBytes(5)); + bits.readUnsigned(2); // point attribute + bits.readUnsigned(1); // fix type + speed += bits.readSigned(7); + heading += bits.readSigned(7); + longitude += bits.readSigned(12); + latitude += bits.readSigned(11); + break; + default: + buf.readUnsignedByte(); // invalid or same + continue; + } + + position.setValid(true); + position.setTime(new Date(time * 1000)); + position.setSpeed(UnitsConverter.knotsFromKph(speed * 0.1)); + position.setCourse(heading); + position.setLongitude(longitude * 0.000001); + position.setLatitude(latitude * 0.000001); + + positions.add(position); + + } + + } else { + + int count = buf.readUnsignedByte(); + + for (int i = 0; i < count; i++) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_BATTERY_LEVEL, battery); + position.set(Position.KEY_POWER, power); + position.set(Position.KEY_SATELLITES, satellites); + + int hdop = buf.readUnsignedByte(); + position.setValid(hdop > 0); + position.set(Position.KEY_HDOP, hdop); + + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); + position.setCourse(buf.readUnsignedShort()); + position.setAltitude(buf.readShort()); + position.setLongitude(buf.readInt() * 0.000001); + position.setLatitude(buf.readInt() * 0.000001); + + position.setTime(decodeTime(buf)); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedShort(), + buf.readUnsignedShort(), buf.readUnsignedShort()))); + + buf.readUnsignedByte(); // reserved + + positions.add(position); + + } + + } + + return positions; + } + + public static final int MSG_EVT_BPL = 6; + public static final int MSG_EVT_VGN = 45; + public static final int MSG_EVT_VGF = 46; + public static final int MSG_EVT_UPD = 15; + public static final int MSG_EVT_IDF = 17; + public static final int MSG_EVT_GSS = 21; + public static final int MSG_EVT_GES = 26; + public static final int MSG_EVT_GPJ = 31; + public static final int MSG_EVT_RMD = 35; + public static final int MSG_EVT_JDS = 33; + public static final int MSG_EVT_CRA = 23; + public static final int MSG_EVT_UPC = 34; + private Position decodeEvent(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { Position position = new Position(); position.setProtocol(getProtocolName()); - buf.readUnsignedByte(); // message type + int type = buf.readUnsignedByte(); + buf.readUnsignedInt(); // mask buf.readUnsignedShort(); // length buf.readUnsignedByte(); // device type @@ -67,13 +230,63 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // motion status position.set(Position.KEY_SATELLITES, buf.readUnsignedByte()); - position.set(Position.KEY_INDEX, buf.readUnsignedByte()); + + switch (type) { + case MSG_EVT_BPL: + buf.readUnsignedShort(); // backup battery voltage + break; + case MSG_EVT_VGN: + case MSG_EVT_VGF: + buf.readUnsignedShort(); // reserved + buf.readUnsignedByte(); // report type + buf.readUnsignedInt(); // ignition duration + break; + case MSG_EVT_UPD: + buf.readUnsignedShort(); // code + buf.readUnsignedByte(); // retry + break; + case MSG_EVT_IDF: + buf.readUnsignedInt(); // idling duration + break; + case MSG_EVT_GSS: + buf.readUnsignedByte(); // gps signal status + buf.readUnsignedInt(); // reserved + break; + case MSG_EVT_GES: + buf.readUnsignedShort(); // trigger geo id + buf.readUnsignedByte(); // trigger geo enable + buf.readUnsignedByte(); // trigger mode + buf.readUnsignedInt(); // radius + buf.readUnsignedInt(); // check interval + break; + case MSG_EVT_GPJ: + buf.readUnsignedByte(); // cw jamming value + buf.readUnsignedByte(); // gps jamming state + break; + case MSG_EVT_RMD: + buf.readUnsignedByte(); // roaming state + break; + case MSG_EVT_JDS: + buf.readUnsignedByte(); // jamming state + break; + case MSG_EVT_CRA: + buf.readUnsignedByte(); // crash counter + break; + case MSG_EVT_UPC: + buf.readUnsignedByte(); // command id + buf.readUnsignedShort(); // result + break; + default: + break; + } + + buf.readUnsignedByte(); // count int hdop = buf.readUnsignedByte(); position.setValid(hdop > 0); position.set(Position.KEY_HDOP, hdop); - position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium())); + position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedMedium() * 0.1)); position.setCourse(buf.readUnsignedShort()); position.setAltitude(buf.readShort()); position.setLongitude(buf.readInt() * 0.000001); @@ -179,6 +392,8 @@ public class Gl200BinaryProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; switch (buf.readBytes(4).toString(StandardCharsets.US_ASCII)) { + case "+RSP": + return decodeLocation(channel, remoteAddress, buf); case "+INF": return decodeInformation(channel, remoteAddress, buf); case "+EVT": diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index cb9cdf759..8a1602de7 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -118,7 +118,7 @@ public class ProtocolTest extends BaseTest { Assert.assertNotNull("list is null", decodedObject); Assert.assertTrue("not a list", decodedObject instanceof List); - Assert.assertFalse("list if empty", ((List) decodedObject).isEmpty()); + Assert.assertFalse("list is empty", ((List) decodedObject).isEmpty()); for (Object item : (List) decodedObject) { verifyDecodedPosition(item, checkLocation, false, expected); diff --git a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java index 24830a953..ebcd4139b 100644 --- a/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200BinaryProtocolDecoderTest.java @@ -10,6 +10,18 @@ public class Gl200BinaryProtocolDecoderTest extends ProtocolTest { Gl200BinaryProtocolDecoder decoder = new Gl200BinaryProtocolDecoder(new Gl200Protocol()); + verifyPosition(decoder, binary( + "2b4556542d00fc1fbf0063450102020956325403000343056437f8220700000200000000010000160100f2007eff75a1f0025c6b1a07e1080108241a02680003189c1ac500000000000002100800000000000000000007e1080108241a19e24e4e0d0a")); + + verifyPositions(decoder, binary( + "2b5253506400fc1fbf058e450102020956325403000343056438ed2205010e61c6f0ff75a1b4025c6af959803d8ba07ffe17dea03f7e1fdda0007df7dfa03e7e3fd0a0befdf7cea001fddfd8a000fdefdca042fd9fe1a0427d6fe9a0017db7dca0407d47e7a0027d67e5bfc0fd77eca03ffd8fe4bfff7dcfddbffd7dbfdebffdfddfe2bfbe7e0fe1bf7f7e67e2bf7bfed7e2bf7c7f5fe2bffbffc7e3a12880a7daa0b9013fe3a0f801b7dfa0bd81efe1a03f8207e0a03e8217e4a07e023fe9a0bd824feca03a02affda07b02d004a07f02e007a00002d808a041830001a003834fefa00402b7eebf8382a7ebbfc28267e9bf81821fe3bf0181d7e3bf01016fe9bf010117edbf4080c7f6bf7f8087fabfbf805ff9a0fa8097fca23401300aa0b4016019a13a817026a13b81883ea0be81a83fa0bd81b03ba00101d83abfc0039874bfc081b835bfbf819834bfc081982fa01004702ea00502500da002827802bfc0825fffbf41821fffbf4081d801bf3f816802bec180fffebec20077fdbf80002801bfc0000800a000000800e0e0a202804ffba14a8127eea0460107e4a0cc809fd9a0c4004fcda0c2004fcaa080007fbfa0410067bebfc100c7b6a03f8037c1bfbf004fc6a03f0057c6a0410027c5a081001fbaa0418017baa001001fb8a0007fe7bca000ffdfb7a0817fc7b7a040ffbfb3a0407fb7b4a0407fb7b1bf807fbfb3a0007fb7b5a0007fb7b1a0007fb7b2a0007fbfb3a0407fafaba000ffb7ada0017f97aba040ff7faca001ff77b6bf3fff67b3bf007f87bea082ff47b4bfc27f17c1bfffff3fc2bebdff9fcabe3effbfe0bf3cff47e9a03c002ff0a1740097e9a1f8813fe1a12f01f7fca0fa028ff8a07f02a7fea041829007a00302bff8bf810287f2a0080257e1a0050207dbbfc481cfd3a044819fcda043015fc3a043810fc2a0c680a7b2a0448027b0a0857fa7aea0c37f67a2a0017ee7a7a0407f0f9fa000ff079fa03ffeffa1a03ffeffa2a07fff17a0a03fff1fa0a03fff2fa2a03fff3fa0a07fff47a2a0007f579fa03fff4f9da03fff679ca0007f679ea000ff4f9ca07fff5f9ca0007f579cbfc07f5f9fbf407f6fa6bf807f6fabbfc07f7fadbf807f87b2a0407f87b0a0407f77aba000ff77afbfc07f77aea03fff7fada07fff7faca000ff7fada0007f77abbfc0ff77b0a000ff7faea042ff2faba0037ee7ada0437e57a1a0037e27abbfc1fdf7bcbf827defc5bf01fe0fcebf017e3fd5bfc17e2fdca0ff7e27d7a13cfe27cba0bd7e0fa7a07d7e6fb9a07d7eb7b3a07efedfaea03ffef7afa0c07eefa7a07f7f07a3a03fff0fa3a03f7f27a2a03f7f37a4bfff7f6fa3bfff7f5fa3a07eff979fa03f7fbfa2a03f7fdfa1bfbf8017a5bfbf0037adbeff004fb8bfbf004fc1beff804fcbbf7f8047d5bf408027debf408007e8a03e804fdebf7e8027f2bf00ffefffa0400017efa0418017f1a041002feca0410017edbf007fbffea0007fdff6a1018027e4bf81ffc7f6a1008017dca0c10087bea0018097baa083ffc7cda0837fafc7a102ff0fc8a0c27effb9a0c2fe87c1a143fbf78ea07f7dcfc0a0bd7dffb3a03d7e47b1a03ffe77afa07ffe77ada0007e77aebfc07e77afbfc07e8faea03ffea7afbfbf7ecfb4bfbcfeffbbbf7bff8fb8bf7d0027bebffb809fc7bffa00ffc9bf78813fd9a03d8197e1a03b81d7e6a07e01efdda00081bfdda00101bfdba03f81a7dfbfc001afdbbfbd81a7f1bfbe0187eebf80814feea0028127e7a081813fe2a0010147e6a03e8147f4a0408167eca040817fe7a0018157e4bfc8011fdaa08b002fd1a009ffa7d5a009fe57f6a04b7df7f4a0097e07eca0027df7edbf807e2feca000fe3feca07ffe37f0a0407e0ff7a040fde7f0a0007de7eea000fdcff4a001fddffaa000fdcff8a0027dcffda07f7dbff3a03f7dc7f402680003189c355300000109000002120700000000000000000007e1080108290019e63b5c0d0a")); + + verifyNotNull(decoder, binary( + "2B5253500300FC1FFF0064450102020867623130302D446F642F442105007018217345005F010100000001100045073C4D4101DB86BD07E106130B2B0F0460000018770013000000030000000106020F2300002714301107E106130B2B1003424EFB0D0A")); + + verifyPositions(decoder, binary( + "2b5253500700fc1fbf005d4501020209563254030003430564377e42071001000000000000007eff75a151025c6a8107e10801081a2a02680003189c1ac500000000000002100700000000000000000007e1080108241019e17ebe0d0a")); + verifyAttributes(decoder, binary( "2b494e4601fd7f0076676231303000000045010202090104020500004100054007e107150b061d0000003f010e02580000000000d0312a1013648935103226313921591f1200000000000302680003189c1ac3001b02680003189c1ac4000d02680003189c1ac5001207e107150b0d3704f658060d0a")); -- cgit v1.2.3 From 237c80296fe947c6857c9509ba1b947ed02b354f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 2 Aug 2017 07:52:33 +1200 Subject: Implement TLV communication protocol --- setup/default.xml | 1 + src/org/traccar/protocol/TlvProtocol.java | 43 ++++++++ src/org/traccar/protocol/TlvProtocolDecoder.java | 109 +++++++++++++++++++++ .../traccar/protocol/TlvProtocolDecoderTest.java | 24 +++++ 4 files changed, 177 insertions(+) create mode 100644 src/org/traccar/protocol/TlvProtocol.java create mode 100644 src/org/traccar/protocol/TlvProtocolDecoder.java create mode 100644 test/org/traccar/protocol/TlvProtocolDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/setup/default.xml b/setup/default.xml index 2c126e6dd..ff0447652 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -234,5 +234,6 @@ 5143 5144 5145 + 5146 diff --git a/src/org/traccar/protocol/TlvProtocol.java b/src/org/traccar/protocol/TlvProtocol.java new file mode 100644 index 000000000..da8d88b8a --- /dev/null +++ b/src/org/traccar/protocol/TlvProtocol.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class TlvProtocol extends BaseProtocol { + + public TlvProtocol() { + super("tlv"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder('\0')); + pipeline.addLast("objectDecoder", new TlvProtocolDecoder(TlvProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/TlvProtocolDecoder.java b/src/org/traccar/protocol/TlvProtocolDecoder.java new file mode 100644 index 000000000..41d65be09 --- /dev/null +++ b/src/org/traccar/protocol/TlvProtocolDecoder.java @@ -0,0 +1,109 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +public class TlvProtocolDecoder extends BaseProtocolDecoder { + + public TlvProtocolDecoder(TlvProtocol protocol) { + super(protocol); + } + + private void sendResponse(Channel channel, String type, String... arguments) { + if (channel != null) { + ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + response.writeBytes(ChannelBuffers.copiedBuffer(type, StandardCharsets.US_ASCII)); + for (String argument : arguments) { + response.writeByte(argument.length()); + response.writeBytes(ChannelBuffers.copiedBuffer(argument, StandardCharsets.US_ASCII)); + } + response.writeByte(0); + channel.write(response); + } + } + + private String readArgument(ChannelBuffer buf) { + return buf.readBytes(buf.readUnsignedByte()).toString(StandardCharsets.US_ASCII); + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + ChannelBuffer buf = (ChannelBuffer) msg; + + String type = buf.readBytes(2).toString(StandardCharsets.US_ASCII); + + if (channel != null) { + switch (type) { + case "0A": + case "0C": + sendResponse(channel, type); + break; + case "0B": + sendResponse(channel, type, "1482202689", "10", "20", "15"); + break; + case "0E": + case "0F": + sendResponse(channel, type, "30", "Unknown"); + break; + default: + break; + } + } + + if (type.equals("0E")) { + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, readArgument(buf)); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setValid(true); + position.setTime(new Date(Long.parseLong(readArgument(buf)) * 1000)); + + readArgument(buf); // location identifier + + position.setLongitude(Double.parseDouble(readArgument(buf))); + position.setLatitude(Double.parseDouble(readArgument(buf))); + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(readArgument(buf)))); + position.setCourse(Double.parseDouble(readArgument(buf))); + + position.set(Position.KEY_SATELLITES, Integer.parseInt(readArgument(buf))); + + return position; + + } + + return null; + } + +} diff --git a/test/org/traccar/protocol/TlvProtocolDecoderTest.java b/test/org/traccar/protocol/TlvProtocolDecoderTest.java new file mode 100644 index 000000000..6c37c4dbb --- /dev/null +++ b/test/org/traccar/protocol/TlvProtocolDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class TlvProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + TlvProtocolDecoder decoder = new TlvProtocolDecoder(new TlvProtocol()); + + verifyNull(decoder, binary( + "30430f383630323437303330303934333931ff10393233323132323030303834353433340f533636385f415f56312e30315f454eff1130303a30433a45373a30303a30303a30300132")); + + verifyNull(decoder, binary( + "30410f383630323437303330303934333931")); + + verifyNull(decoder, binary( + "30420f3836303234373033303039343339310131")); + + } + +} -- cgit v1.2.3 From f182ae04a9857e13482421957140e1a70af2302b Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2017 00:40:48 +1200 Subject: Improve VT400 protocol decoder --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- test/org/traccar/protocol/Vt200ProtocolDecoderTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index f9683f12f..111c29313 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -57,7 +57,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { int type = buf.readUnsignedShort(); buf.readUnsignedShort(); // length - if (type == 0x2084 || type == 0x2082) { + if (type == 0x2086 || type == 0x2084 || type == 0x2082) { Position position = new Position(); position.setProtocol(getProtocolName()); diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 19155af5a..37d9c46d9 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -11,13 +11,13 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { Vt200ProtocolDecoder decoder = new Vt200ProtocolDecoder(new Vt200Protocol()); verifyNull(decoder, binary( - "286310373094563082002701033d00010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); + "286310373094563082002701033d010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); - verifyNull(decoder, binary( - "286310373094562086002101033d0001081714333d15441790420114817637207d090a00000847002001207f00d6f229")); + verifyPosition(decoder, binary( + "286310373094562086002101033d010817143328441790420114817637207d090a00000847002001207f00d6f229")); - verifyNull(decoder, binary( - "286310373094562086002101033d000108171433354417932101148139772c9d080a00000847002001207f00dc6729")); + verifyPosition(decoder, binary( + "286310373094562086002101033d0108171433354417932101148139772c9d080a00000847002001207f00dc6729")); verifyNull(decoder, binary( "2863103730945600880012180108171433004418103801148375470000dd29")); -- cgit v1.2.3 From 3bc4e07dff292c22e29a1fa3bf9d07796d2e89b7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 4 Aug 2017 02:06:51 +1200 Subject: Decode GV500VC rssi value --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 8 +++++++- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 57fecc3fe..63adb1c70 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -66,7 +66,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:[^,]+)?,") // device name .number("(xx),") // state .expression("(?:[0-9F]{20})?,") // iccid - .number("d{1,2},") + .number("(d{1,2}),") // rssi .number("d{1,2},") .expression("[01],") // external power .number("([d.]+)?,") // odometer or external power @@ -388,6 +388,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { + + org.traccar.helper.PatternUtil.MatchResult matchResult = + org.traccar.helper.PatternUtil.checkPattern(PATTERN_INF.pattern(), sentence); + Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); if (position == null) { @@ -396,6 +400,8 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_STATUS, parser.next()); + position.set(Position.KEY_RSSI, parser.nextInt()); + parser.next(); // odometer or external power position.set(Position.KEY_BATTERY, parser.nextDouble(0)); diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index e694022f2..9e2571916 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyNull(decoder, buffer( + "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); + + verifyAttributes(decoder, buffer( + "+RESP:GTINF,2D0300,A1000043D20139,1G1JC5444R7252367,,11,,31,0,1,12986,,4.16,0,2,,,20170802145640,,,,,,+0000,0,20170802145643,CD5A$")); + verifyPosition(decoder, buffer( "+RESP:GTMPN,450102,865084030001323,gb100,0,1.6,0,-93.1,121.393023,31.164105,20170619103113,0460,0000,1806,2142,00,20170619103143,0512$")); -- cgit v1.2.3 From a1b426ce486cd00b08307b0ac53a2fb6d90bf724 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 5 Aug 2017 11:01:51 +1200 Subject: Fix Cradlepoint RSSI decoding --- src/org/traccar/protocol/CradlepointProtocolDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index 1ba50f04b..a1b42edf9 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -43,7 +43,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { .expression("([^,]+),") // carrier .expression("([^,]+)?,") // serdis .number("(-?d+),") // rsrp - .number("(-?d+),") // dbm + .number("(-?d+),") // rssi .number("(-?d+),") // rsrq .expression("([^,]+)?,") // ecio .expression("([^,]+)?") // wan ip @@ -75,7 +75,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); - parser.skip(4); + parser.skip(3); position.set(Position.KEY_RSSI, parser.nextDouble()); -- cgit v1.2.3 From ea1b94b524c880927f85fd0c94a26bd3ec17c898 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 10 Aug 2017 07:02:55 +1200 Subject: Support seconds for Tramigo --- src/org/traccar/protocol/TramigoProtocolDecoder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TramigoProtocolDecoder.java b/src/org/traccar/protocol/TramigoProtocolDecoder.java index b39e3eab1..b1e28e17d 100644 --- a/src/org/traccar/protocol/TramigoProtocolDecoder.java +++ b/src/org/traccar/protocol/TramigoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2017 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. @@ -130,12 +130,13 @@ public class TramigoProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(matcher.group(2)))); } - pattern = Pattern.compile("(\\d{1,2}:\\d{2} \\w{3} \\d{1,2})"); + pattern = Pattern.compile("(\\d{1,2}:\\d{2}(:\\d{2})? \\w{3} \\d{1,2})"); matcher = pattern.matcher(sentence); if (!matcher.find()) { return null; } - DateFormat dateFormat = new SimpleDateFormat("HH:mm MMM d yyyy", Locale.ENGLISH); + DateFormat dateFormat = new SimpleDateFormat( + matcher.group(2) != null ? "HH:mm:ss MMM d yyyy" : "HH:mm MMM d yyyy", Locale.ENGLISH); position.setTime(DateUtil.correctYear( dateFormat.parse(matcher.group(1) + " " + Calendar.getInstance().get(Calendar.YEAR)))); -- cgit v1.2.3 From 3562e0d927d539a1e9730c48ed376ee84ebc2b25 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 11 Aug 2017 05:03:26 +1200 Subject: Fix GL300VC decoding issue --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 6 +----- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 63adb1c70..37793a6ff 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -76,7 +76,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(?:d),") // led .number("(?:d)?,") // gps on need .number("(?:d)?,") // gps antenna type - .number("(?:d),").optional() // gps antenna state + .number("(?:d)?,").optional() // gps antenna state .number("d{14},") // last fix time .groupBegin() .number("(d+),") // battery percentage @@ -388,10 +388,6 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) { - - org.traccar.helper.PatternUtil.MatchResult matchResult = - org.traccar.helper.PatternUtil.checkPattern(PATTERN_INF.pattern(), sentence); - Parser parser = new Parser(PATTERN_INF, sentence); Position position = initPosition(parser, channel, remoteAddress); if (position == null) { diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 9e2571916..ac58049df 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,7 +10,7 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); verifyAttributes(decoder, buffer( -- cgit v1.2.3 From 8012240ac5662d8b0a2ec7907ad3f04e86b17627 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 15 Aug 2017 07:39:46 +1200 Subject: Add VT200 trip message support --- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 58 +++++++++++++++++++--- .../traccar/protocol/Vt200ProtocolDecoderTest.java | 7 ++- 2 files changed, 57 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index 111c29313..6be70c3c1 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -27,6 +27,8 @@ import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.Arrays; +import java.util.Date; public class Vt200ProtocolDecoder extends BaseProtocolDecoder { @@ -40,6 +42,13 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { return degrees + minutes * 0.0001 / 60; } + protected Date decodeDate(ChannelBuffer buf) { + DateBuilder dateBuilder = new DateBuilder() + .setDateReverse(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)) + .setTime(BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); + return dateBuilder.getDate(); + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -66,12 +75,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedByte(); // data type buf.readUnsignedShort(); // trip id - DateBuilder dateBuilder = new DateBuilder(); - dateBuilder.setDateReverse( - BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); - dateBuilder.setTime( - BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2), BcdUtil.readInteger(buf, 2)); - position.setTime(dateBuilder.getDate()); + position.setTime(decodeDate(buf)); position.setLatitude(decodeCoordinate(BcdUtil.readInteger(buf, 8))); position.setLongitude(decodeCoordinate(BcdUtil.readInteger(buf, 9))); @@ -97,6 +101,48 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type == 0x3088) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + buf.readUnsignedShort(); // trip id + buf.skipBytes(8); // imei + buf.skipBytes(8); // imsi + + position.set("tripStart", decodeDate(buf).getTime()); + position.set("tripEnd", decodeDate(buf).getTime()); + position.set("drivingTime", buf.readUnsignedShort()); + + position.set(Position.KEY_FUEL_CONSUMPTION, buf.readUnsignedInt()); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt()); + + position.set("maxSpeed", UnitsConverter.knotsFromKph(buf.readUnsignedByte())); + position.set("maxRpm", buf.readUnsignedShort()); + position.set("maxTemp", buf.readUnsignedByte() - 40); + position.set("hardAccelerationCount", buf.readUnsignedByte()); + position.set("hardBreakingCount", buf.readUnsignedByte()); + + for (String speedType : Arrays.asList("over", "high", "normal", "low")) { + position.set(speedType + "SpeedTime", buf.readUnsignedShort()); + position.set(speedType + "SpeedDistance", buf.readUnsignedInt()); + position.set(speedType + "SpeedFuel", buf.readUnsignedInt()); + } + + position.set("idleTime", buf.readUnsignedShort()); + position.set("idleFuel", buf.readUnsignedInt()); + + position.set("hardCorneringCount", buf.readUnsignedByte()); + position.set("overspeedCount", buf.readUnsignedByte()); + position.set("overheatCount", buf.readUnsignedShort()); + position.set("laneChangeCount", buf.readUnsignedByte()); + position.set("emergencyRefueling", buf.readUnsignedByte()); + + return position; + } return null; diff --git a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java index 37d9c46d9..42ed4a652 100644 --- a/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Vt200ProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "286310373094563082002701033d010817143327c68a14841e00c27f550e9a000000000c000000084700200120007d01af260b29")); + verifyAttributes(decoder, binary( + "2863103730945630880062033d862631037309456f222014604362936f010817140954010817144135076b00002a3800003b7d6127cc91040000000000000000000000005a0000088e000001ce02630000263b000009b401ff00000cb40000069c02af000018190200000102019729")); + verifyPosition(decoder, binary( "286310373094562086002101033d010817143328441790420114817637207d090a00000847002001207f00d6f229")); @@ -25,7 +28,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "28631037309456108800002e29")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "2863103730945630880062033c862631037309456f222014604362936f01081713365601081713571904c800001b2c000034f66827f0840000000000000000000000000047000006e7000001b9022a000023ff000007f2018a00000a10000003f300cd00000d8d0300000302002729")); verifyNull(decoder, binary( @@ -40,7 +43,7 @@ public class Vt200ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "286310373094563089001200032f2107171740144417075001147188872c29")); - verifyNull(decoder, binary( + verifyAttributes(decoder, binary( "2863103730945630880062032f862631037309456f222014604362936f21071717373221071717401400a100000cd700000004020d3c8e0000000000000000000000000000000000000000000000000000000000000000000a000000040000000e009700000cc9000000000000e929")); verifyPosition(decoder, binary( -- cgit v1.2.3 From 7820541530ea9891c001cbd8c53cc6340380a077 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 16 Aug 2017 07:10:33 +1200 Subject: Support new Telic format --- src/org/traccar/protocol/TelicProtocolDecoder.java | 4 ++-- test/org/traccar/ProtocolTest.java | 4 ++++ test/org/traccar/protocol/TelicFrameDecoderTest.java | 14 +++++++------- test/org/traccar/protocol/TelicProtocolDecoderTest.java | 6 ++++++ 4 files changed, 19 insertions(+), 9 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index 62b756ab5..a875009a1 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -34,8 +34,8 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("dddd") - .number("(d{6})") // device id - .number("(d+),") // type + .number("(d{6}|d{15})") // device id + .number("(dd),") // type .number("d{12},") // event time .number("d+,") .number("(dd)(dd)(dd)") // date (ddmmyy) diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index daa495a17..a2c7e4f21 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -82,6 +82,10 @@ public class ProtocolTest extends BaseTest { Assert.assertNotNull(decoder.decode(null, null, object)); } + protected void verifyNull(Object object) throws Exception { + Assert.assertNull(object); + } + protected void verifyNull(BaseProtocolDecoder decoder, Object object) throws Exception { Assert.assertNull(decoder.decode(null, null, object)); } diff --git a/test/org/traccar/protocol/TelicFrameDecoderTest.java b/test/org/traccar/protocol/TelicFrameDecoderTest.java index a091891df..711014c46 100644 --- a/test/org/traccar/protocol/TelicFrameDecoderTest.java +++ b/test/org/traccar/protocol/TelicFrameDecoderTest.java @@ -14,30 +14,30 @@ public class TelicFrameDecoderTest extends ProtocolTest { TelicFrameDecoder decoder = new TelicFrameDecoder(); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363230333339337c3232367c31307c303032303034303130"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363230333339337c3232367c31307c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "3030333032303333393332352c3139303331373038333035322c302c3138303331373130333132372c3235393932342c3434353133332c332c302c302c392c2c2c39332c31323231303134312c2c303031302c30302c34302c3234302c302c30343036"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "630000003030333032303333393332352c3139303331373038333035322c302c3138303331373130333132372c3235393932342c3434353133332c332c302c302c392c2c2c39332c31323231303134312c2c303031302c30302c34302c3234302c302c3034303600"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363239363231385343434530315f534343457c3232367c31307c30323637"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363239363231385343434530315f534343457c3232367c31307c3032363700"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "30303434323936323138544c4f43303236372c30302c3031313030393030303239363231382c3139303331373038333033362c3235353137382c3434353037322c332c302c38322c2c2c2c3136382c31343734313239362c2c30302c30302c302c323137"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "6400000030303434323936323138544c4f43303236372c30302c3031313030393030303239363231382c3139303331373038333033362c3235353137382c3434353037322c332c302c38322c2c2c2c3136382c31343734313239362c2c30302c30302c302c32313700"))); - Assert.assertNull( + verifyNull( decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "00303032363937393238317c3233327c30337c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c303032303034303130"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "303032363937393238317c3233327c30337c30303230303430313000"))); - Assert.assertEquals( + verifyFrame( binary(ByteOrder.LITTLE_ENDIAN, "3030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c30343037"), decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "650000003030323039373932383139392c3231303231363038313930302c302c3231303231363038313835392c3031333839333338352c34363635383639352c332c302c302c382c2c2c3534312c36313239382c2c303030302c30302c302c3139362c302c3034303700"))); diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 85d6f70ac..84b6a797b 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class TelicProtocolDecoderTest extends ProtocolTest { TelicProtocolDecoder decoder = new TelicProtocolDecoder(new TelicProtocol()); + verifyNull(decoder, text( + "0026355565071347499|206|01|001002008")); + + verifyPosition(decoder, text( + "002135556507134749999,010817171138,0,010817171138,004560973,50667173,3,0,0,11,1,1,100,958071,20601,000000,00,4142,0000,0000,0208,10395,0")); + verifyPosition(decoder, text( "442045993198,290317131935,0,290317131935,269158,465748,3,26,183,,,,184,85316567,226,01,00,68,218")); -- cgit v1.2.3 From 4a14edeea2b98062d1d61fe5eee5e1dfaf664916 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 18 Aug 2017 05:42:43 +1200 Subject: Implement eSky ES610 protocol --- setup/default.xml | 1 + src/org/traccar/protocol/EskyFrameDecoder.java | 39 +++++++++ src/org/traccar/protocol/EskyProtocol.java | 46 +++++++++++ src/org/traccar/protocol/EskyProtocolDecoder.java | 92 ++++++++++++++++++++++ .../org/traccar/protocol/EskyFrameDecoderTest.java | 24 ++++++ .../traccar/protocol/EskyProtocolDecoderTest.java | 18 +++++ 6 files changed, 220 insertions(+) create mode 100644 src/org/traccar/protocol/EskyFrameDecoder.java create mode 100644 src/org/traccar/protocol/EskyProtocol.java create mode 100644 src/org/traccar/protocol/EskyProtocolDecoder.java create mode 100644 test/org/traccar/protocol/EskyFrameDecoderTest.java create mode 100644 test/org/traccar/protocol/EskyProtocolDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/setup/default.xml b/setup/default.xml index edb3dd47d..0047949eb 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -236,5 +236,6 @@ 5144 5145 5146 + 5147 diff --git a/src/org/traccar/protocol/EskyFrameDecoder.java b/src/org/traccar/protocol/EskyFrameDecoder.java new file mode 100644 index 000000000..3175698fd --- /dev/null +++ b/src/org/traccar/protocol/EskyFrameDecoder.java @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +public class EskyFrameDecoder extends FrameDecoder { + + @Override + protected Object decode( + ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { + + buf.readerIndex(buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 'E')); + + int endIndex = buf.indexOf(buf.readerIndex() + 1, buf.writerIndex(), (byte) 'E'); + if (endIndex > 0) { + return buf.readBytes(endIndex - buf.readerIndex()); + } else { + return buf.readBytes(buf.readableBytes()); // assume full frame + } + } + +} diff --git a/src/org/traccar/protocol/EskyProtocol.java b/src/org/traccar/protocol/EskyProtocol.java new file mode 100644 index 000000000..4c1d11f7d --- /dev/null +++ b/src/org/traccar/protocol/EskyProtocol.java @@ -0,0 +1,46 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.BaseProtocol; +import org.traccar.TrackerServer; + +import java.util.List; + +public class EskyProtocol extends BaseProtocol { + + public EskyProtocol() { + super("esky"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new EskyFrameDecoder()); + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new EskyProtocolDecoder(EskyProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java new file mode 100644 index 000000000..c12753881 --- /dev/null +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -0,0 +1,92 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class EskyProtocolDecoder extends BaseProtocolDecoder { + + public EskyProtocolDecoder(EskyProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("EO;") // header + .number("d+;") // index + .number("(d+);") // imei + .text("R;") // data type + .number("(d+)").text("+") // satellites + .number("(dd)(dd)(dd)") // date + .number("(dd)(dd)(dd)").text("+") // time + .number("(d+.d+)").text("+") // latitude + .number("(d+.d+)").text("+") // longitude + .number("(d+.d+)").text("+") // speed + .number("(d+)").text("+") // course + .text("0x").number("(d+)").text("+") // input + .number("(d+)").text("+") // message type + .number("(d+)").text("+") // odometer + .number("(d+)") // voltage + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + org.traccar.helper.PatternUtil.MatchResult matchResult = + org.traccar.helper.PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + position.setValid(true); + position.setTime(parser.nextDateTime()); + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromMps(parser.nextDouble())); + position.setCourse(parser.nextDouble()); + + position.set(Position.KEY_INPUT, parser.nextHexInt()); + position.set(Position.KEY_EVENT, parser.nextInt()); + position.set(Position.KEY_ODOMETER, parser.nextInt()); + position.set(Position.KEY_POWER, parser.nextInt()); + + return position; + } + +} diff --git a/test/org/traccar/protocol/EskyFrameDecoderTest.java b/test/org/traccar/protocol/EskyFrameDecoderTest.java new file mode 100644 index 000000000..34a984bb2 --- /dev/null +++ b/test/org/traccar/protocol/EskyFrameDecoderTest.java @@ -0,0 +1,24 @@ +package org.traccar.protocol; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class EskyFrameDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + EskyFrameDecoder decoder = new EskyFrameDecoder(); + + verifyFrame( + binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), + decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); + + verifyFrame( + binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), + decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); + + } + +} diff --git a/test/org/traccar/protocol/EskyProtocolDecoderTest.java b/test/org/traccar/protocol/EskyProtocolDecoderTest.java new file mode 100644 index 000000000..52dff971f --- /dev/null +++ b/test/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -0,0 +1,18 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class EskyProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + EskyProtocolDecoder decoder = new EskyProtocolDecoder(new EskyProtocol()); + + verifyPosition(decoder, text( + "EO;0;864906029196626;R;0+170808155352+0.00000+0.00000+0.00+0+0x1+0+0+0+1233")); + + } + +} -- cgit v1.2.3 From e90e38d8c5db452adc5ab704a6f9dd84db16ce20 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:01:27 +1200 Subject: Advanced TK103 attributes --- src/org/traccar/model/Position.java | 1 + src/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 44 ++++++++++++++++++---- src/org/traccar/protocol/TytanProtocolDecoder.java | 2 +- .../traccar/protocol/Tk103ProtocolDecoderTest.java | 3 ++ 5 files changed, 42 insertions(+), 10 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 66a6f91ce..c188124af 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -75,6 +75,7 @@ public class Position extends Message { public static final String KEY_OPERATOR = "operator"; public static final String KEY_COMMAND = "command"; public static final String KEY_BLOCKED = "blocked"; + public static final String KEY_DOOR = "door"; public static final String KEY_DTCS = "dtcs"; public static final String KEY_OBD_SPEED = "obdSpeed"; // knots diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 186867b9d..4cf4a79eb 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -531,7 +531,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (subType == 0x05) { int flags = buf.readUnsignedByte(); - position.set("door", BitUtil.check(flags, 0)); + position.set(Position.KEY_DOOR, BitUtil.check(flags, 0)); position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); return position; diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 0106e5bf3..14278085b 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -50,7 +50,14 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d)(?:d*,)?") // speed .number("(dd)(dd)(dd),?") // time (hhmmss) .number("(d+.?d{1,2}),?") // course - .number("(?:([01]{8})|(x{8}))?,?") // state + .groupBegin() + .number("([01])") // charge + .number("([01])") // ignition + .number("(x)") // io + .number("(x)") // io + .number("(x)") // io + .number("(xxx),?") // fuel + .groupEnd("?") .number("(?:L(x+))?") // odometer .any() .number("([+-]ddd.d)?") // temperature @@ -260,15 +267,36 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble(0)); - String status = parser.next(); - if (status != null) { - position.set(Position.KEY_STATUS, status); // binary status + if (parser.hasNext(6)) { + position.set(Position.KEY_CHARGE, parser.nextInt() == 0); + position.set(Position.KEY_IGNITION, parser.nextInt() == 1); - int value = Integer.parseInt(new StringBuilder(status).reverse().toString(), 2); - position.set(Position.KEY_CHARGE, !BitUtil.check(value, 0)); - position.set(Position.KEY_IGNITION, BitUtil.check(value, 1)); + int mask1 = parser.nextHexInt(); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask1, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(mask1, 2)); + if (BitUtil.check(mask1, 3)) { + position.set(Position.KEY_BLOCKED, true); + } + + int mask2 = parser.nextHexInt(); + for (int i = 0; i < 3; i++) { + if (BitUtil.check(mask2, i)) { + position.set("hs" + (3 - i), true); + } + } + if (BitUtil.check(mask2, 3)) { + position.set(Position.KEY_DOOR, true); + } + + int mask3 = parser.nextHexInt(); + for (int i = 1; i <= 3; i++) { + if (BitUtil.check(mask3, i)) { + position.set("hs" + (3 - i + 1), true); + } + } + + position.set(Position.KEY_FUEL_LEVEL, parser.nextHexInt()); } - position.set(Position.KEY_STATUS, parser.next()); // hex status if (parser.hasNext()) { position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); diff --git a/src/org/traccar/protocol/TytanProtocolDecoder.java b/src/org/traccar/protocol/TytanProtocolDecoder.java index 030fbce78..0ae669784 100644 --- a/src/org/traccar/protocol/TytanProtocolDecoder.java +++ b/src/org/traccar/protocol/TytanProtocolDecoder.java @@ -111,7 +111,7 @@ public class TytanProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OBD_ODOMETER, buf.readUnsignedInt() * 5); break; case 150: - position.set("door", buf.readUnsignedByte()); + position.set(Position.KEY_DOOR, buf.readUnsignedByte()); break; default: buf.skipBytes(length); diff --git a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java index f2ee8ffe5..a69ff8856 100644 --- a/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Tk103ProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Tk103ProtocolDecoderTest extends ProtocolTest { Tk103ProtocolDecoder decoder = new Tk103ProtocolDecoder(new Tk103Protocol()); + verifyPosition(decoder, text( + "(007611121184BR00170816A2401.5217N07447.0788E000.0221352232.340000004FL0030F14F)")); + verifyNull(decoder, text( "(027044702512BP00027044702512HSO01A4)")); -- cgit v1.2.3 From c35598574e686e1f9e5800af2fe1da19775fffdd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:26:53 +1200 Subject: Support additional Ruptela attributes --- .../traccar/protocol/RuptelaProtocolDecoder.java | 45 ++++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java index ac95ed27a..6036397f6 100644 --- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -74,6 +74,43 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { } } + private long readValue(ChannelBuffer buf, int length, boolean signed) { + switch (length) { + case 1: + return signed ? buf.readByte() : buf.readUnsignedByte(); + case 2: + return signed ? buf.readShort() : buf.readUnsignedShort(); + case 4: + return signed ? buf.readInt() : buf.readUnsignedInt(); + default: + return buf.readLong(); + } + } + + private void decodeParameter(Position position, int id, ChannelBuffer buf, int length) { + switch (id) { + case 2: + case 3: + case 4: + position.set("di" + (id - 1), readValue(buf, length, false)); + break; + case 5: + position.set(Position.KEY_IGNITION, readValue(buf, length, false)); + break; + case 74: + position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); + break; + case 78: + case 79: + case 80: + position.set(Position.PREFIX_TEMP + (id - 78), readValue(buf, length, true) * 0.1); + break; + default: + position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + break; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -133,28 +170,28 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - position.set(Position.PREFIX_IO + id, buf.readUnsignedByte()); + decodeParameter(position, id, buf, 1); } // Read 2 byte data cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - position.set(Position.PREFIX_IO + id, buf.readUnsignedShort()); + decodeParameter(position, id, buf, 2); } // Read 4 byte data cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - position.set(Position.PREFIX_IO + id, buf.readUnsignedInt()); + decodeParameter(position, id, buf, 4); } // Read 8 byte data cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { int id = type == MSG_EXTENDED_RECORDS ? buf.readUnsignedShort() : buf.readUnsignedByte(); - position.set(Position.PREFIX_IO + id, buf.readLong()); + decodeParameter(position, id, buf, 8); } positions.add(position); -- cgit v1.2.3 From 8482304d444ebdd25901be066eaf4b5c4048a278 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:28:02 +1200 Subject: Fix Ruptela ignition --- src/org/traccar/protocol/RuptelaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/RuptelaProtocolDecoder.java b/src/org/traccar/protocol/RuptelaProtocolDecoder.java index 6036397f6..8752d30c0 100644 --- a/src/org/traccar/protocol/RuptelaProtocolDecoder.java +++ b/src/org/traccar/protocol/RuptelaProtocolDecoder.java @@ -95,7 +95,7 @@ public class RuptelaProtocolDecoder extends BaseProtocolDecoder { position.set("di" + (id - 1), readValue(buf, length, false)); break; case 5: - position.set(Position.KEY_IGNITION, readValue(buf, length, false)); + position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); break; case 74: position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); -- cgit v1.2.3 From d7725b0fb8ecde4d883a07d8bc4e77974c56eada Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 12:55:25 +1200 Subject: Add Suntech temperature support --- .../traccar/protocol/SuntechProtocolDecoder.java | 50 +++++++++++++++++++++- .../protocol/SuntechProtocolDecoderTest.java | 23 ++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 42e81f60c..93c53d2cf 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -32,18 +32,34 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { private int protocolType; private boolean hbm; + private boolean includeAdc; + private boolean includeTemp; public SuntechProtocolDecoder(SuntechProtocol protocol) { super(protocol); protocolType = Context.getConfig().getInteger(getProtocolName() + ".protocolType"); hbm = Context.getConfig().getBoolean(getProtocolName() + ".hbm"); + includeAdc = Context.getConfig().getBoolean(getProtocolName() + ".includeAdc"); + includeTemp = Context.getConfig().getBoolean(getProtocolName() + ".includeTemp"); } public void setProtocolType(int protocolType) { this.protocolType = protocolType; } + public void setHbm(boolean hbm) { + this.hbm = hbm; + } + + public void setIncludeAdc(boolean includeAdc) { + this.includeAdc = includeAdc; + } + + public void setIncludeTemp(boolean includeTemp) { + this.includeTemp = includeTemp; + } + private Position decode9( Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { int index = 1; @@ -87,7 +103,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.setValid(values[index++].equals("1")); if (protocolType == 1) { - position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index])); + position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); } return position; @@ -155,7 +171,37 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } if (index < values.length) { - position.set(Position.KEY_BATTERY, Double.parseDouble(values[index])); + position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); + } + + if (index < values.length) { + if (values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); + } + } + + if (includeAdc) { + position.set(Position.PREFIX_ADC + 1, Double.parseDouble(values[index++])); + position.set(Position.PREFIX_ADC + 2, Double.parseDouble(values[index++])); + position.set(Position.PREFIX_ADC + 3, Double.parseDouble(values[index++])); + } + + if (values.length - index >= 2) { + String driverUniqueId = values[index++]; + if (values[index++].equals("1") && !driverUniqueId.isEmpty()) { + position.set(Position.KEY_DRIVER_UNIQUE_ID, driverUniqueId); + } + } + + if (includeTemp) { + for (int i = 1; i <= 3; i++) { + String temperature = values[index++]; + String value = temperature.substring(temperature.indexOf(':') + 1); + if (!value.isEmpty()) { + position.set(Position.PREFIX_TEMP + i, Double.parseDouble(value)); + } + } + } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index a9b13b3e6..bb0710340 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -5,11 +5,34 @@ import org.traccar.ProtocolTest; public class SuntechProtocolDecoderTest extends ProtocolTest { + @Test + public void testDecodeTemperature() throws Exception { + + SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + + decoder.setHbm(true); + decoder.setIncludeAdc(true); + decoder.setIncludeTemp(true); + + /*verifyPosition(decoder, text( + "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:"));*/ + + verifyPosition(decoder, text( + "ST300STT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + verifyPosition(decoder, text( + "ST300EVT;205173382;07;564;20160322;23:23:18;232e19;+19.288278;-099.128750;000.122;000.00;9;1;478391;11.53;000100;2;1;9498;079324;4.3;1;0.00;0.00;0.00;00000000000000;0;2898E16006000058:-20.8;2861626006000039:+2.5;:")); + + } + @Test public void testDecode() throws Exception { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:")); + verifyPosition(decoder, text( "ST910;Location;205576803;500;20170319;12:18:17;-22.846014;-046.322176;000.000;000.00;0;3.8;0;1;9159")); -- cgit v1.2.3 From dd5f81b6ccaca626d07f7524abf44d8cb95b4faf Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 13:01:46 +1200 Subject: Add Suntech ST500 support --- src/org/traccar/protocol/SuntechProtocolDecoder.java | 10 ++++++---- test/org/traccar/protocol/SuntechProtocolDecoderTest.java | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 93c53d2cf..ec764774d 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -109,7 +109,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } - private Position decode23( + private Position decode235( Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException { int index = 0; @@ -132,7 +132,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } position.setDeviceId(deviceSession.getDeviceId()); - if (protocol.equals("ST300")) { + if (protocol.equals("ST300") || protocol.equals("ST500")) { index += 1; // model } @@ -142,7 +142,9 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); position.setTime(dateFormat.parse(values[index++] + values[index++])); - index += 1; // cell + if (!protocol.equals("ST500")) { + index += 1; // cell + } position.setLatitude(Double.parseDouble(values[index++])); position.setLongitude(Double.parseDouble(values[index++])); @@ -220,7 +222,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { if (protocol.equals("ST910")) { return decode9(channel, remoteAddress, values); } else { - return decode23(channel, remoteAddress, protocol, values); + return decode235(channel, remoteAddress, protocol, values); } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index bb0710340..d46ca3d34 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -30,6 +30,9 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "ST500STT;205450135;07;843;20170816;23:24:45;+19.338432;-099.179817;000.283;000.00;6;1;141121;12.89;0;0;1;4659;002.795;0;001.891;611;4.0")); + verifyPosition(decoder, text( "ST300STT;205170303;12;561;20170816;09:10:34;173f53;+19.082370;-098.214287;006.776;000.00;0;0;52982186;12.75;100000;2;6328;155747;4.2;1;0.00;0;0.00;0.00;00000000000000;0;28F2B7600600005D:+5.2;:;:")); -- cgit v1.2.3 From 128f4be3a22ec1ea9a296be05f67ce20fbdd99d0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 19 Aug 2017 18:06:49 +1200 Subject: Implement another GT06 LBS message --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 23 ++++++++++++++-------- .../traccar/protocol/Gt06ProtocolDecoderTest.java | 3 +++ 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 4cf4a79eb..d8da7e6de 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -69,6 +69,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_GPS_LBS_STATUS_1 = 0x16; public static final int MSG_GPS_LBS_STATUS_2 = 0x26; public static final int MSG_GPS_LBS_STATUS_3 = 0x27; + public static final int MSG_LBS_MULTIPLE = 0x28; public static final int MSG_LBS_WIFI = 0x2C; public static final int MSG_LBS_PHONE = 0x17; public static final int MSG_LBS_EXTEND = 0x18; @@ -406,7 +407,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); position.setProtocol(getProtocolName()); - if (type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { + if (type == MSG_LBS_MULTIPLE || type == MSG_LBS_EXTEND || type == MSG_LBS_WIFI) { DateBuilder dateBuilder = new DateBuilder(timeZone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) @@ -418,17 +419,23 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { int mnc = buf.readUnsignedByte(); Network network = new Network(); for (int i = 0; i < 7; i++) { - network.addCellTower(CellTower.from( - mcc, mnc, buf.readUnsignedShort(), buf.readUnsignedMedium(), -buf.readUnsignedByte())); + int lac = buf.readUnsignedShort(); + int cid = buf.readUnsignedMedium(); + int rssi = -buf.readUnsignedByte(); + if (lac > 0) { + network.addCellTower(CellTower.from(mcc, mnc, lac, cid, rssi)); + } } buf.readUnsignedByte(); // time leads - int wifiCount = buf.readUnsignedByte(); - for (int i = 0; i < wifiCount; i++) { - String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); - network.addWifiAccessPoint(WifiAccessPoint.from( - mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + if (type != MSG_LBS_MULTIPLE) { + int wifiCount = buf.readUnsignedByte(); + for (int i = 0; i < wifiCount; i++) { + String mac = ChannelBuffers.hexDump(buf.readBytes(6)).replaceAll("(..)", "$1:"); + network.addWifiAccessPoint(WifiAccessPoint.from( + mac.substring(0, mac.length() - 1), buf.readUnsignedByte())); + } } position.setNetwork(network); diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index 3c767c908..e449a26d4 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -16,6 +16,9 @@ public class Gt06ProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "78780D01086471700328358100093F040D0A")); + verifyNotNull(decoder, binary( + "78783b281108111002050136041bcf0000bf09000000000000000000000000000000000000000000000000000000000000000000000000ff00020007d3280d0a")); + verifyNotNull(decoder, binary( "7878412c11030b011c1f013604cb8a00b17754cb8a00bef357cb8a00b73f5fcb8900b0e25fcb8900b6655fcb8a00b74960cb8a00b178620701001801eb40393800bbbde10d0a")); -- cgit v1.2.3 From 9fb1f19aab9e4535c1c208fdd3dc0e986940b160 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Aug 2017 01:15:46 +1200 Subject: Prevent PatternUtil in production --- src/org/traccar/helper/PatternUtil.java | 7 ++++++- src/org/traccar/protocol/EskyProtocolDecoder.java | 3 --- test/org/traccar/helper/PatternUtilTest.java | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/helper/PatternUtil.java b/src/org/traccar/helper/PatternUtil.java index 12536eaef..1bbb166a6 100644 --- a/src/org/traccar/helper/PatternUtil.java +++ b/src/org/traccar/helper/PatternUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -15,6 +15,7 @@ */ package org.traccar.helper; +import java.lang.management.ManagementFactory; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -49,6 +50,10 @@ public final class PatternUtil { public static MatchResult checkPattern(String pattern, String input) { + if (!ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("-agentlib:jdwp")) { + throw new RuntimeException("PatternUtil usage detected"); + } + MatchResult result = new MatchResult(); for (int i = 0; i < pattern.length(); i++) { diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java index c12753881..0d3dcafb2 100644 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -55,9 +55,6 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - org.traccar.helper.PatternUtil.MatchResult matchResult = - org.traccar.helper.PatternUtil.checkPattern(PATTERN.pattern(), (String) msg); - Parser parser = new Parser(PATTERN, (String) msg); if (!parser.matches()) { return null; diff --git a/test/org/traccar/helper/PatternUtilTest.java b/test/org/traccar/helper/PatternUtilTest.java index b6b05e88c..77660078a 100644 --- a/test/org/traccar/helper/PatternUtilTest.java +++ b/test/org/traccar/helper/PatternUtilTest.java @@ -1,11 +1,13 @@ package org.traccar.helper; +import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.assertEquals; public class PatternUtilTest { - + + @Ignore @Test public void testCheckPattern() { -- cgit v1.2.3 From 2111f7989efcb4a80b382fb0022119413d50140d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Aug 2017 03:02:24 +1200 Subject: Improve TK103 sensor decoding --- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 24 +++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index 14278085b..de3e01faa 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -33,8 +33,11 @@ import java.util.regex.Pattern; public class Tk103ProtocolDecoder extends BaseProtocolDecoder { + private boolean decodeLow; + public Tk103ProtocolDecoder(Tk103Protocol protocol) { super(protocol); + decodeLow = Context.getConfig().getBoolean(getProtocolName() + ".decodeLow"); } private static final Pattern PATTERN = new PatternBuilder() @@ -272,26 +275,27 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, parser.nextInt() == 1); int mask1 = parser.nextHexInt(); - position.set(Position.PREFIX_IN + 2, BitUtil.check(mask1, 0)); - position.set(Position.PREFIX_OUT + 2, BitUtil.check(mask1, 2)); - if (BitUtil.check(mask1, 3)) { - position.set(Position.KEY_BLOCKED, true); + position.set(Position.PREFIX_IN + 2, BitUtil.check(mask1, 0) ? 1 : 0); + position.set("panic", BitUtil.check(mask1, 1) ? 1 : 0); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(mask1, 2) ? 1 : 0); + if (decodeLow || BitUtil.check(mask1, 3)) { + position.set(Position.KEY_BLOCKED, BitUtil.check(mask1, 3) ? 1 : 0); } int mask2 = parser.nextHexInt(); for (int i = 0; i < 3; i++) { - if (BitUtil.check(mask2, i)) { - position.set("hs" + (3 - i), true); + if (decodeLow || BitUtil.check(mask2, i)) { + position.set("hs" + (3 - i), BitUtil.check(mask2, i) ? 1 : 0); } } - if (BitUtil.check(mask2, 3)) { - position.set(Position.KEY_DOOR, true); + if (decodeLow || BitUtil.check(mask2, 3)) { + position.set(Position.KEY_DOOR, BitUtil.check(mask2, 3) ? 1 : 0); } int mask3 = parser.nextHexInt(); for (int i = 1; i <= 3; i++) { - if (BitUtil.check(mask3, i)) { - position.set("hs" + (3 - i + 1), true); + if (decodeLow || BitUtil.check(mask3, i)) { + position.set("hs" + (3 - i + 1), BitUtil.check(mask3, i) ? 1 : 0); } } -- cgit v1.2.3 From baf9c062836987e5316341279c3063a63983725f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 21 Aug 2017 03:41:21 +1200 Subject: Rename TK103 attributes --- src/org/traccar/protocol/Tk103ProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index de3e01faa..aa75f5675 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -295,7 +295,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { int mask3 = parser.nextHexInt(); for (int i = 1; i <= 3; i++) { if (decodeLow || BitUtil.check(mask3, i)) { - position.set("hs" + (3 - i + 1), BitUtil.check(mask3, i) ? 1 : 0); + position.set("ls" + (3 - i + 1), BitUtil.check(mask3, i) ? 1 : 0); } } -- cgit v1.2.3 From 7b486504294329c6ac9f6395e3c6b7ca7000acd7 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 22 Aug 2017 05:43:54 +1200 Subject: Support Chainway CW801 and CW701 --- src/org/traccar/protocol/CarscopProtocolDecoder.java | 8 ++++++-- test/org/traccar/protocol/CarscopProtocolDecoderTest.java | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CarscopProtocolDecoder.java b/src/org/traccar/protocol/CarscopProtocolDecoder.java index ac3df1cd7..2a081bcdd 100644 --- a/src/org/traccar/protocol/CarscopProtocolDecoder.java +++ b/src/org/traccar/protocol/CarscopProtocolDecoder.java @@ -44,8 +44,10 @@ public class CarscopProtocolDecoder extends BaseProtocolDecoder { .number("(ddd.d)") // speed .number("(dd)(dd)(dd)") // date (yymmdd) .number("(ddd.dd)") // course + .groupBegin() .number("(d{8})") // state .number("L(d{6})") // odometer + .groupEnd("?") .compile(); @Override @@ -88,8 +90,10 @@ public class CarscopProtocolDecoder extends BaseProtocolDecoder { position.setCourse(parser.nextDouble(0)); - position.set(Position.KEY_STATUS, parser.next()); - position.set(Position.KEY_ODOMETER, parser.nextInt(0)); + if (parser.hasNext(2)) { + position.set(Position.KEY_STATUS, parser.next()); + position.set(Position.KEY_ODOMETER, parser.nextInt(0)); + } return position; } diff --git a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java index 2d6ea208f..7b6f2f28d 100644 --- a/test/org/traccar/protocol/CarscopProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CarscopProtocolDecoderTest.java @@ -11,6 +11,12 @@ public class CarscopProtocolDecoderTest extends ProtocolTest { CarscopProtocolDecoder decoder = new CarscopProtocolDecoder(new CarscopProtocol()); verifyNull(decoder, text( + "*170821223045UB00HSO")); + + verifyPosition(decoder, text( + "*170821223121UB05ORANGE000731512061825V0000.0000N00000.0000E000.0040331309.62")); + + verifyPosition(decoder, text( "*170724163029UB05ORANGE000000010061825V0000.0000N00000.0000E000.0040331309.62")); verifyNull(decoder, text( -- cgit v1.2.3 From ebd193d4d5a98f7b53cc229f1c7287d05465b13e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 23 Aug 2017 00:51:38 +1200 Subject: Handle eSky negative coords --- src/org/traccar/protocol/EskyProtocolDecoder.java | 4 ++-- test/org/traccar/protocol/EskyFrameDecoderTest.java | 4 ++++ test/org/traccar/protocol/EskyProtocolDecoderTest.java | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/EskyProtocolDecoder.java b/src/org/traccar/protocol/EskyProtocolDecoder.java index 0d3dcafb2..d524224af 100644 --- a/src/org/traccar/protocol/EskyProtocolDecoder.java +++ b/src/org/traccar/protocol/EskyProtocolDecoder.java @@ -40,8 +40,8 @@ public class EskyProtocolDecoder extends BaseProtocolDecoder { .number("(d+)").text("+") // satellites .number("(dd)(dd)(dd)") // date .number("(dd)(dd)(dd)").text("+") // time - .number("(d+.d+)").text("+") // latitude - .number("(d+.d+)").text("+") // longitude + .number("(-?d+.d+)").text("+") // latitude + .number("(-?d+.d+)").text("+") // longitude .number("(d+.d+)").text("+") // speed .number("(d+)").text("+") // course .text("0x").number("(d+)").text("+") // input diff --git a/test/org/traccar/protocol/EskyFrameDecoderTest.java b/test/org/traccar/protocol/EskyFrameDecoderTest.java index 34a984bb2..e8902e8be 100644 --- a/test/org/traccar/protocol/EskyFrameDecoderTest.java +++ b/test/org/traccar/protocol/EskyFrameDecoderTest.java @@ -11,6 +11,10 @@ public class EskyFrameDecoderTest extends ProtocolTest { EskyFrameDecoder decoder = new EskyFrameDecoder(); + verifyFrame( + binary("454c3b313b3836343930363032393139363632363b3137303832323134333432363b"), + decoder.decode(null, null, binary("454c3b313b3836343930363032393139363632363b3137303832323134333432363b"))); + verifyFrame( binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"), decoder.decode(null, null, binary("454f3b303b3836343930363032393139363632363b523b302b3137303830383135353335322b302e30303030302b302e30303030302b302e30302b302b3078312b302b302b302b31323333"))); diff --git a/test/org/traccar/protocol/EskyProtocolDecoderTest.java b/test/org/traccar/protocol/EskyProtocolDecoderTest.java index 52dff971f..0617ba8a9 100644 --- a/test/org/traccar/protocol/EskyProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EskyProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class EskyProtocolDecoderTest extends ProtocolTest { EskyProtocolDecoder decoder = new EskyProtocolDecoder(new EskyProtocol()); + verifyNull(decoder, text( + "EL;1;864906029196626;170822143426;")); + + verifyPosition(decoder, text( + "EO;0;864906029196626;R;7+170822143646+-26.10806+27.94600+0.40+0+0x1+0+102540+0+1242")); + verifyPosition(decoder, text( "EO;0;864906029196626;R;0+170808155352+0.00000+0.00000+0.00+0+0x1+0+0+0+1233")); -- cgit v1.2.3 From 819bca366f89f237f19e52b7a916895ed1761fb9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 26 Aug 2017 09:41:37 +1200 Subject: Decode negative temperature --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 37793a6ff..3bee39cc4 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -614,7 +614,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { for (int i = 1; i <= deviceCount; i++) { index++; // id index++; // type - position.set(Position.PREFIX_TEMP + i, Short.parseShort(data[index++], 16) * 0.0625); + position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index++], 16) * 0.0625); } } } diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index ac58049df..6796f48ee 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyPositions(decoder, buffer( + "+RESP:GTERI,060502,861074023620928,,00000002,27822,10,1,1,0.0,84,2870.9,-78.531796,-0.277329,20170825045344,,,,,,0.0,01138:30:24,,,83,220104,2,1,28FF2776A2150308,1,FFAD,0,20170825045348,A88C$")); + verifyAttributes(decoder, buffer( "+RESP:GTINF,280500,A1000043D20139,GL300VC,41,,31,0,0,,,3.87,0,1,1,,,20170802150751,70,,48.0,,,20170802112145,03AC$")); -- cgit v1.2.3 From 29f7a148e1ca09e0b0667b42776fe6d5e9c26502 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 27 Aug 2017 00:25:38 +1200 Subject: Add new VT1000 alarms (fix #3477) --- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index dbbf61f71..1442f162b 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -194,10 +194,16 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_MOVEMENT; case 0x13: return Position.ALARM_GEOFENCE_ENTER; + case 0x14: + return Position.ALARM_ACCIDENT; case 0x50: return Position.ALARM_POWER_OFF; case 0x53: return Position.ALARM_GPS_ANTENNA_CUT; + case 0x72: + return Position.ALARM_BREAKING; + case 0x73: + return Position.ALARM_ACCELERATION; default: return null; } -- cgit v1.2.3 From 2e6c2fd5a6ed500f3d169131295fc8c5923e81b2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 28 Aug 2017 02:27:03 +1200 Subject: Implement VT1000 inputs (fix #3477) --- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 1442f162b..b9725337b 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -359,7 +359,13 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.setProtocol(getProtocolName()); if (command == MSG_ALARM) { - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + short alarmCode = buf.readUnsignedByte(); + position.set(Position.KEY_ALARM, decodeAlarm(alarmCode)); + if (alarmCode >= 0x02 && alarmCode <= 0x05) { + position.set(Position.PREFIX_IN + alarmCode, 1); + } else if (alarmCode >= 0x32 && alarmCode <= 0x35) { + position.set(Position.PREFIX_IN + (alarmCode - 0x30), 0); + } } else if (command == MSG_POSITION_LOGGED) { buf.skipBytes(6); } -- cgit v1.2.3 From 1756cad4ad66f1b5e932c51a8c0891e27d705ec6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 28 Aug 2017 02:58:43 +1200 Subject: Save Watch movement alert as motion --- src/org/traccar/protocol/WatchProtocolDecoder.java | 8 +++++--- test/org/traccar/protocol/WatchProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index 57f5d7e78..adab65245 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -76,8 +76,6 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_GEOFENCE_ENTER; } else if (BitUtil.check(status, 3)) { return Position.ALARM_OVERSPEED; - } else if (BitUtil.check(status, 4)) { - return Position.ALARM_MOVEMENT; } else if (BitUtil.check(status, 16)) { return Position.ALARM_SOS; } else if (BitUtil.check(status, 17)) { @@ -209,7 +207,11 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { position.set("steps", parser.nextInt(0)); - position.set(Position.KEY_ALARM, decodeAlarm(parser.nextHexInt(0))); + int status = parser.nextHexInt(0); + position.set(Position.KEY_ALARM, decodeAlarm(status)); + if (BitUtil.check(status, 4)) { + position.set(Position.KEY_MOTION, true); + } decodeTail(position, parser.next()); diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java index ef77857a3..c960ccc25 100644 --- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(new WatchProtocol()); + verifyPosition(decoder, buffer( + "[3G*8308373902*0080*AL,230817,095346,A,47.083950,N,15.4821850,E,7.60,273.8,0.0,4,15,44,0,0,00200010,2,255,232,1,7605,42530,118,7605,58036,119,0,65.8]")); + verifyPosition(decoder, buffer( "[SG*9051007430*006C*UD,150817,132115,V,28.435142,N,81.354333,W,2.2038,000,99,00,70,100,0,50,00000000,1,1,310,260,1091,30082,139,,00]")); -- cgit v1.2.3 From 879a25f09033068eb8cb174c1cb3150df594f2e4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 28 Aug 2017 07:56:40 +1200 Subject: Make T55 response optional --- src/org/traccar/protocol/T55ProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index dee7210b1..43e1a57f7 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -30,8 +31,11 @@ import java.util.regex.Pattern; public class T55ProtocolDecoder extends BaseProtocolDecoder { + private final boolean ack; + public T55ProtocolDecoder(T55Protocol protocol) { super(protocol); + ack = Context.getConfig().getBoolean(getProtocolName() + ".ack"); } private static final Pattern PATTERN_GPRMC = new PatternBuilder() @@ -98,7 +102,7 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { private Position decodeGprmc( DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - if (channel != null && !(channel instanceof DatagramChannel)) { + if (ack && channel != null && !(channel instanceof DatagramChannel)) { channel.write("OK1\r\n"); } -- cgit v1.2.3 From b90dfecfdc127d1870f5f61db177f8d63fb9a095 Mon Sep 17 00:00:00 2001 From: Anshul Jain Date: Mon, 28 Aug 2017 11:15:03 +0530 Subject: Fix for Gt06 GPS data length can not be greater than 12. Fix for Alarm packet LBS length skip for 9. --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index d8da7e6de..dbbaeaf03 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -182,6 +182,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (length > 0) { + if (length > 12) { + length = 12; + } buf.skipBytes(length - 12); // skip reserved } @@ -202,7 +205,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); if (length > 0) { - buf.skipBytes(length - 8); + if (hasLength) { + buf.skipBytes(length - 9); + } else { + buf.skipBytes(length - 8); + } } return true; -- cgit v1.2.3 From 538ef8e3f04dd4108b16dc39f3df3e535c7dea7f Mon Sep 17 00:00:00 2001 From: Anshul Jain Date: Mon, 28 Aug 2017 14:10:13 +0530 Subject: Added new column to determine for extended or basic decode. --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index dbbaeaf03..cf2b8c928 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -191,7 +191,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) { + private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength, boolean isExtended) { int length = 0; if (hasLength) { @@ -205,7 +205,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); if (length > 0) { - if (hasLength) { + if (hasLength && !isExtended) { buf.skipBytes(length - 9); } else { buf.skipBytes(length - 8); @@ -468,7 +468,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); + decodeLbs(position, buf, hasStatus(type), false); } if (hasStatus(type)) { @@ -580,7 +580,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } - decodeLbs(position, buf, true); + decodeLbs(position, buf, true, true); buf.skipBytes(buf.readUnsignedByte()); // additional cell towers buf.skipBytes(buf.readUnsignedByte()); // wifi access point -- cgit v1.2.3 From dc00df637dedfc706e13778937a2fd1ddb38ed3d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 29 Aug 2017 02:51:05 +1200 Subject: Use correct E3 speed units --- src/org/traccar/protocol/EasyTrackProtocolDecoder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java index f44c91c4a..799254b65 100644 --- a/src/org/traccar/protocol/EasyTrackProtocolDecoder.java +++ b/src/org/traccar/protocol/EasyTrackProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2017 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. @@ -22,6 +22,7 @@ import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; @@ -92,7 +93,7 @@ public class EasyTrackProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(parser.nextHexInt(0) / 600000.0); } - position.setSpeed(parser.nextHexInt(0) / 100.0); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextHexInt(0) / 100.0)); position.setCourse(parser.nextHexInt(0) / 100.0); position.set(Position.KEY_STATUS, parser.next()); -- cgit v1.2.3 From 0a8d0110d5d3876a292d6ea8213e62e4bb98c252 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 29 Aug 2017 04:56:25 +1200 Subject: Save single position when ignore fix time --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 3bee39cc4..e05182022 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -562,6 +562,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_FUEL_LEVEL, parser.nextInt()); decodeDeviceTime(position, parser); + if (ignoreFixTime) { + positions.clear(); + positions.add(position); + } return positions; } @@ -620,6 +624,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { } decodeDeviceTime(position, parser); + if (ignoreFixTime) { + positions.clear(); + positions.add(position); + } return positions; } -- cgit v1.2.3 From ff949b7ee233cd343f1fb5bb5ef7db7f24991df0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 29 Aug 2017 05:16:55 +1200 Subject: Fix eeLink status decoding --- .../traccar/protocol/EelinkProtocolDecoder.java | 37 +++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index e16866977..11d111e54 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -131,22 +131,37 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { position.setValid((buf.readUnsignedByte() & 0x01) != 0); - if (type == MSG_ALARM) { - position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - } + if (type == MSG_GPS) { - if (buf.readableBytes() >= 2) { - decodeStatus(position, buf.readUnsignedShort()); - } + if (buf.readableBytes() >= 2) { + decodeStatus(position, buf.readUnsignedShort()); + } + + if (buf.readableBytes() >= 2 * 4) { + + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + + position.set(Position.KEY_RSSI, buf.readUnsignedShort()); - if (buf.readableBytes() >= 2 * 4) { + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + } + + } else if (type == MSG_ALARM) { + + position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); - position.set(Position.KEY_RSSI, buf.readUnsignedShort()); + } else if (type == MSG_STATE) { - position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); - position.set(Position.PREFIX_ADC + 2, buf.readUnsignedShort()); + int statusType = buf.readUnsignedByte(); + + position.set(Position.KEY_EVENT, statusType); + + if (statusType == 0x01 || statusType == 0x02 || statusType == 0x03) { + buf.readUnsignedInt(); // device time + decodeStatus(position, buf.readUnsignedShort()); + } } -- cgit v1.2.3 From ac2d2723086b086d8c27a533b6f7c4888d04e63b Mon Sep 17 00:00:00 2001 From: Anshul Jain Date: Tue, 29 Aug 2017 13:22:10 +0530 Subject: Move extended LBS data to skip in decodeExtended instead of decodeLBS. --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index cf2b8c928..5c83f9348 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -191,7 +191,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return true; } - private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength, boolean isExtended) { + private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) { int length = 0; if (hasLength) { @@ -205,11 +205,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(), buf.readUnsignedByte(), buf.readUnsignedShort(), buf.readUnsignedMedium()))); if (length > 0) { - if (hasLength && !isExtended) { - buf.skipBytes(length - 9); - } else { - buf.skipBytes(length - 8); - } + buf.skipBytes(length - (hasLength ? 9 : 8)); } return true; @@ -468,7 +464,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type), false); + decodeLbs(position, buf, hasStatus(type)); + buf.skipBytes(-1); } if (hasStatus(type)) { @@ -580,7 +577,9 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, position.getDeviceTime()); } - decodeLbs(position, buf, true, true); + if (decodeLbs(position, buf, true)) { + buf.skipBytes(1); //Extended data + } buf.skipBytes(buf.readUnsignedByte()); // additional cell towers buf.skipBytes(buf.readUnsignedByte()); // wifi access point -- cgit v1.2.3 From 561915e44fdf630ac10fdc8e4a207e384ea59d9a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 29 Aug 2017 20:37:47 +1200 Subject: Minor GT06 decoder cleanup --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 5c83f9348..ec3cec533 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -181,13 +181,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(flags, 15)); } - if (length > 0) { - if (length > 12) { - length = 12; - } - buf.skipBytes(length - 12); // skip reserved - } - return true; } @@ -578,7 +571,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (decodeLbs(position, buf, true)) { - buf.skipBytes(1); //Extended data + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); } buf.skipBytes(buf.readUnsignedByte()); // additional cell towers -- cgit v1.2.3 From eef6dcea77898d5a917b225cfc8260ed88309a34 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 29 Aug 2017 16:21:49 +0500 Subject: Implement osmand.speedUnits patameter --- src/org/traccar/protocol/OsmAndProtocolDecoder.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 6f8513c41..222369f58 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2017 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. @@ -25,7 +25,9 @@ import org.jboss.netty.handler.codec.http.HttpVersion; import org.jboss.netty.handler.codec.http.QueryStringDecoder; import org.joda.time.format.ISODateTimeFormat; import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; @@ -38,8 +40,11 @@ import java.util.Map; public class OsmAndProtocolDecoder extends BaseProtocolDecoder { + private String speedUnits; + public OsmAndProtocolDecoder(OsmAndProtocol protocol) { super(protocol); + speedUnits = Context.getConfig().getString("osmand.speedUnits", "kn"); } private void sendResponse(Channel channel, HttpResponseStatus status) { @@ -110,7 +115,19 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(Double.parseDouble(location[1])); break; case "speed": - position.setSpeed(Double.parseDouble(value)); + switch (speedUnits) { + case "kph": + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); + break; + case "mps": + position.setSpeed(UnitsConverter.knotsFromMps(Double.parseDouble(value))); + break; + case "mph": + position.setSpeed(UnitsConverter.knotsFromMph(Double.parseDouble(value))); + break; + default: + position.setSpeed(Double.parseDouble(value)); + } break; case "bearing": case "heading": -- cgit v1.2.3 From 72d35d6c63ff80353eae1559d5c5d71c94d137bb Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 29 Aug 2017 17:06:14 +0500 Subject: Move common speed converting code to BaseProtocolDecoder --- src/org/traccar/BaseProtocolDecoder.java | 15 +++++++++++++++ src/org/traccar/protocol/OsmAndProtocolDecoder.java | 19 +------------------ src/org/traccar/protocol/Tk103ProtocolDecoder.java | 13 +------------ src/org/traccar/protocol/XexunProtocolDecoder.java | 11 +---------- 4 files changed, 18 insertions(+), 40 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index cc16000f4..2d6286bf8 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.socket.DatagramChannel; import org.jboss.netty.handler.codec.http.HttpRequestDecoder; import org.traccar.helper.Log; +import org.traccar.helper.UnitsConverter; import org.traccar.model.Device; import org.traccar.model.Position; @@ -66,6 +67,20 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { return protocol.getName(); } + protected double convertSpeed(double value, String defaultUnits) { + switch (Context.getConfig().getString(getProtocolName() + ".speed", defaultUnits)) { + case "kmh": + return UnitsConverter.knotsFromKph(value); + case "mps": + return UnitsConverter.knotsFromMps(value); + case "mph": + return UnitsConverter.knotsFromMph(value); + case "kn": + default: + return value; + } + } + private DeviceSession channelDeviceSession; // connection-based protocols private Map addressDeviceSessions = new HashMap<>(); // connectionless protocols diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index 222369f58..c06582a15 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -25,9 +25,7 @@ import org.jboss.netty.handler.codec.http.HttpVersion; import org.jboss.netty.handler.codec.http.QueryStringDecoder; import org.joda.time.format.ISODateTimeFormat; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; -import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; import java.net.SocketAddress; @@ -40,11 +38,8 @@ import java.util.Map; public class OsmAndProtocolDecoder extends BaseProtocolDecoder { - private String speedUnits; - public OsmAndProtocolDecoder(OsmAndProtocol protocol) { super(protocol); - speedUnits = Context.getConfig().getString("osmand.speedUnits", "kn"); } private void sendResponse(Channel channel, HttpResponseStatus status) { @@ -115,19 +110,7 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(Double.parseDouble(location[1])); break; case "speed": - switch (speedUnits) { - case "kph": - position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(value))); - break; - case "mps": - position.setSpeed(UnitsConverter.knotsFromMps(Double.parseDouble(value))); - break; - case "mph": - position.setSpeed(UnitsConverter.knotsFromMph(Double.parseDouble(value))); - break; - default: - position.setSpeed(Double.parseDouble(value)); - } + position.setSpeed(convertSpeed(Double.parseDouble(value), "kn")); break; case "bearing": case "heading": diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index aa75f5675..be3def453 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.java @@ -23,7 +23,6 @@ import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; -import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; import org.traccar.model.Position; @@ -253,17 +252,7 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - switch (Context.getConfig().getString(getProtocolName() + ".speed", "kmh")) { - case "kn": - position.setSpeed(parser.nextDouble(0)); - break; - case "mph": - position.setSpeed(UnitsConverter.knotsFromMph(parser.nextDouble(0))); - break; - default: - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - break; - } + position.setSpeed(convertSpeed(parser.nextDouble(0), "kmh")); dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); position.setTime(dateBuilder.getDate()); diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index 20804bbb4..a5a38c370 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -17,13 +17,11 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; -import org.traccar.Context; import org.traccar.DeviceSession; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; -import org.traccar.helper.UnitsConverter; import java.net.SocketAddress; import java.util.regex.Pattern; @@ -121,14 +119,7 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - switch (Context.getConfig().getString(getProtocolName() + ".speed", "kn")) { - case "kmh": - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); - break; - default: - position.setSpeed(parser.nextDouble(0)); - break; - } + position.setSpeed(convertSpeed(parser.nextDouble(0), "kn")); position.setCourse(parser.nextDouble(0)); -- cgit v1.2.3 From 7153cce6c715caed906f5e274f8ce50342926262 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 1 Sep 2017 23:43:57 +1200 Subject: Enable UDP for H02 protocol --- src/org/traccar/protocol/H02Protocol.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02Protocol.java b/src/org/traccar/protocol/H02Protocol.java index df64402f8..66965e9db 100644 --- a/src/org/traccar/protocol/H02Protocol.java +++ b/src/org/traccar/protocol/H02Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.string.StringEncoder; @@ -50,5 +51,13 @@ public class H02Protocol extends BaseProtocol { pipeline.addLast("objectDecoder", new H02ProtocolDecoder(H02Protocol.this)); } }); + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("stringEncoder", new StringEncoder()); + pipeline.addLast("objectEncoder", new H02ProtocolEncoder()); + pipeline.addLast("objectDecoder", new H02ProtocolDecoder(H02Protocol.this)); + } + }); } } -- cgit v1.2.3 From 9bb5da56efe20fcf618751d5bb02bf19ba215c74 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 2 Sep 2017 09:52:27 +1200 Subject: Fix code analysis issues --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 4 +--- src/org/traccar/protocol/SuntechProtocolDecoder.java | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index ec3cec533..6c164386d 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -155,9 +155,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return false; } - int length = buf.readUnsignedByte(); - position.set(Position.KEY_SATELLITES, BitUtil.to(length, 4)); - length = BitUtil.from(length, 4); + position.set(Position.KEY_SATELLITES, BitUtil.to(buf.readUnsignedByte(), 4)); double latitude = buf.readUnsignedInt() / 60.0 / 30000.0; double longitude = buf.readUnsignedInt() / 60.0 / 30000.0; diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index ec764774d..68c920899 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -176,10 +176,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, Double.parseDouble(values[index++])); } - if (index < values.length) { - if (values[index++].equals("0")) { - position.set(Position.KEY_ARCHIVE, true); - } + if (index < values.length && values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); } if (includeAdc) { -- cgit v1.2.3 From 1c807549e315d04054b4803518d2624591976324 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 3 Sep 2017 14:09:17 +1200 Subject: Implement Watch custom command --- src/org/traccar/protocol/WatchProtocol.java | 1 + src/org/traccar/protocol/WatchProtocolEncoder.java | 2 ++ test/org/traccar/protocol/WatchProtocolEncoderTest.java | 7 +++++++ 3 files changed, 10 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index 42a640b85..2be2dc9ae 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -29,6 +29,7 @@ public class WatchProtocol extends BaseProtocol { public WatchProtocol() { super("watch"); setSupportedDataCommands( + Command.TYPE_CUSTOM, Command.TYPE_POSITION_SINGLE, Command.TYPE_POSITION_PERIODIC, Command.TYPE_SOS_NUMBER, diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index c5d8fad86..6fcd109c2 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -97,6 +97,8 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin protected Object encodeCommand(Command command) { switch (command.getType()) { + case Command.TYPE_CUSTOM: + return formatCommand(command, command.getString(Command.KEY_DATA)); case Command.TYPE_POSITION_SINGLE: return formatCommand(command, "RG"); case Command.TYPE_SOS_NUMBER: diff --git a/test/org/traccar/protocol/WatchProtocolEncoderTest.java b/test/org/traccar/protocol/WatchProtocolEncoderTest.java index a7c360d7f..7184d278e 100644 --- a/test/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -32,6 +32,12 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command.set(Command.KEY_DATA, "3333"); Assert.assertEquals("[CS*123456789012345*0005*TK,33]", encoder.encodeCommand(command)); + command = new Command(); + command.setDeviceId(1); + command.setType(Command.TYPE_CUSTOM); + command.set(Command.KEY_DATA, "WORK,6-9,11-13,13-15,17-19"); + Assert.assertEquals("[CS*123456789012345*001a*WORK,6-9,11-13,13-15,17-19]", encoder.encodeCommand(command)); + command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); @@ -46,6 +52,7 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command.set(Command.KEY_TIMEZONE, -11 * 60 * 60 - 30 * 60); Assert.assertEquals("[CS*123456789012345*0009*LZ,,-11.5]", encoder.encodeCommand(command)); + } } -- cgit v1.2.3 From 9379a48aee811cf6fe467581778c07ee253c195f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Sep 2017 03:55:55 +1200 Subject: Implement proper TRV response --- src/org/traccar/protocol/TrvProtocolDecoder.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java index 88ac76134..1783bce73 100644 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/org/traccar/protocol/TrvProtocolDecoder.java @@ -84,11 +84,14 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { String type = sentence.substring(id.length(), id.length() + 4); if (channel != null) { + String responseHeader = id + (char) (type.charAt(0) + 1) + type.substring(1); if (type.equals("AP00") && id.equals("IW")) { String time = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); - channel.write(id + (char) (type.charAt(0) + 1) + type.substring(1) + "," + time + ",0#"); + channel.write(responseHeader + "," + time + ",0#"); + } else if (type.equals("AP14")) { + channel.write(responseHeader + ",0.000,0.000#"); } else { - channel.write(id + (char) (type.charAt(0) + 1) + type.substring(1) + "#"); + channel.write(responseHeader + "#"); } } -- cgit v1.2.3 From d0ed5e6964a5e44793b8c72106f09e4ce147f47d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Sep 2017 05:19:40 +1200 Subject: Support CK300 device protocol --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 18 ++++++++++++++++-- .../traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index e05182022..988fd71c8 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -80,7 +80,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("d{14},") // last fix time .groupBegin() .number("(d+),") // battery percentage - .expression("[01]?,") // flash type + .number("[d.]*,") // flash type / power .number("(-?[d.]+)?,,,") // temperature .or() .expression("(?:[01])?,").optional() // pin15 mode @@ -394,7 +394,21 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return null; } - position.set(Position.KEY_STATUS, parser.next()); + String status = parser.next(); + + if (status.charAt(0) == '2') { + position.set(Position.KEY_IGNITION, true); + } else if (status.charAt(0) == '4') { + position.set(Position.KEY_IGNITION, false); + } + + if (status.charAt(1) == '1') { + position.set(Position.KEY_MOTION, false); + } else if (status.charAt(1) == '2') { + position.set(Position.KEY_MOTION, true); + } + + position.set(Position.KEY_STATUS, status); position.set(Position.KEY_RSSI, parser.nextInt()); diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index cb515a73e..812973fb8 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,210102,354524044950583,,42,89011702272048900184,11,99,0,,,4.08,0,1,1,0,0,20170831170831,87,0.00,,,,20170831171010,0064$")); + verifyPosition(decoder, buffer( "+RESP:GTOBD,360701,864251020253807,LSGTC58UX7Y067312,GV500,0,70FFFF,LSGTC58UX7Y067312,1,12309,983A8140,0,0,33,nan,,0,0,0,,10,0,,0,4.4,0,83.7,36.235142,49.967324,20170829112348,0255,0001,2760,9017,00,690.1,20170829112400,3456$")); -- cgit v1.2.3 From 99fd421c76c8e7491095a91630516f6d2db27034 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 4 Sep 2017 07:24:06 +1200 Subject: Implement GenX protocol --- setup/default.xml | 1 + src/org/traccar/protocol/GenxProtocol.java | 45 +++++++++++++ src/org/traccar/protocol/GenxProtocolDecoder.java | 75 ++++++++++++++++++++++ .../traccar/protocol/GenxProtocolDecoderTest.java | 21 ++++++ 4 files changed, 142 insertions(+) create mode 100644 src/org/traccar/protocol/GenxProtocol.java create mode 100644 src/org/traccar/protocol/GenxProtocolDecoder.java create mode 100644 test/org/traccar/protocol/GenxProtocolDecoderTest.java (limited to 'src/org/traccar/protocol') diff --git a/setup/default.xml b/setup/default.xml index fea747c01..d96ceeb6d 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -237,5 +237,6 @@ 5145 5146 5147 + 5148 diff --git a/src/org/traccar/protocol/GenxProtocol.java b/src/org/traccar/protocol/GenxProtocol.java new file mode 100644 index 000000000..deb89e4ae --- /dev/null +++ b/src/org/traccar/protocol/GenxProtocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class GenxProtocol extends BaseProtocol { + + public GenxProtocol() { + super("genx"); + } + + @Override + public void initTrackerServers(List serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new GenxProtocolDecoder(GenxProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java new file mode 100644 index 000000000..6d16db9ad --- /dev/null +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -0,0 +1,75 @@ +/* + * Copyright 2017 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.Context; +import org.traccar.DeviceSession; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.text.SimpleDateFormat; + +public class GenxProtocolDecoder extends BaseProtocolDecoder { + + private int[] reportColumns; + + public GenxProtocolDecoder(GenxProtocol protocol) { + super(protocol); + String[] columns = Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4").split(","); + reportColumns = new int[columns.length]; + for (int i = 0; i < columns.length; i++) { + reportColumns[i] = Integer.parseInt(columns[i]); + } + } + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + String[] values = ((String) msg).split(","); + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setValid(true); + + for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) { + switch (reportColumns[i]) { + case 1: + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); + if (deviceSession != null) { + position.setDeviceId(deviceSession.getDeviceId()); + } + break; + case 2: + position.setTime(new SimpleDateFormat("MM/dd/yy HH:mm:ss").parse(values[i])); + break; + case 3: + position.setLatitude(Double.parseDouble(values[i])); + break; + case 4: + position.setLongitude(Double.parseDouble(values[i])); + break; + default: + break; + } + } + + return position; + } + +} diff --git a/test/org/traccar/protocol/GenxProtocolDecoderTest.java b/test/org/traccar/protocol/GenxProtocolDecoderTest.java new file mode 100644 index 000000000..5e99b8fb8 --- /dev/null +++ b/test/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -0,0 +1,21 @@ +package org.traccar.protocol; + +import org.junit.Test; +import org.traccar.ProtocolTest; + +public class GenxProtocolDecoderTest extends ProtocolTest { + + @Test + public void testDecode() throws Exception { + + GenxProtocolDecoder decoder = new GenxProtocolDecoder(new GenxProtocol()); + + verifyPosition(decoder, text( + "000036004130,08/31/2017 17:24:13,45.47275,-73.65491,5,19,117,1.14,147,ON,1462,0,6,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + + verifyPosition(decoder, text( + "000036004130,08/31/2017 17:24:37,45.47257,-73.65506,3,0,117,1.14,124,ON,1489,0,5,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + + } + +} -- cgit v1.2.3 From 87392d9fbb0289b5486496b6e6b97db1ea84e2b7 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 4 Sep 2017 18:01:43 +0500 Subject: Accept timezone id instead of offset in commands --- .../traccar/protocol/CityeasyProtocolEncoder.java | 8 +++++--- src/org/traccar/protocol/Jt600ProtocolEncoder.java | 6 ++++-- .../traccar/protocol/MeiligaoProtocolEncoder.java | 5 +++-- .../traccar/protocol/MiniFinderProtocolEncoder.java | 6 ++++-- src/org/traccar/protocol/Pt502ProtocolEncoder.java | 20 ++++++++++++++++++-- src/org/traccar/protocol/WatchProtocolEncoder.java | 6 ++++-- .../protocol/CityeasyProtocolEncoderTest.java | 4 ++-- .../traccar/protocol/Jt600ProtocolEncoderTest.java | 2 +- .../protocol/MeiligaoProtocolEncoderTest.java | 4 ++-- .../protocol/MiniFinderProtocolEncoderTest.java | 6 +++--- .../traccar/protocol/Pt502ProtocolEncoderTest.java | 2 +- .../traccar/protocol/WatchProtocolEncoderTest.java | 8 ++++---- 12 files changed, 51 insertions(+), 26 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CityeasyProtocolEncoder.java b/src/org/traccar/protocol/CityeasyProtocolEncoder.java index c800131d6..387926e03 100644 --- a/src/org/traccar/protocol/CityeasyProtocolEncoder.java +++ b/src/org/traccar/protocol/CityeasyProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -15,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.traccar.BaseProtocolEncoder; @@ -56,13 +58,13 @@ public class CityeasyProtocolEncoder extends BaseProtocolEncoder { content.writeShort(0); return encodeContent(CityeasyProtocolDecoder.MSG_LOCATION_INTERVAL, content); case Command.TYPE_SET_TIMEZONE: - int timezone = command.getInteger(Command.KEY_TIMEZONE); + int timezone = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; if (timezone < 0) { content.writeByte(1); } else { content.writeByte(0); } - content.writeShort(Math.abs(timezone) / 60); + content.writeShort(Math.abs(timezone)); return encodeContent(CityeasyProtocolDecoder.MSG_TIMEZONE, content); default: Log.warning(new UnsupportedOperationException(command.getType())); diff --git a/src/org/traccar/protocol/Jt600ProtocolEncoder.java b/src/org/traccar/protocol/Jt600ProtocolEncoder.java index 0bf389460..377f104a3 100644 --- a/src/org/traccar/protocol/Jt600ProtocolEncoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -15,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -29,7 +31,7 @@ public class Jt600ProtocolEncoder extends StringProtocolEncoder { case Command.TYPE_ENGINE_RESUME: return "(S07,1)"; case Command.TYPE_SET_TIMEZONE: - int offset = command.getInteger(Command.KEY_TIMEZONE) / 60; + int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; return "(S09,1," + offset + ")"; case Command.TYPE_REBOOT_DEVICE: return "(S17)"; diff --git a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java index 268bae392..2e0a1e84c 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolEncoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -24,6 +24,7 @@ import org.traccar.model.Command; import javax.xml.bind.DatatypeConverter; import java.nio.charset.StandardCharsets; +import java.util.TimeZone; public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { @@ -78,7 +79,7 @@ public class MeiligaoProtocolEncoder extends BaseProtocolEncoder { content.writeShort(command.getInteger(Command.KEY_RADIUS)); return encodeContent(command.getDeviceId(), MSG_MOVEMENT_ALARM, content); case Command.TYPE_SET_TIMEZONE: - int offset = command.getInteger(Command.KEY_TIMEZONE) / 60; + int offset = TimeZone.getTimeZone(command.getString(Command.KEY_TIMEZONE)).getRawOffset() / 60000; content.writeBytes(String.valueOf(offset).getBytes(StandardCharsets.US_ASCII)); return encodeContent(command.getDeviceId(), MSG_TIME_ZONE, content); case Command.TYPE_REBOOT_DEVICE: diff --git a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java index e5c43e29a..7cf19d352 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -15,6 +15,8 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; @@ -27,7 +29,7 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements if (key.equals(Command.KEY_ENABLE)) { return (Boolean) value ? "1" : "0"; } else if (key.equals(Command.KEY_TIMEZONE)) { - return String.format("%+03d", ((Number) value).longValue() / 3600); + return String.format("%+03d", TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); } else if (key.equals(Command.KEY_INDEX)) { switch (((Number) value).intValue()) { case 0: diff --git a/src/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java index 5f7665e50..d5e219bd2 100644 --- a/src/org/traccar/protocol/Pt502ProtocolEncoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -15,11 +15,27 @@ */ package org.traccar.protocol; +import java.util.TimeZone; + import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -public class Pt502ProtocolEncoder extends StringProtocolEncoder { +public class Pt502ProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { + + @Override + public String formatValue(String key, Object value) { + if (key.equals(Command.KEY_TIMEZONE)) { + return String.valueOf(TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); + } + + return null; + } + + @Override + protected String formatCommand(Command command, String format, String... keys) { + return super.formatCommand(command, format, this, keys); + } @Override protected Object encodeCommand(Command command) { diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index 6fcd109c2..e585a91c1 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2016 - 2017 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. @@ -26,13 +26,14 @@ import java.text.DecimalFormatSymbols; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import java.util.TimeZone; public class WatchProtocolEncoder extends StringProtocolEncoder implements StringProtocolEncoder.ValueFormatter { @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { - double offset = ((Number) value).longValue() / 3600.0; + double offset = TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000.0; DecimalFormat fmt = new DecimalFormat("+#.##;-#.##", DecimalFormatSymbols.getInstance(Locale.US)); return fmt.format(offset); } @@ -41,6 +42,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin } + @Override protected String formatCommand(Command command, String format, String... keys) { String content = super.formatCommand(command, format, this, keys); return String.format("[CS*%s*%04x*%s]", diff --git a/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java b/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java index 96b3c2b74..7c03b7d5b 100644 --- a/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java +++ b/test/org/traccar/protocol/CityeasyProtocolEncoderTest.java @@ -10,11 +10,11 @@ public class CityeasyProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { CityeasyProtocolEncoder encoder = new CityeasyProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 6 * 3600); + command.set(Command.KEY_TIMEZONE, "GMT+6"); verifyCommand(encoder, command, binary("5353001100080001680000000B60820D0A")); diff --git a/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java b/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java index 80802dc35..100d7492a 100644 --- a/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java +++ b/test/org/traccar/protocol/Jt600ProtocolEncoderTest.java @@ -25,7 +25,7 @@ public class Jt600ProtocolEncoderTest extends ProtocolTest { @Test public void testSetTimezone() throws Exception { command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 240 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+4"); assertEquals("(S09,1,240)", encoder.encodeCommand(command)); } diff --git a/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java index f9d77f8a6..ee4a869f9 100644 --- a/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java +++ b/test/org/traccar/protocol/MeiligaoProtocolEncoderTest.java @@ -10,7 +10,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { MeiligaoProtocolEncoder encoder = new MeiligaoProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_POSITION_SINGLE); @@ -23,7 +23,7 @@ public class MeiligaoProtocolEncoderTest extends ProtocolTest { verifyCommand(encoder, command, binary("40400013123456789012344102000a2f4f0d0a")); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 480 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+8"); verifyCommand(encoder, command, binary("4040001412345678901234413234383030ad0d0a")); diff --git a/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java b/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java index 99b250ebc..360ea0008 100644 --- a/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java +++ b/test/org/traccar/protocol/MiniFinderProtocolEncoderTest.java @@ -11,12 +11,12 @@ public class MiniFinderProtocolEncoderTest extends ProtocolTest { public void testEncode() throws Exception { MiniFinderProtocolEncoder encoder = new MiniFinderProtocolEncoder(); - + Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 3600); - + command.set(Command.KEY_TIMEZONE, "GMT+1"); + Assert.assertEquals("123456L+01", encoder.encodeCommand(command)); command = new Command(); diff --git a/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java index ab6446010..62406d3f2 100644 --- a/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java +++ b/test/org/traccar/protocol/Pt502ProtocolEncoderTest.java @@ -30,7 +30,7 @@ public class Pt502ProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 8); + command.set(Command.KEY_TIMEZONE, "GMT+8"); Assert.assertEquals("#TMZ8\r\n", encoder.encodeCommand(command)); diff --git a/test/org/traccar/protocol/WatchProtocolEncoderTest.java b/test/org/traccar/protocol/WatchProtocolEncoderTest.java index 7184d278e..cffe373cf 100644 --- a/test/org/traccar/protocol/WatchProtocolEncoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolEncoderTest.java @@ -41,16 +41,16 @@ public class WatchProtocolEncoderTest extends ProtocolTest { command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_SET_TIMEZONE); - command.set(Command.KEY_TIMEZONE, 60 * 60); + command.set(Command.KEY_TIMEZONE, "Europe/Amsterdam"); Assert.assertEquals("[CS*123456789012345*0006*LZ,,+1]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, 90 * 60); + command.set(Command.KEY_TIMEZONE, "GMT+01:30"); Assert.assertEquals("[CS*123456789012345*0008*LZ,,+1.5]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, -60 * 60); + command.set(Command.KEY_TIMEZONE, "Atlantic/Azores"); Assert.assertEquals("[CS*123456789012345*0006*LZ,,-1]", encoder.encodeCommand(command)); - command.set(Command.KEY_TIMEZONE, -11 * 60 * 60 - 30 * 60); + command.set(Command.KEY_TIMEZONE, "GMT-11:30"); Assert.assertEquals("[CS*123456789012345*0009*LZ,,-11.5]", encoder.encodeCommand(command)); } -- cgit v1.2.3 From 158071c9ff74c5435b8f51ea82215240acb69551 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 5 Sep 2017 08:58:52 +0500 Subject: Use casting and remove super --- src/org/traccar/protocol/MiniFinderProtocolEncoder.java | 2 +- src/org/traccar/protocol/Pt502ProtocolEncoder.java | 4 ++-- src/org/traccar/protocol/WatchProtocolEncoder.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java index 7cf19d352..486f406a5 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolEncoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolEncoder.java @@ -29,7 +29,7 @@ public class MiniFinderProtocolEncoder extends StringProtocolEncoder implements if (key.equals(Command.KEY_ENABLE)) { return (Boolean) value ? "1" : "0"; } else if (key.equals(Command.KEY_TIMEZONE)) { - return String.format("%+03d", TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); + return String.format("%+03d", TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); } else if (key.equals(Command.KEY_INDEX)) { switch (((Number) value).intValue()) { case 0: diff --git a/src/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java index d5e219bd2..4a876f6da 100644 --- a/src/org/traccar/protocol/Pt502ProtocolEncoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -26,7 +26,7 @@ public class Pt502ProtocolEncoder extends StringProtocolEncoder implements Strin @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { - return String.valueOf(TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000); + return String.valueOf(TimeZone.getTimeZone((String) value).getRawOffset() / 3600000); } return null; @@ -34,7 +34,7 @@ public class Pt502ProtocolEncoder extends StringProtocolEncoder implements Strin @Override protected String formatCommand(Command command, String format, String... keys) { - return super.formatCommand(command, format, this, keys); + return formatCommand(command, format, this, keys); } @Override diff --git a/src/org/traccar/protocol/WatchProtocolEncoder.java b/src/org/traccar/protocol/WatchProtocolEncoder.java index e585a91c1..d2d3b52d1 100644 --- a/src/org/traccar/protocol/WatchProtocolEncoder.java +++ b/src/org/traccar/protocol/WatchProtocolEncoder.java @@ -33,7 +33,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin @Override public String formatValue(String key, Object value) { if (key.equals(Command.KEY_TIMEZONE)) { - double offset = TimeZone.getTimeZone(value.toString()).getRawOffset() / 3600000.0; + double offset = TimeZone.getTimeZone((String) value).getRawOffset() / 3600000.0; DecimalFormat fmt = new DecimalFormat("+#.##;-#.##", DecimalFormatSymbols.getInstance(Locale.US)); return fmt.format(offset); } @@ -44,7 +44,7 @@ public class WatchProtocolEncoder extends StringProtocolEncoder implements Strin @Override protected String formatCommand(Command command, String format, String... keys) { - String content = super.formatCommand(command, format, this, keys); + String content = formatCommand(command, format, this, keys); return String.format("[CS*%s*%04x*%s]", getUniqueId(command.getDeviceId()), content.length(), content); } -- cgit v1.2.3 From f36b1eaf32af7ddc51daa558a6bb9e78095bb685 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 5 Sep 2017 16:24:40 +1200 Subject: Fix GenX protocol issues --- src/org/traccar/protocol/GenxProtocol.java | 4 ++-- src/org/traccar/protocol/GenxProtocolDecoder.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/GenxProtocol.java b/src/org/traccar/protocol/GenxProtocol.java index deb89e4ae..2b5b1a43d 100644 --- a/src/org/traccar/protocol/GenxProtocol.java +++ b/src/org/traccar/protocol/GenxProtocol.java @@ -17,9 +17,9 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.frame.LineBasedFrameDecoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.TrackerServer; import java.util.List; @@ -35,7 +35,7 @@ public class GenxProtocol extends BaseProtocol { serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { - pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '\r')); + pipeline.addLast("frameDecoder", new LineBasedFrameDecoder(1024)); pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectDecoder", new GenxProtocolDecoder(GenxProtocol.this)); } diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java index 6d16db9ad..1f9e5512c 100644 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -69,7 +69,7 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { } } - return position; + return position.getDeviceId() != 0 ? position : null; } } -- cgit v1.2.3 From f24bf23ed026abe684cc893924d8a17de065b220 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 5 Sep 2017 23:41:12 +1200 Subject: Remove negative skip (fix #3481) --- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 1 - 1 file changed, 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 6c164386d..fbd1adfc6 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -456,7 +456,6 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (hasLbs(type)) { decodeLbs(position, buf, hasStatus(type)); - buf.skipBytes(-1); } if (hasStatus(type)) { -- cgit v1.2.3 From 36c62f0f2ca21ccd5040f8529f446b1b697dba69 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 6 Sep 2017 09:40:28 +1200 Subject: Fix EV07 login decoding --- src/org/traccar/protocol/MiniFinderProtocolDecoder.java | 6 +++++- test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java index 8bfb4fb36..05994b697 100644 --- a/src/org/traccar/protocol/MiniFinderProtocolDecoder.java +++ b/src/org/traccar/protocol/MiniFinderProtocolDecoder.java @@ -133,7 +133,11 @@ public class MiniFinderProtocolDecoder extends BaseProtocolDecoder { String sentence = (String) msg; if (sentence.startsWith("!1,")) { - getDeviceSession(channel, remoteAddress, sentence.substring(3, sentence.length())); + int index = sentence.indexOf(',', 3); + if (index < 0) { + index = sentence.length(); + } + getDeviceSession(channel, remoteAddress, sentence.substring(3, index)); return null; } diff --git a/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java b/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java index fd16df779..b9003a25d 100644 --- a/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MiniFinderProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MiniFinderProtocolDecoderTest extends ProtocolTest { MiniFinderProtocolDecoder decoder = new MiniFinderProtocolDecoder(new MiniFinderProtocol()); + verifyNull(decoder, text( + "!1,867273023933661,V07S.5701.1621,100")); + verifyNull(decoder, text( "!1,123456789012345")); -- cgit v1.2.3 From 9ebd2a934a5ca3a61863f839733bff321ba30296 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 7 Sep 2017 11:33:22 +0500 Subject: Handle correct and incorrect attribute types --- src/org/traccar/database/DeviceManager.java | 45 ++++++++-------------- src/org/traccar/model/ExtendedModel.java | 2 +- src/org/traccar/notification/NotificationMail.java | 2 +- .../traccar/notification/PropertiesProvider.java | 10 +++++ .../traccar/protocol/OsmAndProtocolDecoder.java | 12 +++++- test/org/traccar/ProtocolTest.java | 4 ++ .../protocol/OsmAndProtocolDecoderTest.java | 3 ++ 7 files changed, 45 insertions(+), 33 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index a485d6dc6..9bc221aa3 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -262,59 +262,44 @@ public class DeviceManager extends BaseObjectManager implements Identity public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Boolean.parseBoolean(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Boolean.parseBoolean(result.toString()) : defaultValue; } public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result; - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? result.toString() : defaultValue; } public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Integer.parseInt(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Integer.parseInt(result.toString()) : defaultValue; } public long lookupAttributeLong( long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Long.parseLong(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Long.parseLong(result.toString()) : defaultValue; } public double lookupAttributeDouble( long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Double.parseDouble(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Double.parseDouble(result.toString()) : defaultValue; } - private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { - String result = null; + private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { + Object result = null; Device device = getById(deviceId); if (device != null) { - result = device.getString(attributeName); + result = device.getAttributes().get(attributeName); if (result == null && lookupGroupsAttribute) { long groupId = device.getGroupId(); while (groupId != 0) { Group group = Context.getGroupsManager().getById(groupId); if (group != null) { - result = group.getString(attributeName); + result = group.getAttributes().get(attributeName); if (result != null) { break; } @@ -329,7 +314,7 @@ public class DeviceManager extends BaseObjectManager implements Identity result = Context.getConfig().getString(attributeName); } else { Server server = Context.getPermissionsManager().getServer(); - result = server.getString(attributeName); + result = server.getAttributes().get(attributeName); } } } diff --git a/src/org/traccar/model/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java index a4bf00e70..2ce503eea 100644 --- a/src/org/traccar/model/ExtendedModel.java +++ b/src/org/traccar/model/ExtendedModel.java @@ -100,7 +100,7 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { - return Boolean.parseBoolean(attributes.get(key).toString()); + return (Boolean) attributes.get(key); } else { return false; } diff --git a/src/org/traccar/notification/NotificationMail.java b/src/org/traccar/notification/NotificationMail.java index d7f3bf64c..fc70a6115 100644 --- a/src/org/traccar/notification/NotificationMail.java +++ b/src/org/traccar/notification/NotificationMail.java @@ -43,7 +43,7 @@ public final class NotificationMail { if (host != null) { properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", provider.getString("mail.smtp.port", "25")); + properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); String starttlsEnable = provider.getString("mail.smtp.starttls.enable"); if (starttlsEnable != null) { diff --git a/src/org/traccar/notification/PropertiesProvider.java b/src/org/traccar/notification/PropertiesProvider.java index 2fea901af..1a4104d2b 100644 --- a/src/org/traccar/notification/PropertiesProvider.java +++ b/src/org/traccar/notification/PropertiesProvider.java @@ -48,4 +48,14 @@ public class PropertiesProvider { return value; } + public int getInteger(String key, int defaultValue) { + if (config != null) { + return config.getInteger(key, defaultValue); + } else if (extendedModel.getAttributes().containsKey(key)) { + return Integer.parseInt(extendedModel.getAttributes().get(key).toString()); + } else { + return defaultValue; + } + } + } diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index c06582a15..15a71c88b 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -135,7 +135,17 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { try { position.set(entry.getKey(), Double.parseDouble(value)); } catch (NumberFormatException e) { - position.set(entry.getKey(), value); + switch (value) { + case "true": + position.set(entry.getKey(), true); + break; + case "false": + position.set(entry.getKey(), false); + break; + default: + position.set(entry.getKey(), value); + break; + } } break; } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index a2c7e4f21..7bff41acd 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -241,6 +241,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_CHARGE) instanceof Boolean); } + if (attributes.containsKey(Position.KEY_IGNITION)) { + Assert.assertTrue(attributes.get(Position.KEY_IGNITION) instanceof Boolean); + } + if (attributes.containsKey(Position.KEY_MOTION)) { Assert.assertTrue(attributes.get(Position.KEY_MOTION) instanceof Boolean); } diff --git a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java index 2d0ef0adf..af860f371 100644 --- a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java +++ b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java @@ -37,6 +37,9 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, request( "/?id=123456×tamp=1377177267&location=60.0,30.0")); + verifyPosition(decoder, request( + "/?id=123456789012345×tamp=1504763810&lat=40.7232948571&lon=-74.0061408571&bearing=7.19889788244&speed=40&ignition=true&rpm=933&fuel=24")); + } } -- cgit v1.2.3 From 5e481bfc1596de062093c5bc01cf168ed906aafc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 03:13:09 +1200 Subject: Support H02 V3 message type --- src/org/traccar/protocol/H02ProtocolDecoder.java | 62 ++++++++++++++++++++++ .../traccar/protocol/H02ProtocolDecoderTest.java | 11 ++-- 2 files changed, 69 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index aa3d47650..091d97cdd 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -222,6 +222,24 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .any() .compile(); + private static final Pattern PATTERN_V3 = new PatternBuilder() + .text("*") + .expression("..,") // manufacturer + .number("(d+),") // imei + .text("V3,") + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(ddd)") // mcc + .number("(d+),") // mnc + .number("(d+),") // count + .expression("(.*),") // cell info + .number("(x{4}),") // battery + .number("d+,") // reboot info + .text("X,") + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(x{8})") // status + .text("#").optional() + .compile(); + private Position decodeText(String sentence, Channel channel, SocketAddress remoteAddress) { Parser parser = new Parser(PATTERN, sentence); @@ -366,6 +384,48 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeV3(String sentence, Channel channel, SocketAddress remoteAddress) { + + Parser parser = new Parser(PATTERN_V3, sentence); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + + int mcc = parser.nextInt(); + int mnc = parser.nextInt(); + + int count = parser.nextInt(); + Network network = new Network(); + String[] values = parser.next().split(","); + for (int i = 0; i < count; i++) { + network.addCellTower(CellTower.from( + mcc, mnc, Integer.parseInt(values[i * 4]), Integer.parseInt(values[i * 4 + 1]))); + } + position.setNetwork(network); + + position.set(Position.KEY_BATTERY, parser.nextHexInt()); + + dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + + getLastLocation(position, dateBuilder.getDate()); + + processStatus(position, parser.nextLong(16, 0)); + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -385,6 +445,8 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { return decodeLbs(sentence, channel, remoteAddress); case "LINK": return decodeLink(sentence, channel, remoteAddress); + case "V3": + return decodeV3(sentence, channel, remoteAddress); default: return decodeText(sentence, channel, remoteAddress); } diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 48f4d987e..a14d57c3c 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyAttributes(decoder, buffer( + "*HQ,353111080001055,V3,044855,28403,01,001450,011473,158,-62,0292,0,X,030817,FFFFFBFF#")); + verifyPosition(decoder, binary( "2442091341332059572807175137358006000183640e000000fffffbfdff001f080000000000ea1e0000000021")); @@ -20,10 +23,10 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,1700086468,LINK,180902,15,0,84,0,0,240517,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020882405,V3,095426,74001,01,010278,045142,128,-92,02DE,0,X,090517,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020882405,V3,095426,74001,04,010278,045142,128,-92,010278,026311,125,,010278,026582,125,,010278,028322,119,,02DD,0,X,090517,FFFFFBFF#")); verifyPosition(decoder, buffer( @@ -50,7 +53,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,4109179024,NBR,103732,722,310,0,6,8106,32010,23,8101,22007,25,8106,12010,23,8106,22105,22,8101,22012,16,8106,42010,5,100217,FFFFFBFF,5#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020930796,V3,002339,62160,06,024852,035421,148,0,024852,035425,143,,022251,036482,137,,024852,000335,133,,024852,031751,133,,024852,035423,133,,02A1,0,X,010104,EFE7FBFF#")); verifyPosition(decoder, buffer( @@ -80,7 +83,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { verifyAttributes(decoder, buffer( "*HQ,1600068860,LINK,112137,20,8,67,0,0,081116,FFFFFBFF#")); - verifyNull(decoder, buffer( + verifyAttributes(decoder, buffer( "*HQ,355488020533263,V3,121536,65501,04,000152,014001,156,-64,000161,010642,138,,000152,014003,129,,000152,013973,126,,02E4,0,X,071116,FFFFFBFF#")); verifyPosition(decoder, buffer( -- cgit v1.2.3 From 3aebd92cc3781b417ded6260d1300434b1418e7e Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 04:45:40 +1200 Subject: Handle GOOME status message --- src/org/traccar/protocol/EelinkProtocolDecoder.java | 4 +++- test/org/traccar/protocol/EelinkProtocolDecoderTest.java | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 11d111e54..2526282b1 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -160,7 +160,9 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { if (statusType == 0x01 || statusType == 0x02 || statusType == 0x03) { buf.readUnsignedInt(); // device time - decodeStatus(position, buf.readUnsignedShort()); + if (buf.readableBytes() >= 2) { + decodeStatus(position, buf.readUnsignedShort()); + } } } diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index 46c85d89a..d62357fe3 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "676705002102b459ae7388fcd360d7034332b1000000028f000a4f64002eb101010159ae7388")); + + verifyPosition(decoder, binary( + "676702001c02b259ae7387fcd360d6034332b2000000028f000a4f64002eb10101")); + verifyPosition(decoder, binary( "6767050022001F59643640000000000000000000000001CC0000249500142000015964A6C0006E")); -- cgit v1.2.3 From 179373c6b3d619922a5daf98220ffe831f56fba2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 05:44:29 +1200 Subject: Improve TRV decoder logic --- src/org/traccar/model/ExtendedModel.java | 4 +- src/org/traccar/protocol/TrvProtocolDecoder.java | 68 +++++++++++++++------- .../traccar/protocol/TrvProtocolDecoderTest.java | 9 +++ 3 files changed, 59 insertions(+), 22 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java index 2ce503eea..8353d0e66 100644 --- a/src/org/traccar/model/ExtendedModel.java +++ b/src/org/traccar/model/ExtendedModel.java @@ -31,7 +31,9 @@ public class ExtendedModel extends BaseModel { } public void set(String key, Boolean value) { - attributes.put(key, value); + if (value != null) { + attributes.put(key, value); + } } public void set(String key, Byte value) { diff --git a/src/org/traccar/protocol/TrvProtocolDecoder.java b/src/org/traccar/protocol/TrvProtocolDecoder.java index 1783bce73..918748f7b 100644 --- a/src/org/traccar/protocol/TrvProtocolDecoder.java +++ b/src/org/traccar/protocol/TrvProtocolDecoder.java @@ -53,8 +53,8 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(ddd)") // satellites .number("(ddd)") // battery .number("(d)") // acc - .number("dd") // arm status - .number("dd,") // working mode + .number("(dd)") // arm status + .number("(dd),") // working mode .number("(d+),") // mcc .number("(d+),") // mnc .number("(d+),") // lac @@ -71,9 +71,41 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { .number("(d)") // acc .number("(dd)") // arm status .number("(dd)") // working mode + .groupBegin() + .number("(ddd)") // interval + .number("d") // vibration alarm + .number("ddd") // vibration sensitivity + .number("d") // automatic arm + .number("dddd") // automatic arm time + .number("(d)") // blocked + .number("(d)") // power status + .number("(d)") // movement status + .groupEnd("?") .any() .compile(); + private Boolean decodeOptionalValue(Parser parser, int activeValue) { + int value = parser.nextInt(); + if (value != 0) { + return value == activeValue; + } + return null; + } + + private void decodeCommon(Position position, Parser parser) { + + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_BATTERY, parser.nextInt()); + position.set(Position.KEY_IGNITION, decodeOptionalValue(parser, 1)); + position.set(Position.KEY_ARMED, decodeOptionalValue(parser, 1)); + + int mode = parser.nextInt(); + if (mode != 0) { + position.set("mode", mode); + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -118,13 +150,13 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_RSSI, parser.nextInt(0)); - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - position.set(Position.KEY_IGNITION, parser.nextInt(0) != 0); + decodeCommon(position, parser); - position.set("arm", parser.nextInt(0)); - position.set("mode", parser.nextInt(0)); + if (parser.hasNext(3)) { + position.set(Position.KEY_BLOCKED, decodeOptionalValue(parser, 2)); + position.set(Position.KEY_CHARGE, decodeOptionalValue(parser, 1)); + position.set(Position.KEY_MOTION, decodeOptionalValue(parser, 1)); + } return position; @@ -140,31 +172,25 @@ public class TrvProtocolDecoder extends BaseProtocolDecoder { position.setDeviceId(deviceSession.getDeviceId()); DateBuilder dateBuilder = new DateBuilder() - .setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setValid(parser.next().equals("A")); position.setLatitude(parser.nextCoordinate()); position.setLongitude(parser.nextCoordinate()); - position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0))); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); - dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + dateBuilder.setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); position.setTime(dateBuilder.getDate()); - position.setCourse(parser.nextDouble(0)); + position.setCourse(parser.nextDouble()); - int rssi = parser.nextInt(0); - position.set(Position.KEY_SATELLITES, parser.nextInt(0)); - position.set(Position.KEY_BATTERY, parser.nextInt(0)); - - int acc = parser.nextInt(0); - if (acc != 0) { - position.set(Position.KEY_IGNITION, acc == 1); - } + decodeCommon(position, parser); position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), parser.nextInt(0), rssi))); + parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextInt()))); return position; + } return null; diff --git a/test/org/traccar/protocol/TrvProtocolDecoderTest.java b/test/org/traccar/protocol/TrvProtocolDecoderTest.java index 319455b9f..a4c0d3343 100644 --- a/test/org/traccar/protocol/TrvProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TrvProtocolDecoderTest.java @@ -10,6 +10,15 @@ public class TrvProtocolDecoderTest extends ProtocolTest { TrvProtocolDecoder decoder = new TrvProtocolDecoder(new TrvProtocol()); + verifyNull(decoder, text( + "TRVAP00352121088015548")); + + verifyPosition(decoder, text( + "TRVAP01170905A5227.1382N00541.4256E001.7095844000.0008100610020100,204,8,3230,13007")); + + verifyAttributes(decoder, text( + "TRVCP01,07800010010000602001206001120124")); + verifyNull(decoder, text( "IWAP00353456789012345")); -- cgit v1.2.3 From e84d1addacd76c05416c31b9e10b6a1618e41c9d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 07:30:17 +1200 Subject: Improve H02 protocol decoder --- src/org/traccar/protocol/H02ProtocolDecoder.java | 43 +++++++++++++++------- .../traccar/protocol/H02ProtocolDecoderTest.java | 13 +++++-- 2 files changed, 39 insertions(+), 17 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index 091d97cdd..69e53ec27 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -150,9 +150,20 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .text("*") .expression("..,") // manufacturer .number("(d+),") // imei - .expression("[^,]+,") + .groupBegin() + .text("VP1,") + .expression("[ABV],") + .or() + .groupBegin() + .text("V1,") + .or() + .text("V4,") .any() + .or() + .text("V19,") + .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) + .groupEnd() .expression("([AV])?,") // validity .groupBegin() .number("-(d+)-(d+.d+),") // latitude @@ -169,25 +180,28 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+.?d*),") // speed .number("(d+.?d*)?,") // course .number("(?:(dd)(dd)(dd))?") // date (ddmmyy) - .any() - .number(",(x{8})") // status + .groupBegin() + .expression(",[^,]*,") + .expression("[^,]*,") + .expression("[^,]*") // sim info + .groupEnd("?") + .groupBegin() + .number(",(x{8})") .groupBegin() .number(",(d+),") // odometer .number("(-?d+),") // temperature .number("(d+.d+),") // fuel .number("(-?d+),") // altitude .number("(x+),") // lac - .number("(x+)#") // cid + .number("(x+)") // cid .or() - .number(",(d+),") - .number("(d+),") - .number("(d+),") - .number("(d+)#") + .text(",") + .expression("(.*)") // data .or() - .expression(",.*") + .groupEnd() .or() - .text("#") .groupEnd() + .text("#") .compile(); private static final Pattern PATTERN_NBR = new PatternBuilder() @@ -289,7 +303,9 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setTime(new Date()); } - processStatus(position, parser.nextLong(16, 0)); + if (parser.hasNext()) { + processStatus(position, parser.nextLong(16, 0)); + } if (parser.hasNext(6)) { position.set(Position.KEY_ODOMETER, parser.nextInt(0)); @@ -302,8 +318,9 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext(4)) { - for (int i = 1; i <= 4; i++) { - position.set(Position.PREFIX_IO + i, parser.nextInt(0)); + String[] values = parser.next().split(","); + for (int i = 0; i < values.length; i++) { + position.set(Position.PREFIX_IO + (i + 1), values[i].trim()); } } diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index a14d57c3c..0b90a4767 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,15 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, buffer( + "*HQ,4209951296,V19,214452,A,5201.0178,N,01830.5029,E,000.00,000,200417,,195.63.13.195,89480610500392633029,BFFFFBFF#")); + + verifyNull(decoder, buffer( + "*hq,356327080425330,VP1,A,2702.7215,S,15251.9309,E,0.62,0.0000,050917#")); + + verifyNull(decoder, buffer( + "*HQ,356327080425330,XT,1,100#")); + verifyAttributes(decoder, buffer( "*HQ,353111080001055,V3,044855,28403,01,001450,011473,158,-62,0292,0,X,030817,FFFFFBFF#")); @@ -215,10 +224,6 @@ public class H02ProtocolDecoderTest extends ProtocolTest { "*HQ,2705171109,V1,213324,A,5002.5849,N,01433.7822,E,0.00,000,140613,FFFFFFFF#"), Position.KEY_STATUS, 0xFFFFFFFFL); - verifyAttribute(decoder, buffer( - "*HQ,4109179024,V19,181519,V,3853.2587,S,06205.9175,W,000.00,000,090217,,5492932630888,8954315265044716555?,FFFFFBFF#"), - Position.KEY_STATUS, 0xFFFFFBFFL); - verifyAttribute(decoder, binary( "2441091144271222470112142233983006114026520E000000FFFFFBFFFF0014060000000001CC00262B0F170A"), Position.KEY_STATUS, 0xFFFFFBFFL); -- cgit v1.2.3 From d36fa0963f8e1045d2f974cd88a0be68aea6f2ef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 07:32:17 +1200 Subject: Handle H02 command results --- src/org/traccar/protocol/H02ProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index 69e53ec27..c31f9edbb 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -158,7 +158,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .text("V1,") .or() .text("V4,") - .any() + .expression("(.*),") // response .or() .text("V19,") .groupEnd() @@ -270,6 +270,10 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + if (parser.hasNext()) { + position.set(Position.KEY_RESULT, parser.next()); + } + DateBuilder dateBuilder = new DateBuilder(); if (parser.hasNext(3)) { dateBuilder.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); -- cgit v1.2.3 From 12586966b63f58e5a008b17f8689110fcd3f5809 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 8 Sep 2017 23:56:00 +1200 Subject: Fix H02 simple message decoding --- src/org/traccar/protocol/H02ProtocolDecoder.java | 3 +-- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 5 ++++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index c31f9edbb..aea8f0b3b 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -152,7 +152,6 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // imei .groupBegin() .text("VP1,") - .expression("[ABV],") .or() .groupBegin() .text("V1,") @@ -164,7 +163,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() - .expression("([AV])?,") // validity + .expression("([ABV])?,") // validity .groupBegin() .number("-(d+)-(d+.d+),") // latitude .or() diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 0b90a4767..103746e5e 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,10 +11,13 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyPosition(decoder, buffer( + "*hq,356327080425330,VP1,A,2702.7245,S,15251.9311,E,0.48,0.0000,080917#")); + verifyPosition(decoder, buffer( "*HQ,4209951296,V19,214452,A,5201.0178,N,01830.5029,E,000.00,000,200417,,195.63.13.195,89480610500392633029,BFFFFBFF#")); - verifyNull(decoder, buffer( + verifyPosition(decoder, buffer( "*hq,356327080425330,VP1,A,2702.7215,S,15251.9309,E,0.62,0.0000,050917#")); verifyNull(decoder, buffer( -- cgit v1.2.3 From 5ab6ae8d6217f3d7565a9d1073e50c1d479c5625 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sat, 9 Sep 2017 22:48:02 +0300 Subject: Improve AdmProtocolDecoder --- src/org/traccar/protocol/AdmProtocolDecoder.java | 105 ++++++++++++++++------- 1 file changed, 73 insertions(+), 32 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index f4a21cad0..4b6a5d3fc 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 Anton Tananaev (anton@traccar.org) + * Copyright 2012 - 2017 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. @@ -33,76 +33,80 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + public static final int CMD_RESPONSE_SIZE = 0x84; public static final int MSG_IMEI = 0x03; public static final int MSG_PHOTO = 0x0A; public static final int MSG_ADM5 = 0x01; - @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - - ChannelBuffer buf = (ChannelBuffer) msg; - - buf.readUnsignedShort(); // device id - buf.readUnsignedByte(); // length - - int type = buf.readUnsignedByte(); - - DeviceSession deviceSession; - if (type == MSG_IMEI) { - deviceSession = getDeviceSession( - channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII)); - } else { - deviceSession = getDeviceSession(channel, remoteAddress); - } + private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + String imei = buf.readBytes(15).toString(StandardCharsets.UTF_8); + return getDeviceSession(channel, remoteAddress, imei); + } + private Position parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; } if (BitUtil.to(type, 2) == 0) { - Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte()); - buf.readUnsignedShort(); // index + position.set(Position.KEY_INDEX, buf.readUnsignedShort()); + + int status = buf.readUnsignedShort(); + position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_STATUS, buf.readUnsignedShort()); + boolean isValid = !BitUtil.check(status, 5); + position.setValid(isValid); - position.setValid(true); position.setLatitude(buf.readFloat()); position.setLongitude(buf.readFloat()); position.setCourse(buf.readUnsignedShort() * 0.1); position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1)); - position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte()); - + position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte() * 0.1); position.setAltitude(buf.readUnsignedShort()); - position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1); position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f); position.setTime(new Date(buf.readUnsignedInt() * 1000)); - position.set(Position.KEY_POWER, buf.readUnsignedShort()); - position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); + position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001); + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); if (BitUtil.check(type, 2)) { - buf.skipBytes(4); + buf.skipBytes(2); // vib, vib_count + + int out = buf.readUnsignedByte(); + for (int i = 0; i <= 3; ++i) { + position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(out, i) ? 1 : 0); + } + + buf.skipBytes(1); // in_alarm } if (BitUtil.check(type, 3)) { - buf.skipBytes(12); + for (int i = 1; i <= 6; ++i) { + position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort() * 0.001); + } } if (BitUtil.check(type, 4)) { - buf.skipBytes(8); + for (int i = 1; i <= 2; ++i) { + position.set(Position.PREFIX_COUNT + i, buf.readUnsignedInt()); + } } if (BitUtil.check(type, 5)) { - buf.skipBytes(9); + buf.skipBytes(6); // fuel level 0..2 + + for (int i = 1; i <= 3; ++i) { + position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte()); + } } if (BitUtil.check(type, 6)) { @@ -119,4 +123,41 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { return null; } + private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_RESULT, buf.readBytes(129).toString(StandardCharsets.UTF_8)); + + return position; + } + + @Override + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + ChannelBuffer buf = (ChannelBuffer) msg; + + buf.readUnsignedShort(); // device id + + int size = buf.readUnsignedByte(); + if (size != CMD_RESPONSE_SIZE) { + int type = buf.readUnsignedByte(); + if (type == MSG_IMEI) { + parseIdentification(channel, remoteAddress, buf); + } else { + return parseData(channel, remoteAddress, buf, type); + } + } else { + return parseCommandResponse(channel, remoteAddress, buf); + } + + return null; + } } -- cgit v1.2.3 From 03844cbfc53d676f41b8c9fb18b74b86a08e95f0 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sat, 9 Sep 2017 22:52:18 +0300 Subject: Implement ADM protocol commands --- src/org/traccar/protocol/AdmProtocol.java | 5 +++ src/org/traccar/protocol/AdmProtocolEncoder.java | 53 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/org/traccar/protocol/AdmProtocolEncoder.java (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java index 442121f0a..db2adfeaa 100644 --- a/src/org/traccar/protocol/AdmProtocol.java +++ b/src/org/traccar/protocol/AdmProtocol.java @@ -20,6 +20,7 @@ import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; +import org.traccar.model.Command; import java.nio.ByteOrder; import java.util.List; @@ -28,6 +29,9 @@ public class AdmProtocol extends BaseProtocol { public AdmProtocol() { super("adm"); + setSupportedDataCommands( + Command.TYPE_GET_DEVICE_STATUS, + Command.TYPE_CUSTOM); } @Override @@ -36,6 +40,7 @@ public class AdmProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 1, -3, 0)); + pipeline.addLast("objectEncoder", new AdmProtocolEncoder()); pipeline.addLast("objectDecoder", new AdmProtocolDecoder(AdmProtocol.this)); } }; diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java new file mode 100644 index 000000000..1cdfbf0b0 --- /dev/null +++ b/src/org/traccar/protocol/AdmProtocolEncoder.java @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.protocol; + +import org.jboss.netty.buffer.ChannelBuffer; +import org.jboss.netty.buffer.ChannelBuffers; +import org.traccar.BaseProtocolEncoder; +import org.traccar.helper.Log; +import org.traccar.model.Command; + +import java.nio.charset.StandardCharsets; + +public class AdmProtocolEncoder extends BaseProtocolEncoder { + + private ChannelBuffer encodeContent(String data) { + ChannelBuffer buf = ChannelBuffers.copiedBuffer(data, StandardCharsets.UTF_8); + buf.writeByte(0x0D); + buf.writeByte(0x0A); + return buf; + } + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_GET_DEVICE_STATUS: + return encodeContent("STATUS"); + + case Command.TYPE_CUSTOM: + return encodeContent(command.getString(Command.KEY_DATA)); + + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } +} -- cgit v1.2.3 From 7f73f2adf965063947aff1b7e1fdf80b614bd347 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 10 Sep 2017 10:21:33 +1200 Subject: Decode Suntech alarms --- .../traccar/protocol/SuntechProtocolDecoder.java | 41 +++++++++++++++++----- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 68c920899..3025bbdd5 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -109,6 +109,24 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private String decodeEmergency(int value) { + switch (value) { + case 1: + return Position.ALARM_SOS; + case 3: + return Position.ALARM_POWER_CUT; + case 5: + case 6: + return Position.ALARM_DOOR; + case 7: + return Position.ALARM_MOVEMENT; + case 8: + return Position.ALARM_SHOCK; + default: + return null; + } + } + private Position decode235( Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException { int index = 0; @@ -121,10 +139,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { Position position = new Position(); position.setProtocol(getProtocolName()); - - if (type.equals("EMG") || type.equals("ALT")) { - position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); - } + position.set(Position.KEY_TYPE, type); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); if (deviceSession == null) { @@ -160,10 +175,20 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_IO + 1, values[index++]); - index += 1; // mode - - if (type.equals("STT")) { - position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); + switch (type) { + case "STT": + index += 1; // mode + position.set(Position.KEY_INDEX, Integer.parseInt(values[index++])); + break; + case "EMG": + position.set(Position.KEY_ALARM, decodeEmergency(Integer.parseInt(values[index++]))); + break; + case "EVT": + case "ALT": + position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); + break; + default: + break; } if (hbm) { -- cgit v1.2.3 From cdc7a0a0f8ba48b9581efeaeaa902f5a4ddcc306 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 01:48:01 +0300 Subject: Simplify ADM protocol decoder --- src/org/traccar/protocol/AdmProtocolDecoder.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index 4b6a5d3fc..b5a5c64dc 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -38,11 +38,6 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PHOTO = 0x0A; public static final int MSG_ADM5 = 0x01; - private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { - String imei = buf.readBytes(15).toString(StandardCharsets.UTF_8); - return getDeviceSession(channel, remoteAddress, imei); - } - private Position parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -59,10 +54,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { int status = buf.readUnsignedShort(); position.set(Position.KEY_STATUS, status); - - boolean isValid = !BitUtil.check(status, 5); - position.setValid(isValid); - + position.setValid(!BitUtil.check(status, 5)); position.setLatitude(buf.readFloat()); position.setLongitude(buf.readFloat()); position.setCourse(buf.readUnsignedShort() * 0.1); @@ -150,7 +142,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { if (size != CMD_RESPONSE_SIZE) { int type = buf.readUnsignedByte(); if (type == MSG_IMEI) { - parseIdentification(channel, remoteAddress, buf); + getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.UTF_8)); } else { return parseData(channel, remoteAddress, buf, type); } -- cgit v1.2.3 From 07e4e89be6e658239125a8b99e05ce4d132e1d9e Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 01:51:31 +0300 Subject: Inherit AdmProtocolEncoder from StringProtocolEncoder --- src/org/traccar/protocol/AdmProtocol.java | 4 +++- src/org/traccar/protocol/AdmProtocolEncoder.java | 19 ++++--------------- test/org/traccar/protocol/AdmProtocolEncoderTest.java | 5 +++-- 3 files changed, 10 insertions(+), 18 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java index db2adfeaa..4d2cbe7b3 100644 --- a/src/org/traccar/protocol/AdmProtocol.java +++ b/src/org/traccar/protocol/AdmProtocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton@traccar.org) + * Copyright 2015 - 2017 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. @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; +import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -40,6 +41,7 @@ public class AdmProtocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 1, -3, 0)); + pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("objectEncoder", new AdmProtocolEncoder()); pipeline.addLast("objectDecoder", new AdmProtocolDecoder(AdmProtocol.this)); } diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java index 1cdfbf0b0..8cbd8618d 100644 --- a/src/org/traccar/protocol/AdmProtocolEncoder.java +++ b/src/org/traccar/protocol/AdmProtocolEncoder.java @@ -16,32 +16,21 @@ */ package org.traccar.protocol; -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.buffer.ChannelBuffers; -import org.traccar.BaseProtocolEncoder; +import org.traccar.StringProtocolEncoder; import org.traccar.helper.Log; import org.traccar.model.Command; -import java.nio.charset.StandardCharsets; - -public class AdmProtocolEncoder extends BaseProtocolEncoder { - - private ChannelBuffer encodeContent(String data) { - ChannelBuffer buf = ChannelBuffers.copiedBuffer(data, StandardCharsets.UTF_8); - buf.writeByte(0x0D); - buf.writeByte(0x0A); - return buf; - } +public class AdmProtocolEncoder extends StringProtocolEncoder { @Override protected Object encodeCommand(Command command) { switch (command.getType()) { case Command.TYPE_GET_DEVICE_STATUS: - return encodeContent("STATUS"); + return formatCommand(command, "STATUS\r\n"); case Command.TYPE_CUSTOM: - return encodeContent(command.getString(Command.KEY_DATA)); + return formatCommand(command, "{%s}\r\n", Command.KEY_DATA); default: Log.warning(new UnsupportedOperationException(command.getType())); diff --git a/test/org/traccar/protocol/AdmProtocolEncoderTest.java b/test/org/traccar/protocol/AdmProtocolEncoderTest.java index 3a72036bf..6d2452e26 100644 --- a/test/org/traccar/protocol/AdmProtocolEncoderTest.java +++ b/test/org/traccar/protocol/AdmProtocolEncoderTest.java @@ -16,6 +16,7 @@ */ package org.traccar.protocol; +import org.junit.Assert; import org.junit.Test; import org.traccar.ProtocolTest; import org.traccar.model.Command; @@ -30,13 +31,13 @@ public class AdmProtocolEncoderTest extends ProtocolTest { Command command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_GET_DEVICE_STATUS); - verifyCommand(encoder, command, binary("5354415455530D0A")); + Assert.assertEquals("STATUS\r\n", encoder.encodeCommand(command)); command = new Command(); command.setDeviceId(1); command.setType(Command.TYPE_CUSTOM); command.set(Command.KEY_DATA, "INPUT 0"); - verifyCommand(encoder, command, binary("494E50555420300D0A")); + Assert.assertEquals("INPUT 0\r\n", encoder.encodeCommand(command)); } } -- cgit v1.2.3 From 31d46d03bd29e9d29c2797f5e72735450a9bf45b Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 02:11:43 +0300 Subject: Rename method --- src/org/traccar/protocol/AdmProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index b5a5c64dc..df96c6b8d 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -38,7 +38,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_PHOTO = 0x0A; public static final int MSG_ADM5 = 0x01; - private Position parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { + private Position decodeData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; @@ -144,7 +144,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { if (type == MSG_IMEI) { getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.UTF_8)); } else { - return parseData(channel, remoteAddress, buf, type); + return decodeData(channel, remoteAddress, buf, type); } } else { return parseCommandResponse(channel, remoteAddress, buf); -- cgit v1.2.3 From fa3e682e2b309ca89d0cc7dcb11957f9b380c6d4 Mon Sep 17 00:00:00 2001 From: Anatoliy Golubev Date: Sun, 10 Sep 2017 11:43:13 +0300 Subject: Fix command response decode --- src/org/traccar/protocol/AdmProtocolDecoder.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index df96c6b8d..80c580967 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -127,7 +127,11 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { getLastLocation(position, null); - position.set(Position.KEY_RESULT, buf.readBytes(129).toString(StandardCharsets.UTF_8)); + int responseTextLength = buf.bytesBefore((byte) 0); + if (responseTextLength < 0) { + responseTextLength = CMD_RESPONSE_SIZE - 3; + } + position.set(Position.KEY_RESULT, buf.readBytes(responseTextLength).toString(StandardCharsets.UTF_8)); return position; } -- cgit v1.2.3 From 8aa35f1e9d3a32f7935415d1d910b4bc19f53df0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Sep 2017 20:00:01 +1200 Subject: Minor ADM protocol cleanup --- src/org/traccar/protocol/AdmProtocolDecoder.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java index 80c580967..f93c55e18 100644 --- a/src/org/traccar/protocol/AdmProtocolDecoder.java +++ b/src/org/traccar/protocol/AdmProtocolDecoder.java @@ -39,6 +39,7 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_ADM5 = 0x01; private Position decodeData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; @@ -71,32 +72,34 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); if (BitUtil.check(type, 2)) { - buf.skipBytes(2); // vib, vib_count + buf.readUnsignedByte(); // vib + buf.readUnsignedByte(); // vib_count int out = buf.readUnsignedByte(); - for (int i = 0; i <= 3; ++i) { + for (int i = 0; i <= 3; i++) { position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(out, i) ? 1 : 0); } - buf.skipBytes(1); // in_alarm + buf.readUnsignedByte(); // in_alarm } if (BitUtil.check(type, 3)) { - for (int i = 1; i <= 6; ++i) { + for (int i = 1; i <= 6; i++) { position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort() * 0.001); } } if (BitUtil.check(type, 4)) { - for (int i = 1; i <= 2; ++i) { + for (int i = 1; i <= 2; i++) { position.set(Position.PREFIX_COUNT + i, buf.readUnsignedInt()); } } if (BitUtil.check(type, 5)) { - buf.skipBytes(6); // fuel level 0..2 - - for (int i = 1; i <= 3; ++i) { + for (int i = 1; i <= 3; i++) { + buf.readUnsignedShort(); // fuel level + } + for (int i = 1; i <= 3; i++) { position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte()); } } @@ -156,4 +159,5 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder { return null; } + } -- cgit v1.2.3 From a11b2887789f962a55dd3cd219b493f3a148ec98 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 11 Sep 2017 20:28:39 +1200 Subject: Add new Teltonika parameters --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 15c5b8e80..aa9bfe4fe 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -104,6 +104,15 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 9: position.set(Position.PREFIX_ADC + 1, readValue(buf, length, false)); break; + case 17: + position.set("axisX", readValue(buf, length, true)); + break; + case 18: + position.set("axisY", readValue(buf, length, true)); + break; + case 19: + position.set("axisZ", readValue(buf, length, true)); + break; case 66: position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); break; -- cgit v1.2.3 From 32ff541cc909d14bdf8c8721114b083d5d30728d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Sep 2017 22:46:45 +1200 Subject: Support SunTech IO decoding --- src/org/traccar/protocol/SuntechProtocolDecoder.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 3025bbdd5..39804159f 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -173,7 +173,15 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++])); position.set(Position.KEY_POWER, Double.parseDouble(values[index++])); - position.set(Position.PREFIX_IO + 1, values[index++]); + String io = values[index++]; + if (io.length() == 6) { + position.set(Position.KEY_IGNITION, io.charAt(0) == '1'); + position.set(Position.PREFIX_IN + 1, io.charAt(1) == '1'); + position.set(Position.PREFIX_IN + 2, io.charAt(2) == '1'); + position.set(Position.PREFIX_IN + 3, io.charAt(3) == '1'); + position.set(Position.PREFIX_OUT + 1, io.charAt(4) == '1'); + position.set(Position.PREFIX_OUT + 2, io.charAt(5) == '1'); + } switch (type) { case "STT": -- cgit v1.2.3 From 195e7b5b45c08fa4fad4f9c8797f8807ded1dbea Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 12 Sep 2017 23:13:03 +1200 Subject: Support universal Suntech format --- .../traccar/protocol/SuntechProtocolDecoder.java | 116 ++++++++++++++++++--- .../protocol/SuntechProtocolDecoderTest.java | 6 ++ 2 files changed, 108 insertions(+), 14 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 39804159f..3b350ba64 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -19,6 +19,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.BitUtil; import org.traccar.helper.UnitsConverter; import org.traccar.model.Position; @@ -70,19 +71,19 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + Position position = new Position(); position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); if (type.equals("Emergency") || type.equals("Alert")) { position.set(Position.KEY_ALARM, Position.ALARM_GENERAL); } - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - if (!type.equals("Alert") || protocolType == 0) { position.set(Position.KEY_VERSION_FW, values[index++]); } @@ -137,15 +138,15 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.set(Position.KEY_TYPE, type); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); if (protocol.equals("ST300") || protocol.equals("ST500")) { index += 1; // model @@ -242,18 +243,105 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { return position; } + private Position decodeUniversal( + Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException { + int index = 0; + + String type = values[index++]; + + if (!type.equals("STT")) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + position.set(Position.KEY_TYPE, type); + + int mask = Integer.parseInt(values[index++], 16); + + if (BitUtil.check(mask, 1)) { + index += 1; // model + } + + if (BitUtil.check(mask, 2)) { + position.set(Position.KEY_VERSION_FW, values[index++]); + } + + if (BitUtil.check(mask, 3) && values[index++].equals("0")) { + position.set(Position.KEY_ARCHIVE, true); + } + + if (BitUtil.check(mask, 4) && BitUtil.check(mask, 5)) { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + position.setTime(dateFormat.parse(values[index++] + values[index++])); + } + + if (BitUtil.check(mask, 6)) { + index += 1; // cell + } + + if (BitUtil.check(mask, 7)) { + index += 1; // mcc + } + + if (BitUtil.check(mask, 8)) { + index += 1; // mnc + } + + if (BitUtil.check(mask, 9)) { + index += 1; // lac + } + + if (BitUtil.check(mask, 10)) { + position.set(Position.KEY_RSSI, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 11)) { + position.setLatitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 12)) { + position.setLongitude(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 13)) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + } + + if (BitUtil.check(mask, 14)) { + position.setCourse(Double.parseDouble(values[index++])); + } + + if (BitUtil.check(mask, 15)) { + position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++])); + } + + if (BitUtil.check(mask, 16)) { + position.setValid(values[index++].equals("1")); + } + + return position; + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String[] values = ((String) msg).split(";"); - String protocol = values[0].substring(0, 5); - - if (protocol.equals("ST910")) { + if (values[0].length() < 5) { + return decodeUniversal(channel, remoteAddress, values); + } else if (values[0].equals("ST910")) { return decode9(channel, remoteAddress, values); } else { - return decode235(channel, remoteAddress, protocol, values); + return decode235(channel, remoteAddress, values[0].substring(0, 5), values); } } diff --git a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java index d46ca3d34..45230a339 100644 --- a/test/org/traccar/protocol/SuntechProtocolDecoderTest.java +++ b/test/org/traccar/protocol/SuntechProtocolDecoderTest.java @@ -30,6 +30,12 @@ public class SuntechProtocolDecoderTest extends ProtocolTest { SuntechProtocolDecoder decoder = new SuntechProtocolDecoder(new SuntechProtocol()); + verifyPosition(decoder, text( + "STT;100850000;3FFFFF;26;010;1;20161117;08:37:39;0000004F;450;0;0014;20;+37.479323;+126.887827;62.03;65.43;10;1;00000101;00001000;1;2;0492")); + + verifyPosition(decoder, text( + "STT;6009999006;3FFFFF;26;398;0;20170827;20:04:37;087d4760;310;410;0ba0;23;+40.123420;-074.995971;000.031;000.00;8;1;00000001;00000000;1;1;0006")); + verifyPosition(decoder, text( "ST500STT;205450135;07;843;20170816;23:24:45;+19.338432;-099.179817;000.283;000.00;6;1;141121;12.89;0;0;1;4659;002.795;0;001.891;611;4.0")); -- cgit v1.2.3 From e05f0b83a911c522123a5a2cd14d6c16bd2de027 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 13 Sep 2017 04:38:18 +1200 Subject: Fix GV200 INF message decoding --- src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 2 +- test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 988fd71c8..090e02812 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -65,7 +65,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .expression("(?:[0-9A-Z]{17},)?") // vin .expression("(?:[^,]+)?,") // device name .number("(xx),") // state - .expression("(?:[0-9F]{20})?,") // iccid + .expression("(?:[0-9Ff]{20})?,") // iccid .number("(d{1,2}),") // rssi .number("d{1,2},") .expression("[01],") // external power diff --git a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java index 812973fb8..2b0395e48 100644 --- a/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gl200TextProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class Gl200TextProtocolDecoderTest extends ProtocolTest { Gl200TextProtocolDecoder decoder = new Gl200TextProtocolDecoder(new Gl200Protocol()); + verifyAttributes(decoder, buffer( + "+RESP:GTINF,04040E,861074023747143,gv200,41,8959301000648637556f,24,0,1,0,1,4.4,0,1,0,0,20170912221854,0,00,01,-0500,1,20170912193448,1D5B$")); + verifyAttributes(decoder, buffer( "+RESP:GTINF,210102,354524044950583,,42,89011702272048900184,11,99,0,,,4.08,0,1,1,0,0,20170831170831,87,0.00,,,,20170831171010,0064$")); -- cgit v1.2.3 From c82fd979ad17ecfb7dd8f3e366c067b66f4cdabc Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 15 Sep 2017 02:46:40 +1200 Subject: Handle MVT380 no power value --- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 2 +- test/org/traccar/protocol/MeitrackProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 469ef3f76..2d0590f5e 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -69,7 +69,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { .number("(x+)?|") // adc2 .number("(x+)?|") // adc3 .number("(x+)|") // battery - .number("(x+),") // power + .number("(x+)?,") // power .groupBegin() .expression("([^,]+)?,") // event specific .expression("[^,]*,") // reserved diff --git a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java index d50cae8bc..cbbbd17f6 100644 --- a/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MeitrackProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class MeitrackProtocolDecoderTest extends ProtocolTest { MeitrackProtocolDecoder decoder = new MeitrackProtocolDecoder(new MeitrackProtocol()); + verifyPosition(decoder, buffer( + "$$B136,011691002364761,AAA,29,47.055220,28.893193,170914144240,V,0,7,0,0,0,132,129754946,129793197,259|2|02F8|413F,0000,000D|000C||028C|,*9E")); + verifyNotNull(decoder, buffer( "$$F153,863835026880190,AAA,29,25.313160,55.422473,170628150902,V,0,0,0,0,0.0,0,6553,6697,0|0|0000|00000000,0000,0002|0000|0000|018B|0000,,,3,0000,,110,386*22")); -- cgit v1.2.3 From bb599edbd964dd036f3433625034ce985cfc4eef Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 17 Sep 2017 10:23:39 +1200 Subject: Handle all Telic formats --- src/org/traccar/protocol/TelicProtocolDecoder.java | 2 +- test/org/traccar/protocol/TelicProtocolDecoderTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TelicProtocolDecoder.java b/src/org/traccar/protocol/TelicProtocolDecoder.java index a875009a1..2c0d714c6 100644 --- a/src/org/traccar/protocol/TelicProtocolDecoder.java +++ b/src/org/traccar/protocol/TelicProtocolDecoder.java @@ -35,7 +35,7 @@ public class TelicProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("dddd") .number("(d{6}|d{15})") // device id - .number("(dd),") // type + .number("(d{1,2}),") // type .number("d{12},") // event time .number("d+,") .number("(dd)(dd)(dd)") // date (ddmmyy) diff --git a/test/org/traccar/protocol/TelicProtocolDecoderTest.java b/test/org/traccar/protocol/TelicProtocolDecoderTest.java index 84b6a797b..ed8245e1f 100644 --- a/test/org/traccar/protocol/TelicProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TelicProtocolDecoderTest.java @@ -13,6 +13,12 @@ public class TelicProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, text( "0026355565071347499|206|01|001002008")); + verifyPosition(decoder, text( + "052028495198,160917073641,0,160917073642,43879,511958,3,24,223,17,,,-3,142379,,0010,00,64,205,0,0499")); + + verifyPosition(decoder, text( + "01302849516,160917073503,0,160917073504,43907,512006,3,11,160,14,,,-7,141811,,0010,00,64,206,0,0499")); + verifyPosition(decoder, text( "002135556507134749999,010817171138,0,010817171138,004560973,50667173,3,0,0,11,1,1,100,958071,20601,000000,00,4142,0000,0000,0208,10395,0")); -- cgit v1.2.3 From bfdd87a80fb57e065dfb84d6d10f5339f77fdaf4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 18 Sep 2017 07:44:00 +1200 Subject: Fix Aplicom EBS decoding --- .../traccar/protocol/AplicomProtocolDecoder.java | 98 +++++++++++----------- .../protocol/AplicomProtocolDecoderTest.java | 3 + 2 files changed, 52 insertions(+), 49 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index ef02cda7e..94d12c633 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -470,59 +470,59 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // length while (buf.readableBytes() > 0) { - position.set("towedPosition", buf.readUnsignedByte()); + buf.readUnsignedByte(); // towed position int type = buf.readUnsignedByte(); int length = buf.readUnsignedByte(); + int end = buf.readerIndex() + length; - if (type == 0x01) { - position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x02) { - position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); - position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); - position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); - position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); - } else if (type == 0x03) { - position.set("axleLoadSum", buf.readUnsignedShort() * 2); - } else if (type == 0x04) { - position.set("tyrePressure", buf.readUnsignedByte() * 10); - position.set("pneumaticPressure", buf.readUnsignedByte() * 5); - } else if (type == 0x05) { - position.set("brakeLining", buf.readUnsignedByte() * 0.4); - position.set("brakeTemperature", buf.readUnsignedByte() * 10); - } else if (type == 0x06) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5); - position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5); - position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5); - } else if (type == 0x0A) { - ChannelBuffer brakeData = buf.readBytes(length); - position.set("absStatusCounter", brakeData.readUnsignedShort()); - position.set("atvbStatusCounter", brakeData.readUnsignedShort()); - position.set("vdcActiveCounter", brakeData.readUnsignedShort()); - } else if (type == 0x0B) { - position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x0C) { - position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length))); - } else if (type == 0x0D) { - switch (buf.readUnsignedByte()) { - case 1: - position.set("brakeManufacturer", "Wabco"); - break; - case 2: - position.set("brakeManufacturer", "Knorr"); - break; - case 3: - position.set("brakeManufacturer", "Haldex"); - break; - default: - position.set("brakeManufacturer", "Unknown"); - break; - } - buf.readUnsignedByte(); - position.set(Position.KEY_VIN, buf.readBytes(17).toString(StandardCharsets.US_ASCII)); - position.set("towedDetectionStatus", buf.readUnsignedByte()); - } else if (type == 0x0E) { - buf.skipBytes(length); + switch (type) { + case 0x01: + position.set("brakeFlags", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x02: + position.set("wheelSpeed", buf.readUnsignedShort() / 256.0); + position.set("wheelSpeedDifference", buf.readUnsignedShort() / 256.0 - 125.0); + position.set("lateralAcceleration", buf.readUnsignedByte() / 10.0 - 12.5); + position.set("vehicleSpeed", buf.readUnsignedShort() / 256.0); + break; + case 0x03: + position.set("axleLoadSum", buf.readUnsignedShort() * 2); + break; + case 0x04: + position.set("tyrePressure", buf.readUnsignedByte() * 10); + position.set("pneumaticPressure", buf.readUnsignedByte() * 5); + break; + case 0x05: + position.set("brakeLining", buf.readUnsignedByte() * 0.4); + position.set("brakeTemperature", buf.readUnsignedByte() * 10); + break; + case 0x06: + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt() * 5L); + position.set(Position.KEY_ODOMETER_TRIP, buf.readUnsignedInt() * 5L); + position.set(Position.KEY_ODOMETER_SERVICE, (buf.readUnsignedInt() - 2105540607) * 5L); + break; + case 0x0A: + position.set("absStatusCounter", buf.readUnsignedShort()); + position.set("atvbStatusCounter", buf.readUnsignedShort()); + position.set("vdcActiveCounter", buf.readUnsignedShort()); + break; + case 0x0B: + position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x0C: + position.set("missingPgn", ChannelBuffers.hexDump(buf.readBytes(length))); + break; + case 0x0D: + buf.readUnsignedByte(); + position.set("towedDetectionStatus", buf.readUnsignedInt()); + buf.skipBytes(17); // vin + break; + case 0x0E: + default: + break; } + + buf.readerIndex(end); } } diff --git a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java index 2498d94b3..862cff055 100644 --- a/test/org/traccar/protocol/AplicomProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AplicomProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class AplicomProtocolDecoderTest extends ProtocolTest { AplicomProtocolDecoder decoder = new AplicomProtocolDecoder(new AplicomProtocol()); + verifyAttributes(decoder, binary( + "44c30144f667c4316500e903ffdfbc00f059aebeb659aebeb302e3f5860065fe32120000ae0000000e47000000000000000000000000000127cd0000014c00000000000000ff010a002900000000000000014542016d0001010090070e140144f667c4316559ae620402e3f7f300660714c0010d15ff0f3332373937313100000000000000000000002a01010737341d331fffcf0103020b8601060c0001a5860001a58600000000010b1001ca01ca7d007d007c7cffffffffffff010a240000ffff0000000100010001ffff0000ffffffffffffffffffffffffffff00000002ffff010c06fec6febffeec")); + verifyAttributes(decoder, binary( "45c20144f667c06ff9005d0161ef17000104596da2dc4b10c0c01d99020d6c04004cba7a010d44463030303235333731363238303030000000000000000000000000000000000000000000000000000001010d44463030303235333731363238303030000000000000031c")); -- cgit v1.2.3 From 849878cf105baed2348c605f7232012efb294480 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 20 Sep 2017 05:57:33 +1200 Subject: Add genx format setter --- src/org/traccar/protocol/GenxProtocolDecoder.java | 6 +++++- test/org/traccar/protocol/GenxProtocolDecoderTest.java | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java index 1f9e5512c..3b716796c 100644 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -30,7 +30,11 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { public GenxProtocolDecoder(GenxProtocol protocol) { super(protocol); - String[] columns = Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4").split(","); + setReportColumns(Context.getConfig().getString(getProtocolName() + ".reportColumns", "1,2,3,4")); + } + + public void setReportColumns(String format) { + String[] columns = format.split(","); reportColumns = new int[columns.length]; for (int i = 0; i < columns.length; i++) { reportColumns[i] = Integer.parseInt(columns[i]); diff --git a/test/org/traccar/protocol/GenxProtocolDecoderTest.java b/test/org/traccar/protocol/GenxProtocolDecoderTest.java index 5e99b8fb8..43d9e7d6e 100644 --- a/test/org/traccar/protocol/GenxProtocolDecoderTest.java +++ b/test/org/traccar/protocol/GenxProtocolDecoderTest.java @@ -16,6 +16,11 @@ public class GenxProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, text( "000036004130,08/31/2017 17:24:37,45.47257,-73.65506,3,0,117,1.14,124,ON,1489,0,5,N,0,0.000,-95.0,-1.0,0,0.0000,0.0000,0.000,0,0.00,0.00,0.00,NA,U,UUU,0,-95.0,U")); + decoder.setReportColumns("1,2,3,4"); + + verifyPosition(decoder, text( + "000036035855,04/16/2017 21:19:07,45.46485,-73.65424,24,32,61:213,342.51,157,ON,20984,0,12,O,18,0.000,95.0,24.0,1990,64.0894,0.0219,316.009,71,0.00,16.78,5.10,NA,U,UUU,0,-95.0,U")); + } } -- cgit v1.2.3 From 90459fe4f15c3cfa4a5062ca421a4640a73e7314 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 21 Sep 2017 15:37:57 +0500 Subject: Teltonika: store command response as KEY_RESULT --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index aa9bfe4fe..4700350d4 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -76,7 +76,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_TYPE, buf.readUnsignedByte()); - position.set(Position.KEY_COMMAND, buf.readBytes(buf.readInt()).toString(StandardCharsets.US_ASCII)); + position.set(Position.KEY_RESULT, buf.readBytes(buf.readInt()).toString(StandardCharsets.US_ASCII)); } -- cgit v1.2.3 From 76639c6b2284a5dfc4b45c17e533788dd739bcf1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 22 Sep 2017 05:15:32 +1200 Subject: Add missing Totem alarm --- src/org/traccar/protocol/TotemProtocolDecoder.java | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TotemProtocolDecoder.java b/src/org/traccar/protocol/TotemProtocolDecoder.java index a4ae4cb8f..3c2dee8ec 100644 --- a/src/org/traccar/protocol/TotemProtocolDecoder.java +++ b/src/org/traccar/protocol/TotemProtocolDecoder.java @@ -171,6 +171,8 @@ public class TotemProtocolDecoder extends BaseProtocolDecoder { return Position.ALARM_LOW_BATTERY; case 0x11: return Position.ALARM_OVERSPEED; + case 0x30: + return Position.ALARM_PARKING; case 0x42: return Position.ALARM_GEOFENCE_EXIT; case 0x43: -- cgit v1.2.3 From fd59d77dbd6037c7b72eb6f4d132db4bde6877a0 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Sep 2017 12:14:38 +1300 Subject: Support all Meitrack versions (fix #3535) --- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 2d0590f5e..4714e24ea 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -73,12 +73,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { .groupBegin() .expression("([^,]+)?,") // event specific .expression("[^,]*,") // reserved - .number("d*,") // protocol + .number("(d+)?,") // protocol .number("(x{4})?") // fuel .number("(?:,(x{6}(?:|x{6})*))?") // temperature - .or() + .groupEnd("?") .any() - .groupEnd() .text("*") .number("xx") .text("\r\n").optional() @@ -209,6 +208,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } + int protocol = parser.nextInt(0); + if (parser.hasNext()) { String fuel = parser.next(); position.set(Position.KEY_FUEL_LEVEL, @@ -218,9 +219,14 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { for (String temp : parser.next().split("\\|")) { int index = Integer.valueOf(temp.substring(0, 2), 16); - double value = Byte.valueOf(temp.substring(2, 4), 16); - value += (value < 0 ? -0.01 : 0.01) * Integer.valueOf(temp.substring(4), 16); - position.set(Position.PREFIX_TEMP + index, value); + if (protocol >= 3) { + double value = Short.valueOf(temp.substring(2), 16); + position.set(Position.PREFIX_TEMP + index, value * 0.01); + } else { + double value = Byte.valueOf(temp.substring(2, 4), 16); + value += (value < 0 ? -0.01 : 0.01) * Integer.valueOf(temp.substring(4), 16); + position.set(Position.PREFIX_TEMP + index, value); + } } } -- cgit v1.2.3 From 62e2696c2d8e619d90cb978fa60f714312649866 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 24 Sep 2017 14:45:14 +1300 Subject: Support additional eeLink parameters --- src/org/traccar/model/Position.java | 1 + .../traccar/protocol/EelinkProtocolDecoder.java | 41 ++++++++++++++++++++++ src/org/traccar/protocol/H02ProtocolDecoder.java | 2 +- src/org/traccar/protocol/WatchProtocolDecoder.java | 2 +- .../protocol/EelinkProtocolDecoderTest.java | 3 ++ 5 files changed, 47 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index c188124af..31af3d38a 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -37,6 +37,7 @@ public class Position extends Message { public static final String KEY_ODOMETER_SERVICE = "serviceOdometer"; // meters public static final String KEY_ODOMETER_TRIP = "tripOdometer"; // meters public static final String KEY_HOURS = "hours"; + public static final String KEY_STEPS = "steps"; public static final String KEY_INPUT = "input"; public static final String KEY_OUTPUT = "output"; public static final String KEY_IMAGE = "image"; diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 2526282b1..8d0f8016a 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -217,6 +217,45 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(7); // bss2 } + if (buf.readableBytes() >= 2) { + int status = buf.readUnsignedShort(); + position.setValid(BitUtil.check(status, 0)); + if (BitUtil.check(status, 1)) { + position.set(Position.KEY_IGNITION, BitUtil.check(status, 2)); + } + position.set(Position.KEY_STATUS, status); + } + + if (buf.readableBytes() >= 2) { + position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001); + } + + if (buf.readableBytes() >= 4) { + position.set(Position.PREFIX_ADC + 0, buf.readUnsignedShort()); + position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort()); + } + + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + + if (buf.readableBytes() >= 4) { + buf.readUnsignedShort(); // gsm counter + buf.readUnsignedShort(); // gps counter + } + + if (buf.readableBytes() >= 4) { + position.set(Position.KEY_STEPS, buf.readUnsignedShort()); + buf.readUnsignedShort(); // walking time + } + + if (buf.readableBytes() >= 12) { + position.set(Position.PREFIX_TEMP + 1, buf.readUnsignedShort() / 256.0); + position.set("humidity", buf.readUnsignedShort() * 0.1); + position.set("illuminance", buf.readUnsignedInt() / 256.0); + position.set("co2", buf.readUnsignedInt()); + } + return position; } @@ -240,6 +279,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { getDeviceSession(channel, remoteAddress, ChannelBuffers.hexDump(buf.readBytes(8)).substring(1)); } else { + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { return null; @@ -262,6 +302,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { return position; } + } return null; diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index aea8f0b3b..e4b18e277 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -392,7 +392,7 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextInt()); position.set(Position.KEY_SATELLITES, parser.nextInt()); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt()); - position.set("steps", parser.nextInt()); + position.set(Position.KEY_STEPS, parser.nextInt()); position.set("turnovers", parser.nextInt()); dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index adab65245..86dc9456d 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -205,7 +205,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextInt(0)); position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt(0)); - position.set("steps", parser.nextInt(0)); + position.set(Position.KEY_STEPS, parser.nextInt(0)); int status = parser.nextHexInt(0); position.set(Position.KEY_ALARM, decodeAlarm(status)); diff --git a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java index ca2bb463e..115eef1a3 100644 --- a/test/org/traccar/protocol/EelinkProtocolDecoderTest.java +++ b/test/org/traccar/protocol/EelinkProtocolDecoderTest.java @@ -13,6 +13,9 @@ public class EelinkProtocolDecoderTest extends ProtocolTest { verifyNull(decoder, binary( "676701000c007b03525440717505180104")); + verifyPosition(decoder, binary( + "6767120048000559c1829213059a7400008e277d000c000000000800cc00080d2a000034df3cf0b429dd82cad3048910320000000000007b7320d005ba0000000019a000000000000000000000")); + verifyPosition(decoder, binary( "6767050020213b59c6aecdff41dce70b8b977d00000001fe000a36e30078fe010159c6aecd")); -- cgit v1.2.3 From b5fc7e0899475547da99c06319ede5cc68f647e4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 25 Sep 2017 23:03:11 +1300 Subject: Improve H02 protocol decoder --- src/org/traccar/protocol/H02ProtocolDecoder.java | 4 +--- test/org/traccar/protocol/H02ProtocolDecoderTest.java | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index e4b18e277..dd5d4abd7 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -154,12 +154,10 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .text("VP1,") .or() .groupBegin() - .text("V1,") - .or() .text("V4,") .expression("(.*),") // response .or() - .text("V19,") + .expression("V[^,]*,") .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index 59882a91f..e0130aa5d 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); + verifyNull(decoder, buffer( + "*HQ,353505221264507,VI1,075146,0,5238.25900,N,00507.33429,E,0.54,0,250917,FFFFFFFF,cc,28, db,d75b#")); + verifyNull(decoder, buffer( "*HQ,353505510948929,V1,,V,,N,,E,0.00,0,,FFFFF7FF,f0,a,11a0,c0c6#")); -- cgit v1.2.3 From 152dde860450adb9ae8409d69f429f35ad1b3b13 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 26 Sep 2017 11:57:08 +0500 Subject: Improve Teltonika IO decoding --- src/org/traccar/model/CellTower.java | 6 ++ .../traccar/protocol/TeltonikaProtocolDecoder.java | 120 ++++++++++++++++++--- test/org/traccar/ProtocolTest.java | 4 + .../protocol/TeltonikaProtocolDecoderTest.java | 6 ++ 4 files changed, 124 insertions(+), 12 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/CellTower.java b/src/org/traccar/model/CellTower.java index 2eb56dd33..6d1dfbd7f 100644 --- a/src/org/traccar/model/CellTower.java +++ b/src/org/traccar/model/CellTower.java @@ -106,4 +106,10 @@ public class CellTower { this.signalStrength = signalStrength; } + public void setOperator(long operator) { + String operatorString = String.valueOf(operator); + mobileCountryCode = Integer.parseInt(operatorString.substring(0, 3)); + mobileNetworkCode = Integer.parseInt(operatorString.substring(3)); + } + } diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 4700350d4..3dd00ead7 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -113,15 +113,15 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 19: position.set("axisZ", readValue(buf, length, true)); break; + case 21: + position.set("gsmLevel", readValue(buf, length, false)); + break; case 66: position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); break; case 67: position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); break; - case 70: - position.set(Position.KEY_DEVICE_TEMP, readValue(buf, length, true) * 0.1); - break; case 72: position.set(Position.PREFIX_TEMP + 1, readValue(buf, length, true) * 0.1); break; @@ -134,15 +134,92 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 78: position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false))); break; + case 80: + position.set("workMode", readValue(buf, length, false)); + break; + case 179: + position.set(Position.PREFIX_OUT + 1, readValue(buf, length, false) == 1); + break; + case 180: + position.set(Position.PREFIX_OUT + 2, readValue(buf, length, false) == 1); + break; + case 181: + position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + break; case 182: position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); break; + case 239: + position.set(Position.KEY_IGNITION, readValue(buf, length, false) == 1); + break; + case 240: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + break; + case 241: + position.set(Position.KEY_OPERATOR, readValue(buf, length, false)); + break; + default: + position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); + break; + } + } + + private void decodeGh3000Parameter(Position position, int id, ChannelBuffer buf, int length) { + switch (id) { + case 1: + position.set(Position.KEY_BATTERY_LEVEL, readValue(buf, length, false)); + break; + case 2: + position.set("usbConnected", readValue(buf, length, false) == 1); + break; + case 5: + position.set("uptime", readValue(buf, length, false)); + break; + case 20: + position.set(Position.KEY_HDOP, readValue(buf, length, false) * 0.1); + break; + case 21: + position.set(Position.KEY_VDOP, readValue(buf, length, false) * 0.1); + break; + case 22: + position.set(Position.KEY_PDOP, readValue(buf, length, false) * 0.1); + break; + case 67: + position.set(Position.KEY_BATTERY, readValue(buf, length, false) * 0.001); + break; + case 221: + position.set("button", readValue(buf, length, false)); + break; + case 222: + if (readValue(buf, length, false) == 1) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + break; + case 240: + position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); + break; + case 244: + position.set("roaming", readValue(buf, length, false) == 1); + break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); break; } } + private void decodeNetwork(Position position) { + long cid = position.getLong(Position.PREFIX_IO + 205); + int lac = position.getInteger(Position.PREFIX_IO + 206); + if (cid != 0 && lac != 0) { + CellTower cellTower = CellTower.fromLacCid(lac, cid); + long operator = position.getInteger(Position.KEY_OPERATOR); + if (operator != 0) { + cellTower.setOperator(operator); + } + position.setNetwork(new Network(cellTower)); + } + } + private void decodeLocation(Position position, ChannelBuffer buf, int codec) { int globalMask = 0x0f; @@ -189,14 +266,19 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { cellTower.setSignalStrength((int) buf.readUnsignedByte()); } - position.setNetwork(new Network(cellTower)); + if (BitUtil.check(locationMask, 7)) { + cellTower.setOperator(buf.readUnsignedInt()); + } - } else if (BitUtil.check(locationMask, 6)) { - position.set(Position.KEY_RSSI, buf.readUnsignedByte()); - } + position.setNetwork(new Network(cellTower)); - if (BitUtil.check(locationMask, 7)) { - position.set(Position.KEY_OPERATOR, buf.readUnsignedInt()); + } else { + if (BitUtil.check(locationMask, 6)) { + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); + } + if (BitUtil.check(locationMask, 7)) { + position.set(Position.KEY_OPERATOR, buf.readUnsignedInt()); + } } } else { @@ -233,7 +315,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 1); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 1); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 1); + } } } @@ -241,7 +327,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 2); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 2); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 2); + } } } @@ -249,7 +339,11 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 4); + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 4); + } else { + decodeParameter(position, buf.readUnsignedByte(), buf, 4); + } } } @@ -269,6 +363,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + decodeNetwork(position); + } private List parseData( diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 7bff41acd..01395fc11 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -257,6 +257,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_DRIVER_UNIQUE_ID) instanceof String); } + if (attributes.containsKey(Position.KEY_STEPS)) { + Assert.assertTrue(attributes.get(Position.KEY_STEPS) instanceof Number); + } + if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { for (CellTower cellTower : position.getNetwork().getCellTowers()) { checkInteger(cellTower.getMobileCountryCode(), 0, 999); diff --git a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java index a945178a1..beae48d67 100644 --- a/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TeltonikaProtocolDecoderTest.java @@ -59,6 +59,12 @@ public class TeltonikaProtocolDecoderTest extends ProtocolTest { verifyPositions(decoder, binary( "00000000000000a608010000013f14a1d1ce000f0eb790209a778000ab010c0500000000000000000100003390")); + verifyPositions(decoder, binary( + "000000000000004508010000015eb70a86d00024089d4d21dee3860137005f12005f000e06ef01f00150011503c800450108b5000bb6000642382718005fcd057ace19d3430f57440000000001000002bf")); + + verifyPositions(decoder, binary( + "000000000000004a08010000015ebc1da508002411926621f15246010b00b913005e000f06ef01f00150011505c800450108b5000bb6000642381b18005ecd0318ce19cd430f5844000001f1000061a900010000c8e1")); + decoder.setExtended(true); verifyPositions(decoder, false, binary( -- cgit v1.2.3 From 2e4fe0f4201ff43f65e36fb1ba386a1fa26b9aab Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 26 Sep 2017 14:17:28 +0500 Subject: Added intermediate "decodeParameter" function and KEY_ROAMING attribute --- src/org/traccar/model/Position.java | 1 + .../traccar/protocol/TeltonikaProtocolDecoder.java | 32 ++++++++++------------ test/org/traccar/ProtocolTest.java | 4 +++ 3 files changed, 19 insertions(+), 18 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 31af3d38a..93456b1b0 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -30,6 +30,7 @@ public class Position extends Message { public static final String KEY_SATELLITES_VISIBLE = "satVisible"; public static final String KEY_RSSI = "rssi"; public static final String KEY_GPS = "gps"; + public static final String KEY_ROAMING = "roaming"; public static final String KEY_EVENT = "event"; public static final String KEY_ALARM = "alarm"; public static final String KEY_STATUS = "status"; diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 3dd00ead7..8754d7d81 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -93,7 +93,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - private void decodeParameter(Position position, int id, ChannelBuffer buf, int length) { + private void decodeOtherParameter(Position position, int id, ChannelBuffer buf, int length) { switch (id) { case 1: case 2: @@ -199,7 +199,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_MOTION, readValue(buf, length, false) == 1); break; case 244: - position.set("roaming", readValue(buf, length, false) == 1); + position.set(Position.KEY_ROAMING, readValue(buf, length, false) == 1); break; default: position.set(Position.PREFIX_IO + id, readValue(buf, length, false)); @@ -207,6 +207,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeParameter(Position position, int id, ChannelBuffer buf, int length, int codec) { + if (codec == CODEC_GH3000) { + decodeGh3000Parameter(position, id, buf, length); + } else { + decodeOtherParameter(position, id, buf, length); + } + } + private void decodeNetwork(Position position) { long cid = position.getLong(Position.PREFIX_IO + 205); int lac = position.getInteger(Position.PREFIX_IO + 206); @@ -315,11 +323,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 1)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 1); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 1); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 1, codec); } } @@ -327,11 +331,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 2)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 2); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 2); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 2, codec); } } @@ -339,11 +339,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (BitUtil.check(globalMask, 3)) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - if (codec == CODEC_GH3000) { - decodeGh3000Parameter(position, buf.readUnsignedByte(), buf, 4); - } else { - decodeParameter(position, buf.readUnsignedByte(), buf, 4); - } + decodeParameter(position, buf.readUnsignedByte(), buf, 4, codec); } } @@ -351,7 +347,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (codec == CODEC_FM4X00) { int cnt = buf.readUnsignedByte(); for (int j = 0; j < cnt; j++) { - decodeParameter(position, buf.readUnsignedByte(), buf, 8); + decodeOtherParameter(position, buf.readUnsignedByte(), buf, 8); } } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index 01395fc11..1daefabd6 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -261,6 +261,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_STEPS) instanceof Number); } + if (attributes.containsKey(Position.KEY_ROAMING)) { + Assert.assertTrue(attributes.get(Position.KEY_ROAMING) instanceof Boolean); + } + if (position.getNetwork() != null && position.getNetwork().getCellTowers() != null) { for (CellTower cellTower : position.getNetwork().getCellTowers()) { checkInteger(cellTower.getMobileCountryCode(), 0, 999); -- cgit v1.2.3 From 5a515b9e2995602a686436106922362910b8a5c1 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 26 Sep 2017 16:47:14 +0500 Subject: Use RSSI to store GSM signal level --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 8754d7d81..ddc113816 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -114,7 +114,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set("axisZ", readValue(buf, length, true)); break; case 21: - position.set("gsmLevel", readValue(buf, length, false)); + position.set(Position.KEY_RSSI, readValue(buf, length, false)); break; case 66: position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); -- cgit v1.2.3 From b44223a1bdba7c3c793600f4beac232206067b01 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 27 Sep 2017 06:05:16 +1300 Subject: Decode SunTech alerts --- .../traccar/protocol/SuntechProtocolDecoder.java | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 3b350ba64..320df9c94 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -114,6 +114,8 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { switch (value) { case 1: return Position.ALARM_SOS; + case 2: + return Position.ALARM_PARKING; case 3: return Position.ALARM_POWER_CUT; case 5: @@ -128,6 +130,33 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { } } + private String decodeAlert(int value) { + switch (value) { + case 1: + return Position.ALARM_OVERSPEED; + case 5: + return Position.ALARM_GEOFENCE_EXIT; + case 6: + return Position.ALARM_GEOFENCE_ENTER; + case 14: + return Position.ALARM_LOW_BATTERY; + case 15: + return Position.ALARM_SHOCK; + case 16: + return Position.ALARM_ACCIDENT; + case 46: + return Position.ALARM_ACCELERATION; + case 47: + return Position.ALARM_BREAKING; + case 48: + return Position.ALARM_ACCIDENT; + case 50: + return Position.ALARM_JAMMING; + default: + return null; + } + } + private Position decode235( Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException { int index = 0; @@ -193,9 +222,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, decodeEmergency(Integer.parseInt(values[index++]))); break; case "EVT": - case "ALT": position.set(Position.KEY_EVENT, Integer.parseInt(values[index++])); break; + case "ALT": + position.set(Position.KEY_ALARM, decodeAlert(Integer.parseInt(values[index++]))); + break; default: break; } -- cgit v1.2.3 From 4ef26b62cb97fc2afa5fdcf260c5fffbdc454c25 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 27 Sep 2017 15:27:10 +1300 Subject: Fix typo in alarm name --- src/org/traccar/model/Position.java | 2 +- src/org/traccar/protocol/AplicomProtocolDecoder.java | 2 +- src/org/traccar/protocol/AquilaProtocolDecoder.java | 4 ++-- src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 14 +++++++------- src/org/traccar/protocol/Pt502ProtocolDecoder.java | 2 +- src/org/traccar/protocol/SuntechProtocolDecoder.java | 2 +- src/org/traccar/protocol/TaipProtocolDecoder.java | 2 +- src/org/traccar/protocol/TzoneProtocolDecoder.java | 2 +- src/org/traccar/protocol/Vt200ProtocolDecoder.java | 2 +- src/org/traccar/protocol/VtfmsProtocolDecoder.java | 2 +- 10 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 93456b1b0..099e6d686 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -115,7 +115,7 @@ public class Position extends Message { public static final String ALARM_ACCIDENT = "accident"; public static final String ALARM_TOW = "tow"; public static final String ALARM_ACCELERATION = "hardAcceleration"; - public static final String ALARM_BREAKING = "hardBreaking"; + public static final String ALARM_BRAKING = "hardBraking"; public static final String ALARM_CORNERING = "hardCornering"; public static final String ALARM_FATIGUE_DRIVING = "fatigueDriving"; public static final String ALARM_POWER_CUT = "powerCut"; diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java index 94d12c633..154451b5b 100644 --- a/src/org/traccar/protocol/AplicomProtocolDecoder.java +++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java @@ -568,7 +568,7 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_OBD_SPEED, buf.readUnsignedByte()); position.set("speedMax", buf.readUnsignedByte()); position.set("speedMin", buf.readUnsignedByte()); - position.set("hardBreaking", buf.readUnsignedByte()); + position.set("hardBraking", buf.readUnsignedByte()); } if ((selector & 0x0200) != 0) { diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java index 5ff974a7d..773210b04 100644 --- a/src/org/traccar/protocol/AquilaProtocolDecoder.java +++ b/src/org/traccar/protocol/AquilaProtocolDecoder.java @@ -81,7 +81,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("[01],") // corner packet .number("(?:d+,){6}") // reserved .number("[01],") // hard acceleration - .number("[01],") // hard breaking + .number("[01],") // hard braking .number("[01],[01],[01],[01],") // course bits .number("(d+),") // external voltage .number("(d+),") // internal voltage @@ -115,7 +115,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder { .number("[01],") // do 1 .number("[01],") // reserved .number("[01],") // hard acceleration - .number("[01],") // hard breaking + .number("[01],") // hard braking .number("(?:[01],){4}") // reserved .number("(d+),") // external voltage .number("(d+),") // internal voltage diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index b9725337b..e41a42843 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -94,8 +94,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+),") // single fuel consumption .number("(d+.d+),") // total fuel consumption .number("(d+),") // error code count - .number("(d+),") // harsh acceleration count - .number("(d+)") // harsh break count + .number("(d+),") // hard acceleration count + .number("(d+)") // hard brake count .compile(); private static final Pattern PATTERN_OBDA = new PatternBuilder() @@ -106,8 +106,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // average speed .number("(d+),") // history highest speed .number("(d+),") // history highest rpm - .number("(d+),") // total harsh acceleration - .number("(d+)") // total harsh break n0 + .number("(d+),") // total hard acceleration + .number("(d+)") // total hard brake .compile(); public static final int MSG_HEARTBEAT = 0x0001; @@ -201,7 +201,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { case 0x53: return Position.ALARM_GPS_ANTENNA_CUT; case 0x72: - return Position.ALARM_BREAKING; + return Position.ALARM_BRAKING; case 0x73: return Position.ALARM_ACCELERATION; default: @@ -301,8 +301,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.set("singleFuelConsumption", parser.nextDouble()); position.set("totalFuelConsumption", parser.nextDouble()); position.set(Position.KEY_DTCS, parser.nextInt()); - position.set("harshAcelerationNo", parser.nextInt()); - position.set("harshBreakerNo", parser.nextInt()); + position.set("hardAccelerationCount", parser.nextInt()); + position.set("hardBrakingCount", parser.nextInt()); return position; } diff --git a/src/org/traccar/protocol/Pt502ProtocolDecoder.java b/src/org/traccar/protocol/Pt502ProtocolDecoder.java index e12bbdf28..fef5d9b39 100644 --- a/src/org/traccar/protocol/Pt502ProtocolDecoder.java +++ b/src/org/traccar/protocol/Pt502ProtocolDecoder.java @@ -67,7 +67,7 @@ public class Pt502ProtocolDecoder extends BaseProtocolDecoder { case "HDA": return Position.ALARM_ACCELERATION; case "HDB": - return Position.ALARM_BREAKING; + return Position.ALARM_BRAKING; case "FDA": return Position.ALARM_FATIGUE_DRIVING; case "SKA": diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java index 320df9c94..6dfc6f77f 100644 --- a/src/org/traccar/protocol/SuntechProtocolDecoder.java +++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java @@ -147,7 +147,7 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder { case 46: return Position.ALARM_ACCELERATION; case 47: - return Position.ALARM_BREAKING; + return Position.ALARM_BRAKING; case 48: return Position.ALARM_ACCIDENT; case 50: diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index 6edf4a93e..c6220ab1d 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -124,7 +124,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION); break; case 23: - position.set(Position.KEY_ALARM, Position.ALARM_BREAKING); + position.set(Position.KEY_ALARM, Position.ALARM_BRAKING); break; case 24: position.set(Position.KEY_ALARM, Position.ALARM_ACCIDENT); diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index 69aa916df..76903c90c 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java @@ -43,7 +43,7 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { case 0x11: return Position.ALARM_OVERSPEED; case 0x14: - return Position.ALARM_BREAKING; + return Position.ALARM_BRAKING; case 0x15: return Position.ALARM_ACCELERATION; case 0x30: diff --git a/src/org/traccar/protocol/Vt200ProtocolDecoder.java b/src/org/traccar/protocol/Vt200ProtocolDecoder.java index 6be70c3c1..2ae24efbb 100644 --- a/src/org/traccar/protocol/Vt200ProtocolDecoder.java +++ b/src/org/traccar/protocol/Vt200ProtocolDecoder.java @@ -124,7 +124,7 @@ public class Vt200ProtocolDecoder extends BaseProtocolDecoder { position.set("maxRpm", buf.readUnsignedShort()); position.set("maxTemp", buf.readUnsignedByte() - 40); position.set("hardAccelerationCount", buf.readUnsignedByte()); - position.set("hardBreakingCount", buf.readUnsignedByte()); + position.set("hardBrakingCount", buf.readUnsignedByte()); for (String speedType : Arrays.asList("over", "high", "normal", "low")) { position.set(speedType + "SpeedTime", buf.readUnsignedShort()); diff --git a/src/org/traccar/protocol/VtfmsProtocolDecoder.java b/src/org/traccar/protocol/VtfmsProtocolDecoder.java index 852b9a749..5fb687e6d 100644 --- a/src/org/traccar/protocol/VtfmsProtocolDecoder.java +++ b/src/org/traccar/protocol/VtfmsProtocolDecoder.java @@ -84,7 +84,7 @@ public class VtfmsProtocolDecoder extends BaseProtocolDecoder { case 15: return Position.ALARM_POWER_RESTORED; case 32: - return Position.ALARM_BREAKING; + return Position.ALARM_BRAKING; case 33: return Position.ALARM_ACCELERATION; default: -- cgit v1.2.3 From 7573aa48ebc870005cd03c6246290efed5c8e657 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 28 Sep 2017 01:47:17 +1300 Subject: Support new H02 message types --- src/org/traccar/protocol/H02ProtocolDecoder.java | 8 ++++++++ test/org/traccar/protocol/H02ProtocolDecoderTest.java | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/H02ProtocolDecoder.java b/src/org/traccar/protocol/H02ProtocolDecoder.java index dd5d4abd7..4414870d2 100644 --- a/src/org/traccar/protocol/H02ProtocolDecoder.java +++ b/src/org/traccar/protocol/H02ProtocolDecoder.java @@ -161,7 +161,11 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { .groupEnd() .number("(?:(dd)(dd)(dd))?,") // time (hhmmss) .groupEnd() + .groupBegin() .expression("([ABV])?,") // validity + .or() + .number("(d+),") // coding scheme + .groupEnd() .groupBegin() .number("-(d+)-(d+.d+),") // latitude .or() @@ -279,6 +283,10 @@ public class H02ProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { position.setValid(parser.next().equals("A")); } + if (parser.hasNext()) { + parser.nextInt(); // coding scheme + position.setValid(true); + } if (parser.hasNext(2)) { position.setLatitude(-parser.nextCoordinate()); diff --git a/test/org/traccar/protocol/H02ProtocolDecoderTest.java b/test/org/traccar/protocol/H02ProtocolDecoderTest.java index e0130aa5d..bea65a540 100644 --- a/test/org/traccar/protocol/H02ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/H02ProtocolDecoderTest.java @@ -11,7 +11,7 @@ public class H02ProtocolDecoderTest extends ProtocolTest { H02ProtocolDecoder decoder = new H02ProtocolDecoder(new H02Protocol()); - verifyNull(decoder, buffer( + verifyPosition(decoder, buffer( "*HQ,353505221264507,VI1,075146,0,5238.25900,N,00507.33429,E,0.54,0,250917,FFFFFFFF,cc,28, db,d75b#")); verifyNull(decoder, buffer( -- cgit v1.2.3 From d793e868311918f039fc201fbe2608c6bd5ae3f3 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 29 Sep 2017 01:45:43 +1300 Subject: Add more GL200 states --- .../traccar/protocol/Gl200TextProtocolDecoder.java | 41 ++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 090e02812..2f03cbb8f 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -394,22 +394,35 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return null; } - String status = parser.next(); - - if (status.charAt(0) == '2') { - position.set(Position.KEY_IGNITION, true); - } else if (status.charAt(0) == '4') { - position.set(Position.KEY_IGNITION, false); - } - - if (status.charAt(1) == '1') { - position.set(Position.KEY_MOTION, false); - } else if (status.charAt(1) == '2') { - position.set(Position.KEY_MOTION, true); + switch (parser.nextHexInt()) { + case 0x16: + case 0x1A: + case 0x12: + position.set(Position.KEY_IGNITION, false); + position.set(Position.KEY_MOTION, true); + break; + case 0x11: + position.set(Position.KEY_IGNITION, false); + position.set(Position.KEY_MOTION, false); + break; + case 0x21: + position.set(Position.KEY_IGNITION, true); + position.set(Position.KEY_MOTION, false); + break; + case 0x22: + position.set(Position.KEY_IGNITION, true); + position.set(Position.KEY_MOTION, true); + break; + case 0x41: + position.set(Position.KEY_MOTION, false); + break; + case 0x42: + position.set(Position.KEY_MOTION, true); + break; + default: + break; } - position.set(Position.KEY_STATUS, status); - position.set(Position.KEY_RSSI, parser.nextInt()); parser.next(); // odometer or external power -- cgit v1.2.3 From cff01fd43198ce786981dd8a51061dd0d415ccfd Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 29 Sep 2017 19:17:55 +1300 Subject: Improve GT06 frame decoder --- src/org/traccar/protocol/Gt06FrameDecoder.java | 19 +++++++++---------- test/org/traccar/protocol/Gt06FrameDecoderTest.java | 12 ++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index f35af6572..9b93979e4 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 - 2016 Anton Tananaev (anton@traccar.org) + * Copyright 2014 - 2017 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. @@ -26,7 +26,6 @@ public class Gt06FrameDecoder extends FrameDecoder { protected Object decode( ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { - // Check minimum length if (buf.readableBytes() < 5) { return null; } @@ -35,19 +34,19 @@ public class Gt06FrameDecoder extends FrameDecoder { if (buf.getByte(buf.readerIndex()) == 0x78) { length += 1 + buf.getUnsignedByte(buf.readerIndex() + 2); - - int type = buf.getUnsignedByte(buf.readerIndex() + 3); - if (type == Gt06ProtocolDecoder.MSG_STATUS && length == 13) { - length += 2; // workaround for #1727 - } - } else { length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); } - // Check length and return buffer if (buf.readableBytes() >= length) { - return buf.readBytes(length); + if (buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { + return buf.readBytes(length); + } else { + int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x0d); + if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { + return buf.readBytes(endIndex + 2 - buf.readerIndex()); + } + } } return null; diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 12ee6bb60..78d1eb920 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -11,6 +11,18 @@ public class Gt06FrameDecoderTest extends ProtocolTest { Gt06FrameDecoder decoder = new Gt06FrameDecoder(); + Assert.assertEquals( + binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"), + decoder.decode(null, null, binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"))); + + Assert.assertEquals( + binary("7878121011091c0b1e2e98058507f80097a6ac03344a0d0a"), + decoder.decode(null, null, binary("7878121011091c0b1e2e98058507f80097a6ac03344a0d0a"))); + + Assert.assertEquals( + binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"), + decoder.decode(null, null, binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"))); + Assert.assertEquals( binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); -- cgit v1.2.3 From 36d09739e518f715800c924c90f0b598a9912433 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 30 Sep 2017 20:22:05 +1300 Subject: Decode StarLink alarms --- .../traccar/protocol/StarLinkProtocolDecoder.java | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/StarLinkProtocolDecoder.java b/src/org/traccar/protocol/StarLinkProtocolDecoder.java index 38f6980f6..79f013fac 100644 --- a/src/org/traccar/protocol/StarLinkProtocolDecoder.java +++ b/src/org/traccar/protocol/StarLinkProtocolDecoder.java @@ -69,6 +69,29 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { return value.charAt(0) == '+' ? result : -result; } + private String decodeAlarm(int event) { + switch (event) { + case 6: + return Position.ALARM_OVERSPEED; + case 7: + return Position.ALARM_GEOFENCE_ENTER; + case 8: + return Position.ALARM_GEOFENCE_EXIT; + case 9: + return Position.ALARM_POWER_CUT; + case 11: + return Position.ALARM_LOW_BATTERY; + case 26: + return Position.ALARM_TOW; + case 36: + return Position.ALARM_SOS; + case 42: + return Position.ALARM_JAMMING; + default: + return null; + } + } + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -109,6 +132,7 @@ public class StarLinkProtocolDecoder extends BaseProtocolDecoder { break; case "#EID#": event = Integer.parseInt(data[i]); + position.set(Position.KEY_ALARM, decodeAlarm(event)); position.set(Position.KEY_EVENT, event); break; case "#PDT#": -- cgit v1.2.3 From 81e6d5825615fbe0be253e500b2c997f304349e6 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 1 Oct 2017 08:56:53 +1300 Subject: Workaround for GT06 frame decoder --- src/org/traccar/protocol/Gt06FrameDecoder.java | 19 ++++++++++--------- test/org/traccar/protocol/Gt06FrameDecoderTest.java | 8 ++++---- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/Gt06FrameDecoder.java b/src/org/traccar/protocol/Gt06FrameDecoder.java index 9b93979e4..c8b5e56ae 100644 --- a/src/org/traccar/protocol/Gt06FrameDecoder.java +++ b/src/org/traccar/protocol/Gt06FrameDecoder.java @@ -38,17 +38,18 @@ public class Gt06FrameDecoder extends FrameDecoder { length += 2 + buf.getUnsignedShort(buf.readerIndex() + 2); } - if (buf.readableBytes() >= length) { - if (buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { - return buf.readBytes(length); - } else { - int endIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x0d); - if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { - return buf.readBytes(endIndex + 2 - buf.readerIndex()); - } - } + if (buf.readableBytes() >= length && buf.getUnsignedShort(buf.readerIndex() + length - 2) == 0x0d0a) { + return buf.readBytes(length); } + int endIndex = buf.readerIndex() - 1; + do { + endIndex = buf.indexOf(endIndex + 1, buf.writerIndex(), (byte) 0x0d); + if (endIndex > 0 && buf.writerIndex() > endIndex + 1 && buf.getByte(endIndex + 1) == 0x0a) { + return buf.readBytes(endIndex + 2 - buf.readerIndex()); + } + } while (endIndex > 0); + return null; } diff --git a/test/org/traccar/protocol/Gt06FrameDecoderTest.java b/test/org/traccar/protocol/Gt06FrameDecoderTest.java index 78d1eb920..ff9d4f51d 100644 --- a/test/org/traccar/protocol/Gt06FrameDecoderTest.java +++ b/test/org/traccar/protocol/Gt06FrameDecoderTest.java @@ -11,6 +11,10 @@ public class Gt06FrameDecoderTest extends ProtocolTest { Gt06FrameDecoder decoder = new Gt06FrameDecoder(); + Assert.assertEquals( + binary("78780d0103563140414198583c0d0a"), + decoder.decode(null, null, binary("78780d0103563140414198583c0d0a"))); + Assert.assertEquals( binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"), decoder.decode(null, null, binary("787800691709261259400700cc0400d376714600d37a3d5000d37a3c5000d393505a00d3765d5a00d376735a00d32e6b640d0a"))); @@ -23,10 +27,6 @@ public class Gt06FrameDecoderTest extends ProtocolTest { binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"), decoder.decode(null, null, binary("787808171709281135331491827b75594dc8d719a9708452cad719a9708550cad719a97086521491827b75574cac9e17b308085dc8d71939633947cad71939633a480700cc0400d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a00d37a3d5a0d0a"))); - Assert.assertEquals( - binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"), - decoder.decode(null, null, binary("78781f1210020e140613cc04770690003e3f2e3414b20000000000000000044c446a0d0a"))); - Assert.assertEquals( binary("787808134606020002044dc5050d0a"), decoder.decode(null, null, binary("787808134606020002044dc5050d0a"))); -- cgit v1.2.3 From 662cbd6f1b2c0eae0bbc59fe9341c043f5b7872a Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 5 Oct 2017 08:38:46 +0900 Subject: Make some parameters optional --- src/org/traccar/protocol/CradlepointProtocolDecoder.java | 8 ++++---- test/org/traccar/protocol/CradlepointProtocolDecoderTest.java | 6 ++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index a1b42edf9..67a140cf7 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -40,11 +40,11 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { .expression("([EW]),") .number("(d+.d+)?,") // speed .number("(d+.d+)?,") // course - .expression("([^,]+),") // carrier + .expression("([^,]+)?,") // carrier .expression("([^,]+)?,") // serdis - .number("(-?d+),") // rsrp - .number("(-?d+),") // rssi - .number("(-?d+),") // rsrq + .number("(-?d+)?,") // rsrp + .number("(-?d+)?,") // rssi + .number("(-?d+)?,") // rsrq .expression("([^,]+)?,") // ecio .expression("([^,]+)?") // wan ip .compile(); diff --git a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 4f37d3e1e..7eae791d5 100644 --- a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { CradlepointProtocolDecoder decoder = new CradlepointProtocolDecoder(new CradlepointProtocol()); + verifyPosition(decoder, text( + "353547063544681,170515,3613.25,N,11559.14,W,0.0,,,,,,,,")); + + verifyPosition(decoder, text( + "353547060558130,170519,4337.17,N,11612.34,W,0.0,294.7,,,,,,,")); + verifyPosition(decoder, text( "+12084014675,162658,4337.174385,N,11612.338373,W,0.0,,Verizon,,-71,-44,-11,,")); -- cgit v1.2.3 From 7ae0d8de4b5c78e9265a9a5cbb5b19ef19a4f017 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 8 Oct 2017 13:43:01 +0800 Subject: Support alternative Xexun ignition --- src/org/traccar/protocol/XexunProtocolDecoder.java | 2 ++ test/org/traccar/protocol/XexunProtocolDecoderTest.java | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index a5a38c370..ca0a8669e 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -68,9 +68,11 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { if (value != null) { switch (value.toLowerCase()) { case "acc on": + case "ACCStart": position.set(Position.KEY_IGNITION, true); break; case "acc off": + case "ACCStop": position.set(Position.KEY_IGNITION, false); break; case "help me!": diff --git a/test/org/traccar/protocol/XexunProtocolDecoderTest.java b/test/org/traccar/protocol/XexunProtocolDecoderTest.java index 686d3f53f..8587ee295 100644 --- a/test/org/traccar/protocol/XexunProtocolDecoderTest.java +++ b/test/org/traccar/protocol/XexunProtocolDecoderTest.java @@ -55,6 +55,12 @@ public class XexunProtocolDecoderTest extends ProtocolTest { decoder = new XexunProtocolDecoder(new XexunProtocol(), true); + verifyPosition(decoder, text( + "171007160505,,GPRMC,160505.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*7A,F,ACCStart, imei:864504031916915,10,41.1,F:4.28V,1,135,19824,234,15,0062,B7D5")); + + verifyPosition(decoder, text( + "171007160525,,GPRMC,160525.000,A,5323.4680,N,00252.4202,W,000.0,129.7,071017,,,A*78,F,ACCStop, imei:864504031916915,10,41.1,F:4.28V,1,134,42896,234,15,0062,B7D5")); + verifyPosition(decoder, text( "170505103845,TELKOMSEL,GPRMC,103845.000,A,0340.2482,N,09841.9689,E,0.00,68.23,050517,,,A*5D,F,ACC On, imei:013227002782161,05,-8.2,F:4.22V,1,141,44712,510,10,2BE5,EC47")); -- cgit v1.2.3 From b2ed61db9d33324222c7cbdc5a133152ede0c1ac Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 9 Oct 2017 08:14:47 +0800 Subject: Decode hex driver id --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index ddc113816..80f0045d5 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -132,7 +132,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); break; case 78: - position.set(Position.KEY_DRIVER_UNIQUE_ID, String.valueOf(readValue(buf, length, false))); + position.set(Position.KEY_DRIVER_UNIQUE_ID, String.format("%016X", readValue(buf, length, false))); break; case 80: position.set("workMode", readValue(buf, length, false)); -- cgit v1.2.3 From bf44a4d63d6e1b2a52999ec656a23f90ed4e4389 Mon Sep 17 00:00:00 2001 From: Kirk Ryan Date: Tue, 10 Oct 2017 11:19:03 +0100 Subject: Update case statement Xexun A proposed change to allow for the correct use of value.toLowerCase() handling (case-insensitive switch statement functionality. --- src/org/traccar/protocol/XexunProtocolDecoder.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/XexunProtocolDecoder.java b/src/org/traccar/protocol/XexunProtocolDecoder.java index ca0a8669e..bb4b4f48c 100644 --- a/src/org/traccar/protocol/XexunProtocolDecoder.java +++ b/src/org/traccar/protocol/XexunProtocolDecoder.java @@ -68,11 +68,11 @@ public class XexunProtocolDecoder extends BaseProtocolDecoder { if (value != null) { switch (value.toLowerCase()) { case "acc on": - case "ACCStart": + case "accstart": position.set(Position.KEY_IGNITION, true); break; case "acc off": - case "ACCStop": + case "accstop": position.set(Position.KEY_IGNITION, false); break; case "help me!": -- cgit v1.2.3 From 3f5a5e81fe08c7ae0b136d52b4840d5085e12f23 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 15 Oct 2017 11:15:55 +0800 Subject: Update tzone protocol --- src/org/traccar/protocol/TzoneProtocolDecoder.java | 11 ++++++++++- test/org/traccar/protocol/TzoneProtocolDecoderTest.java | 3 +++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TzoneProtocolDecoder.java b/src/org/traccar/protocol/TzoneProtocolDecoder.java index 76903c90c..079ad3126 100644 --- a/src/org/traccar/protocol/TzoneProtocolDecoder.java +++ b/src/org/traccar/protocol/TzoneProtocolDecoder.java @@ -203,7 +203,16 @@ public class TzoneProtocolDecoder extends BaseProtocolDecoder { if (blockLength >= 13) { position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); position.set("terminalInfo", buf.readUnsignedByte()); - position.set(Position.PREFIX_IO + 1, buf.readUnsignedShort()); + + int status = buf.readUnsignedByte(); + position.set(Position.PREFIX_OUT + 1, BitUtil.check(status, 0)); + position.set(Position.PREFIX_OUT + 2, BitUtil.check(status, 1)); + status = buf.readUnsignedByte(); + position.set(Position.PREFIX_IN + 1, BitUtil.check(status, 4)); + if (BitUtil.check(status, 0)) { + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + } + position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set("gsmStatus", buf.readUnsignedByte()); position.set(Position.KEY_BATTERY, buf.readUnsignedShort()); diff --git a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java index aa8f61772..68c8bbdbc 100644 --- a/test/org/traccar/protocol/TzoneProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TzoneProtocolDecoderTest.java @@ -11,6 +11,9 @@ public class TzoneProtocolDecoderTest extends ProtocolTest { TzoneProtocolDecoder decoder = new TzoneProtocolDecoder(new TzoneProtocol()); + verifyPosition(decoder, binary( + "545a005624240111010e0000086169303626931411091b151d2600160801de26ec002f633411091b151d2500000000160c0000040d2a34df000eaa4000001b37016000000000319c0000000000000000000000000000003a84240d0a")); + verifyPosition(decoder, binary( "545a005024240153011000000863835025559464110103080a22001609011bed79245964a9110103080a22000a0000550c00000604396f04222c000daac000151701a204870000000000000003000959000546190d0a")); -- cgit v1.2.3 From 4ba8252588c0d280434c83b9d855098be3a15dd9 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 19 Oct 2017 04:35:39 +1300 Subject: Update Cradlepoint decoder (fix #3581) --- .../protocol/CradlepointProtocolDecoder.java | 26 +++++++++++++++------- .../protocol/CradlepointProtocolDecoderTest.java | 12 ++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/CradlepointProtocolDecoder.java b/src/org/traccar/protocol/CradlepointProtocolDecoder.java index 67a140cf7..e8f95a60c 100644 --- a/src/org/traccar/protocol/CradlepointProtocolDecoder.java +++ b/src/org/traccar/protocol/CradlepointProtocolDecoder.java @@ -18,11 +18,13 @@ package org.traccar.protocol; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.model.Position; import java.net.SocketAddress; +import java.util.Date; import java.util.regex.Pattern; public class CradlepointProtocolDecoder extends BaseProtocolDecoder { @@ -33,7 +35,7 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .expression("([^,]+),") // id - .number("(dd)(dd)(dd),") // time (hhmmss) + .number("(d{1,6}),") // time (hhmmss) .number("(d+)(dd.d+),") // latitude .expression("([NS]),") .number("(d+)(dd.d+),") // longitude @@ -58,16 +60,21 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS)); + int time = parser.nextInt(); + DateBuilder dateBuilder = new DateBuilder(new Date()); + dateBuilder.setHour(time / 100 / 100); + dateBuilder.setMinute(time / 100 % 100); + dateBuilder.setSecond(time % 100); + position.setTime(dateBuilder.getDate()); position.setValid(true); position.setLatitude(parser.nextCoordinate()); @@ -75,9 +82,12 @@ public class CradlepointProtocolDecoder extends BaseProtocolDecoder { position.setSpeed(parser.nextDouble(0)); position.setCourse(parser.nextDouble(0)); - parser.skip(3); - - position.set(Position.KEY_RSSI, parser.nextDouble()); + position.set("carrid", parser.next()); + position.set("serdis", parser.next()); + position.set("rsrp", parser.next()); + position.set("dbm", parser.next()); + position.set("rsrq", parser.next()); + position.set("ecio", parser.next()); return position; } diff --git a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java index 7eae791d5..757298682 100644 --- a/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java +++ b/test/org/traccar/protocol/CradlepointProtocolDecoderTest.java @@ -10,6 +10,18 @@ public class CradlepointProtocolDecoderTest extends ProtocolTest { CradlepointProtocolDecoder decoder = new CradlepointProtocolDecoder(new CradlepointProtocol()); + verifyPosition(decoder, text( + "356526070063940,0,4337.19009,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); + + verifyPosition(decoder, text( + "356526070063940,1,4337.19008,N,11612.34705,W,0.0,277.2,AT&T,,,-79,,-14.0,")); + + verifyPosition(decoder, text( + "+14063964266,162658,4333.62404,N,11636.23469,W,0.0,,Verizon Wireless,LTE,-107,-74,-16,,100.68.169.178")); + + verifyPosition(decoder, text( + "+12084014675,162658,4337.174385,N,11612.338373,W,0.0,,Verizon,,-71,-44,-11,,")); + verifyPosition(decoder, text( "353547063544681,170515,3613.25,N,11559.14,W,0.0,,,,,,,,")); -- cgit v1.2.3 From f5d309d193d1549d29314310b9c2a7bf0caf42af Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 20 Oct 2017 00:02:59 +1300 Subject: Fix download photo command --- src/org/traccar/protocol/MeitrackProtocolDecoder.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 4714e24ea..efc9c24db 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -20,6 +20,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.Context; import org.traccar.DeviceSession; +import org.traccar.helper.Checksum; import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; @@ -313,7 +314,6 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; - // Find type int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); index = buf.indexOf(index + 1, buf.writerIndex(), (byte) ','); @@ -323,7 +323,11 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (channel != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); - channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n"); + String content = "D00,camera_picture.jpg,0"; + int length = 1 + imei.length() + 1 + content.length() + 5; + String response = String.format("@@O%02d,%s,%s*", length, imei, content); + response += Checksum.sum(response) + "\r\n"; + channel.write(response); } return null; case "CCC": -- cgit v1.2.3 From 6b5c8006f27153886618e091466073dbb9983c0f Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 Oct 2017 11:30:35 +1300 Subject: Allow per-device configuration --- src/org/traccar/protocol/T55ProtocolDecoder.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index 43e1a57f7..6b4ee6ebd 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -31,11 +31,8 @@ import java.util.regex.Pattern; public class T55ProtocolDecoder extends BaseProtocolDecoder { - private final boolean ack; - public T55ProtocolDecoder(T55Protocol protocol) { super(protocol); - ack = Context.getConfig().getBoolean(getProtocolName() + ".ack"); } private static final Pattern PATTERN_GPRMC = new PatternBuilder() @@ -102,8 +99,11 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { private Position decodeGprmc( DeviceSession deviceSession, String sentence, SocketAddress remoteAddress, Channel channel) { - if (ack && channel != null && !(channel instanceof DatagramChannel)) { - channel.write("OK1\r\n"); + if (deviceSession != null && channel != null && !(channel instanceof DatagramChannel)) { + if (Context.getIdentityManager().lookupAttributeBoolean( + deviceSession.getDeviceId(), getProtocolName() + ".ack", false, true)) { + channel.write("OK1\r\n"); + } } Parser parser = new Parser(PATTERN_GPRMC, sentence); -- cgit v1.2.3 From 9ace2318b9ea5a2d949800eedff8398808d3a6ce Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 21 Oct 2017 18:24:27 +1300 Subject: Support GVT900E device protocol --- src/org/traccar/protocol/MegastekProtocolDecoder.java | 8 ++++---- test/org/traccar/protocol/MegastekProtocolDecoderTest.java | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 994e2d983..3ef52acd1 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -267,7 +267,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { .or().text(" ") .groupEnd("?").text(",") .number("(d+)?,") // rfid - .number("d*,") + .expression("[^,]*,") .number("(d+)?,") // battery .expression("([^,]*);") // alert .any() @@ -280,13 +280,13 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { return null; } - Position position = new Position(); - position.setProtocol(getProtocolName()); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); if (parser.next().equals("S")) { diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java index 106baff98..583de513c 100644 --- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java +++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java @@ -10,6 +10,9 @@ public class MegastekProtocolDecoderTest extends ProtocolTest { MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(new MegastekProtocol()); + verifyPosition(decoder, text( + "0170$MGV002,354550056642321,GVT900-3,S,011017,090208,A,1635.8484,N,10446.6095,E,00,09,00,0.91,16.980,257.73,177.6,0.0,457,01,0741,00C0,21,0000,0000,20,10,0, , ,,1-1,54,Dist;!")); + verifyNull(decoder, text( "0140$MGV002,354550056642321,GVT900-3,S,300917,071731,V,,,,,00,00,00,99.9,0.000,0.00,,0.0,457,01,0741,00CD,,0000,0000,20,10,0, , ,,1-1,94,PW ON;!")); -- cgit v1.2.3 From 96e15853b9c28bd31295ca2c014e226e4a50aaa1 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 24 Oct 2017 23:41:30 +1300 Subject: Improve TAIP validity handling --- src/org/traccar/protocol/TaipProtocolDecoder.java | 3 +-- test/org/traccar/protocol/TaipProtocolDecoderTest.java | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/org/traccar/protocol') diff --git a/src/org/traccar/protocol/TaipProtocolDecoder.java b/src/org/traccar/protocol/TaipProtocolDecoder.java index c6220ab1d..e7117a5c9 100644 --- a/src/org/traccar/protocol/TaipProtocolDecoder.java +++ b/src/org/traccar/protocol/TaipProtocolDecoder.java @@ -68,7 +68,6 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { .number("(x{8})") // odometer .number("[01]") // gps power .groupEnd("?") - .number("(d)") // fix mode .any() .compile(); @@ -162,7 +161,7 @@ public class TaipProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_ODOMETER, parser.nextLong(16, 0)); } - position.setValid(parser.nextInt(0) != 0); + position.setValid(true); String[] attributes = null; beginIndex = sentence.indexOf(';'); diff --git a/test/org/traccar/protocol/TaipProtocolDecoderTest.java b/test/org/traccar/protocol/TaipProtocolDecoderTest.java index e2de26ec0..beba54d74 100644 --- a/test/org/traccar/protocol/TaipProtocolDecoderTest.java +++ b/test/org/traccar/protocol/TaipProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class TaipProtocolDecoderTest extends ProtocolTest { TaipProtocolDecoder decoder = new TaipProtocolDecoder(new TaipProtocol()); + verifyPosition(decoder, text( + ">RPV46640+4197412-0752857900015802;ID=5102;*71<")); + + verifyNull(decoder, text( + ">RCP46640+419741-075285802;ID=5102;*6C<")); + verifyPosition(decoder, text( ">REV001958003965+0307178+1016144900031532;IO=300;SV=8;BL=4159;CF=8161,C,13;AD=14145;IX=10233040;FF=0,0,0,0;VO=338578;ID=357042063052352<")); -- cgit v1.2.3