aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-09-11 19:52:51 +1200
committerGitHub <noreply@github.com>2017-09-11 19:52:51 +1200
commit3426e6fb00c64540a846b8b1e4d5e626ae791fd7 (patch)
tree62be548121d53cf8660bba9432e68835a17e2afd
parent7f73f2adf965063947aff1b7e1fdf80b614bd347 (diff)
parent871b9a9c611388394dcbc2eb5ed0e5e30a5411c2 (diff)
downloadtraccar-server-3426e6fb00c64540a846b8b1e4d5e626ae791fd7.tar.gz
traccar-server-3426e6fb00c64540a846b8b1e4d5e626ae791fd7.tar.bz2
traccar-server-3426e6fb00c64540a846b8b1e4d5e626ae791fd7.zip
Merge pull request #3517 from naihil/adm
Improve ADM protocol
-rw-r--r--src/org/traccar/protocol/AdmProtocol.java9
-rw-r--r--src/org/traccar/protocol/AdmProtocolDecoder.java105
-rw-r--r--src/org/traccar/protocol/AdmProtocolEncoder.java42
-rw-r--r--test/org/traccar/protocol/AdmProtocolDecoderTest.java2
-rw-r--r--test/org/traccar/protocol/AdmProtocolEncoderTest.java43
5 files changed, 166 insertions, 35 deletions
diff --git a/src/org/traccar/protocol/AdmProtocol.java b/src/org/traccar/protocol/AdmProtocol.java
index 442121f0a..4d2cbe7b3 100644
--- a/src/org/traccar/protocol/AdmProtocol.java
+++ b/src/org/traccar/protocol/AdmProtocol.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 Anton Tananaev (anton@traccar.org)
+ * Copyright 2015 - 2017 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,10 @@ package org.traccar.protocol;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
+import org.jboss.netty.handler.codec.string.StringEncoder;
import org.traccar.BaseProtocol;
import org.traccar.TrackerServer;
+import org.traccar.model.Command;
import java.nio.ByteOrder;
import java.util.List;
@@ -28,6 +30,9 @@ public class AdmProtocol extends BaseProtocol {
public AdmProtocol() {
super("adm");
+ setSupportedDataCommands(
+ Command.TYPE_GET_DEVICE_STATUS,
+ Command.TYPE_CUSTOM);
}
@Override
@@ -36,6 +41,8 @@ public class AdmProtocol extends BaseProtocol {
@Override
protected void addSpecificHandlers(ChannelPipeline pipeline) {
pipeline.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 2, 1, -3, 0));
+ pipeline.addLast("stringEncoder", new StringEncoder());
+ pipeline.addLast("objectEncoder", new AdmProtocolEncoder());
pipeline.addLast("objectDecoder", new AdmProtocolDecoder(AdmProtocol.this));
}
};
diff --git a/src/org/traccar/protocol/AdmProtocolDecoder.java b/src/org/traccar/protocol/AdmProtocolDecoder.java
index f4a21cad0..80c580967 100644
--- a/src/org/traccar/protocol/AdmProtocolDecoder.java
+++ b/src/org/traccar/protocol/AdmProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,76 +33,72 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ public static final int CMD_RESPONSE_SIZE = 0x84;
public static final int MSG_IMEI = 0x03;
public static final int MSG_PHOTO = 0x0A;
public static final int MSG_ADM5 = 0x01;
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
-
- ChannelBuffer buf = (ChannelBuffer) msg;
-
- buf.readUnsignedShort(); // device id
- buf.readUnsignedByte(); // length
-
- int type = buf.readUnsignedByte();
-
- DeviceSession deviceSession;
- if (type == MSG_IMEI) {
- deviceSession = getDeviceSession(
- channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.US_ASCII));
- } else {
- deviceSession = getDeviceSession(channel, remoteAddress);
- }
-
+ private Position decodeData(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf, int type) {
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
if (deviceSession == null) {
return null;
}
if (BitUtil.to(type, 2) == 0) {
-
Position position = new Position();
position.setProtocol(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
position.set(Position.KEY_VERSION_FW, buf.readUnsignedByte());
- buf.readUnsignedShort(); // index
-
- position.set(Position.KEY_STATUS, buf.readUnsignedShort());
+ position.set(Position.KEY_INDEX, buf.readUnsignedShort());
- position.setValid(true);
+ int status = buf.readUnsignedShort();
+ position.set(Position.KEY_STATUS, status);
+ position.setValid(!BitUtil.check(status, 5));
position.setLatitude(buf.readFloat());
position.setLongitude(buf.readFloat());
position.setCourse(buf.readUnsignedShort() * 0.1);
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1));
- position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte());
-
+ position.set(Position.KEY_ACCELERATION, buf.readUnsignedByte() * 0.1);
position.setAltitude(buf.readUnsignedShort());
-
position.set(Position.KEY_HDOP, buf.readUnsignedByte() * 0.1);
position.set(Position.KEY_SATELLITES, buf.readUnsignedByte() & 0x0f);
position.setTime(new Date(buf.readUnsignedInt() * 1000));
- position.set(Position.KEY_POWER, buf.readUnsignedShort());
- position.set(Position.KEY_BATTERY, buf.readUnsignedShort());
+ position.set(Position.KEY_POWER, buf.readUnsignedShort() * 0.001);
+ position.set(Position.KEY_BATTERY, buf.readUnsignedShort() * 0.001);
if (BitUtil.check(type, 2)) {
- buf.skipBytes(4);
+ buf.skipBytes(2); // vib, vib_count
+
+ int out = buf.readUnsignedByte();
+ for (int i = 0; i <= 3; ++i) {
+ position.set(Position.PREFIX_OUT + (i + 1), BitUtil.check(out, i) ? 1 : 0);
+ }
+
+ buf.skipBytes(1); // in_alarm
}
if (BitUtil.check(type, 3)) {
- buf.skipBytes(12);
+ for (int i = 1; i <= 6; ++i) {
+ position.set(Position.PREFIX_ADC + i, buf.readUnsignedShort() * 0.001);
+ }
}
if (BitUtil.check(type, 4)) {
- buf.skipBytes(8);
+ for (int i = 1; i <= 2; ++i) {
+ position.set(Position.PREFIX_COUNT + i, buf.readUnsignedInt());
+ }
}
if (BitUtil.check(type, 5)) {
- buf.skipBytes(9);
+ buf.skipBytes(6); // fuel level 0..2
+
+ for (int i = 1; i <= 3; ++i) {
+ position.set(Position.PREFIX_TEMP + i, buf.readUnsignedByte());
+ }
}
if (BitUtil.check(type, 6)) {
@@ -119,4 +115,45 @@ public class AdmProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ private Position parseCommandResponse(Channel channel, SocketAddress remoteAddress, ChannelBuffer buf) {
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession == null) {
+ return null;
+ }
+
+ Position position = new Position();
+ position.setProtocol(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
+ getLastLocation(position, null);
+
+ int responseTextLength = buf.bytesBefore((byte) 0);
+ if (responseTextLength < 0) {
+ responseTextLength = CMD_RESPONSE_SIZE - 3;
+ }
+ position.set(Position.KEY_RESULT, buf.readBytes(responseTextLength).toString(StandardCharsets.UTF_8));
+
+ return position;
+ }
+
+ @Override
+ protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
+ ChannelBuffer buf = (ChannelBuffer) msg;
+
+ buf.readUnsignedShort(); // device id
+
+ int size = buf.readUnsignedByte();
+ if (size != CMD_RESPONSE_SIZE) {
+ int type = buf.readUnsignedByte();
+ if (type == MSG_IMEI) {
+ getDeviceSession(channel, remoteAddress, buf.readBytes(15).toString(StandardCharsets.UTF_8));
+ } else {
+ return decodeData(channel, remoteAddress, buf, type);
+ }
+ } else {
+ return parseCommandResponse(channel, remoteAddress, buf);
+ }
+
+ return null;
+ }
}
diff --git a/src/org/traccar/protocol/AdmProtocolEncoder.java b/src/org/traccar/protocol/AdmProtocolEncoder.java
new file mode 100644
index 000000000..8cbd8618d
--- /dev/null
+++ b/src/org/traccar/protocol/AdmProtocolEncoder.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.traccar.StringProtocolEncoder;
+import org.traccar.helper.Log;
+import org.traccar.model.Command;
+
+public class AdmProtocolEncoder extends StringProtocolEncoder {
+
+ @Override
+ protected Object encodeCommand(Command command) {
+
+ switch (command.getType()) {
+ case Command.TYPE_GET_DEVICE_STATUS:
+ return formatCommand(command, "STATUS\r\n");
+
+ case Command.TYPE_CUSTOM:
+ return formatCommand(command, "{%s}\r\n", Command.KEY_DATA);
+
+ default:
+ Log.warning(new UnsupportedOperationException(command.getType()));
+ break;
+ }
+
+ return null;
+ }
+}
diff --git a/test/org/traccar/protocol/AdmProtocolDecoderTest.java b/test/org/traccar/protocol/AdmProtocolDecoderTest.java
index 4299001c3..9a7f91d26 100644
--- a/test/org/traccar/protocol/AdmProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/AdmProtocolDecoderTest.java
@@ -30,6 +30,8 @@ public class AdmProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, binary(ByteOrder.LITTLE_ENDIAN,
"01002200333508202000000000000000007F0D9F030000000000E39A1056E24A8210"));
+ verifyNotNull(decoder, binary(ByteOrder.LITTLE_ENDIAN,
+ "01008449443d3120536f66743d30783531204750533d313036382054696d653d30383a35393a32302031302e30392e31372056616c3d30204c61743d36312e36373738204c6f6e3d35302e3832343520563d3020536174436e743d342b3720537461743d30783030313020496e5f616c61726d3d30783030000000000000000000000000"));
}
}
diff --git a/test/org/traccar/protocol/AdmProtocolEncoderTest.java b/test/org/traccar/protocol/AdmProtocolEncoderTest.java
new file mode 100644
index 000000000..6d2452e26
--- /dev/null
+++ b/test/org/traccar/protocol/AdmProtocolEncoderTest.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2017 Anatoliy Golubev (darth.naihil@gmail.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.traccar.protocol;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.traccar.ProtocolTest;
+import org.traccar.model.Command;
+
+public class AdmProtocolEncoderTest extends ProtocolTest {
+
+ @Test
+ public void testEncode() throws Exception {
+
+ AdmProtocolEncoder encoder = new AdmProtocolEncoder();
+
+ Command command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_GET_DEVICE_STATUS);
+ Assert.assertEquals("STATUS\r\n", encoder.encodeCommand(command));
+
+ command = new Command();
+ command.setDeviceId(1);
+ command.setType(Command.TYPE_CUSTOM);
+ command.set(Command.KEY_DATA, "INPUT 0");
+ Assert.assertEquals("INPUT 0\r\n", encoder.encodeCommand(command));
+ }
+
+}