From 1a86616ca2032fa0c3fee7446a6dc545f4f77451 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Thu, 5 Nov 2015 14:59:40 +1300 Subject: Partially refactor AutoFon 45 decoder --- .../traccar/protocol/AutoFon45ProtocolDecoder.java | 77 +++++++++++----------- .../traccar/protocol/AutoFonProtocolDecoder.java | 8 +-- .../protocol/AutoFon45ProtocolDecoderTest.java | 4 ++ 3 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/org/traccar/protocol/AutoFon45ProtocolDecoder.java b/src/org/traccar/protocol/AutoFon45ProtocolDecoder.java index 92ffaedeb..12020d161 100644 --- a/src/org/traccar/protocol/AutoFon45ProtocolDecoder.java +++ b/src/org/traccar/protocol/AutoFon45ProtocolDecoder.java @@ -1,4 +1,5 @@ /* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) * Copyright 2015 Vitaly Litvak (vitavaque@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,12 +18,12 @@ package org.traccar.protocol; import java.net.SocketAddress; import java.util.Arrays; -import java.util.Calendar; -import java.util.TimeZone; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; +import org.traccar.helper.BitUtil; +import org.traccar.helper.DateBuilder; import org.traccar.model.Event; import org.traccar.model.Position; import static org.traccar.protocol.AutoFon45FrameDecoder.MSG_LOCATION; @@ -30,9 +31,17 @@ import static org.traccar.protocol.AutoFon45FrameDecoder.MSG_LOGIN; public class AutoFon45ProtocolDecoder extends BaseProtocolDecoder { - private static double convertCoordinate(short degrees, int raw) { - double seconds = (raw >> 4 & 0xffffff) / 600000.0; - return (degrees + seconds) * ((raw & 0x0f) == 0 ? -1 : 1); + public AutoFon45ProtocolDecoder(AutoFon45Protocol protocol) { + super(protocol); + } + + private static double convertCoordinate(short degrees, int minutes) { + double value = degrees + BitUtil.from(minutes, 4) / 600000.0; + if (BitUtil.check(minutes, 0)) { + return value; + } else { + return -value; + } } private static byte checksum(byte[] bytes, int offset, int len) { @@ -46,19 +55,16 @@ public class AutoFon45ProtocolDecoder extends BaseProtocolDecoder { return result; } - public AutoFon45ProtocolDecoder(AutoFon45Protocol protocol) { - super(protocol); - } - @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; - int type = buf.getUnsignedByte(0); + int type = buf.getUnsignedByte(buf.readerIndex()); if (type == MSG_LOGIN) { + byte[] bytes = new byte[19]; buf.readBytes(bytes); @@ -67,24 +73,25 @@ public class AutoFon45ProtocolDecoder extends BaseProtocolDecoder { return null; } - // Send response (CRC) + // Send response (checksum) if (channel != null) { byte[] response = "resp_crc=".getBytes("US-ASCII"); response = Arrays.copyOf(response, response.length + 1); response[response.length - 1] = checksum(bytes, 0, 18); channel.write(ChannelBuffers.wrappedBuffer(response)); } + } else if (type == MSG_LOCATION) { + buf.readUnsignedByte(); - // Create new position Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); short status = buf.readUnsignedByte(); - position.set(Event.KEY_ALARM, (status & 0x80) != 0); - position.set(Event.KEY_BATTERY, status & 0x7F); + position.set(Event.KEY_ALARM, BitUtil.check(status, 7)); + position.set(Event.KEY_BATTERY, BitUtil.to(status, 7)); buf.skipBytes(2); // remaining time @@ -94,37 +101,27 @@ public class AutoFon45ProtocolDecoder extends BaseProtocolDecoder { buf.readByte(); // mode buf.readByte(); // gprs sending interval - buf.skipBytes(6); // MCC, MNC, LAC, CID + buf.skipBytes(6); // mcc, mnc, lac, cid - // GPS status int valid = buf.readUnsignedByte(); - position.setValid((valid & 0xc0) != 0); - position.set(Event.KEY_SATELLITES, valid & 0x3f); - - // Date and time - int timeOfDay = buf.readUnsignedByte() << 16 | buf.readUnsignedByte() << 8 | buf.readUnsignedByte(); - int date = buf.readUnsignedByte() << 16 | buf.readUnsignedByte() << 8 | buf.readUnsignedByte(); - - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - time.set(Calendar.HOUR_OF_DAY, timeOfDay / 10000); - time.set(Calendar.MINUTE, (timeOfDay - time.get(Calendar.HOUR_OF_DAY) * 10000) / 100); - time.set(Calendar.SECOND, (timeOfDay - time.get(Calendar.HOUR_OF_DAY) * 10000 - time.get(Calendar.MINUTE) * 100)); - time.set(Calendar.DAY_OF_MONTH, date / 10000); - time.set(Calendar.MONTH, (date - time.get(Calendar.DAY_OF_MONTH) * 10000) / 100 - 1); - time.set(Calendar.YEAR, 2000 + (date - time.get(Calendar.DAY_OF_MONTH) * 10000 - (time.get(Calendar.MONTH) + 1) * 100)); - position.setTime(time.getTime()); - - // Location - position.setLatitude(convertCoordinate(buf.readUnsignedByte(), - buf.readUnsignedByte() << 16 | buf.readUnsignedByte() << 8 | buf.readUnsignedByte())); - position.setLongitude(convertCoordinate(buf.readUnsignedByte(), - buf.readUnsignedByte() << 16 | buf.readUnsignedByte() << 8 | buf.readUnsignedByte())); + position.setValid(BitUtil.from(valid, 6) != 0); + position.set(Event.KEY_SATELLITES, BitUtil.from(valid, 6)); + + int time = buf.readUnsignedMedium(); + int date = buf.readUnsignedMedium(); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(time / 10000, time / 100 % 100, time % 100) + .setDateReverse(date / 10000, date / 100 % 100, date % 100); + position.setTime(dateBuilder.getDate()); + + position.setLatitude(convertCoordinate(buf.readUnsignedByte(), buf.readUnsignedMedium())); + position.setLongitude(convertCoordinate(buf.readUnsignedByte(), buf.readUnsignedMedium())); position.setSpeed(buf.readUnsignedByte()); - position.setCourse(buf.readUnsignedByte() << 8 | buf.readUnsignedByte()); + position.setCourse(buf.readUnsignedShort()); - buf.readUnsignedByte(); // checksum return position; + } return null; diff --git a/src/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/org/traccar/protocol/AutoFonProtocolDecoder.java index 1da024e0b..c0c3aaf08 100644 --- a/src/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -45,7 +45,6 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { private Position decodePosition(ChannelBuffer buf, boolean history) { - // Create new position Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(getDeviceId()); @@ -61,7 +60,6 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { position.set(Event.KEY_BATTERY, buf.readUnsignedByte()); buf.skipBytes(6); // time - // Timers if (!history) { for (int i = 0; i < 2; i++) { buf.skipBytes(5); // time @@ -77,12 +75,10 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { buf.readUnsignedShort(); // lac buf.readUnsignedShort(); // cid - // GPS status int valid = buf.readUnsignedByte(); position.setValid((valid & 0xc0) != 0); position.set(Event.KEY_SATELLITES, valid & 0x3f); - // Date and time Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); time.clear(); time.set(Calendar.DAY_OF_MONTH, buf.readUnsignedByte()); @@ -93,7 +89,6 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { time.set(Calendar.SECOND, buf.readUnsignedByte()); position.setTime(time.getTime()); - // Location position.setLatitude(convertCoordinate(buf.readInt())); position.setLongitude(convertCoordinate(buf.readInt())); position.setAltitude(buf.readShort()); @@ -109,8 +104,7 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { @Override protected Object decode( - Channel channel, SocketAddress remoteAddress, Object msg) - throws Exception { + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; diff --git a/test/org/traccar/protocol/AutoFon45ProtocolDecoderTest.java b/test/org/traccar/protocol/AutoFon45ProtocolDecoderTest.java index 50df04117..547189a1e 100644 --- a/test/org/traccar/protocol/AutoFon45ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AutoFon45ProtocolDecoderTest.java @@ -14,6 +14,10 @@ public class AutoFon45ProtocolDecoderTest extends ProtocolDecoderTest { verifyNothing(decoder, binary( "41032125656985547543619173484002123481")); + verifyPosition(decoder, binary( + "023E00001E004D411EFA01772F185285009C48041F1E366C2961380F26B10B00911C"), + position("2010-01-27 04:00:08.000", true, 54.73838, 56.10343)); + verifyPosition(decoder, binary( "023E00001E004D411EFA01772F185285009C48041F1E366C2961380F26B10B00911C")); } -- cgit v1.2.3