diff options
4 files changed, 108 insertions, 2 deletions
diff --git a/src/org/traccar/protocol/L100FrameDecoder.java b/src/org/traccar/protocol/L100FrameDecoder.java index b7caa14f4..9e08120dd 100644 --- a/src/org/traccar/protocol/L100FrameDecoder.java +++ b/src/org/traccar/protocol/L100FrameDecoder.java @@ -20,6 +20,8 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import org.traccar.BaseFrameDecoder; +import java.nio.charset.StandardCharsets; + public class L100FrameDecoder extends BaseFrameDecoder { @Override @@ -30,6 +32,15 @@ public class L100FrameDecoder extends BaseFrameDecoder { return null; } + if (buf.getCharSequence(buf.readerIndex(), 4, StandardCharsets.US_ASCII).equals("ATL,")) { + return decodeNew(buf); + } else { + return decodeOld(buf); + } + } + + private Object decodeOld(ByteBuf buf) { + int header = buf.getByte(buf.readerIndex()); boolean obd = header == 'L' || header == 'H'; @@ -38,9 +49,9 @@ public class L100FrameDecoder extends BaseFrameDecoder { index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*'); } else { index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x02); - if (index == -1) { + if (index < 0) { index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) 0x04); - if (index == -1) { + if (index < 0) { return null; } } @@ -60,4 +71,20 @@ public class L100FrameDecoder extends BaseFrameDecoder { return null; } + private Object decodeNew(ByteBuf buf) { + + int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '@'); + if (index < 0) { + return null; + } + + if (buf.writerIndex() >= index + 1) { + ByteBuf frame = buf.readRetainedSlice(index - buf.readerIndex()); + buf.skipBytes(1); // delimiter + return frame; + } + + return null; + } + } diff --git a/src/org/traccar/protocol/L100ProtocolDecoder.java b/src/org/traccar/protocol/L100ProtocolDecoder.java index 07c5622cb..c4a4c0d58 100644 --- a/src/org/traccar/protocol/L100ProtocolDecoder.java +++ b/src/org/traccar/protocol/L100ProtocolDecoder.java @@ -109,6 +109,27 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { .expression("(.+)") // data .compile(); + private static final Pattern PATTERN_NEW = new PatternBuilder() + .groupBegin() + .text("ATL,") + .expression("[LH],") // archive + .number("(d{15}),") // imei + .groupEnd("?") + .expression("([NPT]),") // alarm + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .expression("([AV]),") // validity + .number("(d+.d+),([NS]),") // latitude + .number("(d+.d+),([EW]),") // longitude + .number("(d+.?d*),") // speed + .expression("(?:GPS|GSM|INV),") + .number("(d+),") // battery + .number("(d+),") // mcc + .number("(d+),") // mnc + .number("(d+),") // lac + .number("(d+)") // cid + .compile(); + @Override protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { @@ -121,6 +142,8 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { } else { return decodeObdLocation(channel, remoteAddress, sentence); } + } else if (sentence.startsWith("ATL,") || sentence.substring(0, 1).matches("[NPT]")) { + return decodeNew(channel, remoteAddress, sentence); } else { return decodeNormal(channel, remoteAddress, sentence); } @@ -264,4 +287,50 @@ public class L100ProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeNew(Channel channel, SocketAddress remoteAddress, String sentence) { + + Parser parser = new Parser(PATTERN_NEW, sentence); + if (!parser.matches()) { + return null; + } + + String imei = parser.next(); + DeviceSession deviceSession; + if (imei != null) { + deviceSession = getDeviceSession(channel, remoteAddress, imei); + } else { + deviceSession = getDeviceSession(channel, remoteAddress); + } + if (deviceSession == null) { + return null; + } + + Position position = new Position(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + switch (parser.next()) { + case "P": + position.set(Position.KEY_ALARM, Position.ALARM_SOS); + break; + case "T": + position.set(Position.KEY_ALARM, Position.ALARM_TAMPERING); + break; + default: + break; + } + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setLongitude(parser.nextCoordinate(Parser.CoordinateFormat.DEG_HEM)); + position.setSpeed(parser.nextDouble()); + + position.set(Position.KEY_BATTERY, parser.nextInt() * 0.001); + + position.setNetwork(new Network(CellTower.from( + parser.nextInt(), parser.nextInt(), parser.nextInt(), parser.nextHexInt()))); + + return position; + } + } diff --git a/test/org/traccar/protocol/L100FrameDecoderTest.java b/test/org/traccar/protocol/L100FrameDecoderTest.java index a94f2eb0d..5ffa3d8d1 100644 --- a/test/org/traccar/protocol/L100FrameDecoderTest.java +++ b/test/org/traccar/protocol/L100FrameDecoderTest.java @@ -11,6 +11,10 @@ public class L100FrameDecoderTest extends ProtocolTest { L100FrameDecoder decoder = new L100FrameDecoder(); verifyFrame( + binary("41544c2c4c2c3836383334353033383137313936332c4e2c3230313231382c3039333031362c412c3032352e3036373134342c4e2c3035352e3134343833332c452c3030302e302c4750532c333933392c3432342c30332c30303430352c303038383334"), + decoder.decode(null, null, binary("41544c2c4c2c3836383334353033383137313936332c4e2c3230313231382c3039333031362c412c3032352e3036373134342c4e2c3035352e3134343833332c452c3030302e302c4750532c333933392c3432342c30332c30303430352c30303838333440"))); + + verifyFrame( binary("4c2c41544c2c3836363739353033303437373935322c30312c303033352c"), decoder.decode(null, null, binary("4c2c41544c2c3836363739353033303437373935322c30312c303033352c2a28"))); diff --git a/test/org/traccar/protocol/L100ProtocolDecoderTest.java b/test/org/traccar/protocol/L100ProtocolDecoderTest.java index e86ea0e81..e61e133a4 100644 --- a/test/org/traccar/protocol/L100ProtocolDecoderTest.java +++ b/test/org/traccar/protocol/L100ProtocolDecoderTest.java @@ -10,6 +10,12 @@ public class L100ProtocolDecoderTest extends ProtocolTest { L100ProtocolDecoder decoder = new L100ProtocolDecoder(null); + verifyPosition(decoder, text( + "ATL,L,868345038171963,N,201218,093016,A,025.067144,N,055.144833,E,000.0,GPS,3939,424,03,00405,008834")); + + verifyPosition(decoder, text( + "N,111116,090031,A,028.123456,N,077.123456,E,000.0,GPS,4180,404,11,00159,064753")); + verifyAttributes(decoder, text( "L,ATLOBD,866795030475584,03,7429,143344,130918,CAN,0101:00076100,0103:0200,0104:3C,0105:84,010A:XX,010B:19,010C:0F98,010D:22,010E:68,010F:5A,0110:XXXX,0111:28,011C:20,011F:XXXX,0121:0000,0122:XXXX,012F:XX,0162:XX,0132:XXXX,0133:61,0143:00A8,0145:0F,0146:XX,0147:30,0148:XX,0149:31,014A:18,014B:XX,014C:92,0151:XX,0131:00BB,0144:8000,015E:XXXX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0902:XXXXXXXXXXXXXXX")); |