aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/Context.java4
-rw-r--r--src/org/traccar/protocol/WatchProtocolDecoder.java36
-rw-r--r--test/org/traccar/protocol/WatchProtocolDecoderTest.java43
3 files changed, 73 insertions, 10 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index 95d433795..b0db90416 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -516,6 +516,10 @@ public final class Context {
identityManager = testIdentityManager;
}
+ public static void initMediaManager(MediaManager mediaManager) {
+ Context.mediaManager = mediaManager;
+ }
+
public static <T extends BaseModel> BaseObjectManager<T> getManager(Class<T> clazz) {
if (clazz.equals(Device.class)) {
return (BaseObjectManager<T>) deviceManager;
diff --git a/src/org/traccar/protocol/WatchProtocolDecoder.java b/src/org/traccar/protocol/WatchProtocolDecoder.java
index 78b190030..bf4d99a49 100644
--- a/src/org/traccar/protocol/WatchProtocolDecoder.java
+++ b/src/org/traccar/protocol/WatchProtocolDecoder.java
@@ -17,6 +17,8 @@ package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.DeviceSession;
@@ -38,6 +40,8 @@ import java.util.regex.Pattern;
public class WatchProtocolDecoder extends BaseProtocolDecoder {
+ private static final Logger LOGGER = LoggerFactory.getLogger(WatchProtocolDecoder.class);
+
public WatchProtocolDecoder(Protocol protocol) {
super(protocol);
}
@@ -174,41 +178,45 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
return manufacturer;
}
+ protected int nextIndexOf(ByteBuf buf, char delimiter) {
+ return buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) delimiter);
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
- buf.skipBytes(1); // header
+ buf.skipBytes(1); // '[' header
manufacturer = buf.readSlice(2).toString(StandardCharsets.US_ASCII);
- buf.skipBytes(1); // delimiter
+ buf.skipBytes(1); // '*' delimiter
- int idIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*');
+ int idIndex = nextIndexOf(buf, '*');
String id = buf.readSlice(idIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII);
DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, id);
if (deviceSession == null) {
return null;
}
- buf.skipBytes(1); // delimiter
+ buf.skipBytes(1); // '*' delimiter
String index = null;
- int contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*');
+ int contentIndex = nextIndexOf(buf, '*');
if (contentIndex + 5 < buf.writerIndex() && buf.getByte(contentIndex + 5) == '*'
&& buf.toString(contentIndex + 1, 4, StandardCharsets.US_ASCII).matches("\\p{XDigit}+")) {
- int indexLength = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '*') - buf.readerIndex();
+ int indexLength = nextIndexOf(buf, '*') - buf.readerIndex();
hasIndex = true;
index = buf.readSlice(indexLength).toString(StandardCharsets.US_ASCII);
- buf.skipBytes(1); // delimiter
+ buf.skipBytes(1); // '*' delimiter
}
buf.skipBytes(4); // length
- buf.skipBytes(1); // delimiter
+ buf.skipBytes(1); // '*' delimiter
- buf.writerIndex(buf.writerIndex() - 1); // ignore ending
+ buf.writerIndex(buf.writerIndex() - 1); // ']' ignore ending
- contentIndex = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) ',');
+ contentIndex = nextIndexOf(buf, ',');
if (contentIndex < 0) {
contentIndex = buf.writerIndex();
}
@@ -296,6 +304,14 @@ public class WatchProtocolDecoder extends BaseProtocolDecoder {
} else if (type.equals("TK")) {
+ if (buf.readableBytes() == 1) {
+ byte result = buf.readByte();
+ if (result != '1') {
+ LOGGER.error(type + "," + result);
+ }
+ return null;
+ }
+
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
diff --git a/test/org/traccar/protocol/WatchProtocolDecoderTest.java b/test/org/traccar/protocol/WatchProtocolDecoderTest.java
index b7c8d83f9..c4e5bf61a 100644
--- a/test/org/traccar/protocol/WatchProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/WatchProtocolDecoderTest.java
@@ -1,7 +1,17 @@
package org.traccar.protocol;
+import io.netty.buffer.ByteBuf;
import org.junit.Test;
+import org.traccar.Context;
import org.traccar.ProtocolTest;
+import org.traccar.database.MediaManager;
+import org.traccar.model.Position;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class WatchProtocolDecoderTest extends ProtocolTest {
@@ -101,7 +111,40 @@ public class WatchProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, buffer(
"[ZJ*014111001350304*0038*008a*UD,070318,021027,V,00.000000,N,000.000000,E,0,0,0,0,100,18,1000,50,00000000,4,255,460,0,9346,5223,42,9346,5214,20,9784,4083,11,9346,5221,5]"));
+ }
+
+ @Test
+ public void testDecodeTK() throws Exception {
+ WatchProtocolDecoder decoder = new WatchProtocolDecoder(null);
+ verifyNull(decoder.decode(null, null, buffer("[CS*1234567890*0004*TK,1]")));
+
+ MockMediaManager mockMediaManager = new MockMediaManager("/tmp");
+ Context.initMediaManager(mockMediaManager);
+ String hex = "7d5b5d2c2aff";
+ Object decodedObject = decoder.decode(null, null, concatenateBuffers(buffer("[CS*1234567890*000e*TK,#!AMR"), binary(hex), buffer("]")));
+ assertTrue("not a position", decodedObject instanceof Position);
+ Position position = (Position) decodedObject;
+ assertEquals("1234567890/mock.amr", position.getAttributes().get("audio"));
+ verifyFrame(concatenateBuffers(buffer("#!AMR"), binary(hex)), mockMediaManager.readFile("1234567890/mock.amr"));
}
+ private static class MockMediaManager extends MediaManager {
+ Map<String, ByteBuf> files = new HashMap<>();
+
+ MockMediaManager(String path) {
+ super(path);
+ }
+
+ @Override
+ public String writeFile(String uniqueId, ByteBuf buf, String extension) {
+ String fileName = uniqueId + "/mock." + extension;
+ files.put(fileName, buf);
+ return fileName;
+ }
+
+ ByteBuf readFile(String fileName) {
+ return files.get(fileName);
+ }
+ }
}