diff options
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r-- | src/org/traccar/protocol/AtrackProtocolDecoder.java | 52 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gt06ProtocolDecoder.java | 161 | ||||
-rw-r--r-- | src/org/traccar/protocol/MeitrackProtocolDecoder.java | 3 | ||||
-rw-r--r-- | src/org/traccar/protocol/Tk103Protocol.java | 7 | ||||
-rw-r--r-- | src/org/traccar/protocol/Tk103ProtocolDecoder.java | 159 | ||||
-rw-r--r-- | src/org/traccar/protocol/Tk103ProtocolEncoder.java | 14 | ||||
-rw-r--r-- | src/org/traccar/protocol/WatchProtocolDecoder.java | 17 |
7 files changed, 326 insertions, 87 deletions
diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index 3566631f0..79b3c36cc 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -22,6 +22,8 @@ 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.helper.UnitsConverter; import org.traccar.model.CellTower; import org.traccar.model.Network; @@ -34,6 +36,7 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; public class AtrackProtocolDecoder extends BaseProtocolDecoder { @@ -195,29 +198,62 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } } - private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } + private static final Pattern PATTERN_INFO = new PatternBuilder() + .text("$INFO=") + .number("(d+),") // unit id + .expression("([^,]+),") // model + .expression("([^,]+),") // firmware version + .number("d+,") // imei + .number("d+,") // imsi + .number("d+,") // sim card id + .number("(d+),") // power + .number("(d+),") // battery + .number("(d+),") // satellites + .number("d+,") // gsm status + .number("(d+),") // rssi + .number("d+,") // connection status + .number("d+") // antenna status + .any() + .compile(); + private Position decodeString(Channel channel, SocketAddress remoteAddress, String sentence) { Position position = new Position(); position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); + DeviceSession deviceSession; + if (sentence.startsWith("$INFO")) { - return null; + Parser parser = new Parser(PATTERN_INFO, sentence); + if (!parser.matches()) { + return null; + } + + deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + + position.set("model", parser.next()); + position.set(Position.KEY_VERSION_FW, parser.next()); + position.set(Position.KEY_POWER, parser.nextInt() * 0.1); + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.1); + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.KEY_RSSI, parser.nextInt()); } else { + deviceSession = getDeviceSession(channel, remoteAddress); + position.set(Position.KEY_RESULT, sentence); } - return position; + if (deviceSession == null) { + return null; + } else { + position.setDeviceId(deviceSession.getDeviceId()); + return position; + } } @Override diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 261278539..261c86825 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -28,11 +28,14 @@ import org.traccar.helper.Parser; import org.traccar.helper.PatternBuilder; import org.traccar.helper.UnitsConverter; import org.traccar.model.CellTower; +import org.traccar.model.Device; import org.traccar.model.Network; import org.traccar.model.Position; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import java.util.regex.Pattern; @@ -41,6 +44,10 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { private boolean forceTimeZone = false; private final TimeZone timeZone = TimeZone.getTimeZone("UTC"); + private int serverIndex; + + private final Map<Integer, ChannelBuffer> photos = new HashMap<>(); + public Gt06ProtocolDecoder(Gt06Protocol protocol) { super(protocol); @@ -66,6 +73,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_LBS_STATUS = 0x19; public static final int MSG_GPS_PHONE = 0x1A; public static final int MSG_GPS_LBS_EXTEND = 0x1E; + public static final int MSG_AZ735_GPS = 0x32; + public static final int MSG_AZ735_ALARM = 0x33; + public static final int MSG_X1_GPS = 0x34; + public static final int MSG_X1_PHOTO_INFO = 0x35; + public static final int MSG_X1_PHOTO_DATA = 0x36; public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; @@ -92,26 +104,54 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { || type == MSG_GPS_LBS_STATUS_1 || type == MSG_GPS_LBS_STATUS_2 || type == MSG_GPS_LBS_STATUS_3; } - private static void sendResponse(Channel channel, int type, int index) { + private void sendResponse(Channel channel, boolean extended, int type) { if (channel != null) { ChannelBuffer response = ChannelBuffers.dynamicBuffer(); - response.writeByte(0x78); response.writeByte(0x78); // header - response.writeByte(5); // size + if (extended) { + response.writeShort(0x7979); + response.writeShort(5); + } else { + response.writeShort(0x7878); + response.writeByte(5); + } response.writeByte(type); - response.writeShort(index); - response.writeShort(Checksum.crc16(Checksum.CRC16_X25, response.toByteBuffer(2, 4))); - response.writeByte(0x0D); response.writeByte(0x0A); // ending + response.writeShort(++serverIndex); + response.writeShort(Checksum.crc16(Checksum.CRC16_X25, + response.toByteBuffer(2, response.writerIndex() - 2))); + response.writeByte('\r'); response.writeByte('\n'); // ending + channel.write(response); + } + } + + private void sendPhotoRequest(Channel channel, int pictureId) { + if (channel != null) { + ChannelBuffer photo = photos.get(pictureId); + ChannelBuffer response = ChannelBuffers.dynamicBuffer(); + response.writeShort(0x7878); // header + response.writeByte(15); // size + response.writeByte(MSG_X1_PHOTO_DATA); + response.writeInt(pictureId); + response.writeInt(photo.writerIndex()); + response.writeShort(Math.min(photo.writableBytes(), 1024)); + response.writeShort(++serverIndex); + response.writeShort(Checksum.crc16(Checksum.CRC16_X25, + response.toByteBuffer(2, response.writerIndex() - 2))); + response.writeByte('\r'); response.writeByte('\n'); // ending channel.write(response); } } - private void decodeGps(Position position, ChannelBuffer buf) { + private boolean decodeGps(Position position, ChannelBuffer buf, boolean hasLength) { DateBuilder dateBuilder = new DateBuilder(timeZone) .setDate(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()) .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()); position.setTime(dateBuilder.getDate()); + if (hasLength && buf.readUnsignedByte() == 0) { + return false; + } + int length = buf.readUnsignedByte(); position.set(Position.KEY_SATELLITES, BitUtil.to(length, 4)); length = BitUtil.from(length, 4); @@ -138,10 +178,14 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_IGNITION, BitUtil.check(flags, 15)); } - buf.skipBytes(length - 12); // skip reserved + if (length > 0) { + buf.skipBytes(length - 12); // skip reserved + } + + return true; } - private void decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) { + private boolean decodeLbs(Position position, ChannelBuffer buf, boolean hasLength) { int lbsLength = 0; if (hasLength) { @@ -154,9 +198,11 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (lbsLength > 0) { buf.skipBytes(lbsLength - 9); } + + return true; } - private void decodeStatus(Position position, ChannelBuffer buf) { + private boolean decodeStatus(Position position, ChannelBuffer buf) { int status = buf.readUnsignedByte(); @@ -185,6 +231,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_BATTERY, buf.readUnsignedByte()); position.set(Position.KEY_RSSI, buf.readUnsignedByte()); position.set(Position.KEY_ALARM, decodeAlarm(buf.readUnsignedByte())); + + return true; } private String decodeAlarm(short value) { @@ -266,12 +314,20 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return position; } - protected Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeBasic(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { int length = buf.readUnsignedByte(); int dataLength = length - 5; int type = buf.readUnsignedByte(); + DeviceSession deviceSession = null; + if (type != MSG_LOGIN) { + deviceSession = getDeviceSession(channel, remoteAddress); + if (deviceSession == null) { + return null; + } + } + if (type == MSG_LOGIN) { String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); @@ -292,16 +348,45 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } if (getDeviceSession(channel, remoteAddress, imei) != null) { - buf.skipBytes(buf.readableBytes() - 6); - sendResponse(channel, type, buf.readUnsignedShort()); + sendResponse(channel, false, type); } - } else { + } else if (type == MSG_X1_GPS) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - if (deviceSession == null) { - return null; - } + Position position = new Position(); + position.setDeviceId(deviceSession.getDeviceId()); + position.setProtocol(getProtocolName()); + + buf.readUnsignedInt(); // data and alarm + + decodeGps(position, buf, false); + + buf.readUnsignedShort(); // terminal info + + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + + position.setNetwork(new Network(CellTower.from( + buf.readUnsignedShort(), buf.readUnsignedByte(), + buf.readUnsignedShort(), buf.readUnsignedInt()))); + + return position; + + } else if (type == MSG_X1_PHOTO_INFO) { + + buf.skipBytes(6); // time + buf.readUnsignedByte(); // fix status + buf.readUnsignedInt(); // latitude + buf.readUnsignedInt(); // longitude + buf.readUnsignedByte(); // camera id + buf.readUnsignedByte(); // photo source + buf.readUnsignedByte(); // picture format + + ChannelBuffer photo = ChannelBuffers.buffer(buf.readInt()); + int pictureId = buf.readInt(); + photos.put(pictureId, photo); + sendPhotoRequest(channel, pictureId); + + } else { Position position = new Position(); position.setDeviceId(deviceSession.getDeviceId()); @@ -340,7 +425,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } else if (isSupported(type)) { if (hasGps(type)) { - decodeGps(position, buf); + decodeGps(position, buf, false); } else { getLastLocation(position, null); } @@ -361,16 +446,13 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { buf.skipBytes(dataLength); if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, type, buf.readUnsignedShort()); + sendResponse(channel, false, type); } return null; } - if (buf.readableBytes() > 6) { - buf.skipBytes(buf.readableBytes() - 6); - } - sendResponse(channel, type, buf.readUnsignedShort()); + sendResponse(channel, false, type); return position; @@ -379,7 +461,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { return null; } - protected Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + private Object decodeExtended(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); if (deviceSession == null) { @@ -431,6 +513,35 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } + } else if (type == MSG_X1_PHOTO_DATA) { + + int pictureId = buf.readInt(); + + ChannelBuffer photo = photos.get(pictureId); + + buf.readUnsignedInt(); // offset + buf.readBytes(photo, buf.readUnsignedShort()); + + if (photo.writableBytes() > 0) { + sendPhotoRequest(channel, pictureId); + } else { + Device device = Context.getDeviceManager().getDeviceById(deviceSession.getDeviceId()); + Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg"); + photos.remove(pictureId); + } + + } else if (type == MSG_AZ735_GPS || type == MSG_AZ735_ALARM) { + + if (!decodeGps(position, buf, true)) { + getLastLocation(position, position.getDeviceTime()); + } + + decodeLbs(position, buf, true); + + sendResponse(channel, true, type); + + return position; + } return null; diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 11ecb5d72..38ecde519 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -218,7 +218,8 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { for (String temp : parser.next().split("\\|")) { int index = Integer.valueOf(temp.substring(0, 2), 16); - int value = Integer.valueOf(temp.substring(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); } } diff --git a/src/org/traccar/protocol/Tk103Protocol.java b/src/org/traccar/protocol/Tk103Protocol.java index 6fc00195e..07a68e2d8 100644 --- a/src/org/traccar/protocol/Tk103Protocol.java +++ b/src/org/traccar/protocol/Tk103Protocol.java @@ -1,4 +1,5 @@ /* + * Copyright 2017 Christoph Krey (c@ckrey.de) * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +33,12 @@ public class Tk103Protocol extends BaseProtocol { public Tk103Protocol() { super("tk103"); setSupportedDataCommands( + Command.TYPE_POSITION_SINGLE, + Command.TYPE_POSITION_PERIODIC, + Command.TYPE_POSITION_STOP, + Command.TYPE_GET_VERSION, + Command.TYPE_REBOOT_DEVICE, + Command.TYPE_SET_ODOMETER, Command.TYPE_ENGINE_STOP, Command.TYPE_ENGINE_RESUME); } diff --git a/src/org/traccar/protocol/Tk103ProtocolDecoder.java b/src/org/traccar/protocol/Tk103ProtocolDecoder.java index baaa6c6fe..4c7da12e0 100644 --- a/src/org/traccar/protocol/Tk103ProtocolDecoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolDecoder.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. @@ -39,8 +39,8 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { private static final Pattern PATTERN = new PatternBuilder() .number("(d+)(,)?") // device id - .expression(".{4},?") // command - .number("d*") // imei? + .expression("(.{4}),?") // command + .number("(d*)") .number("(dd)(dd)(dd),?") // date (mmddyy if comma-delimited, otherwise yyddmm) .expression("([AV]),?") // validity .number("(d+)(dd.d+)") // latitude @@ -97,19 +97,106 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeType(Position position, String type, String data) { + switch (type) { + case "BO01": + position.set(Position.KEY_ALARM, decodeAlarm(data.charAt(0) - '0')); + break; + case "ZC11": + position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT); + break; + case "ZC12": + position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY); + break; + case "ZC13": + position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT); + break; + case "ZC15": + position.set(Position.KEY_IGNITION, true); + break; + case "ZC16": + position.set(Position.KEY_IGNITION, false); + break; + case "ZC17": + position.set(Position.KEY_ALARM, Position.ALARM_REMOVING); + break; + case "ZC25": + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + break; + case "ZC26": + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + break; + case "ZC27": + position.set(Position.KEY_ALARM, Position.ALARM_LOW_POWER); + break; + default: + break; + } + } + + private Position decodeBattery(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_BATTERY, 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()); + + getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + int battery = parser.nextInt(0); + if (battery != 65535) { + position.set(Position.KEY_BATTERY, battery * 0.01); + } + + int power = parser.nextInt(0); + if (power != 65535) { + position.set(Position.KEY_POWER, power * 0.1); + } + + return position; + } + + private Position decodeNetwork(Channel channel, SocketAddress remoteAddress, String sentence) { + Parser parser = new Parser(PATTERN_NETWORK, 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()); + + getLastLocation(position, null); + + position.setNetwork(new Network(CellTower.from( + parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); + + return position; + } @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - // Find message start int beginIndex = sentence.indexOf('('); if (beginIndex != -1) { sentence = sentence.substring(beginIndex + 1); } - // Send response if (channel != null) { String id = sentence.substring(0, 12); String type = sentence.substring(12, 16); @@ -127,49 +214,13 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { } } - Position position = new Position(); - position.setProtocol(getProtocolName()); - - Parser parser = new Parser(PATTERN_BATTERY, sentence); - if (parser.matches()) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); - - int battery = parser.nextInt(0); - if (battery != 65535) { - position.set(Position.KEY_BATTERY, battery * 0.01); - } - - int power = parser.nextInt(0); - if (power != 65535) { - position.set(Position.KEY_POWER, power * 0.1); - } - - return position; - } - - parser = new Parser(PATTERN_NETWORK, sentence); - if (parser.matches()) { - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); - if (deviceSession == null) { - return null; - } - position.setDeviceId(deviceSession.getDeviceId()); - - getLastLocation(position, null); - - position.setNetwork(new Network(CellTower.from( - parser.nextInt(0), parser.nextInt(0), parser.nextHexInt(0), parser.nextHexInt(0)))); - - return position; + if (sentence.contains("ZC20")) { + return decodeBattery(channel, remoteAddress, sentence); + } else if (sentence.contains("BZ00")) { + return decodeNetwork(channel, remoteAddress, sentence); } - parser = new Parser(PATTERN, sentence); + Parser parser = new Parser(PATTERN, sentence); if (!parser.matches()) { return null; } @@ -178,18 +229,20 @@ public class Tk103ProtocolDecoder extends BaseProtocolDecoder { if (deviceSession == null) { return null; } + + Position position = new Position(); + position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); - int alarm = sentence.indexOf("BO01"); - if (alarm != -1) { - position.set(Position.KEY_ALARM, decodeAlarm(Integer.parseInt(sentence.substring(alarm + 4, alarm + 5)))); - } + boolean alternative = parser.next() != null; + + decodeType(position, parser.next(), parser.next()); DateBuilder dateBuilder = new DateBuilder(); - if (parser.next() == null) { - dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); - } else { + if (alternative) { dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); + } else { + dateBuilder.setDate(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0)); } position.setValid(parser.next().equals("A")); diff --git a/src/org/traccar/protocol/Tk103ProtocolEncoder.java b/src/org/traccar/protocol/Tk103ProtocolEncoder.java index ce995a65f..9e49b6ff1 100644 --- a/src/org/traccar/protocol/Tk103ProtocolEncoder.java +++ b/src/org/traccar/protocol/Tk103ProtocolEncoder.java @@ -1,4 +1,5 @@ /* + * Copyright 2017 Christoph Krey (c@ckrey.de) * Copyright 2017 Anton Tananaev (anton@traccar.org) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +26,19 @@ public class Tk103ProtocolEncoder extends StringProtocolEncoder { protected Object encodeCommand(Command command) { switch (command.getType()) { + case Command.TYPE_GET_VERSION: + return formatCommand(command, "({%s}AP07)", Command.KEY_UNIQUE_ID); + case Command.TYPE_REBOOT_DEVICE: + return formatCommand(command, "({%s}AT00)", Command.KEY_UNIQUE_ID); + case Command.TYPE_SET_ODOMETER: + return formatCommand(command, "({%s}AX01)", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_SINGLE: + return formatCommand(command, "({%s}AP00)", Command.KEY_UNIQUE_ID); + case Command.TYPE_POSITION_PERIODIC: + return formatCommand(command, "({%s}AR00%s0000)", Command.KEY_UNIQUE_ID, + String.format("%04X", command.getInteger(Command.KEY_FREQUENCY))); + case Command.TYPE_POSITION_STOP: + return formatCommand(command, "({%s}AR0000000000)", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_STOP: return formatCommand(command, "({%s}AV011)", Command.KEY_UNIQUE_ID); case Command.TYPE_ENGINE_RESUME: diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index d0c066954..57f5d7e78 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -222,15 +222,20 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (type.equals("PULSE") || type.equals("heart")) { if (buf.readable()) { + Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, new Date()); + position.setValid(false); String pulse = buf.toString(StandardCharsets.US_ASCII); position.set("pulse", pulse); position.set(Position.KEY_RESULT, pulse); + return position; + } } else if (type.equals("img")) { @@ -247,6 +252,18 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { return position; + } else if (type.equals("TK")) { + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + getLastLocation(position, null); + + position.set(Position.KEY_AUDIO, Context.getMediaManager().writeFile(id, buf, "amr")); + + return position; + } return null; |