From 0a7bfdfbcec8dbb587882c63919456a3855930b4 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 21 Jan 2015 15:31:09 +1300 Subject: Finish AutoFon implementation --- .../traccar/protocol/AutoFonProtocolDecoder.java | 153 +++++++++++++-------- .../protocol/AutoFonProtocolDecoderTest.java | 4 +- 2 files changed, 98 insertions(+), 59 deletions(-) diff --git a/src/org/traccar/protocol/AutoFonProtocolDecoder.java b/src/org/traccar/protocol/AutoFonProtocolDecoder.java index 6218a30a4..fbc142846 100644 --- a/src/org/traccar/protocol/AutoFonProtocolDecoder.java +++ b/src/org/traccar/protocol/AutoFonProtocolDecoder.java @@ -21,13 +21,12 @@ import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.traccar.BaseProtocolDecoder; import org.traccar.database.DataManager; +import org.traccar.helper.ChannelBufferTools; import org.traccar.helper.Log; import org.traccar.model.ExtendedInfoFormatter; import org.traccar.model.Position; -import java.util.Calendar; -import java.util.Properties; -import java.util.TimeZone; +import java.util.*; public class AutoFonProtocolDecoder extends BaseProtocolDecoder { @@ -39,6 +38,80 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { private static final int MSG_LOCATION = 0x11; private static final int MSG_HISTORY = 0x12; + private long deviceId; + + private static double convertCoordinate(int raw) { + double result = raw / 1000000; + result += (raw % 1000000) / 600000.0; + return result; + } + + private Position decodePosition(ChannelBuffer buf, boolean history) { + + // Create new position + Position position = new Position(); + ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter(getProtocol()); + position.setDeviceId(deviceId); + + if (!history) { + buf.readUnsignedByte(); // interval + buf.skipBytes(8); // settings + } + buf.readUnsignedByte(); // status + if (!history) { + buf.readUnsignedShort(); + } + extendedInfo.set("battery", buf.readUnsignedByte()); + buf.skipBytes(6); // time + + // Timers + if (!history) { + for (int i = 0; i < 2; i++) { + buf.skipBytes(5); // time + buf.readUnsignedShort(); // interval + buf.skipBytes(5); // mode + } + } + + extendedInfo.set("temperature", buf.readByte()); + extendedInfo.set("gsm", buf.readUnsignedByte()); + buf.readUnsignedShort(); // mcc + buf.readUnsignedShort(); // mnc + buf.readUnsignedShort(); // lac + buf.readUnsignedShort(); // cid + + // GPS status + int valid = buf.readUnsignedByte(); + position.setValid((valid & 0xc0) != 0); + extendedInfo.set("satellites", valid & 0x3f); + + // Date and time + Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + time.clear(); + time.set(Calendar.DAY_OF_MONTH, buf.readUnsignedByte()); + time.set(Calendar.MONTH, buf.readUnsignedByte() - 1); + time.set(Calendar.YEAR, 2000 + buf.readUnsignedByte()); + time.set(Calendar.HOUR_OF_DAY, buf.readUnsignedByte()); + time.set(Calendar.MINUTE, buf.readUnsignedByte()); + time.set(Calendar.SECOND, buf.readUnsignedByte()); + position.setTime(time.getTime()); + + // Location + position.setLatitude(convertCoordinate(buf.readInt())); + position.setLongitude(convertCoordinate(buf.readInt())); + position.setAltitude((double) buf.readShort()); + position.setSpeed((double) buf.readUnsignedByte()); + position.setCourse(buf.readUnsignedByte() * 2.0); + + extendedInfo.set("hdop", buf.readUnsignedShort()); + + buf.readUnsignedShort(); // reserved + buf.readUnsignedByte(); // checksum + + position.setExtendedInfo(extendedInfo.toString()); + return position; + } + @Override protected Object decode( ChannelHandlerContext ctx, Channel channel, Object msg) @@ -46,77 +119,43 @@ public class AutoFonProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; - /*buf.skipBytes(2); // header - buf.readByte(); // size - - // Zero for location messages - buf.readByte(); // voltage - buf.readByte(); // gsm signal - - String imei = readImei(buf); - long index = buf.readUnsignedShort(); int type = buf.readUnsignedByte(); - if (type == MSG_HEARTBEAT) { - if (channel != null) { - byte[] response = {0x54, 0x68, 0x1A, 0x0D, 0x0A}; - channel.write(ChannelBuffers.wrappedBuffer(response)); - } - } - - else if (type == MSG_DATA) { + if (type == MSG_LOGIN) { - // Create new position - Position position = new Position(); - ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter(getProtocol()); - extendedInfo.set("index", index); + buf.readUnsignedByte(); // hardware version + buf.readUnsignedByte(); // software version - // Get device id + String imei = ChannelBufferTools.readHexString(buf, 16).substring(1); try { - position.setDeviceId(getDataManager().getDeviceByImei(imei).getId()); + deviceId = getDataManager().getDeviceByImei(imei).getId(); } catch(Exception error) { Log.warning("Unknown device - " + imei); return null; } - // Date and time - Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - time.clear(); - time.set(Calendar.YEAR, 2000 + buf.readUnsignedByte()); - time.set(Calendar.MONTH, buf.readUnsignedByte() - 1); - time.set(Calendar.DAY_OF_MONTH, buf.readUnsignedByte()); - time.set(Calendar.HOUR_OF_DAY, buf.readUnsignedByte()); - time.set(Calendar.MINUTE, buf.readUnsignedByte()); - time.set(Calendar.SECOND, buf.readUnsignedByte()); - position.setTime(time.getTime()); - - // Latitude - double latitude = buf.readUnsignedInt() / (60.0 * 30000.0); + // Send response + if (channel != null) { + channel.write(ChannelBuffers.wrappedBuffer(new byte[] { buf.readByte() })); + } - // Longitude - double longitude = buf.readUnsignedInt() / (60.0 * 30000.0); + } else if (type == MSG_LOCATION) { - // Speed - position.setSpeed((double) buf.readUnsignedByte()); + return decodePosition(buf, false); - // Course - position.setCourse((double) buf.readUnsignedShort()); + } else if (type == MSG_HISTORY) { - buf.skipBytes(3); // reserved + int count = buf.readUnsignedByte() & 0x0f; + buf.readUnsignedShort(); // total count + List positions = new LinkedList(); - // Flags - long flags = buf.readUnsignedInt(); - position.setValid((flags & 0x1) == 0x1); - if ((flags & 0x2) == 0) latitude = -latitude; - if ((flags & 0x4) == 0) longitude = -longitude; + for (int i = 0; i < count; i++) { + positions.add(decodePosition(buf, true)); + } - position.setLatitude(latitude); - position.setLongitude(longitude); - position.setAltitude(0.0); + return positions; - position.setExtendedInfo(extendedInfo.toString()); - return position; - }*/ + } return null; } diff --git a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java index 13b58c464..7e0e13541 100644 --- a/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java +++ b/test/org/traccar/protocol/AutoFonProtocolDecoderTest.java @@ -18,8 +18,8 @@ public class AutoFonProtocolDecoderTest { assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( "10556103592310314825728F")))); - //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( - // "111E00000000000000000100007101010B0C020302010B0C0005A053FFFFFFFF02010B0C00276047FFFFFFFF1F5600FA000176F218C7850C0B0B0C203A033DBD46035783EF009E00320014FFFF45")))); + verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( + "111E00000000000000000100007101010B0C020302010B0C0005A053FFFFFFFF02010B0C00276047FFFFFFFF1F5600FA000176F218C7850C0B0B0C203A033DBD46035783EF009E00320014FFFF45")))); //verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString( // "12060000007501010B0C00089CFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000003E7FFFF02007601010B0C00269CFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000003E7FFFF4A007601010B0C01089CFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000003E7FFFF04007501010B0C01269CFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000003E7FFFF80007601010B0C02089CFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000003E7FFFFA6007501010B0C02231F5600FA000176F218C70000000000000000000000000000000000000003E7FFFF9629")))); -- cgit v1.2.3