aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2018-03-23 05:38:03 +1300
committerAnton Tananaev <anton.tananaev@gmail.com>2018-03-23 05:38:03 +1300
commitfeaa6e2f2816efad85bdb3a29e40bd2313e65475 (patch)
tree27685541898749a5cf15781dd227f062e4d053ec
parent7e1da0e6223f1b07269fb3e43369e35c1f3baf3e (diff)
downloadtrackermap-server-feaa6e2f2816efad85bdb3a29e40bd2313e65475.tar.gz
trackermap-server-feaa6e2f2816efad85bdb3a29e40bd2313e65475.tar.bz2
trackermap-server-feaa6e2f2816efad85bdb3a29e40bd2313e65475.zip
Initial EGTS protocol implementation
-rw-r--r--setup/default.xml1
-rw-r--r--src/org/traccar/protocol/EgtsFrameDecoder.java45
-rw-r--r--src/org/traccar/protocol/EgtsProtocol.java42
-rw-r--r--src/org/traccar/protocol/EgtsProtocolDecoder.java149
-rw-r--r--test/org/traccar/protocol/EgtsFrameDecoderTest.java21
-rw-r--r--test/org/traccar/protocol/EgtsProtocolDecoderTest.java27
6 files changed, 285 insertions, 0 deletions
diff --git a/setup/default.xml b/setup/default.xml
index 1b106d2d0..912006bcf 100644
--- a/setup/default.xml
+++ b/setup/default.xml
@@ -231,5 +231,6 @@
<entry key='opengts.port'>5159</entry>
<entry key='cautela.port'>5160</entry>
<entry key='continental.port'>5161</entry>
+ <entry key='egts.port'>5162</entry>
</properties>
diff --git a/src/org/traccar/protocol/EgtsFrameDecoder.java b/src/org/traccar/protocol/EgtsFrameDecoder.java
new file mode 100644
index 000000000..71ffc1811
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsFrameDecoder.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+
+public class EgtsFrameDecoder extends FrameDecoder {
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception {
+
+ if (buf.readableBytes() < 10) {
+ return null;
+ }
+
+ int headerLength = buf.getUnsignedByte(buf.readerIndex() + 3);
+ int frameLength = buf.getUnsignedShort(buf.readerIndex() + 5);
+
+ int length = headerLength + frameLength + (frameLength > 0 ? 2 : 0);
+
+ if (buf.readableBytes() >= length) {
+ return buf.readBytes(length);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/EgtsProtocol.java b/src/org/traccar/protocol/EgtsProtocol.java
new file mode 100644
index 000000000..0a57f0061
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsProtocol.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2018 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.traccar.BaseProtocol;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class EgtsProtocol extends BaseProtocol {
+
+ public EgtsProtocol() {
+ super("egts");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(new ServerBootstrap(), getName()) {
+ @Override
+ protected void addSpecificHandlers(ChannelPipeline pipeline) {
+ pipeline.addLast("frameDecoder", new EgtsFrameDecoder());
+ pipeline.addLast("objectDecoder", new EgtsProtocolDecoder(EgtsProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/EgtsProtocolDecoder.java b/src/org/traccar/protocol/EgtsProtocolDecoder.java
new file mode 100644
index 000000000..f32f564ed
--- /dev/null
+++ b/src/org/traccar/protocol/EgtsProtocolDecoder.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2018 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.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.BitUtil;
+import org.traccar.model.Position;
+
+import java.net.SocketAddress;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+
+public class EgtsProtocolDecoder extends BaseProtocolDecoder {
+
+ public EgtsProtocolDecoder(EgtsProtocol protocol) {
+ super(protocol);
+ }
+
+ public static final int SERVICE_AUTH = 1;
+ public static final int SERVICE_TELEDATA = 2;
+ public static final int SERVICE_COMMANDS = 4;
+ public static final int SERVICE_FIRMWARE = 9;
+ public static final int SERVICE_ECALL = 10;
+
+ public static final int MSG_RECORD_RESPONSE = 0;
+ public static final int MSG_TERM_IDENTITY = 1;
+ public static final int MSG_MODULE_DATA = 2;
+ public static final int MSG_VEHICLE_DATA = 3;
+ public static final int MSG_AUTH_PARAMS = 4;
+ public static final int MSG_AUTH_INFO = 5;
+ public static final int MSG_SERVICE_INFO = 6;
+ public static final int MSG_RESULT_CODE = 7;
+ public static final int MSG_POS_DATA = 16;
+ public static final int MSG_EXT_POS_DATA = 17;
+ public static final int MSG_AD_SENSORS_DATA = 18;
+ public static final int MSG_COUNTERS_DATA = 19;
+ public static final int MSG_STATE_DATA = 20;
+ public static final int MSG_LOOPIN_DATA = 22;
+ public static final int MSG_ABS_DIG_SENS_DATA = 23;
+ public static final int MSG_ABS_AN_SENS_DATA = 24;
+ public static final int MSG_ABS_CNTR_DATA = 25;
+ public static final int MSG_ABS_LOOPIN_DATA = 26;
+ public static final int MSG_LIQUID_LEVEL_SENSOR = 27;
+ public static final int MSG_PASSENGERS_COUNTERS = 28;
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.skipBytes(buf.getUnsignedByte(buf.readerIndex() + 3));
+
+ DeviceSession deviceSession = null;
+ List<Position> positions = new LinkedList<>();
+
+ while (buf.readableBytes() > 2) {
+
+ int length = buf.readUnsignedShort();
+
+ buf.readUnsignedShort(); // index
+
+ int flags = buf.readUnsignedByte();
+
+ if (BitUtil.check(flags, 0)) {
+ String deviceId = String.valueOf(buf.readUnsignedInt());
+ if (deviceSession == null) {
+ deviceSession = getDeviceSession(channel, remoteAddress, deviceId);
+ }
+ }
+
+ if (deviceSession == null) {
+ deviceSession = getDeviceSession(channel, remoteAddress);
+ }
+
+ if (BitUtil.check(flags, 1)) {
+ buf.readUnsignedInt(); // event id
+ }
+ if (BitUtil.check(flags, 2)) {
+ buf.readUnsignedInt(); // time
+ }
+
+ buf.readUnsignedByte(); // source service type
+ buf.readUnsignedByte(); // recipient service type
+
+ int recordEnd = buf.readerIndex() + length;
+
+ while (buf.readerIndex() < recordEnd) {
+ int type = buf.readUnsignedByte();
+ int end = buf.readUnsignedShort() + buf.readerIndex();
+
+ if (type == MSG_POS_DATA) {
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ position.setTime(new Date((buf.readUnsignedInt() + 1262304000) * 1000)); // since 2010-01-01
+ position.setLatitude(buf.readUnsignedInt() * 90.0 / 0xFFFFFFFFL);
+ position.setLongitude(buf.readUnsignedInt() * 180.0 / 0xFFFFFFFFL);
+
+ int positionFlags = buf.readUnsignedByte();
+ position.setValid(BitUtil.check(positionFlags, 0));
+ if (BitUtil.check(positionFlags, 5)) {
+ position.setLatitude(-position.getLatitude());
+ }
+ if (BitUtil.check(positionFlags, 6)) {
+ position.setLongitude(-position.getLongitude());
+ }
+
+ int speed = buf.readUnsignedShort();
+ position.setSpeed(BitUtil.to(speed, 14));
+ position.setCourse(buf.readUnsignedByte() + (BitUtil.check(speed, 15) ? 0x100 : 0));
+
+ position.set(Position.KEY_ODOMETER, buf.readUnsignedMedium() * 100);
+ position.set(Position.KEY_INPUT, buf.readUnsignedByte());
+ position.set(Position.KEY_EVENT, buf.readUnsignedByte());
+
+ if (BitUtil.check(positionFlags, 7)) {
+ position.setAltitude(buf.readMedium());
+ }
+
+ positions.add(position);
+ }
+
+ buf.readerIndex(end);
+ }
+
+ }
+
+ return positions.isEmpty() ? null : positions;
+ }
+
+}
diff --git a/test/org/traccar/protocol/EgtsFrameDecoderTest.java b/test/org/traccar/protocol/EgtsFrameDecoderTest.java
new file mode 100644
index 000000000..91a53525e
--- /dev/null
+++ b/test/org/traccar/protocol/EgtsFrameDecoderTest.java
@@ -0,0 +1,21 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+import java.nio.ByteOrder;
+
+public class EgtsFrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ EgtsFrameDecoder decoder = new EgtsFrameDecoder();
+
+ verifyFrame(
+ binary("0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"),
+ decoder.decode(null, null, binary(ByteOrder.LITTLE_ENDIAN, "0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2")));
+
+ }
+
+}
diff --git a/test/org/traccar/protocol/EgtsProtocolDecoderTest.java b/test/org/traccar/protocol/EgtsProtocolDecoderTest.java
new file mode 100644
index 000000000..9a3434bec
--- /dev/null
+++ b/test/org/traccar/protocol/EgtsProtocolDecoderTest.java
@@ -0,0 +1,27 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+import java.nio.ByteOrder;
+
+public class EgtsProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ EgtsProtocolDecoder decoder = new EgtsProtocolDecoder(new EgtsProtocol());
+
+ verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN,
+ "0100020B0025003A5701C91A003A5701CD6E68490202101700CBB4740F7617FD924364104F116A0000000000010300001EC2"),
+ position("2018-03-21 05:38:19.000", true, 51.67569, 55.59189));
+
+ verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN,
+ "0100020B0079000000011F6A001424951CA5CB0F23B5740F020210180023B5740F0A301994DA9C524C9128000A000000100082000011040018110300120900000003150100E803001B0700010000340900001B0700420000000000001B0700430000000000001B0700440000000000001B0700450000000000001B0700460000000000008020"));
+
+ verifyPositions(decoder, binary(ByteOrder.LITTLE_ENDIAN,
+ "0100020B00F200000001D66A001224951CA5CB0FFCB4740F0202101800FCB4740F502119943D9F524C9119805C000000100084000011040018110300120900000003150100E803001B0700410000000000001B0700420000000000001B0700430000000000001B0700440000000000001B0700450000000000001B0700460000000000006A001324951CA5CB0F05B5740F020210180005B5740F222519942D9E524C9100008B000000100083000011040018110300120900000003160100E803001B0700010000310900001B0700420000000000001B0700430000000000001B0700440000000000001B0700450000000000001B070046000000000000134E"));
+
+ }
+
+}