From c8793e2163f59a25c2d78aaa141ffab2e6338dff Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 5 May 2015 11:05:36 +1200 Subject: Support new Noran format --- src/org/traccar/protocol/NoranProtocolDecoder.java | 72 ++++++++++++++++------ .../traccar/protocol/NoranProtocolDecoderTest.java | 4 +- 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/org/traccar/protocol/NoranProtocolDecoder.java b/src/org/traccar/protocol/NoranProtocolDecoder.java index ff35a287a..69ed623d8 100644 --- a/src/org/traccar/protocol/NoranProtocolDecoder.java +++ b/src/org/traccar/protocol/NoranProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2014 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2013 - 2015 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. @@ -18,7 +18,10 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.nio.ByteOrder; import java.nio.charset.Charset; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; import java.util.TimeZone; import org.jboss.netty.buffer.ChannelBuffer; @@ -36,6 +39,8 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { super(protocol); } + private static final DateFormat dateFormat = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); + private static final int MSG_UPLOAD_POSITION = 0x0008; private static final int MSG_CONTROL_RESPONSE = 0x8009; private static final int MSG_ALARM = 0x0003; @@ -70,7 +75,17 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { else if (type == MSG_UPLOAD_POSITION || type == MSG_CONTROL_RESPONSE || type == MSG_ALARM) { - + + boolean newFormat = false; + /*if (((type == MSG_UPLOAD_POSITION || type == MSG_ALARM) && buf.readableBytes() == 30) || + ((type == MSG_CONTROL_RESPONSE) && buf.readableBytes() == 39)) { + newFormat = false; + }*/ + if (((type == MSG_UPLOAD_POSITION || type == MSG_ALARM) && buf.readableBytes() == 48) || + ((type == MSG_CONTROL_RESPONSE) && buf.readableBytes() == 57)) { + newFormat = true; + } + // Create new position Position position = new Position(); position.setProtocol(getProtocol()); @@ -88,35 +103,52 @@ public class NoranProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_ALARM, buf.readUnsignedByte()); // Location - position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedShort()); + if (newFormat) { + position.setSpeed(buf.readUnsignedInt()); + position.setCourse(buf.readFloat()); + } else { + position.setSpeed(buf.readUnsignedByte()); + position.setCourse(buf.readUnsignedShort()); + } position.setLongitude(buf.readFloat()); position.setLatitude(buf.readFloat()); // Time - long timeValue = buf.readUnsignedInt(); - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - time.set(Calendar.YEAR, 2000 + (int) (timeValue >> 26)); - time.set(Calendar.MONTH, (int) (timeValue >> 22 & 0x0f) - 1); - time.set(Calendar.DAY_OF_MONTH, (int) (timeValue >> 17 & 0x1f)); - time.set(Calendar.HOUR_OF_DAY, (int) (timeValue >> 12 & 0x1f)); - time.set(Calendar.MINUTE, (int) (timeValue >> 6 & 0x3f)); - time.set(Calendar.SECOND, (int) (timeValue & 0x3f)); - position.setTime(time.getTime()); + if (!newFormat) { + long timeValue = buf.readUnsignedInt(); + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + time.clear(); + time.set(Calendar.YEAR, 2000 + (int) (timeValue >> 26)); + time.set(Calendar.MONTH, (int) (timeValue >> 22 & 0x0f) - 1); + time.set(Calendar.DAY_OF_MONTH, (int) (timeValue >> 17 & 0x1f)); + time.set(Calendar.HOUR_OF_DAY, (int) (timeValue >> 12 & 0x1f)); + time.set(Calendar.MINUTE, (int) (timeValue >> 6 & 0x3f)); + time.set(Calendar.SECOND, (int) (timeValue & 0x3f)); + position.setTime(time.getTime()); + } // Identification - String id = buf.readBytes(11).toString(Charset.defaultCharset()).replaceAll("[^\\p{Print}]", ""); + String id = buf.readBytes(newFormat ? 12 : 11).toString(Charset.defaultCharset()).replaceAll("[^\\p{Print}]", ""); if (!identify(id)) { return null; } position.setDeviceId(getDeviceId()); - // IO status - position.set(Event.PREFIX_IO + 1, buf.readUnsignedByte()); - - // Fuel - position.set(Event.KEY_FUEL, buf.readUnsignedByte()); + // Time + if (newFormat) { + position.setTime(dateFormat.parse(buf.readBytes(17).toString(Charset.defaultCharset()))); + buf.readByte(); + } + + if (!newFormat) { + + // IO status + position.set(Event.PREFIX_IO + 1, buf.readUnsignedByte()); + + // Fuel + position.set(Event.KEY_FUEL, buf.readUnsignedByte()); + } + return position; } diff --git a/test/org/traccar/protocol/NoranProtocolDecoderTest.java b/test/org/traccar/protocol/NoranProtocolDecoderTest.java index 583ba56d1..e51741835 100644 --- a/test/org/traccar/protocol/NoranProtocolDecoderTest.java +++ b/test/org/traccar/protocol/NoranProtocolDecoderTest.java @@ -14,11 +14,11 @@ public class NoranProtocolDecoderTest extends ProtocolDecoderTest { NoranProtocolDecoder decoder = new NoranProtocolDecoder(null); - /*verify(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( + verify(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( "3400080001090000000000001D43A29BE842E62520424E523039423036363932000031322D30332D30352031313A34373A343300")))); verify(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( - "34000800010c000000000080a3438e20944149bd07c24e523039423139323832000031352d30342d32362030383a34333a353300"))));*/ + "34000800010c000000000080a3438e20944149bd07c24e523039423139323832000031352d30342d32362030383a34333a353300")))); assertNull(decoder.decode(null, null, null, ChannelBuffers.wrappedBuffer(ByteOrder.LITTLE_ENDIAN, ChannelBufferTools.convertHexString( "0f0000004e52303946303431353500")))); -- cgit v1.2.3