diff options
Diffstat (limited to 'src/org/traccar')
-rw-r--r-- | src/org/traccar/MainEventHandler.java | 4 | ||||
-rw-r--r-- | src/org/traccar/WindowsService.java | 4 | ||||
-rw-r--r-- | src/org/traccar/protocol/EelinkProtocolDecoder.java | 2 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 38 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gps103ProtocolDecoder.java | 6 | ||||
-rw-r--r-- | src/org/traccar/protocol/ItsProtocolDecoder.java | 11 | ||||
-rw-r--r-- | src/org/traccar/protocol/T55ProtocolDecoder.java | 2 | ||||
-rw-r--r-- | src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 97 |
8 files changed, 135 insertions, 29 deletions
diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index c905508e0..75dafcc29 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -117,14 +117,14 @@ public class MainEventHandler extends ChannelInboundHandlerAdapter { } @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { + public void channelActive(ChannelHandlerContext ctx) { if (!(ctx.channel() instanceof DatagramChannel)) { LOGGER.info(formatChannel(ctx.channel()) + " connected"); } } @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { + public void channelInactive(ChannelHandlerContext ctx) { LOGGER.info(formatChannel(ctx.channel()) + " disconnected"); closeChannel(ctx.channel()); diff --git a/src/org/traccar/WindowsService.java b/src/org/traccar/WindowsService.java index 1906a6d50..4a8955608 100644 --- a/src/org/traccar/WindowsService.java +++ b/src/org/traccar/WindowsService.java @@ -56,8 +56,8 @@ public abstract class WindowsService { File jar = new File(WindowsService.class.getProtectionDomain().getCodeSource().getLocation().toURI()); String command = javaBinary - + " -Duser.dir=\"" + jar.getAbsolutePath() + "\"" - + " -jar \"" + jar.getParentFile().getAbsolutePath() + "\"" + + " -Duser.dir=\"" + jar.getParentFile().getAbsolutePath() + "\"" + + " -jar \"" + jar.getAbsolutePath() + "\"" + " --service \"" + config + "\""; boolean success = false; diff --git a/src/org/traccar/protocol/EelinkProtocolDecoder.java b/src/org/traccar/protocol/EelinkProtocolDecoder.java index 14bf44fbf..fce176ec5 100644 --- a/src/org/traccar/protocol/EelinkProtocolDecoder.java +++ b/src/org/traccar/protocol/EelinkProtocolDecoder.java @@ -268,7 +268,7 @@ public class EelinkProtocolDecoder extends BaseProtocolDecoder { } if (buf.readableBytes() >= 2) { - position.set(Position.PREFIX_TEMP + 2, buf.readUnsignedShort() / 16.0); + position.set(Position.PREFIX_TEMP + 2, buf.readShort() / 16.0); } } diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 31ff4a670..aeb57a116 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -314,6 +314,18 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .text("$").optional() .compile(); + private static final Pattern PATTERN_PNA = new PatternBuilder() + .text("+RESP:GT").expression("P[NF]A,") + .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version + .number("(d{15}|x{14}),") // imei + .expression("[^,]*,") // device name + .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 @@ -497,6 +509,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private void skipLocation(Parser parser) { + parser.skip(19); + } + private void decodeLocation(Position position, Parser parser) { Integer hdop = parser.nextInt(); position.setValid(hdop == null || hdop > 0); @@ -806,7 +822,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { Position position = positions.getLast(); - decodeLocation(position, parser); + skipLocation(parser); if (power != null && power > 10) { position.set(Position.KEY_POWER, power * 0.001); // only on some devices @@ -871,7 +887,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { Position position = positions.getLast(); - decodeLocation(position, parser); + skipLocation(parser); if (power != null) { position.set(Position.KEY_POWER, power * 0.001); @@ -1034,6 +1050,20 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodePna(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_PNA, sentence); + Position position = initPosition(parser, channel, remoteAddress); + if (position == null) { + return null; + } + + getLastLocation(position, null); + + position.set(Position.KEY_ALARM, sentence.contains("PNA") ? Position.ALARM_POWER_ON : Position.ALARM_POWER_OFF); + + 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); @@ -1206,6 +1236,10 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "VER": result = decodeVer(channel, remoteAddress, sentence); break; + case "PNA": + case "PFA": + result = decodePna(channel, remoteAddress, sentence); + break; default: result = decodeOther(channel, remoteAddress, sentence, type); break; diff --git a/src/org/traccar/protocol/Gps103ProtocolDecoder.java b/src/org/traccar/protocol/Gps103ProtocolDecoder.java index 27b94739b..aa02e8ad4 100644 --- a/src/org/traccar/protocol/Gps103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gps103ProtocolDecoder.java @@ -81,10 +81,10 @@ public class Gps103ProtocolDecoder extends BaseProtocolDecoder { .number(",([01])?").optional() // ignition .number(",([01])?").optional() // door .groupBegin() - .number(",(?:(d+.d+)%)?") // fuel 1 - .number(",(?:(d+.d+)%|d+)?") // fuel 2 + .number(",(?:(d+.d+)%)?") // fuel 1 + .number(",(?:(d+.d+)%|d+)?") // fuel 2 .groupEnd("?") - .number(",([-+]?d+)?") // temperature + .number(",([-+]?d+)?").optional() // temperature .groupEnd() .any() .compile(); diff --git a/src/org/traccar/protocol/ItsProtocolDecoder.java b/src/org/traccar/protocol/ItsProtocolDecoder.java index 62bf1f1e6..e2b1dc238 100644 --- a/src/org/traccar/protocol/ItsProtocolDecoder.java +++ b/src/org/traccar/protocol/ItsProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2018 - 2019 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. @@ -35,6 +35,7 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { } private static final Pattern PATTERN = new PatternBuilder() + .expression("[^$]*") .text("$,") .expression("[^,]+,") // event .groupBegin() @@ -59,8 +60,8 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { .number("(d+.d+),([NS]),") // latitude .number("(d+.d+),([EW]),") // longitude .groupBegin() - .number("(d+.d+),") // speed - .number("(d+.d+),") // course + .number("(d+.?d*),") // speed + .number("(d+.?d*),") // course .number("(d+),") // satellites .or() .number("(-?d+.d+),") // altitude @@ -108,8 +109,8 @@ public class ItsProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_SATELLITES, parser.nextInt()); } - if (parser.hasNext()) { - position.setAltitude(parser.nextDouble(0)); + if (parser.hasNext(2)) { + position.setAltitude(parser.nextDouble()); position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble())); } diff --git a/src/org/traccar/protocol/T55ProtocolDecoder.java b/src/org/traccar/protocol/T55ProtocolDecoder.java index 214a40a49..ba231a635 100644 --- a/src/org/traccar/protocol/T55ProtocolDecoder.java +++ b/src/org/traccar/protocol/T55ProtocolDecoder.java @@ -249,6 +249,8 @@ public class T55ProtocolDecoder extends BaseProtocolDecoder { if (sentence.startsWith("$PGID")) { getDeviceSession(channel, remoteAddress, sentence.substring(6, sentence.length() - 3)); + } else if (sentence.startsWith("$DEVID")) { + getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.lastIndexOf('*'))); } else if (sentence.startsWith("$PCPTI")) { getDeviceSession(channel, remoteAddress, sentence.substring(7, sentence.indexOf(",", 7))); } else if (sentence.startsWith("IMEI")) { diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index f69059104..c80cd9cda 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2018 Anton Tananaev (anton@traccar.org) + * Copyright 2013 - 2019 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,6 +25,7 @@ import org.traccar.DeviceSession; import org.traccar.NetworkMessage; import org.traccar.Protocol; import org.traccar.helper.BitUtil; +import org.traccar.helper.Checksum; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -33,13 +34,18 @@ import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; import java.util.Date; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { + private static final int IMAGE_PACKET_MAX = 2048; + private boolean connectionless; private boolean extended; + private Map<Long, ByteBuf> photos = new HashMap<>(); public void setExtended(boolean extended) { this.extended = extended; @@ -51,7 +57,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { this.extended = Context.getConfig().getBoolean(getProtocolName() + ".extended"); } - private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { + private void parseIdentification(Channel channel, SocketAddress remoteAddress, ByteBuf buf) { int length = buf.readUnsignedShort(); String imei = buf.toString(buf.readerIndex(), length, StandardCharsets.US_ASCII); @@ -66,7 +72,6 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); } - return deviceSession; } public static final int CODEC_GH3000 = 0x07; @@ -75,14 +80,74 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { public static final int CODEC_12 = 0x0C; public static final int CODEC_16 = 0x10; - private void decodeSerial(Position position, ByteBuf buf) { + private void sendImageRequest(Channel channel, SocketAddress remoteAddress, long id, int offset, int size) { + if (channel != null) { + ByteBuf response = Unpooled.buffer(); + response.writeInt(0); + response.writeShort(0); + response.writeShort(19); // length + response.writeByte(CODEC_12); + response.writeByte(1); // nod + response.writeByte(0x0D); // camera + response.writeInt(11); // payload length + response.writeByte(2); // command + response.writeInt((int) id); + response.writeInt(offset); + response.writeShort(size); + response.writeByte(1); // nod + response.writeShort(0); + response.writeShort(Checksum.crc16( + Checksum.CRC16_IBM, response.nioBuffer(8, response.readableBytes() - 8))); + channel.writeAndFlush(new NetworkMessage(response, remoteAddress)); + } + } + + private void decodeSerial(Channel channel, SocketAddress remoteAddress, Position position, ByteBuf buf) { getLastLocation(position, null); - position.set(Position.KEY_TYPE, buf.readUnsignedByte()); + int type = buf.readUnsignedByte(); + if (type == 0x0D) { + + buf.readInt(); // length + int subtype = buf.readUnsignedByte(); + if (subtype == 0x01) { + + long photoId = buf.readUnsignedInt(); + ByteBuf photo = Unpooled.buffer(buf.readInt()); + photos.put(photoId, photo); + sendImageRequest( + channel, remoteAddress, photoId, + 0, Math.min(IMAGE_PACKET_MAX, photo.capacity())); + + } else if (subtype == 0x02) { + + long photoId = buf.readUnsignedInt(); + buf.readInt(); // offset + ByteBuf photo = photos.get(photoId); + photo.writeBytes(buf, buf.readUnsignedShort()); + if (photo.writableBytes() > 0) { + sendImageRequest( + channel, remoteAddress, photoId, + photo.writerIndex(), Math.min(IMAGE_PACKET_MAX, photo.writableBytes())); + } else { + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); + photos.remove(photoId); + try { + position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg")); + } finally { + photo.release(); + } + } + + } - position.set(Position.KEY_RESULT, buf.readSlice(buf.readInt()).toString(StandardCharsets.US_ASCII)); + } else { + position.set(Position.KEY_TYPE, type); + position.set(Position.KEY_RESULT, buf.readSlice(buf.readInt()).toString(StandardCharsets.US_ASCII)); + + } } private long readValue(ByteBuf buf, int length, boolean signed) { @@ -121,6 +186,12 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { case 21: position.set(Position.KEY_RSSI, readValue(buf, length, false)); break; + case 25: + case 26: + case 27: + case 28: + position.set(Position.PREFIX_TEMP + (id - 24), readValue(buf, length, true) * 0.1); + break; case 66: position.set(Position.KEY_POWER, readValue(buf, length, false) * 0.001); break; @@ -131,13 +202,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.set("gpsStatus", readValue(buf, length, false)); break; case 72: - position.set(Position.PREFIX_TEMP + 1, readValue(buf, length, true) * 0.1); - break; case 73: - position.set(Position.PREFIX_TEMP + 2, readValue(buf, length, true) * 0.1); - break; case 74: - position.set(Position.PREFIX_TEMP + 3, readValue(buf, length, true) * 0.1); + position.set(Position.PREFIX_TEMP + (id - 71), readValue(buf, length, true) * 0.1); break; case 78: long driverUniqueId = readValue(buf, length, false); @@ -462,12 +529,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { position.setValid(true); if (codec == CODEC_12) { - decodeSerial(position, buf); + decodeSerial(channel, remoteAddress, position, buf); } else { decodeLocation(position, buf, codec); } - positions.add(position); + if (!position.getOutdated() || !position.getAttributes().isEmpty()) { + positions.add(position); + } } if (channel != null) { @@ -486,7 +555,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } } - return positions; + return positions.isEmpty() ? null : positions; } @Override |