aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2018-06-11 05:49:35 +1200
committerAnton Tananaev <anton.tananaev@gmail.com>2018-06-11 05:49:35 +1200
commit9cbd8fafc312996b9b5dae68b6c3ecf68d8facf0 (patch)
tree0c8c863e145d688b7885235aeb27b170f4644617 /src
parent77f5a12b9c50cdf317528a8e1569c3cf47b251f4 (diff)
downloadtraccar-server-9cbd8fafc312996b9b5dae68b6c3ecf68d8facf0.tar.gz
traccar-server-9cbd8fafc312996b9b5dae68b6c3ecf68d8facf0.tar.bz2
traccar-server-9cbd8fafc312996b9b5dae68b6c3ecf68d8facf0.zip
Implement Atlanta OBD protocol
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/protocol/L100FrameDecoder.java24
-rw-r--r--src/org/traccar/protocol/L100ProtocolDecoder.java109
2 files changed, 124 insertions, 9 deletions
diff --git a/src/org/traccar/protocol/L100FrameDecoder.java b/src/org/traccar/protocol/L100FrameDecoder.java
index 98c2f9768..c8a520772 100644
--- a/src/org/traccar/protocol/L100FrameDecoder.java
+++ b/src/org/traccar/protocol/L100FrameDecoder.java
@@ -26,22 +26,32 @@ public class L100FrameDecoder extends FrameDecoder {
protected Object decode(
ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
- if (buf.readableBytes() < 80) {
+ if (buf.readableBytes() < 10) {
return null;
}
- int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02);
- if (index == -1) {
- index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04);
+ int header = buf.getByte(buf.readerIndex());
+ boolean obd = header == 'L' || header == 'H';
+
+ int index;
+ if (obd) {
+ index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*');
+ } else {
+ index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02);
if (index == -1) {
- return null;
+ index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04);
+ if (index == -1) {
+ return null;
+ }
}
}
index += 2; // checksum
- if (buf.readableBytes() >= index - buf.readerIndex()) {
- buf.skipBytes(2); // header
+ if (buf.writerIndex() >= index) {
+ if (!obd) {
+ buf.skipBytes(2); // header
+ }
ChannelBuffer frame = buf.readBytes(index - buf.readerIndex() - 2);
buf.skipBytes(2); // footer
return frame;
diff --git a/src/org/traccar/protocol/L100ProtocolDecoder.java b/src/org/traccar/protocol/L100ProtocolDecoder.java
index fe2c298e1..5842b35b6 100644
--- a/src/org/traccar/protocol/L100ProtocolDecoder.java
+++ b/src/org/traccar/protocol/L100ProtocolDecoder.java
@@ -18,6 +18,7 @@ package org.traccar.protocol;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
+import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
import org.traccar.helper.PatternBuilder;
@@ -66,23 +67,59 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder {
.text("ATL")
.compile();
+ private static final Pattern PATTERN_OBD = new PatternBuilder()
+ .expression("[LH],") // archive
+ .text("ATL,")
+ .number("(d{15}),") // imei
+ .number("(d+),") // type
+ .number("(d+),") // index
+ .groupBegin()
+ .number("(dd)(dd)(dd),") // time (hhmmss)
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .expression("([AV]),") // validity
+ .number("(d+.d+);([NS]),") // latitude
+ .number("(d+.d+);([EW]),") // longitude
+ .number("(d+),") // speed
+ .number("(d+),") // course
+ .number("(d+.d+),") // odometer
+ .number("(d+.d+),") // battery
+ .number("(d+),") // rssi
+ .number("(d+),") // mcc
+ .number("(d+),") // mnc
+ .number("(d+),") // lac
+ .number("(x+),") // cid
+ .number("#(d)(d)(d)(d),") // status
+ .number("(d),") // overspeed
+ .text("ATL,")
+ .groupEnd("?")
+ .compile();
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
String sentence = (String) msg;
+ if (sentence.startsWith("L") || sentence.startsWith("H")) {
+ return decodeObd(channel, remoteAddress, sentence);
+ } else {
+ return decodeNormal(channel, remoteAddress, sentence);
+ }
+ }
+
+ private Object decodeNormal(Channel channel, SocketAddress remoteAddress, String sentence) {
+
Parser parser = new Parser(PATTERN, sentence);
if (!parser.matches()) {
return null;
}
- Position position = new Position(getProtocolName());
-
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
if (deviceSession == null) {
return null;
}
+
+ Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
DateBuilder dateBuilder = new DateBuilder()
@@ -112,4 +149,72 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder {
return position;
}
+ private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) {
+
+ Parser parser = new Parser(PATTERN_OBD, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ String imei = parser.next();
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ int type = parser.nextInt();
+ int index = parser.nextInt();
+
+ if (type == 1) {
+ if (channel != null) {
+ String response = "@" + imei + ",00," + index + ",";
+ response += "*" + (char) Checksum.xor(response);
+ channel.write(response, remoteAddress);
+ }
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(parser.nextDateTime(Parser.DateTimeFormat.HMS_DMY));
+ position.setValid(parser.next().equals("A"));
+ position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM));
+ position.setSpeed(parser.nextInt());
+ position.setCourse(parser.nextInt());
+
+ position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
+ position.set(Position.KEY_BATTERY, parser.nextDouble());
+
+ int rssi = parser.nextInt();
+ position.setNetwork(new Network(CellTower.from(
+ parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextHexInt(), rssi)));
+
+ position.set(Position.KEY_IGNITION, parser.nextInt() == 1);
+ parser.next(); // reserved
+
+ switch (parser.nextInt()) {
+ case 0:
+ position.set(Position.KEY_ALARM, Position.ALARM_BRAKING);
+ break;
+ case 2:
+ position.set(Position.KEY_ALARM, Position.ALARM_ACCELERATION);
+ break;
+ case 1:
+ position.set(Position.KEY_ALARM, Position.ALARM_GENERAL);
+ break;
+ default:
+ break;
+ }
+
+ position.set(Position.KEY_CHARGE, parser.nextInt() == 1);
+
+ if (parser.nextInt() == 1) {
+ position.set(Position.KEY_ALARM, Position.ALARM_OVERSPEED);
+ }
+
+ return position;
+ }
+
}