From 0e22ee92528ed1a1ec76f536881928c4f7b78042 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Mon, 22 Dec 2014 21:16:39 +1300 Subject: Support UDP for Atrack (fix #341) --- src/org/traccar/protocol/AtrackFrameDecoder.java | 4 ++-- src/org/traccar/protocol/AtrackProtocolDecoder.java | 18 ++++++++++++++---- .../traccar/protocol/AtrackProtocolDecoderTest.java | 20 ++++++++++---------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/org/traccar/protocol/AtrackFrameDecoder.java b/src/org/traccar/protocol/AtrackFrameDecoder.java index 90dfa68b6..35db02baf 100644 --- a/src/org/traccar/protocol/AtrackFrameDecoder.java +++ b/src/org/traccar/protocol/AtrackFrameDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2013 - 2014 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ public class AtrackFrameDecoder extends LengthFieldBasedFrameDecoder { // Keep alive message if (buf.readableBytes() >= KEEPALIVE_LENGTH && buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { - channel.write(buf.readBytes(KEEPALIVE_LENGTH)); + return buf.readBytes(KEEPALIVE_LENGTH); } return super.decode(ctx, channel, buf); diff --git a/src/org/traccar/protocol/AtrackProtocolDecoder.java b/src/org/traccar/protocol/AtrackProtocolDecoder.java index db6cdb7e1..1323ce8a3 100644 --- a/src/org/traccar/protocol/AtrackProtocolDecoder.java +++ b/src/org/traccar/protocol/AtrackProtocolDecoder.java @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import java.net.SocketAddress; import java.nio.charset.Charset; import java.util.Date; import java.util.LinkedList; @@ -41,13 +42,13 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { private static final int MSG_HEARTBEAT = 0x1A; private static final int MSG_DATA = 0x10; - private static void sendResponse(Channel channel, long rawId, int index) { + private static void sendResponse(Channel channel, SocketAddress remoteAddress, long rawId, int index) { if (channel != null) { ChannelBuffer response = ChannelBuffers.directBuffer(12); response.writeShort(0xfe02); response.writeLong(rawId); response.writeShort(index); - channel.write(response); + channel.write(response, remoteAddress); } } @@ -69,10 +70,19 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { @Override protected Object decode( - ChannelHandlerContext ctx, Channel channel, Object msg) + ChannelHandlerContext ctx, Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; + + // Keep alive message + if (buf.getUnsignedShort(buf.readerIndex()) == 0xfe02) { + if (channel != null) { + channel.write(buf, remoteAddress); + } + return null; + } + buf.skipBytes(2); // prefix buf.readUnsignedShort(); // checksum buf.readUnsignedShort(); // length @@ -90,7 +100,7 @@ public class AtrackProtocolDecoder extends BaseProtocolDecoder { } // Send acknowledgement - sendResponse(channel, rawId, index); + sendResponse(channel, remoteAddress, rawId, index); List positions = new LinkedList(); diff --git a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java index 5911bf0ab..6c6d10771 100644 --- a/test/org/traccar/protocol/AtrackProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AtrackProtocolDecoderTest.java @@ -14,21 +14,21 @@ public class AtrackProtocolDecoderTest { AtrackProtocolDecoder decoder = new AtrackProtocolDecoder(new TestDataManager(), null, null); - //int[] buf1 = {0xfe,0x02,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x00,0x01}; - //assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf1)))); + assertNull(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray( + new int[] {0xfe,0x02,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x00,0x01})))); - int[] buf2 = {0x40,0x50,0x99,0x3f,0x00,0x5c,0x00,0x02,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x52,0x56,0x66,0xc2,0x52,0x56,0x8c,0x3c,0x52,0x56,0x8c,0x63,0xff,0xc8,0x33,0x84,0x02,0x69,0x88,0x85,0x00,0x00,0x02,0x00,0x00,0x09,0xcf,0x03,0xde,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x52,0x56,0x66,0xc2,0x52,0x56,0x8c,0x5a,0x52,0x56,0x8c,0x63,0xff,0xc8,0x33,0x84,0x02,0x69,0x88,0x85,0x00,0x00,0x02,0x00,0x00,0x09,0xcf,0x03,0xde,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00}; - verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf2)))); + verify(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray( + new int[] {0x40,0x50,0x99,0x3f,0x00,0x5c,0x00,0x02,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x52,0x56,0x66,0xc2,0x52,0x56,0x8c,0x3c,0x52,0x56,0x8c,0x63,0xff,0xc8,0x33,0x84,0x02,0x69,0x88,0x85,0x00,0x00,0x02,0x00,0x00,0x09,0xcf,0x03,0xde,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x52,0x56,0x66,0xc2,0x52,0x56,0x8c,0x5a,0x52,0x56,0x8c,0x63,0xff,0xc8,0x33,0x84,0x02,0x69,0x88,0x85,0x00,0x00,0x02,0x00,0x00,0x09,0xcf,0x03,0xde,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00})))); - int[] buf3 = {0x40,0x50,0x1e,0x58,0x00,0x33,0x01,0xe0,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x52,0x5e,0xcd,0x5d,0x52,0x5e,0xe3,0x44,0x52,0x5e,0xe3,0x5e,0xff,0xc8,0x88,0x15,0x02,0x6a,0xb4,0xd7,0x00,0x00,0x02,0x00,0x00,0x10,0x44,0x03,0xde,0x01,0x00,0x0b,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00}; - verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf3)))); + verify(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray( + new int[] {0x40,0x50,0x1e,0x58,0x00,0x33,0x01,0xe0,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x52,0x5e,0xcd,0x5d,0x52,0x5e,0xe3,0x44,0x52,0x5e,0xe3,0x5e,0xff,0xc8,0x88,0x15,0x02,0x6a,0xb4,0xd7,0x00,0x00,0x02,0x00,0x00,0x10,0x44,0x03,0xde,0x01,0x00,0x0b,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00})))); // 7-byte date - //int[] buf4 = {0x02,0x03,0xb4,0x94,0x00,0x3c,0x00,0xeb,0x00,0x01,0x41,0x04,0xd8,0xdd,0x3a,0x3e,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x00,0x30,0x7f,0x28,0x03,0x05,0x74,0xd3,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x16,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00}; - //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf4)))); + //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray( + // new int[] {0x02,0x03,0xb4,0x94,0x00,0x3c,0x00,0xeb,0x00,0x01,0x41,0x04,0xd8,0xdd,0x3a,0x3e,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x07,0xde,0x01,0x1b,0x0b,0x1f,0x03,0x00,0x30,0x7f,0x28,0x03,0x05,0x74,0xd3,0x00,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x16,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00})))); - //int[] buf5 = {0x40,0x50,0xd2,0xc5,0x00,0xda,0x05,0x52,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x53,0x07,0x55,0x51,0x53,0x07,0x55,0x50,0x53,0x07,0x55,0x81,0xff,0xbb,0xa6,0x6a,0x02,0x31,0x29,0x5c,0x00,0x19,0x02,0x00,0x00,0x00,0xda,0x00,0x0a,0x01,0x00,0x83,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0e,0x09,0x00,0x85,0x53,0x07,0x55,0x60,0x53,0x07,0x55,0x5f,0x53,0x07,0x55,0x82,0xff,0xbb,0xb0,0x41,0x02,0x31,0x3b,0x4b,0x00,0x18,0x02,0x00,0x00,0x00,0xe0,0x00,0x0c,0x01,0x00,0x85,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0d,0x00,0x00,0x86,0x53,0x07,0x55,0x6f,0x53,0x07,0x55,0x6e,0x53,0x07,0x55,0x82,0xff,0xbb,0xbb,0xea,0x02,0x31,0x4b,0x49,0x00,0x24,0x02,0x00,0x00,0x00,0xe5,0x00,0x0a,0x01,0x00,0x7b,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0d,0x02,0x00,0x85,0x53,0x07,0x55,0x7e,0x53,0x07,0x55,0x7d,0x53,0x07,0x55,0x82,0xff,0xbb,0xc9,0x87,0x02,0x31,0x59,0x82,0x00,0x25,0x02,0x00,0x00,0x00,0xea,0x00,0x09,0x01,0x00,0x7a,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x13,0x00,0x18,0x0d,0x08,0x00,0x7b}; - //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf5)))); + //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray( + // new int[] {0x40,0x50,0xd2,0xc5,0x00,0xda,0x05,0x52,0x00,0x01,0x41,0x04,0xd8,0xf1,0x96,0x82,0x53,0x07,0x55,0x51,0x53,0x07,0x55,0x50,0x53,0x07,0x55,0x81,0xff,0xbb,0xa6,0x6a,0x02,0x31,0x29,0x5c,0x00,0x19,0x02,0x00,0x00,0x00,0xda,0x00,0x0a,0x01,0x00,0x83,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0e,0x09,0x00,0x85,0x53,0x07,0x55,0x60,0x53,0x07,0x55,0x5f,0x53,0x07,0x55,0x82,0xff,0xbb,0xb0,0x41,0x02,0x31,0x3b,0x4b,0x00,0x18,0x02,0x00,0x00,0x00,0xe0,0x00,0x0c,0x01,0x00,0x85,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0d,0x00,0x00,0x86,0x53,0x07,0x55,0x6f,0x53,0x07,0x55,0x6e,0x53,0x07,0x55,0x82,0xff,0xbb,0xbb,0xea,0x02,0x31,0x4b,0x49,0x00,0x24,0x02,0x00,0x00,0x00,0xe5,0x00,0x0a,0x01,0x00,0x7b,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x08,0x0d,0x02,0x00,0x85,0x53,0x07,0x55,0x7e,0x53,0x07,0x55,0x7d,0x53,0x07,0x55,0x82,0xff,0xbb,0xc9,0x87,0x02,0x31,0x59,0x82,0x00,0x25,0x02,0x00,0x00,0x00,0xea,0x00,0x09,0x01,0x00,0x7a,0x00,0x00,0x00,0x00,0x07,0xd0,0x07,0xd0,0x00,0x00,0x00,0x00,0x00,0x13,0x00,0x18,0x0d,0x08,0x00,0x7b})))); } -- cgit v1.2.3