Skip to content

Commit

Permalink
Implement TEK733 protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
tananaev committed Jul 14, 2018
1 parent f421a3f commit ab81b14
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 2 deletions.
1 change: 1 addition & 0 deletions setup/default.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
3 changes: 1 addition & 2 deletions src/org/traccar/protocol/OpenGtsProtocolDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ protected Object decode(
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);
Expand Down
42 changes: 42 additions & 0 deletions src/org/traccar/protocol/TekFrameDecoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2018 Anton Tananaev ([email protected])
*
* 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;
}

}
41 changes: 41 additions & 0 deletions src/org/traccar/protocol/TekProtocol.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2018 Anton Tananaev ([email protected])
*
* 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));
}
});
}

}
138 changes: 138 additions & 0 deletions src/org/traccar/protocol/TekProtocolDecoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright 2018 Anton Tananaev ([email protected])
*
* 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;
}

}
23 changes: 23 additions & 0 deletions test/org/traccar/protocol/TekFrameDecoderTest.java
Original file line number Diff line number Diff line change
@@ -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")));

}

}
24 changes: 24 additions & 0 deletions test/org/traccar/protocol/TekProtocolDecoderTest.java
Original file line number Diff line number Diff line change
@@ -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"));

}

}

0 comments on commit ab81b14

Please sign in to comment.