From 2bc8572b6e93cff19cf47f2cb0183594fe3cb510 Mon Sep 17 00:00:00 2001 From: Srgian Danity Date: Wed, 18 Jan 2017 14:40:44 +0200 Subject: Added UDP support on Teltonika Decoder --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 52 ++++++++++++++++++---- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 074d89703..a9bb4c6a0 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -18,6 +18,7 @@ package org.traccar.protocol; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.socket.DatagramChannel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BitUtil; @@ -211,11 +212,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } - private List parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private List parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, + boolean connectionless, int avlOffset, short packetId) { List positions = new LinkedList<>(); - buf.skipBytes(4); // marker - buf.readUnsignedInt(); // data length + buf.skipBytes(avlOffset); // marker + if (!connectionless) { + buf.readUnsignedInt(); // data length + } int codec = buf.readUnsignedByte(); int count = buf.readUnsignedByte(); @@ -240,27 +244,57 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - ChannelBuffer response = ChannelBuffers.directBuffer(4); - response.writeInt(count); - channel.write(response); + if (connectionless) { + ChannelBuffer response = ChannelBuffers.directBuffer(5); + response.writeShort(3); + response.writeShort(packetId); + response.writeByte(0x02); + channel.write(response, remoteAddress); + } else { + ChannelBuffer response = ChannelBuffers.directBuffer(4); + response.writeInt(count); + channel.write(response); + } } return positions; } @Override - protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; + if (channel instanceof DatagramChannel) { + return decodeUDP(channel, remoteAddress, buf); + } else { + return decodeTCP(channel, remoteAddress, buf); + } + } + + protected Object decodeTCP(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { - return parseData(channel, remoteAddress, buf); + return parseData(channel, remoteAddress, buf, false, 4, (short) 0); } return null; } + protected Object decodeUDP(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + int udpPacketLength = buf.getUnsignedShort(0); + short udpPacketId = buf.getShort(2); + byte udpPacketType = buf.getByte(4); + + byte packetId = buf.getByte(5); + int imeiLength = buf.getUnsignedShort(6); + String imei = buf.toString(8, imeiLength, StandardCharsets.US_ASCII); + int avlDataArrOffset = 8 + imeiLength; + int avlDataArrLength = udpPacketLength - avlDataArrOffset + 2; + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + return parseData(channel, remoteAddress, buf, true, avlDataArrOffset, udpPacketId); + } + } -- cgit v1.2.3 From 49c50ef9b823a5e3c726739f801bf7b406c43bb0 Mon Sep 17 00:00:00 2001 From: Srgian Danity Date: Thu, 19 Jan 2017 09:27:18 +0200 Subject: Implemented code review suggestions - improved variables naming - droped bool 'connectionless' and used channel implementation for execution branching - CamelCasedAbbreviationsToo - optimized use of deviceSession --- .../traccar/protocol/TeltonikaProtocolDecoder.java | 41 +++++++++++----------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index a9bb4c6a0..2c5e31afb 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -39,7 +39,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private void parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { + private DeviceSession parseIdentification(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) { int length = buf.readUnsignedShort(); String imei = buf.toString(buf.readerIndex(), length, StandardCharsets.US_ASCII); @@ -54,6 +54,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } channel.write(response); } + return deviceSession; } public static final int CODEC_GH3000 = 0x07; @@ -212,18 +213,21 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } - private List parseData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, - boolean connectionless, int avlOffset, short packetId) { + private List parseData( + Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int offset, int packetId, String... imei) { List positions = new LinkedList<>(); - buf.skipBytes(avlOffset); // marker - if (!connectionless) { + buf.skipBytes(offset); // marker + + if (!(channel instanceof DatagramChannel)) { buf.readUnsignedInt(); // data length } + int codec = buf.readUnsignedByte(); int count = buf.readUnsignedByte(); - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); + if (deviceSession == null) { return null; } @@ -244,7 +248,7 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } if (channel != null) { - if (connectionless) { + if (channel instanceof DatagramChannel) { ChannelBuffer response = ChannelBuffers.directBuffer(5); response.writeShort(3); response.writeShort(packetId); @@ -266,35 +270,32 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; if (channel instanceof DatagramChannel) { - return decodeUDP(channel, remoteAddress, buf); + return decodeUdp(channel, remoteAddress, buf); } else { - return decodeTCP(channel, remoteAddress, buf); + return decodeTcp(channel, remoteAddress, buf); } } - protected Object decodeTCP(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { + protected Object decodeTcp(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { - return parseData(channel, remoteAddress, buf, false, 4, (short) 0); + return parseData(channel, remoteAddress, buf, 4, 0); } return null; } - protected Object decodeUDP(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { - int udpPacketLength = buf.getUnsignedShort(0); - short udpPacketId = buf.getShort(2); - byte udpPacketType = buf.getByte(4); + protected Object decodeUdp(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { - byte packetId = buf.getByte(5); + int packetId = buf.getShort(2); int imeiLength = buf.getUnsignedShort(6); String imei = buf.toString(8, imeiLength, StandardCharsets.US_ASCII); - int avlDataArrOffset = 8 + imeiLength; - int avlDataArrLength = udpPacketLength - avlDataArrOffset + 2; - DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, imei); - return parseData(channel, remoteAddress, buf, true, avlDataArrOffset, udpPacketId); + int offset = 8 + imeiLength; + + return parseData(channel, remoteAddress, buf, offset, packetId, imei); + } } -- cgit v1.2.3 From d8e06f0f17f3c82c4410b7dc9e540e8c75e4faa7 Mon Sep 17 00:00:00 2001 From: Srgian Danity Date: Thu, 19 Jan 2017 13:06:47 +0200 Subject: Switched from getXxx to readXxx on buffer --- src/org/traccar/protocol/TeltonikaProtocolDecoder.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java index 2c5e31afb..bc1a4704e 100644 --- a/src/org/traccar/protocol/TeltonikaProtocolDecoder.java +++ b/src/org/traccar/protocol/TeltonikaProtocolDecoder.java @@ -214,11 +214,9 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { } private List parseData( - Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int offset, int packetId, String... imei) { + Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int packetId, String... imei) { List positions = new LinkedList<>(); - buf.skipBytes(offset); // marker - if (!(channel instanceof DatagramChannel)) { buf.readUnsignedInt(); // data length } @@ -281,7 +279,8 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { if (buf.getUnsignedShort(0) > 0) { parseIdentification(channel, remoteAddress, buf); } else { - return parseData(channel, remoteAddress, buf, 4, 0); + buf.skipBytes(4); + return parseData(channel, remoteAddress, buf, 0); } return null; @@ -289,12 +288,14 @@ public class TeltonikaProtocolDecoder extends BaseProtocolDecoder { protected Object decodeUdp(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) throws Exception { - int packetId = buf.getShort(2); - int imeiLength = buf.getUnsignedShort(6); + buf.skipBytes(2); + int packetId = buf.readUnsignedShort(); + buf.skipBytes(2); + int imeiLength = buf.readUnsignedShort(); String imei = buf.toString(8, imeiLength, StandardCharsets.US_ASCII); - int offset = 8 + imeiLength; + buf.skipBytes(imeiLength); - return parseData(channel, remoteAddress, buf, offset, packetId, imei); + return parseData(channel, remoteAddress, buf, packetId, imei); } -- cgit v1.2.3