diff options
3 files changed, 58 insertions, 17 deletions
diff --git a/src/main/java/org/traccar/protocol/WialonProtocol.java b/src/main/java/org/traccar/protocol/WialonProtocol.java index 3838791a7..fd183dd2c 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocol.java +++ b/src/main/java/org/traccar/protocol/WialonProtocol.java @@ -38,11 +38,28 @@ public class WialonProtocol extends BaseProtocol { @Override protected void addProtocolHandlers(PipelineBuilder pipeline) { pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); - pipeline.addLast(new StringEncoder()); boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); if (utf8) { + pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); } else { + pipeline.addLast(new StringEncoder()); + pipeline.addLast(new StringDecoder()); + } + pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this)); + pipeline.addLast(new WialonProtocolDecoder(WialonProtocol.this)); + } + }); + addServer(new TrackerServer(true, getName()) { + @Override + protected void addProtocolHandlers(PipelineBuilder pipeline) { + pipeline.addLast(new LineBasedFrameDecoder(4 * 1024)); + boolean utf8 = Context.getConfig().getBoolean(getName() + ".utf8"); + if (utf8) { + pipeline.addLast(new StringEncoder(StandardCharsets.UTF_8)); + pipeline.addLast(new StringDecoder(StandardCharsets.UTF_8)); + } else { + pipeline.addLast(new StringEncoder()); pipeline.addLast(new StringDecoder()); } pipeline.addLast(new WialonProtocolEncoder(WialonProtocol.this)); diff --git a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java index 42ff3177e..8488ca2d1 100644 --- a/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java +++ b/src/main/java/org/traccar/protocol/WialonProtocolDecoder.java @@ -38,6 +38,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private static final Pattern PATTERN_ANY = new PatternBuilder() + .expression("([^#]*)?") // imei + .text("#") // start byte + .expression("([^#]+)") // type + .text("#") // separator + .expression("(.*)") // message + .compile(); + private static final Pattern PATTERN = new PatternBuilder() .number("(dd)(dd)(dd);") // date (ddmmyy) .number("(dd)(dd)(dd);") // time (hhmmss) @@ -62,7 +70,8 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { private void sendResponse(Channel channel, SocketAddress remoteAddress, String type, Integer number) { if (channel != null) { StringBuilder response = new StringBuilder("#A"); - response.append(type.substring(1)); + response.append(type); + response.append("#"); if (number != null) { response.append(number); } @@ -71,9 +80,9 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodePosition(Channel channel, SocketAddress remoteAddress, String substring) { + private Position decodePosition(Channel channel, SocketAddress remoteAddress, String id, String substring) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; } @@ -135,12 +144,20 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - String type = sentence.substring(0, sentence.indexOf('#', 1) + 1); + + Parser parser = new Parser(PATTERN_ANY, sentence); + if (!parser.matches()) { + return null; + } + + String id = parser.next(); + String type = parser.next(); + String data = parser.next(); switch (type) { - case "#L#": - String[] values = sentence.substring(3).split(";"); + case "L": + String[] values = data.split(";"); String imei = values[0].indexOf('.') >= 0 ? values[1] : values[0]; DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); @@ -149,14 +166,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#P#": + case "P": sendResponse(channel, remoteAddress, type, null); // heartbeat break; - case "#D#": - case "#SD#": + case "D": + case "SD": Position position = decodePosition( - channel, remoteAddress, sentence.substring(sentence.indexOf('#', 1) + 1)); + channel, remoteAddress, id, data); if (position != null) { sendResponse(channel, remoteAddress, type, 1); @@ -164,12 +181,12 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#B#": - String[] messages = sentence.substring(sentence.indexOf('#', 1) + 1).split("\\|"); + case "B": + String[] messages = data.split("\\|"); List<Position> positions = new LinkedList<>(); for (String message : messages) { - position = decodePosition(channel, remoteAddress, message); + position = decodePosition(channel, remoteAddress, id, message); if (position != null) { position.set(Position.KEY_ARCHIVE, true); positions.add(position); @@ -182,14 +199,14 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder { } break; - case "#M#": - deviceSession = getDeviceSession(channel, remoteAddress); + case "M": + deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession != null) { position = new Position(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, new Date()); position.setValid(false); - position.set(Position.KEY_RESULT, sentence.substring(sentence.indexOf('#', 1) + 1)); + position.set(Position.KEY_RESULT, data); sendResponse(channel, remoteAddress, type, 1); return position; } diff --git a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java index 40b0469ea..72e56fb44 100644 --- a/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java +++ b/src/test/java/org/traccar/protocol/WialonProtocolDecoderTest.java @@ -26,6 +26,9 @@ public class WialonProtocolDecoderTest extends ProtocolTest { "#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A")); verifyPosition(decoder, text( + "99999999#D#101118;061143;0756.0930;N;12338.6403;E;18.223;99.766;-4.000;10;0.800;NA;NA;NA;NA;101_521347:1:521249,101_521126:1:6593598,101_521127:1:774780,101_521072_21.1:1:0,101_521072_21.2:1:71353;F24A")); + + verifyPosition(decoder, text( "#D#151216;135910;5321.1466;N;04441.7929;E;87;156;265.000000;12;1.000000;241;NA;NA;NA;odo:2:0.000000,total_fuel:1:430087,can_fls:1:201,can_taho:1:11623,can_mileage:1:140367515")); verifyPosition(decoder, text( @@ -36,6 +39,10 @@ public class WialonProtocolDecoderTest extends ProtocolTest { position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139)); verifyPosition(decoder, text( + "99999999#SD#270413;205601;5544.6025;N;03739.6834;E;1;2;3;4"), + position("2013-04-27 20:56:01.000", true, 55.74338, 37.66139)); + + verifyPosition(decoder, text( "#SD#021214;065947;2237.7552;N;11404.8851;E;0.000;;170.9;5")); verifyPosition(decoder, text( |