diff options
-rw-r--r-- | src/org/traccar/protocol/Gt06ProtocolDecoder.java | 83 | ||||
-rw-r--r-- | test/org/traccar/protocol/Gt06ProtocolDecoderTest.java | 14 |
2 files changed, 73 insertions, 24 deletions
diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index a3306dc97..93f2eee42 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import java.nio.charset.Charset; import java.util.Calendar; import java.util.TimeZone; import org.jboss.netty.buffer.ChannelBuffer; @@ -54,10 +55,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { } private static final int MSG_LOGIN = 0x01; - private static final int MSG_DATA = 0x12; - private static final int MSG_HEARTBEAT = 0x13; + private static final int MSG_GPS = 0x10; + private static final int MSG_LBS = 0x11; + private static final int MSG_GPS_LBS = 0x12; + private static final int MSG_STATUS = 0x13; private static final int MSG_STRING = 0x15; - private static final int MSG_ALARM = 0x16; + private static final int MSG_GPS_LBS_STATUS = 0x16; private static void sendResponse(Channel channel, int type, int index) { if (channel != null) { @@ -83,7 +86,8 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; buf.skipBytes(2); // header - buf.readByte(); // size + int length = buf.readByte(); // size + int dataLength = length - 5; int type = buf.readUnsignedByte(); @@ -91,18 +95,19 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { String imei = readImei(buf); try { deviceId = getDataManager().getDeviceByImei(imei).getId(); + buf.skipBytes(dataLength - 8); sendResponse(channel, type, buf.readUnsignedShort()); } catch(Exception error) { Log.warning("Unknown device - " + imei); } } - else if (type == MSG_HEARTBEAT) { - buf.skipBytes(5); + else if (type == MSG_STATUS) { + buf.skipBytes(dataLength); sendResponse(channel, type, buf.readUnsignedShort()); } - else if (type == MSG_DATA) { + else if (type == MSG_GPS || type == MSG_GPS_LBS || type == MSG_GPS_LBS_STATUS) { // Create new position Position position = new Position(); position.setDeviceId(deviceId); @@ -119,10 +124,12 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { time.set(Calendar.SECOND, buf.readUnsignedByte()); position.setTime(time.getTime()); - // Satellites count + // GPS length and Satellites count + int gpsLength = buf.readUnsignedByte(); extendedInfo.append("<satellites>"); - extendedInfo.append(buf.readUnsignedByte()); + extendedInfo.append(gpsLength & 0xf); extendedInfo.append("</satellites>"); + gpsLength >>= 4; // Latitude double latitude = buf.readUnsignedInt() / (60.0 * 30000.0); @@ -144,22 +151,52 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { position.setLongitude(longitude); position.setAltitude(0.0); - // Cell information - extendedInfo.append("<mcc>"); - extendedInfo.append(buf.readUnsignedShort()); - extendedInfo.append("</mcc>"); - extendedInfo.append("<mnc>"); - extendedInfo.append(buf.readUnsignedByte()); - extendedInfo.append("</mnc>"); - extendedInfo.append("<lac>"); - extendedInfo.append(buf.readUnsignedShort()); - extendedInfo.append("</lac>"); - extendedInfo.append("<cell>"); - extendedInfo.append(buf.readUnsignedShort() << 8 + buf.readUnsignedByte()); - extendedInfo.append("</cell>"); + buf.skipBytes(gpsLength - 12); // skip reserved + + if (type == MSG_GPS_LBS || type == MSG_GPS_LBS_STATUS) { + + int lbsLength = 0; + if (type == MSG_GPS_LBS_STATUS) { + lbsLength = buf.readUnsignedByte(); + } + + // Cell information + extendedInfo.append("<mcc>"); + extendedInfo.append(buf.readUnsignedShort()); + extendedInfo.append("</mcc>"); + extendedInfo.append("<mnc>"); + extendedInfo.append(buf.readUnsignedByte()); + extendedInfo.append("</mnc>"); + extendedInfo.append("<lac>"); + extendedInfo.append(buf.readUnsignedShort()); + extendedInfo.append("</lac>"); + extendedInfo.append("<cell>"); + extendedInfo.append(buf.readUnsignedShort() << 8 + buf.readUnsignedByte()); + extendedInfo.append("</cell>"); + buf.skipBytes(lbsLength - 9); + + // Status + if (type == MSG_GPS_LBS_STATUS) { + int flags = buf.readUnsignedByte(); // TODO parse flags + extendedInfo.append("<alarm>true</alarm>"); + + // Voltage + position.setPower((double) buf.readUnsignedByte()); + + // GSM signal + extendedInfo.append("<gsm>"); + extendedInfo.append(buf.readUnsignedByte()); + extendedInfo.append("</gsm>"); + } + } // Index - position.setId((long) buf.readUnsignedShort()); + if (buf.readableBytes() > 6) { + buf.skipBytes(buf.readableBytes() - 6); + } + int index = buf.readUnsignedShort(); + position.setId((long) index); + sendResponse(channel, type, index); position.setExtendedInfo(extendedInfo.toString()); return position; diff --git a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java index c738cd79d..a6822e23c 100644 --- a/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/Gt06ProtocolDecoderTest.java @@ -13,7 +13,7 @@ public class Gt06ProtocolDecoderTest { Gt06ProtocolDecoder decoder = new Gt06ProtocolDecoder(null); decoder.setDataManager(new TestDataManager()); - byte[] buf1 = {0x78,0x78,0x0d,0x01,0x03,0x53,0x41,(byte)0x90,0x36,0x06,0x60,0x61,0x00,0x03,(byte)0xc3,(byte)0xdf,0x0d,0x0a}; + byte[] buf1 = {0x78,0x78,0x11,0x01,0x01,0x23,0x45,0x67,(byte)0x89,0x01,0x23,0x45,0x10,0x0B,0x32,0x01,0x00,0x01,0x71,(byte)0x93,0x0D,0x0A}; assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf1))); byte[] buf2 = {0x78,0x78,0x1F,0x12,0x0B,0x08,0x1D,0x11,0x2E,0x10,(byte)0xCC,0x02,0x7A,(byte)0xC7,(byte)0xEB,0x0C,0x46,0x58,0x49,0x00,0x14,(byte)0x8F,0x01,(byte)0xCC,0x00,0x28,0x7D,0x00,0x1F,(byte)0xB8,0x00,0x03,(byte)0x80,(byte)0x81,0x0D,0x0A}; @@ -25,6 +25,18 @@ public class Gt06ProtocolDecoderTest { byte[] buf4 = {0x78,0x78,0x0D,0x01,0x01,0x23,0x45,0x67,(byte)0x89,0x01,0x23,0x45,0x00,0x01,(byte)0x8C,(byte)0xDD,0x0D,0x0A}; assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf4))); + byte[] buf5 = {0x78,0x78,0x0d,0x01,0x03,0x53,0x41,(byte)0x90,0x36,0x06,0x60,0x61,0x00,0x03,(byte)0xc3,(byte)0xdf,0x0d,0x0a}; + assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf5))); + + byte[] buf6 = {0x78,0x78,0x19,0x10,0x0B,0x03,0x1A,0x0B,0x1B,0x31,(byte)0xCC,0x02,0x7A,(byte)0xC7,(byte)0xFD,0x0C,0x46,0x57,(byte)0xBF,0x01,0x15,0x21,0x00,0x01,0x00,0x1C,(byte)0xC6,0x07,0x0D,0x0A}; + assertNotNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf6))); + + byte[] buf7 = {78,0x78,0x21,0x12,0x0C,0x01,0x0C,0x0F,0x15,0x1F,(byte)0xCF,0x02,0x7A,(byte)0xC8,(byte)0x84,0x0C,0x46,0x57,(byte)0xEC,0x00,0x14,0x00,0x01,(byte)0xCC,0x00,0x28,0x7D,0x00,0x1F,0x72,0x00,0x01,0x00,0x0F,0x53,(byte)0xA0,0x0D,0x0A}; + assertNotNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf7))); + + byte[] buf8 = {0x78,0x78,0x25,0x16,0x0B,0x05,0x1B,0x09,0x35,0x23,(byte)0xCF,0x02,0x7A,(byte)0xC8,0x36,0x0C,0x46,0x57,(byte)0xB3,0x00,0x14,0x00,0x09,0x01,(byte)0xCC,0x00,0x26,0x6A,0x00,0x1E,0x17,0x40,0x05,0x04,0x00,0x02,0x00,0x08,(byte)0xD7,(byte)0xB1,0x0D,0x0A}; + assertNotNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(buf8))); + } } |