aboutsummaryrefslogtreecommitdiff
path: root/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'src/org')
-rw-r--r--src/org/traccar/api/resource/MaintenanceResource.java2
-rw-r--r--src/org/traccar/protocol/Gl200TextProtocolDecoder.java78
-rw-r--r--src/org/traccar/protocol/SuntechProtocolDecoder.java8
-rw-r--r--src/org/traccar/protocol/TeltonikaProtocolDecoder.java64
-rw-r--r--src/org/traccar/protocol/WialonProtocolDecoder.java2
-rw-r--r--src/org/traccar/protocol/Xrb28ProtocolDecoder.java13
6 files changed, 133 insertions, 34 deletions
diff --git a/src/org/traccar/api/resource/MaintenanceResource.java b/src/org/traccar/api/resource/MaintenanceResource.java
index b3726b429..fa1b359ce 100644
--- a/src/org/traccar/api/resource/MaintenanceResource.java
+++ b/src/org/traccar/api/resource/MaintenanceResource.java
@@ -24,7 +24,7 @@ import javax.ws.rs.core.MediaType;
import org.traccar.api.ExtendedObjectResource;
import org.traccar.model.Maintenance;
-@Path("maintenances")
+@Path("maintenance")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class MaintenanceResource extends ExtendedObjectResource<Maintenance> {
diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
index 0d600e240..e004ce994 100644
--- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
@@ -581,6 +581,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
index += 1; // report type
index += 1; // canbus state
long reportMask = Long.parseLong(values[index++], 16);
+ long reportMaskExt = 0;
if (BitUtil.check(reportMask, 0)) {
position.set(Position.KEY_VIN, values[index++]);
@@ -649,7 +650,79 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
position.set("engineOverspeed", Double.parseDouble(values[index - 1]));
}
if (BitUtil.check(reportMask, 29)) {
- index += 1; // expansion
+ reportMaskExt = Long.parseLong(values[index++], 16);
+ }
+ if (BitUtil.check(reportMaskExt, 0) && !values[index++].isEmpty()) {
+ position.set("adBlueLevel", Integer.parseInt(values[index - 1]));
+ }
+ if (BitUtil.check(reportMaskExt, 1) && !values[index++].isEmpty()) {
+ position.set("axleWeight1", Integer.parseInt(values[index - 1]));
+ }
+ if (BitUtil.check(reportMaskExt, 2) && !values[index++].isEmpty()) {
+ position.set("axleWeight3", Integer.parseInt(values[index - 1]));
+ }
+ if (BitUtil.check(reportMaskExt, 3) && !values[index++].isEmpty()) {
+ position.set("axleWeight4", Integer.parseInt(values[index - 1]));
+ }
+ if (BitUtil.check(reportMaskExt, 4)) {
+ index += 1; // tachograph overspeed
+ }
+ if (BitUtil.check(reportMaskExt, 5)) {
+ index += 1; // tachograph motion
+ }
+ if (BitUtil.check(reportMaskExt, 6)) {
+ index += 1; // tachograph direction
+ }
+ if (BitUtil.check(reportMaskExt, 7) && !values[index++].isEmpty()) {
+ position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[index - 1]) * 0.001);
+ }
+ if (BitUtil.check(reportMaskExt, 8)) {
+ index += 1; // pedal breaking factor
+ }
+ if (BitUtil.check(reportMaskExt, 9)) {
+ index += 1; // engine breaking factor
+ }
+ if (BitUtil.check(reportMaskExt, 10)) {
+ index += 1; // total accelerator kick-downs
+ }
+ if (BitUtil.check(reportMaskExt, 11)) {
+ index += 1; // total effective engine speed
+ }
+ if (BitUtil.check(reportMaskExt, 12)) {
+ index += 1; // total cruise control time
+ }
+ if (BitUtil.check(reportMaskExt, 13)) {
+ index += 1; // total accelerator kick-down time
+ }
+ if (BitUtil.check(reportMaskExt, 14)) {
+ index += 1; // total brake application
+ }
+ if (BitUtil.check(reportMaskExt, 15) && !values[index++].isEmpty()) {
+ position.set("driver1Card", values[index - 1]);
+ }
+ if (BitUtil.check(reportMaskExt, 16) && !values[index++].isEmpty()) {
+ position.set("driver2Card", values[index - 1]);
+ }
+ if (BitUtil.check(reportMaskExt, 17) && !values[index++].isEmpty()) {
+ position.set("driver1Name", values[index - 1]);
+ }
+ if (BitUtil.check(reportMaskExt, 18) && !values[index++].isEmpty()) {
+ position.set("driver2Name", values[index - 1]);
+ }
+ if (BitUtil.check(reportMaskExt, 19) && !values[index++].isEmpty()) {
+ position.set("registration", values[index - 1]);
+ }
+ if (BitUtil.check(reportMaskExt, 20)) {
+ index += 1; // expansion information
+ }
+ if (BitUtil.check(reportMaskExt, 21)) {
+ index += 1; // rapid brakings
+ }
+ if (BitUtil.check(reportMaskExt, 22)) {
+ index += 1; // rapid accelerations
+ }
+ if (BitUtil.check(reportMaskExt, 23)) {
+ index += 1; // engine torque
}
DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
@@ -674,10 +747,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(reportMask, 31)) {
index += 4; // cell
+ index += 1; // reserved
}
- index += 1; // reserved
-
if (ignoreFixTime) {
position.setTime(dateFormat.parse(values[index]));
} else {
diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java
index 48eb3a71d..ad1da537b 100644
--- a/src/org/traccar/protocol/SuntechProtocolDecoder.java
+++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java
@@ -317,9 +317,11 @@ public class SuntechProtocolDecoder extends BaseProtocolDecoder {
}
if (includeAdc) {
- position.set(Position.PREFIX_ADC + 1, Double.parseDouble(values[index++]));
- position.set(Position.PREFIX_ADC + 2, Double.parseDouble(values[index++]));
- position.set(Position.PREFIX_ADC + 3, Double.parseDouble(values[index++]));
+ for (int i = 1; i <= 3; i++) {
+ if (!values[index++].isEmpty()) {
+ position.set(Position.PREFIX_ADC + i, Double.parseDouble(values[index - 1]));
+ }
+ }
}
if (values.length - index >= 2) {
diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
index 5c3af026c..f69059104 100644
--- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -70,7 +70,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
public static final int CODEC_GH3000 = 0x07;
- public static final int CODEC_FM4X00 = 0x08;
+ public static final int CODEC_8 = 0x08;
+ public static final int CODEC_8_EXT = 0x8E;
public static final int CODEC_12 = 0x0C;
public static final int CODEC_16 = 0x10;
@@ -271,6 +272,21 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
}
+ private int readExtByte(ByteBuf buf, int codec, int... codecs) {
+ boolean ext = false;
+ for (int c : codecs) {
+ if (codec == c) {
+ ext = true;
+ break;
+ }
+ }
+ if (ext) {
+ return buf.readUnsignedShort();
+ } else {
+ return buf.readUnsignedByte();
+ }
+ }
+
private void decodeLocation(Position position, ByteBuf buf, int codec) {
int globalMask = 0x0f;
@@ -354,62 +370,70 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort()));
+ position.set(Position.KEY_EVENT, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16));
if (codec == CODEC_16) {
- position.set(Position.KEY_EVENT, buf.readUnsignedShort());
buf.readUnsignedByte(); // generation type
- } else {
- position.set(Position.KEY_EVENT, buf.readUnsignedByte());
}
- buf.readUnsignedByte(); // total IO data records
+ readExtByte(buf, codec, CODEC_8_EXT); // total IO data records
}
// Read 1 byte data
if (BitUtil.check(globalMask, 1)) {
- int cnt = buf.readUnsignedByte();
+ int cnt = readExtByte(buf, codec, CODEC_8_EXT);
for (int j = 0; j < cnt; j++) {
- int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte();
- decodeParameter(position, id, buf, 1, codec);
+ decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 1, codec);
}
}
// Read 2 byte data
if (BitUtil.check(globalMask, 2)) {
- int cnt = buf.readUnsignedByte();
+ int cnt = readExtByte(buf, codec, CODEC_8_EXT);
for (int j = 0; j < cnt; j++) {
- int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte();
- decodeParameter(position, id, buf, 2, codec);
+ decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 2, codec);
}
}
// Read 4 byte data
if (BitUtil.check(globalMask, 3)) {
- int cnt = buf.readUnsignedByte();
+ int cnt = readExtByte(buf, codec, CODEC_8_EXT);
for (int j = 0; j < cnt; j++) {
- int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte();
- decodeParameter(position, id, buf, 4, codec);
+ decodeParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 4, codec);
}
}
// Read 8 byte data
- if (codec == CODEC_FM4X00 || codec == CODEC_16) {
- int cnt = buf.readUnsignedByte();
+ if (codec == CODEC_8 || codec == CODEC_8_EXT || codec == CODEC_16) {
+ int cnt = readExtByte(buf, codec, CODEC_8_EXT);
for (int j = 0; j < cnt; j++) {
- int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte();
- decodeOtherParameter(position, id, buf, 8);
+ decodeOtherParameter(position, readExtByte(buf, codec, CODEC_8_EXT, CODEC_16), buf, 8);
}
}
// Read 16 byte data
if (extended) {
- int cnt = buf.readUnsignedByte();
+ int cnt = readExtByte(buf, codec, CODEC_8_EXT);
for (int j = 0; j < cnt; j++) {
- int id = codec == CODEC_16 ? buf.readUnsignedShort() : buf.readUnsignedByte();
+ int id = readExtByte(buf, codec, CODEC_8_EXT, CODEC_16);
position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(16)));
}
}
+ // Read X byte data
+ if (codec == CODEC_8_EXT) {
+ int cnt = buf.readUnsignedShort();
+ for (int j = 0; j < cnt; j++) {
+ int id = buf.readUnsignedShort();
+ int length = buf.readUnsignedShort();
+ if (id == 256) {
+ position.set(Position.KEY_VIN, buf.readSlice(length).toString(StandardCharsets.US_ASCII));
+ } else {
+ position.set(Position.PREFIX_IO + id, ByteBufUtil.hexDump(buf.readSlice(length)));
+ }
+ }
+ }
+
decodeNetwork(position);
}
diff --git a/src/org/traccar/protocol/WialonProtocolDecoder.java b/src/org/traccar/protocol/WialonProtocolDecoder.java
index 7939c7b67..de7073b67 100644
--- a/src/org/traccar/protocol/WialonProtocolDecoder.java
+++ b/src/org/traccar/protocol/WialonProtocolDecoder.java
@@ -47,7 +47,7 @@ public class WialonProtocolDecoder extends BaseProtocolDecoder {
.expression("([EW]);")
.number("(d+.?d*)?;") // speed
.number("(d+.?d*)?;") // course
- .number("(?:NA|(d+.?d*));") // altitude
+ .number("(?:NA|(-?d+.?d*));") // altitude
.number("(?:NA|(d+))") // satellites
.groupBegin().text(";")
.number("(?:NA|(d+.?d*));") // hdop
diff --git a/src/org/traccar/protocol/Xrb28ProtocolDecoder.java b/src/org/traccar/protocol/Xrb28ProtocolDecoder.java
index c3af2c4f3..7c382900a 100644
--- a/src/org/traccar/protocol/Xrb28ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Xrb28ProtocolDecoder.java
@@ -42,7 +42,8 @@ public class Xrb28ProtocolDecoder extends BaseProtocolDecoder {
}
private static final Pattern PATTERN = new PatternBuilder()
- .text("*HBCR,")
+ .text("*")
+ .expression("....,")
.expression("..,") // vendor
.number("d{15},") // imei
.expression("..,") // type
@@ -67,25 +68,25 @@ public class Xrb28ProtocolDecoder extends BaseProtocolDecoder {
String sentence = (String) msg;
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(10, 26));
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, sentence.substring(8, 24));
if (deviceSession == null) {
return null;
}
- String type = sentence.substring(27, 29);
+ String type = sentence.substring(25, 27);
if (channel != null) {
if (type.matches("L0|L1|W0|E1")) {
channel.write(new NetworkMessage(
- sentence.substring(0, 29) + "#\n", remoteAddress));
+ sentence.substring(0, 27) + "#\n", remoteAddress));
} else if (type.equals("R0") && pendingCommand != null) {
String command = pendingCommand.equals(Command.TYPE_ALARM_ARM) ? "L1," : "L0,";
channel.write(new NetworkMessage(
- sentence.substring(0, 27) + command + sentence.substring(32) + "\n", remoteAddress));
+ sentence.substring(0, 25) + command + sentence.substring(30) + "\n", remoteAddress));
pendingCommand = null;
}
}
- Parser parser = new Parser(PATTERN, sentence.substring(2));
+ Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}