From 883d296cc80e11279c5fca2d3d7a737eff762479 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 31 May 2017 21:42:53 +1200 Subject: Convert Watch to binary protocol --- src/org/traccar/protocol/WatchFrameDecoder.java | 2 +- src/org/traccar/protocol/WatchProtocol.java | 3 - src/org/traccar/protocol/WatchProtocolDecoder.java | 70 +++++++++++----------- .../traccar/protocol/WatchProtocolDecoderTest.java | 44 +++++++------- 4 files changed, 59 insertions(+), 60 deletions(-) diff --git a/src/org/traccar/protocol/WatchFrameDecoder.java b/src/org/traccar/protocol/WatchFrameDecoder.java index b02048079..26aba68c7 100644 --- a/src/org/traccar/protocol/WatchFrameDecoder.java +++ b/src/org/traccar/protocol/WatchFrameDecoder.java @@ -25,7 +25,7 @@ import java.nio.charset.StandardCharsets; public class WatchFrameDecoder extends FrameDecoder { - private static final int MESSAGE_HEADER = 20; + public static final int MESSAGE_HEADER = 20; @Override protected Object decode( diff --git a/src/org/traccar/protocol/WatchProtocol.java b/src/org/traccar/protocol/WatchProtocol.java index 72a260423..42a640b85 100644 --- a/src/org/traccar/protocol/WatchProtocol.java +++ b/src/org/traccar/protocol/WatchProtocol.java @@ -17,10 +17,8 @@ package org.traccar.protocol; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; -import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; import org.traccar.BaseProtocol; -import org.traccar.CharacterDelimiterFrameDecoder; import org.traccar.TrackerServer; import org.traccar.model.Command; @@ -53,7 +51,6 @@ public class WatchProtocol extends BaseProtocol { protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new WatchFrameDecoder()); pipeline.addLast("stringEncoder", new StringEncoder()); - pipeline.addLast("stringDecoder", new StringDecoder()); pipeline.addLast("objectEncoder", new WatchProtocolEncoder()); pipeline.addLast("objectDecoder", new WatchProtocolDecoder(WatchProtocol.this)); } diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java index ad43215a2..cfd165d06 100644 --- a/src/org/traccar/protocol/WatchProtocolDecoder.java +++ b/src/org/traccar/protocol/WatchProtocolDecoder.java @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; @@ -28,6 +29,7 @@ import org.traccar.model.Position; import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.regex.Pattern; @@ -37,17 +39,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { super(protocol); } - private static final Pattern PATTERN = new PatternBuilder() - .text("[") - .expression("(..)").text("*") // manufacturer - .number("(d+)").text("*") // equipment id - .number("xxxx").text("*") // length - .expression("([^,]+)") // type - .expression("(.*)") // content - .compile(); - private static final Pattern PATTERN_POSITION = new PatternBuilder() - .text(",") .number("(dd)(dd)(dd),") // date (ddmmyy) .number("(dd)(dd)(dd),") // time (hhmmss) .expression("([AV]),") // validity @@ -64,8 +56,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { .number("(d+),") // steps .number("d+,") // tumbles .number("(x+),") // status - .expression("([^\\]]*)") // cell and wifi - .text("]") + .expression("(.*)") // cell and wifi .compile(); private void sendResponse(Channel channel, String manufacturer, String id, String content) { @@ -132,36 +123,46 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { protected Object decode( Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { - Parser parser = new Parser(PATTERN, (String) msg); - if (!parser.matches()) { - return null; - } + ChannelBuffer buf = (ChannelBuffer) msg; - String manufacturer = parser.next(); - String id = parser.next(); + buf.skipBytes(1); // header + String manufacturer = buf.readBytes(2).toString(StandardCharsets.US_ASCII); + buf.skipBytes(1); // delimiter + + String id = buf.readBytes(10).toString(StandardCharsets.US_ASCII); DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id); if (deviceSession == null) { return null; } - String type = parser.next(); - String content = parser.next(); + buf.skipBytes(1); // delimiter + buf.skipBytes(4); // length + buf.skipBytes(1); // delimiter + + String content = null; + int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ','); + if (contentIndex > 0) { + content = buf.toString(contentIndex + 1, buf.writerIndex() - 2 - contentIndex, StandardCharsets.US_ASCII); + } else { + contentIndex = buf.writerIndex() - 1; + } + + String type = buf.readBytes(contentIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII); if (type.equals("LK")) { sendResponse(channel, manufacturer, id, "LK"); - if (!content.isEmpty()) { + if (content != null) { String[] values = content.split(","); - if (values.length >= 4) { + if (values.length >= 3) { Position position = new Position(); position.setProtocol(getProtocolName()); position.setDeviceId(deviceSession.getDeviceId()); getLastLocation(position, null); - position.set(Position.KEY_BATTERY_LEVEL, - Integer.parseInt(values[3].substring(0, values[3].length() - 1))); + position.set(Position.KEY_BATTERY_LEVEL, Integer.parseInt(values[2])); return position; } @@ -174,7 +175,7 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { sendResponse(channel, manufacturer, id, "AL"); } - parser = new Parser(PATTERN_POSITION, content); + Parser parser = new Parser(PATTERN_POSITION, content); if (!parser.matches()) { return null; } @@ -210,15 +211,16 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder { } else if (type.equals("PULSE") || type.equals("heart")) { - Position position = new Position(); - position.setProtocol(getProtocolName()); - position.setDeviceId(deviceSession.getDeviceId()); - getLastLocation(position, new Date()); - position.setValid(false); - String pulse = content.substring(1); - position.set("pulse", pulse); - position.set(Position.KEY_RESULT, pulse); - return position; + if (content != null) { + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + getLastLocation(position, new Date()); + position.setValid(false); + position.set("pulse", content); + position.set(Position.KEY_RESULT, content); + return position; + } } diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java index 0961dcd50..23e1e35fb 100644 --- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java +++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java @@ -10,72 +10,72 @@ public class WatchProtocolDecoderTest extends ProtocolTest { WatchProtocolDecoder decoder = new WatchProtocolDecoder(new WatchProtocol()); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*6005412902*011F*WT,170517,133811,V,18.512200,N,73.7750283,E,0.00,0.0,0.0,0,92,82,4262,0,00000010,2,1,404,22,10125,8301,141,10125,13921,122,5,Skynet,28:c6:8e:be:87:c0,-60,Intel Wi-Fi,4c:60:de:32:3d:38,-70,Nirvanic-2,40:e3:d6:4a:d9:c2,-73,A4-Guest,40:e3:d6:4a:d9:c4,-73,A4Idatix,40:e3:d6:4a:d9:c3,-73,13.8]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*8308406279*00CC*UD3,170417,190930,V,54.739618,N,25.273213,E,0.0,323.53,175.1,6,51,83,0,0,00000000,1,1,246,01,200,13242758,51,3,TEO-189835,00:8c:54:58:1d:64,-84,Cgates_7137,78:54:2e:e3:71:37,-85,ASUS,9c:5c:8e:b8:d4:78,-93]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*9051004074*0058*AL,120117,145602,V,40.058413,N,76.336618,W,11.519,188,99,00,01,80,0,50,00000000,0,1,0,0,,10]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*9051000884*009B*UD,030117,161129,V,52.745450,N,0.369512,,0.1481,000,99,00,70,5,0,50,00000000,5,1,234,15,893,3611,135,893,3612,132,893,3993,131,893,30986,129,893,40088,126,,00]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*6430073509*00E7*UD2,241016,081622,V,09.951861,N,-84.1422119,W,0.00,0.0,0.0,0,39,94,0,0,00000000,1,0,712,3,2007,18961,123,4,Luz,00:23:6a:34:ee:76,-70,familia,b0:c5:54:b9:90:ef,-78,fam salas delgado,fc:b4:e6:5d:50:ea,-81,QWERTY,c8:3a:35:43:0f:e8,-93]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*6105117105*008D*UD2,210716,231601,V,-33.480366,N,-70.7630692,E,0.00,0.0,0.0,0,100,34,0,0,00000000,3,255,730,2,29731,54315,167,29731,54316,162,29731,54317,145]"), position("2016-07-21 23:16:01.000", false, -33.48037, -70.76307)); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*4700222306*0077*UD,120316,140610,V,48.779045,N, 9.1574736,E,0.00,0.0,0.0,0,25,83,0,0,00000000,2,255,262,1,21041,9067,121,21041,5981,116]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*4700222306*011F*UD2,120316,140444,A,48.779045,N, 9.1574736,E,0.57,12.8,0.0,7,28,77,0,0,00000000,2,2,262,1,21041,9067,121,21041,5981,116,5,WG-Superlativ,34:31:c4:c8:a9:22,-67,EasyBox-28E858,18:83:bf:28:e8:f4,-70,MoMaXXg,be:05:43:b7:19:15,-72,MoMaXX2,bc:05:43:b7:19:15,-72,Gastzugang,18:83:bf:28:e8:f5,-72]")); - verifyNull(decoder, text( + verifyNull(decoder, buffer( "[SG*9081000548*0009*LK,0,100]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*9081000548*00A9*UD,110116,113639,V,16.479064,S,68.119072,,0.7593,000,99,00,80,80,0,50,00000000,5,1,736,2,10103,10732,153,10103,11061,152,10103,11012,152,10103,10151,150,10103,10731,143,,00]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*2256002206*0079*UD2,100116,153723,A,38.000000,N,-9.000000,W,0.44,299.3,0.0,7,100,86,0,0,00000008,2,0,268,3,3010,51042,146,3010,51043,132]")); - verifyNull(decoder, text( + verifyNull(decoder, buffer( "[3G*8800000015*0003*TKQ]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[3G*4700186508*00B1*UD,301015,084840,V,45.853100,N,14.6224899,E,0.00,0.0,0.0,0,84,61,0,11,00000008,7,255,293,70,60,6453,139,60,6432,139,60,6431,132,60,6457,127,60,16353,126,60,6451,121,60,16352,118]")); - verifyNull(decoder, text( + verifyNull(decoder, buffer( "[SG*8800000015*0002*LK]")); - verifyAttributes(decoder, text( + verifyAttributes(decoder, buffer( "[3G*4700186508*000B*LK,0,10,100]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*8800000015*0087*UD,220414,134652,A,22.571707,N,113.8613968,E,0.1,0.0,100,7,60,90,1000,50,0000,4,1,460,0,9360,4082,131,9360,4092,148,9360,4091,143,9360,4153,141]"), position("2014-04-22 13:46:52.000", true, 22.57171, 113.86140)); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*8800000015*0087*UD,220414,134652,A,22.571707,N,113.8613968,E,0.1,0.0,100,7,60,90,1000,50,0000,4,1,460,0,9360,4082,131,9360,4092,148,9360,4091,143,9360,4153,141]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*8800000015*0088*UD2,220414,134652,A,22.571707,N,113.8613968,E,0.1,0.0,100,7,60,90,1000,50,0000,4,1,460,0,9360,4082,131,9360,4092,148,9360,4091,143,9360,4153,141]")); - verifyPosition(decoder, text( + verifyPosition(decoder, buffer( "[SG*8800000015*0087*AL,220414,134652,A,22.571707,N,113.8613968,E,0.1,0.0,100,7,60,90,1000,50,0001,4,1,460,0,9360,4082,131,9360,4092,148,9360,4091,143,9360,4153,141]")); - verifyAttributes(decoder, text( + verifyAttributes(decoder, buffer( "[CS*8800000015*0008*PULSE,72]")); - verifyAttributes(decoder, text( + verifyAttributes(decoder, buffer( "[3G*6005412902*0007*heart,0]")); - verifyAttributes(decoder, text( + verifyAttributes(decoder, buffer( "[3G*6005412902*0008*heart,71]")); } -- cgit v1.2.3