From b5eb588704b76a4535e656253f3d50df1b046c68 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Fri, 13 Mar 2015 15:18:57 +1300 Subject: Reimplement BCE frame decoder --- src/org/traccar/protocol/BceFrameDecoder.java | 31 ++++++++++++++++------ .../traccar/protocol/BceProtocolDecoderTest.java | 4 ++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/org/traccar/protocol/BceFrameDecoder.java b/src/org/traccar/protocol/BceFrameDecoder.java index 2bb249348..8accc02d8 100644 --- a/src/org/traccar/protocol/BceFrameDecoder.java +++ b/src/org/traccar/protocol/BceFrameDecoder.java @@ -18,30 +18,45 @@ 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; import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder; -public class BceFrameDecoder extends LengthFieldBasedFrameDecoder { +public class BceFrameDecoder extends FrameDecoder { private static final int HANDSHAKE_LENGTH = 7; // "#BCE#\r\n" - + private boolean header = true; - - public BceFrameDecoder() { - super(1024, 8, 2, 8 + 2 + 1, 0); + + private static byte checksum(ChannelBuffer buf, int end) { + byte result = 0; + for (int i = 0; i < end; i++) { + result += buf.getByte(buf.readerIndex() + i); + } + return result; } - + @Override protected Object decode( ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { - + if (header && buf.readableBytes() >= HANDSHAKE_LENGTH) { buf.skipBytes(HANDSHAKE_LENGTH); header = false; } - return super.decode(ctx, channel, buf); + int end = 8; // IMEI + + while (buf.readableBytes() >= end + 2 + 1 + 1 + 1) { + end += buf.getUnsignedShort(buf.readerIndex() + end) + 2; + + if (buf.readableBytes() > end && checksum(buf, end) == buf.getByte(buf.readerIndex() + end)) { + return buf.readBytes(end + 1); + } + } + + return null; } } diff --git a/test/org/traccar/protocol/BceProtocolDecoderTest.java b/test/org/traccar/protocol/BceProtocolDecoderTest.java index 21ef125d5..f8120bfa9 100644 --- a/test/org/traccar/protocol/BceProtocolDecoderTest.java +++ b/test/org/traccar/protocol/BceProtocolDecoderTest.java @@ -1,6 +1,8 @@ package org.traccar.protocol; import java.nio.ByteOrder; + +import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.junit.Test; import org.traccar.helper.ChannelBufferTools; @@ -26,7 +28,7 @@ public class BceProtocolDecoderTest { verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( "2d41abfa2e4501004e02a5a0068609f96a009106260af96a00a006260af96a009106960af96a00a306a60af96a008f06b60af96a009106960cf96a00a03e0715f96affc300804000e6a23a4230ccc441001f47850200000000a0000000bd6542651a110d004b1000000000a401045a56bf4d02480000000000000000061623f96a00a0062623f96a00913ea728f96affc300804000e6a23a4230ccc441001f7f850200000000a0000000bd6542651a110d004a1000000000a401045a56bf4d02480000000000000000069639f96a00a006a639f96a00913e373cf96affc300804000e6a23a4230ccc441001f7f850200000000a0000000ad6534651a110d004a1000000000a401045a56bf4d024800000000000000003ed74ff96affc300804000e6a23a4230ccc441001f7f850200000000a0000000ad6534651a111b004a1000000000a401045a56bf4d01480000000000000000061650f96a00a0062650f96a00913e6763f96affc300804000e6a23a4230ccc441001f7f850200000000a0000000ad6534651a110d004a1000000000a401045a56bf4d01480000000000000000069666f96a00a006a666f96a00913e0777f96affc300804000e6a23a4230ccc441001f7f850200000000a0000000ad6534651a110d004a1000000000a401045a56bf4d0148000000000000000006067df96a00a006167df96a0091063687f96a00a3064687f96a008f065687f96a0091063689f96a00a03e978af96affc300804000e6a23a4230ccc441001f87850200000000a0000000ad6527651a110d004a1000000000a401045a56bf4d024800000000000000000e")))); - *//*verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( + verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( "be76619c834601003302a5e8327764726bff432fc52a420e2c93410028afd2070000000080024a0005040000000000008e06547f0000a401043cf21f390e54328764726bff432fc52a420e2c93410028afd2070000000080024c0005040000000000008e064f7f0000a401043cf21f390e54329764726bff432fc52a420e2c93410028afd2070000000080024e0002040000000000008d064f7f0000a401043cf21f390e5432a764726bff432fc52a420e2c93410028afd2070000000080024e0004040000000000008e06587f0000a401043cf21f390e5432b764726bff432fc52a420e2c93410028afd207000000008002460005040000000000008e06557f0000a401043cf21f390e5432c764726bff432fc52a420e2c93410028afd2070000000080024e0004040000000000008e06347f0000a401043cf21f390e5432d764726bff432fc52a420e2c93410028afd2070000000080024e0002040000000000008e06547f0000a401043cf21f390e5432e764726bff432fc52a420e2c93410028afd207000000008002540002040000000000008e06477f0000a401043cf21f390e5432f764726bff432fc52a420e2c93410028afd207000000008002540004040000000000008d064f7f0000a401043cf21f390e54320765726bff432fc52a420e2c93410028afd207000000008002540004040000000000008e064d7f0000a401043cf21f390e54321765726bff432fc52a420e2c93410028afd207000000008002540004040000000000008e06467f0000a401043cf21f390e544200a0003f3743c96bffc3db0060c81c42d885ab41002aaf060000000000d102380167040000000000008a064f7f0000a4010412a46b330033000000000000000000000025")))); verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( -- cgit v1.2.3