aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2018-07-14 23:43:23 +0300
committerAnton Tananaev <anton.tananaev@gmail.com>2018-07-14 23:43:23 +0300
commitab81b1434504d9ed288079f2cf0eb81aaffa668c (patch)
tree4a7270b07b5add7b16d04da85971304e8ea7ce69
parentf421a3f7205966cc4359bc0e01ae5afbceb006fb (diff)
downloadtrackermap-server-ab81b1434504d9ed288079f2cf0eb81aaffa668c.tar.gz
trackermap-server-ab81b1434504d9ed288079f2cf0eb81aaffa668c.tar.bz2
trackermap-server-ab81b1434504d9ed288079f2cf0eb81aaffa668c.zip
Implement TEK733 protocol
-rw-r--r--setup/default.xml1
-rw-r--r--src/org/traccar/protocol/OpenGtsProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/TekFrameDecoder.java42
-rw-r--r--src/org/traccar/protocol/TekProtocol.java41
-rw-r--r--src/org/traccar/protocol/TekProtocolDecoder.java138
-rw-r--r--test/org/traccar/protocol/TekFrameDecoderTest.java23
-rw-r--r--test/org/traccar/protocol/TekProtocolDecoderTest.java24
7 files changed, 270 insertions, 2 deletions
diff --git a/setup/default.xml b/setup/default.xml
index 83447ef83..49c6bb4a2 100644
--- a/setup/default.xml
+++ b/setup/default.xml
@@ -250,5 +250,6 @@
<entry key='freematics.port'>5170</entry>
<entry key='avema.port'>5171</entry>
<entry key='autotrack.port'>5172</entry>
+ <entry key='tek.port'>5173</entry>
</properties>
diff --git a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java
index b61426085..6ae3dc3ad 100644
--- a/src/org/traccar/protocol/OpenGtsProtocolDecoder.java
+++ b/src/org/traccar/protocol/OpenGtsProtocolDecoder.java
@@ -59,8 +59,7 @@ public class OpenGtsProtocolDecoder extends BaseHttpProtocolDecoder {
QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
Map<String, List<String>> params = decoder.parameters();
- Position position = new Position();
- position.setProtocol(getProtocolName());
+ Position position = new Position(getProtocolName());
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
String value = entry.getValue().get(0);
diff --git a/src/org/traccar/protocol/TekFrameDecoder.java b/src/org/traccar/protocol/TekFrameDecoder.java
new file mode 100644
index 000000000..44d2c590e
--- /dev/null
+++ b/src/org/traccar/protocol/TekFrameDecoder.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 io.netty.buffer.ByteBuf;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelHandlerContext;
+import org.traccar.BaseFrameDecoder;
+import org.traccar.helper.BitUtil;
+
+public class TekFrameDecoder extends BaseFrameDecoder {
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, ByteBuf buf) throws Exception {
+
+ if (buf.readableBytes() < 17) {
+ return null;
+ }
+
+ int length = 17 + buf.getUnsignedByte(16) + (BitUtil.from(buf.getUnsignedByte(15), 6) << 6);
+ if (buf.readableBytes() >= length) {
+ return buf.readBytes(length);
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/org/traccar/protocol/TekProtocol.java b/src/org/traccar/protocol/TekProtocol.java
new file mode 100644
index 000000000..4618fdf00
--- /dev/null
+++ b/src/org/traccar/protocol/TekProtocol.java
@@ -0,0 +1,41 @@
+/*
+ * 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.traccar.BaseProtocol;
+import org.traccar.PipelineBuilder;
+import org.traccar.TrackerServer;
+
+import java.util.List;
+
+public class TekProtocol extends BaseProtocol {
+
+ public TekProtocol() {
+ super("tek");
+ }
+
+ @Override
+ public void initTrackerServers(List<TrackerServer> serverList) {
+ serverList.add(new TrackerServer(false, getName()) {
+ @Override
+ protected void addProtocolHandlers(PipelineBuilder pipeline) {
+ pipeline.addLast("frameDecoder", new TekFrameDecoder());
+ pipeline.addLast("objectDecoder", new TekProtocolDecoder(TekProtocol.this));
+ }
+ });
+ }
+
+}
diff --git a/src/org/traccar/protocol/TekProtocolDecoder.java b/src/org/traccar/protocol/TekProtocolDecoder.java
new file mode 100644
index 000000000..497981832
--- /dev/null
+++ b/src/org/traccar/protocol/TekProtocolDecoder.java
@@ -0,0 +1,138 @@
+/*
+ * 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 io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.channel.Channel;
+import org.traccar.BaseProtocolDecoder;
+import org.traccar.DeviceSession;
+import org.traccar.helper.BitUtil;
+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.nio.charset.StandardCharsets;
+import java.util.regex.Pattern;
+
+public class TekProtocolDecoder extends BaseProtocolDecoder {
+
+ public TekProtocolDecoder(TekProtocol protocol) {
+ super(protocol);
+ }
+
+ private static final Pattern PATTERN = new PatternBuilder()
+ .number(",d+,")
+ .number("(dd)(dd)(dd).d,") // time (hhmmss)
+ .number("(dd)(dd.d+)") // latitude
+ .expression("([NS]),")
+ .number("(ddd)(dd.d+)") // longitude
+ .expression("([EW]),")
+ .number("(d+.d+),") // hdop
+ .number("(d+.d+),") // altitude
+ .number("(d+),") // fix mode
+ .number("(d+.d+),") // course
+ .number("d+.d+,") // speed km
+ .number("(d+.d+),") // speed kn
+ .number("(dd)(dd)(dd),") // date (ddmmyy)
+ .number("(d+),") // satellites
+ .any()
+ .compile();
+
+ @Override
+ protected Object decode(
+ Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+
+ ByteBuf buf = (ByteBuf) msg;
+
+ buf.readUnsignedByte(); // product type
+ buf.readUnsignedByte(); // hardware version
+ buf.readUnsignedByte(); // firmware version
+ buf.readUnsignedByte(); // contact reason
+ buf.readUnsignedByte(); // alarm / status
+ buf.readUnsignedByte(); // rssi
+ buf.readUnsignedByte(); // battery / status
+
+ String imei = ByteBufUtil.hexDump(buf.readBytes(8)).substring(1);
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ int type = BitUtil.to(buf.readUnsignedByte(), 6);
+ buf.readUnsignedByte(); // length
+
+ if (type == 4 || type == 8) {
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ int count = buf.readUnsignedShort();
+ buf.readUnsignedByte(); // hours / tickets
+ buf.readUnsignedByte(); // error code
+ buf.readUnsignedByte(); // reserved
+ buf.readUnsignedByte(); // logger speed
+ buf.readUnsignedByte(); // login time
+ buf.readUnsignedByte(); // minutes
+
+ for (int i = 0; i < count; i++) {
+ position.set("rssi" + (i + 1), buf.readUnsignedByte());
+ position.set("temp" + (i + 1), buf.readUnsignedByte() - 30);
+ int data = buf.readUnsignedShort();
+ position.set("src" + (i + 1), BitUtil.from(data, 10));
+ position.set("ullage" + (i + 1), BitUtil.to(data, 10));
+ }
+
+ return position;
+
+ } else if (type == 17) {
+
+ String sentence = buf.toString(StandardCharsets.US_ASCII);
+
+ Parser parser = new Parser(PATTERN, sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ DateBuilder dateBuilder = new DateBuilder()
+ .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt());
+
+ position.setLatitude(parser.nextCoordinate());
+ position.setLongitude(parser.nextCoordinate());
+
+ position.set(Position.KEY_HDOP, parser.nextDouble());
+
+ position.setAltitude(parser.nextDouble());
+ position.setValid(parser.nextInt() > 0);
+ position.setCourse(parser.nextDouble());
+ position.setSpeed(parser.nextDouble());
+
+ dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt());
+ position.setTime(dateBuilder.getDate());
+
+ return position;
+
+ }
+
+ return null;
+ }
+
+}
diff --git a/test/org/traccar/protocol/TekFrameDecoderTest.java b/test/org/traccar/protocol/TekFrameDecoderTest.java
new file mode 100644
index 000000000..0446670d8
--- /dev/null
+++ b/test/org/traccar/protocol/TekFrameDecoderTest.java
@@ -0,0 +1,23 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class TekFrameDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ TekFrameDecoder decoder = new TekFrameDecoder();
+
+ verifyFrame(
+ binary("020315048715E70861074028023219026200400A0340002C007F0009000000000000000000402842064028420641284206402844064128440640284406402844064028440641284406402844060010010C04052B000253000000000001060A0000000000000228330000FF0000FF360014B394"),
+ decoder.decode(null, null, binary("020315048715E70861074028023219026200400A0340002C007F0009000000000000000000402842064028420641284206402844064128440640284406402844064028440641284406402844060010010C04052B000253000000000001060A0000000000000228330000FF0000FF360014B394")));
+
+ verifyFrame(
+ binary("0501C2828E14750861075021004551047B00019700000082010F0A5B28770A5B28770A5B28760A5B28770A5B28770A5B28770A5B28770A5B28760A5B28760A5B28760A5B28770A5B28760A5B28760A5B28760A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5F2877000000000000000000000000EEBA"),
+ decoder.decode(null, null, binary("0501C2828E14750861075021004551047B00019700000082010F0A5B28770A5B28770A5B28760A5B28770A5B28770A5B28770A5B28770A5B28760A5B28760A5B28760A5B28770A5B28760A5B28760A5B28760A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5F2877000000000000000000000000EEBA")));
+
+ }
+
+}
diff --git a/test/org/traccar/protocol/TekProtocolDecoderTest.java b/test/org/traccar/protocol/TekProtocolDecoderTest.java
new file mode 100644
index 000000000..64bcf1285
--- /dev/null
+++ b/test/org/traccar/protocol/TekProtocolDecoderTest.java
@@ -0,0 +1,24 @@
+package org.traccar.protocol;
+
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+
+public class TekProtocolDecoderTest extends ProtocolTest {
+
+ @Test
+ public void testDecode() throws Exception {
+
+ TekProtocolDecoder decoder = new TekProtocolDecoder(new TekProtocol());
+
+ verifyPosition(decoder, binary(
+ "0501E304E00E76086107502100455111492C33332C3137303935342E302C353235352E393933344E2C30303833322E34333935572C322E312C3133342E382C322C302E30302C302E302C302E302C3234303931352C30362C3C45"));
+
+ verifyAttributes(decoder, binary(
+ "0501C2828E14750861075021004551047B00019700000082010F0A5B28770A5B28770A5B28760A5B28770A5B28770A5B28770A5B28770A5B28760A5B28760A5B28760A5B28770A5B28760A5B28760A5B28760A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5D28770A5F2877000000000000000000000000EEBA"));
+
+ verifyAttributes(decoder, binary(
+ "0509220886157E0863835020373564087B00018C0000018003160A6E28790A6E28790A6E287A0A6E287A0A6E287A0A6E287A0A6E287A0A6E287A0A6E287A0A6E287A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000BD35"));
+
+ }
+
+}