diff options
Diffstat (limited to 'src/org/traccar')
-rw-r--r-- | src/org/traccar/api/resource/CommandResource.java | 10 | ||||
-rw-r--r-- | src/org/traccar/database/CommandsManager.java | 65 | ||||
-rw-r--r-- | src/org/traccar/database/ConnectionManager.java | 5 | ||||
-rw-r--r-- | src/org/traccar/model/Command.java | 7 | ||||
-rw-r--r-- | src/org/traccar/protocol/CradlepointProtocolDecoder.java | 26 | ||||
-rw-r--r-- | src/org/traccar/protocol/MegastekProtocolDecoder.java | 8 | ||||
-rw-r--r-- | src/org/traccar/protocol/MeitrackProtocolDecoder.java | 16 | ||||
-rw-r--r-- | src/org/traccar/protocol/T55ProtocolDecoder.java | 10 | ||||
-rw-r--r-- | src/org/traccar/protocol/TaipProtocolDecoder.java | 3 | ||||
-rw-r--r-- | src/org/traccar/protocol/TzoneProtocolDecoder.java | 11 |
10 files changed, 102 insertions, 59 deletions
diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java index 8da9f8447..703638701 100644 --- a/src/org/traccar/api/resource/CommandResource.java +++ b/src/org/traccar/api/resource/CommandResource.java @@ -62,15 +62,15 @@ public class CommandResource extends ExtendedObjectResource<Command> { Context.getPermissionsManager().checkReadonly(getUserId()); long deviceId = entity.getDeviceId(); long id = entity.getId(); - if (deviceId != 0 && id != 0) { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + if (id != 0) { Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id); - Context.getCommandsManager().sendCommand(id, deviceId); } else { Context.getPermissionsManager().checkLimitCommands(getUserId()); - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - Context.getCommandsManager().sendCommand(entity); + } + if (!Context.getCommandsManager().sendCommand(entity)) { + return Response.accepted(entity).build(); } return Response.ok(entity).build(); } diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java index 521a2e1d1..9ceb995ef 100644 --- a/src/org/traccar/database/CommandsManager.java +++ b/src/org/traccar/database/CommandsManager.java @@ -21,6 +21,10 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import org.traccar.BaseProtocol; import org.traccar.Context; @@ -31,26 +35,22 @@ import org.traccar.model.Position; public class CommandsManager extends ExtendedObjectManager<Command> { - private boolean fallbackToText; + private final Map<Long, Queue<Command>> deviceQueues = new ConcurrentHashMap<>(); public CommandsManager(DataManager dataManager) { super(dataManager, Command.class); - fallbackToText = Context.getConfig().getBoolean("command.fallbackToSms"); } public boolean checkDeviceCommand(long deviceId, long commandId) { return !getAllDeviceItems(deviceId).contains(commandId); } - public void sendCommand(Command command) throws Exception { - sendCommand(command, command.getDeviceId(), fallbackToText); - } - - public void sendCommand(long commandId, long deviceId) throws Exception { - sendCommand(getById(commandId), deviceId, false); - } - - public void sendCommand(Command command, long deviceId, boolean fallbackToText) throws Exception { + public boolean sendCommand(Command command) throws Exception { + long deviceId = command.getDeviceId(); + if (command.getId() != 0) { + command = getById(command.getId()).clone(); + command.setDeviceId(deviceId); + } if (command.getTextChannel()) { Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); String phone = Context.getIdentityManager().getById(deviceId).getPhone(); @@ -71,32 +71,27 @@ public class CommandsManager extends ExtendedObjectManager<Command> { if (activeDevice != null) { activeDevice.sendCommand(command); } else { - if (fallbackToText) { - command.setTextChannel(true); - sendCommand(command, deviceId, false); - } else { - throw new RuntimeException("Device is not online"); - } + getDeviceQueue(deviceId).add(command); + return false; } } + return true; } public Collection<Long> getSupportedCommands(long deviceId) { List<Long> result = new ArrayList<>(); Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); - boolean online = Context.getConnectionManager().getActiveDevice(deviceId) != null; for (long commandId : getAllDeviceItems(deviceId)) { Command command = getById(commandId); - if (command.getTextChannel() || online) { - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - if (protocol.getSupportedTextCommands().contains(command.getType()) - || online && protocol.getSupportedDataCommands().contains(command.getType())) { - result.add(commandId); - } - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + if (command.getTextChannel() && protocol.getSupportedTextCommands().contains(command.getType()) + || !command.getTextChannel() + && protocol.getSupportedDataCommands().contains(command.getType())) { result.add(commandId); } + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + result.add(commandId); } } return result; @@ -133,4 +128,22 @@ public class CommandsManager extends ExtendedObjectManager<Command> { return result; } + private Queue<Command> getDeviceQueue(long deviceId) { + if (!deviceQueues.containsKey(deviceId)) { + deviceQueues.put(deviceId, new ConcurrentLinkedQueue<Command>()); + } + return deviceQueues.get(deviceId); + } + + public void sendQueuedCommands(ActiveDevice activeDevice) { + Queue<Command> deviceQueue = deviceQueues.get(activeDevice.getDeviceId()); + if (deviceQueue != null) { + Command command = deviceQueue.poll(); + while (command != null) { + activeDevice.sendCommand(command); + command = deviceQueue.poll(); + } + } + } + } diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index de11db21b..e5a7a272f 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -57,7 +57,9 @@ public class ConnectionManager { } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { - activeDevices.put(deviceId, new ActiveDevice(deviceId, protocol, channel, remoteAddress)); + ActiveDevice activeDevice = new ActiveDevice(deviceId, protocol, channel, remoteAddress); + activeDevices.put(deviceId, activeDevice); + Context.getCommandsManager().sendQueuedCommands(activeDevice); } public void removeActiveDevice(Channel channel) { @@ -122,6 +124,7 @@ public class ConnectionManager { public void run(Timeout timeout) throws Exception { if (!timeout.isCancelled()) { updateDevice(deviceId, Device.STATUS_UNKNOWN, null); + activeDevices.remove(deviceId); } } }, deviceTimeout, TimeUnit.MILLISECONDS)); diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java index 67134dc7d..16205ede1 100644 --- a/src/org/traccar/model/Command.java +++ b/src/org/traccar/model/Command.java @@ -20,7 +20,7 @@ import org.traccar.database.QueryIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) -public class Command extends Message { +public class Command extends Message implements Cloneable { public static final String TYPE_CUSTOM = "custom"; public static final String TYPE_IDENTIFICATION = "deviceIdentification"; @@ -77,6 +77,11 @@ public class Command extends Message { public static final String KEY_SERVER = "server"; public static final String KEY_PORT = "port"; + @Override + public Command clone() throws CloneNotSupportedException { + return (Command) super.clone(); + } + private boolean textChannel; public boolean getTextChannel() { 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/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/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 4714e24ea..a74d5ca62 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; @@ -218,13 +219,13 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { if (parser.hasNext()) { for (String temp : parser.next().split("\\|")) { - int index = Integer.valueOf(temp.substring(0, 2), 16); + int index = Integer.parseInt(temp.substring(0, 2), 16); if (protocol >= 3) { - double value = Short.valueOf(temp.substring(2), 16); + double value = (short) Integer.parseInt(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); + double value = Byte.parseByte(temp.substring(2, 4), 16); + value += (value < 0 ? -0.01 : 0.01) * Integer.parseInt(temp.substring(4), 16); position.set(Position.PREFIX_TEMP + index, value); } } @@ -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": 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); 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/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()); |