aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/api/resource/CommandResource.java2
-rw-r--r--src/org/traccar/protocol/AquilaProtocolDecoder.java75
-rw-r--r--src/org/traccar/protocol/Gl200ProtocolDecoder.java37
-rw-r--r--src/org/traccar/protocol/MxtProtocolDecoder.java21
-rw-r--r--src/org/traccar/protocol/PricolProtocol.java43
-rw-r--r--src/org/traccar/protocol/PricolProtocolDecoder.java96
-rw-r--r--src/org/traccar/protocol/SuntechProtocolDecoder.java166
-rw-r--r--src/org/traccar/protocol/TeltonikaProtocolDecoder.java52
8 files changed, 400 insertions, 92 deletions
diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java
index cce2dac2b..e13ae9de8 100644
--- a/src/org/traccar/api/resource/CommandResource.java
+++ b/src/org/traccar/api/resource/CommandResource.java
@@ -33,6 +33,8 @@ public class CommandResource extends BaseResource {
@POST
public Response add(Command entity) {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkDeviceReadonly(getUserId());
Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId());
Context.getConnectionManager().getActiveDevice(entity.getDeviceId()).sendCommand(entity);
return Response.ok(entity).build();
diff --git a/src/org/traccar/protocol/AquilaProtocolDecoder.java b/src/org/traccar/protocol/AquilaProtocolDecoder.java
index 60a9c4708..e1cebd20d 100644
--- a/src/org/traccar/protocol/AquilaProtocolDecoder.java
+++ b/src/org/traccar/protocol/AquilaProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 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.
@@ -46,6 +46,7 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
.number("(d+),") // gsm
.number("(d+),") // speed
.number("(d+),") // distance
+ .groupBegin()
.number("d+,") // driver code
.number("(d+),") // fuel
.number("([01]),") // io 1
@@ -65,8 +66,36 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
.number("([01]),") // course bit 1
.number("([01]),") // course bit 2
.number("([01]),") // course bit 3
+ .or()
+ .number("(d+),") // course
+ .number("(?:d+,){3}") // reserved
+ .number("[01],") // over speed start
+ .number("[01],") // over speed end
+ .number("(?:d+,){3}") // reserved
+ .number("([01]),") // power status
+ .number("(?:d+,){2}") // reserved
+ .number("[01],") // ignition on event
+ .number("([01]),") // ignition
+ .number("[01],") // ignition off event
+ .number("(?:d+,){5}") // reserved
+ .number("[01],") // low battery
+ .number("[01],") // corner packet
+ .number("(?:d+,){6}") // reserved
+ .number("[01],") // hard acceleration
+ .number("[01],") // hard breaking
+ .number("[01],[01],[01],[01],") // course bits
+ .number("(d+),") // external voltage
+ .number("(d+),") // internal voltage
+ .number("(?:d+,){6}") // reserved
+ .expression("P([^,]+),") // obd
+ .expression("D([^,]+),") // dtcs
+ .number("-?d+,") // accelerometer x
+ .number("-?d+,") // accelerometer y
+ .number("-?d+,") // accelerometer z
+ .number("d+,") // delta distance
+ .groupEnd()
.text("*")
- .number("(xx)") // checksum
+ .number("xx") // checksum
.compile();
@Override
@@ -78,13 +107,13 @@ public class AquilaProtocolDecoder 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.set(Position.KEY_EVENT, parser.nextInt());
@@ -104,16 +133,36 @@ public class AquilaProtocolDecoder extends BaseProtocolDecoder {
position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
position.set(Position.KEY_ODOMETER, parser.next());
- position.set(Position.KEY_FUEL, parser.next());
- position.set(Position.PREFIX_IO + 1, parser.next());
- position.set(Position.KEY_CHARGE, parser.next());
- position.set(Position.PREFIX_IO + 2, parser.next());
- position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ if (parser.hasNext(9)) {
+
+ position.set(Position.KEY_FUEL, parser.next());
+ position.set(Position.PREFIX_IO + 1, parser.next());
+ position.set(Position.KEY_CHARGE, parser.next());
+ position.set(Position.PREFIX_IO + 2, parser.next());
+
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+
+ int course = (parser.nextInt() << 3) + (parser.nextInt() << 2) + (parser.nextInt() << 1) + parser.nextInt();
+ if (course > 0 && course <= 8) {
+ position.setCourse((course - 1) * 45);
+ }
+
+ } else {
+
+ position.setCourse(parser.nextInt());
+
+ position.set(Position.KEY_CHARGE, parser.next());
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ position.set(Position.KEY_POWER, parser.nextInt());
+ position.set(Position.KEY_BATTERY, parser.nextInt());
+
+ String obd = parser.next();
+ position.set("obd", obd.substring(1, obd.length() - 1));
+
+ String dtcs = parser.next();
+ position.set(Position.KEY_DTCS, dtcs.substring(1, dtcs.length() - 1).replace('|', ' '));
- int course = (parser.nextInt() << 3) + (parser.nextInt() << 2) + (parser.nextInt() << 1) + parser.nextInt();
- if (course > 0 && course <= 8) {
- position.setCourse((course - 1) * 45);
}
return position;
diff --git a/src/org/traccar/protocol/Gl200ProtocolDecoder.java b/src/org/traccar/protocol/Gl200ProtocolDecoder.java
index ab6507122..59f013313 100644
--- a/src/org/traccar/protocol/Gl200ProtocolDecoder.java
+++ b/src/org/traccar/protocol/Gl200ProtocolDecoder.java
@@ -278,11 +278,15 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder {
.number("(d{1,3}.d)?,") // speed
.number("(d{1,3})?,") // course
.number("(-?d{1,5}.d)?,") // altitude
- .number("(-?d{1,3}.d{6}),") // longitude
- .number("(-?d{1,2}.d{6}),") // latitude
+ .number("(-?d{1,3}.d{6})?,") // longitude
+ .number("(-?d{1,2}.d{6})?,") // latitude
.number("(dddd)(dd)(dd)") // date
- .number("(dd)(dd)(dd)") // time
+ .number("(dd)(dd)(dd)").optional(2) // time
.text(",")
+ .number("(0ddd),") // mcc
+ .number("(0ddd),") // mnc
+ .number("(xxxx),") // lac
+ .number("(xxxx),").optional(4) // cell
.any()
.number("(dddd)(dd)(dd)") // date
.number("(dd)(dd)(dd)").optional(2) // time
@@ -703,17 +707,28 @@ public class Gl200ProtocolDecoder extends BaseProtocolDecoder {
position.setCourse(parser.nextDouble());
position.setAltitude(parser.nextDouble());
- position.setValid(true);
- position.setLongitude(parser.nextDouble());
- position.setLatitude(parser.nextDouble());
+ if (parser.hasNext(2)) {
+ position.setValid(true);
+ position.setLongitude(parser.nextDouble());
+ position.setLatitude(parser.nextDouble());
+ } else {
+ getLastLocation(position, null);
+ }
- DateBuilder dateBuilder = new DateBuilder()
- .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt())
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
- position.setTime(dateBuilder.getDate());
+ if (parser.hasNext(6)) {
+ DateBuilder dateBuilder = new DateBuilder()
+ .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt())
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+ }
+
+ if (parser.hasNext(4)) {
+ position.setNetwork(new Network(CellTower.from(
+ parser.nextInt(), parser.nextInt(), parser.nextInt(16), parser.nextInt(16))));
+ }
if (parser.hasNext(6)) {
- dateBuilder = new DateBuilder()
+ DateBuilder dateBuilder = new DateBuilder()
.setDate(parser.nextInt(), parser.nextInt(), parser.nextInt())
.setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
if (!position.getOutdated() && position.getFixTime().after(dateBuilder.getDate())) {
diff --git a/src/org/traccar/protocol/MxtProtocolDecoder.java b/src/org/traccar/protocol/MxtProtocolDecoder.java
index c9eba5bed..eaeeacc97 100644
--- a/src/org/traccar/protocol/MxtProtocolDecoder.java
+++ b/src/org/traccar/protocol/MxtProtocolDecoder.java
@@ -27,6 +27,7 @@ import org.traccar.helper.UnitsConverter;
import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.ByteOrder;
public class MxtProtocolDecoder extends BaseProtocolDecoder {
@@ -40,16 +41,26 @@ public class MxtProtocolDecoder extends BaseProtocolDecoder {
private static void sendResponse(Channel channel, int device, long id, int crc) {
if (channel != null) {
- ChannelBuffer response = ChannelBuffers.dynamicBuffer();
- response.writeByte(0x01); // header
+ ChannelBuffer response = ChannelBuffers.dynamicBuffer(ByteOrder.LITTLE_ENDIAN, 0);
response.writeByte(device);
response.writeByte(MSG_ACK);
response.writeInt((int) id);
response.writeShort(crc);
response.writeShort(Checksum.crc16(
- Checksum.CRC16_CCITT_FALSE, response.toByteBuffer(0, response.readableBytes())));
- response.writeByte(0x04); // ending
- channel.write(response);
+ Checksum.CRC16_XMODEM, response.toByteBuffer()));
+
+ ChannelBuffer encoded = ChannelBuffers.dynamicBuffer();
+ encoded.writeByte(0x01); // header
+ while (response.readable()) {
+ int b = response.readByte();
+ if (b == 0x01 || b == 0x04 || b == 0x10 || b == 0x11 || b == 0x13) {
+ encoded.writeByte(0x10);
+ b += 0x20;
+ }
+ encoded.writeByte(b);
+ }
+ encoded.writeByte(0x04); // ending
+ channel.write(encoded);
}
}
diff --git a/src/org/traccar/protocol/PricolProtocol.java b/src/org/traccar/protocol/PricolProtocol.java
new file mode 100644
index 000000000..924c7c1d6
--- /dev/null
+++ b/src/org/traccar/protocol/PricolProtocol.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.handler.codec.frame.FixedLengthFrameDecoder;
+import org.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class PricolProtocol extends BaseProtocol {
+
+ public PricolProtocol() {
+ super("pricol");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new FixedLengthFrameDecoder(64));
+ pipeline.addLast("objectDecoder", new PricolProtocolDecoder(PricolProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/PricolProtocolDecoder.java b/src/org/traccar/protocol/PricolProtocolDecoder.java
new file mode 100644
index 000000000..52b68cca6
--- /dev/null
+++ b/src/org/traccar/protocol/PricolProtocolDecoder.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.DateBuilder;
+import org.traccar.helper.UnitsConverter;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+
+public class PricolProtocolDecoder extends BaseProtocolDecoder {
+
+ public PricolProtocolDecoder(PricolProtocol protocol) {
+ super(protocol);
+ }
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.readUnsignedByte(); // header
+
+ DeviceSession deviceSession = getDeviceSession(
+ channel, remoteAddress, buf.readBytes(7).toString(StandardCharsets.US_ASCII));
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ buf.readUnsignedByte(); // event type
+ buf.readUnsignedByte(); // packet version
+ buf.readUnsignedByte(); // device status
+ buf.readUnsignedByte(); // gsm status
+ buf.readUnsignedByte(); // gps status
+
+ position.setTime(new DateBuilder()
+ .setDateReverse(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte())
+ .setTime(buf.readUnsignedByte(), buf.readUnsignedByte(), buf.readUnsignedByte()).getDate());
+
+ position.setValid(true);
+
+ double lat = buf.getUnsignedShort(buf.readerIndex()) / 100;
+ lat += (buf.readUnsignedShort() % 100 * 10000 + buf.readUnsignedShort()) / 600000.0;
+ position.setLatitude(buf.readUnsignedByte() == 'S' ? -lat : lat);
+
+ double lon = buf.getUnsignedMedium(buf.readerIndex()) / 100;
+ lon += (buf.readUnsignedMedium() % 100 * 10000 + buf.readUnsignedShort()) / 600000.0;
+ position.setLongitude(buf.readUnsignedByte() == 'W' ? -lon : lon);
+
+ position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedByte()));
+
+ position.set(Position.KEY_INPUT, buf.readUnsignedShort());
+ position.set(Position.KEY_OUTPUT, buf.readUnsignedByte());
+
+ buf.readUnsignedByte(); // analog alerts
+ buf.readUnsignedShort(); // custom alert types
+
+ for (int i = 1; i <= 5; i++) {
+ position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort());
+ }
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium());
+ position.set(Position.KEY_RPM, buf.readUnsignedShort());
+
+ if (channel != null) {
+ channel.write(ChannelBuffers.copiedBuffer("ACK", StandardCharsets.US_ASCII));
+ }
+
+ return position;
+ }
+
+}
diff --git a/src/org/traccar/protocol/SuntechProtocolDecoder.java b/src/org/traccar/protocol/SuntechProtocolDecoder.java
index c9235f47f..d081cb901 100644
--- a/src/org/traccar/protocol/SuntechProtocolDecoder.java
+++ b/src/org/traccar/protocol/SuntechProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013 - 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2013 - 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.
@@ -17,85 +17,157 @@ package org.traccar.protocol;
import org.jboss.netty.channel.Channel;
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.Position;
import java.net.SocketAddress;
-import java.util.regex.Pattern;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.TimeZone;
public class SuntechProtocolDecoder extends BaseProtocolDecoder {
+ private int protocolType;
+
public SuntechProtocolDecoder(SuntechProtocol protocol) {
super(protocol);
+
+ protocolType = Context.getConfig().getInteger(getProtocolName() + ".protocolType");
}
- private static final Pattern PATTERN = new PatternBuilder()
- .expression("S.")
- .number("ddd")
- .expression("(?:[A-Z]{3})?;") // header
- .expression("([^;]+);").optional() // type
- .number("(d{6,});") // device id
- .number("d+;").optional()
- .number("(d+);") // version
- .number("(dddd)(dd)(dd);") // date
- .number("(dd):(dd):(dd);") // time
- .number("(x+);").optional() // cell
- .number("([-+]dd.d+);") // latitude
- .number("([-+]ddd.d+);") // longitude
- .number("(ddd.ddd);") // speed
- .number("(ddd.dd);") // course
- .number("d+;").optional()
- .number("(d+.d+)?") // battery
- .any() // full format
- .compile();
+ public void setProtocolType(int protocolType) {
+ this.protocolType = protocolType;
+ }
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ private Position decode9(
+ Channel channel, SocketAddress remoteAddress, String[] values) throws ParseException {
+ int index = 1;
+
+ String type = values[index++];
+
+ if (!type.equals("Location") && !type.equals("Emergency") && !type.equals("Alert")) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+
+ if (type.equals("Emergency") || type.equals("Alert")) {
+ position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
+ }
+
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]);
+ if (deviceSession == null) {
+ return null;
+ }
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.set(Position.KEY_VERSION, values[index++]);
+
+ DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ position.setTime(dateFormat.parse(values[index++] + values[index++]));
+
+ if (protocolType == 1) {
+ index += 1; // cell
+ }
+
+ position.setLatitude(Double.parseDouble(values[index++]));
+ position.setLongitude(Double.parseDouble(values[index++]));
+ position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++])));
+ position.setCourse(Double.parseDouble(values[index++]));
+
+ position.setValid(values[index++].equals("1"));
+
+ if (protocolType == 1) {
+ position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index]));
+ }
+
+ return position;
+ }
- Parser parser = new Parser(PATTERN, (String) msg);
- if (!parser.matches()) {
+ private Position decode23(
+ Channel channel, SocketAddress remoteAddress, String protocol, String[] values) throws ParseException {
+ int index = 0;
+
+ String type = values[index++].substring(5);
+
+ if (!type.equals("STT") && !type.equals("EMG") && !type.equals("EVT") && !type.equals("ALT")) {
return null;
}
Position position = new Position();
position.setProtocol(getProtocolName());
- if (parser.hasNext()) {
- String type = parser.next();
- if (type.equals("Alert") || type.equals("Emergency")) {
- position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
- }
+ if (type.equals("EMG") || type.equals("ALT")) {
+ position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
}
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]);
if (deviceSession == null) {
return null;
}
position.setDeviceId(deviceSession.getDeviceId());
- position.set(Position.KEY_VERSION, parser.next());
+ if (protocol.equals("ST300")) {
+ index += 1; // model
+ }
+
+ position.set(Position.KEY_VERSION, values[index++]);
+
+ DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHH:mm:ss");
+ dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
+ position.setTime(dateFormat.parse(values[index++] + values[index++]));
+
+ index += 1; // cell
+
+ position.setLatitude(Double.parseDouble(values[index++]));
+ position.setLongitude(Double.parseDouble(values[index++]));
+ position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++])));
+ position.setCourse(Double.parseDouble(values[index++]));
- DateBuilder dateBuilder = new DateBuilder()
- .setDate(parser.nextInt(), parser.nextInt(), parser.nextInt())
- .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
- position.setTime(dateBuilder.getDate());
+ position.set(Position.KEY_SATELLITES, Integer.parseInt(values[index++]));
- parser.next(); // location code + bsic
+ position.setValid(values[index++].equals("1"));
- position.setValid(true);
- position.setLatitude(parser.nextDouble());
- position.setLongitude(parser.nextDouble());
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble()));
- position.setCourse(parser.nextDouble());
+ position.set(Position.KEY_ODOMETER, Integer.parseInt(values[index++]));
+ position.set(Position.KEY_POWER, Double.parseDouble(values[index++]));
- position.set(Position.KEY_BATTERY, parser.next());
+ position.set(Position.PREFIX_IO + 1, values[index++]);
+
+ index += 1; // mode
+
+ if (type.equals("STT")) {
+ position.set(Position.KEY_INDEX, Integer.parseInt(values[index++]));
+ }
+
+ if (index < values.length) {
+ position.set(Position.KEY_HOURS, Integer.parseInt(values[index++]));
+ }
+
+ if (index < values.length) {
+ position.set(Position.KEY_BATTERY, Double.parseDouble(values[index]));
+ }
return position;
}
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ String[] values = ((String) msg).split(";");
+
+ String protocol = values[0].substring(0, 5);
+
+ if (protocol.equals("ST910")) {
+ return decode9(channel, remoteAddress, values);
+ } else {
+ return decode23(channel, remoteAddress, protocol, values);
+ }
+ }
+
}
diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
index 6f3af0bb2..411915400 100644
--- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
+++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java
@@ -71,28 +71,48 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
}
- private void decodeParameter(Position position, int id, long value) {
+ private void decodeParameter(Position position, int id, ChannelBuffer buf, int length) {
switch (id) {
case 9:
- position.set(Position.PREFIX_ADC + 1, value);
+ position.set(Position.PREFIX_ADC + 1, buf.readUnsignedShort());
break;
case 66:
- position.set(Position.KEY_POWER, value);
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() + "mV");
break;
- case 68:
- position.set(Position.KEY_BATTERY, value);
+ case 67:
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() + "mV");
break;
- case 85:
- position.set(Position.KEY_RPM, value);
+ case 72:
+ position.set(Position.PREFIX_TEMP + 1, buf.readInt() * 0.1);
break;
- case 182:
- position.set(Position.KEY_HDOP, value);
+ case 73:
+ position.set(Position.PREFIX_TEMP + 2, buf.readInt() * 0.1);
+ break;
+ case 74:
+ position.set(Position.PREFIX_TEMP + 3, buf.readInt() * 0.1);
break;
- case 239:
- position.set(Position.KEY_IGNITION, value == 1);
+ case 78:
+ position.set(Position.KEY_RFID, buf.readLong());
+ break;
+ case 182:
+ position.set(Position.KEY_HDOP, buf.readUnsignedShort() * 0.1);
break;
default:
- position.set(Position.PREFIX_IO + id, value);
+ switch (length) {
+ case 1:
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedByte());
+ break;
+ case 2:
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedShort());
+ break;
+ case 4:
+ position.set(Position.PREFIX_IO + id, buf.readUnsignedInt());
+ break;
+ case 8:
+ default:
+ position.set(Position.PREFIX_IO + id, buf.readLong());
+ break;
+ }
break;
}
}
@@ -183,7 +203,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(globalMask, 1)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- decodeParameter(position, buf.readUnsignedByte(), buf.readUnsignedByte());
+ decodeParameter(position, buf.readUnsignedByte(), buf, 1);
}
}
@@ -191,7 +211,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(globalMask, 2)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- decodeParameter(position, buf.readUnsignedByte(), buf.readUnsignedShort());
+ decodeParameter(position, buf.readUnsignedByte(), buf, 2);
}
}
@@ -199,7 +219,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
if (BitUtil.check(globalMask, 3)) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- decodeParameter(position, buf.readUnsignedByte(), buf.readUnsignedInt());
+ decodeParameter(position, buf.readUnsignedByte(), buf, 4);
}
}
@@ -207,7 +227,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder {
if (codec == CODEC_FM4X00) {
int cnt = buf.readUnsignedByte();
for (int j = 0; j < cnt; j++) {
- decodeParameter(position, buf.readUnsignedByte(), buf.readLong());
+ decodeParameter(position, buf.readUnsignedByte(), buf, 8);
}
}