aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar')
-rw-r--r--src/org/traccar/api/resource/CommandResource.java10
-rw-r--r--src/org/traccar/database/CommandsManager.java65
-rw-r--r--src/org/traccar/database/ConnectionManager.java5
-rw-r--r--src/org/traccar/model/Command.java7
-rw-r--r--src/org/traccar/protocol/CradlepointProtocolDecoder.java26
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java8
-rw-r--r--src/org/traccar/protocol/MeitrackProtocolDecoder.java16
-rw-r--r--src/org/traccar/protocol/T55ProtocolDecoder.java10
-rw-r--r--src/org/traccar/protocol/TaipProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TzoneProtocolDecoder.java11
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());