aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/traccar/protocol/IotmProtocolDecoder.java117
-rw-r--r--src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java11
2 files changed, 125 insertions, 3 deletions
diff --git a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java
index 1bf3e4a8d..9a3a4dee1 100644
--- a/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/IotmProtocolDecoder.java
@@ -16,6 +16,7 @@
package org.traccar.protocol;
import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttConnAckMessage;
import io.netty.handler.codec.mqtt.MqttConnectMessage;
@@ -26,8 +27,13 @@ import org.traccar.BaseProtocolDecoder;
import org.traccar.DeviceSession;
import org.traccar.NetworkMessage;
import org.traccar.Protocol;
+import org.traccar.model.Position;
import java.net.SocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
public class IotmProtocolDecoder extends BaseProtocolDecoder {
@@ -35,6 +41,58 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
+ private Object readValue(ByteBuf buf, int sensorType) {
+ switch (sensorType) {
+ case 0:
+ return false;
+ case 1:
+ return true;
+ case 3:
+ return 0;
+ case 4:
+ return buf.readUnsignedByte();
+ case 5:
+ return buf.readUnsignedShortLE();
+ case 6:
+ return buf.readUnsignedIntLE();
+ case 7:
+ case 11:
+ return buf.readLongLE();
+ case 8:
+ return buf.readByte();
+ case 9:
+ return buf.readShortLE();
+ case 10:
+ return buf.readIntLE();
+ case 12:
+ return buf.readFloatLE();
+ case 13:
+ return buf.readDoubleLE();
+ case 32:
+ return buf.readCharSequence(buf.readUnsignedByte(), StandardCharsets.US_ASCII).toString();
+ case 33:
+ return ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedByte()));
+ case 64:
+ return buf.readCharSequence(buf.readUnsignedShortLE(), StandardCharsets.US_ASCII).toString();
+ case 65:
+ return ByteBufUtil.hexDump(buf.readSlice(buf.readUnsignedShortLE()));
+ case 2:
+ default:
+ return null;
+ }
+ }
+
+ private String getKey(int sensorId) {
+ switch (sensorId) {
+ case 0x300C:
+ return Position.KEY_RPM;
+ case 0x4003:
+ return Position.KEY_ODOMETER;
+ default:
+ return null;
+ }
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
@@ -52,7 +110,9 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder {
MqttConnAckMessage response = MqttMessageBuilders.connAck().returnCode(returnCode).build();
- channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ if (channel != null) {
+ channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ }
} else if (msg instanceof MqttPublishMessage) {
@@ -61,10 +121,61 @@ public class IotmProtocolDecoder extends BaseProtocolDecoder {
return null;
}
+ List<Position> positions = new LinkedList<>();
+
MqttPublishMessage message = (MqttPublishMessage) msg;
- ByteBuf bug = message.payload();
+ ByteBuf buf = message.payload();
+
+ buf.readUnsignedByte(); // structure version
+
+ while (buf.readableBytes() > 1) {
+ int type = buf.readUnsignedByte();
+ int length = buf.readUnsignedShortLE();
+ if (type == 1) {
+
+ ByteBuf record = buf.readSlice(length);
+
+ Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+ position.setTime(new Date(record.readUnsignedIntLE()));
+
+ while (record.readableBytes() > 0) {
+ int sensorType = record.readUnsignedByte();
+ int sensorId = record.readUnsignedShortLE();
+ if (sensorType == 14) {
+
+ position.setValid(true);
+ position.setLatitude(record.readFloatLE());
+ position.setLongitude(record.readFloatLE());
+ position.setSpeed(record.readUnsignedShortLE());
+
+ position.set(Position.KEY_HDOP, record.readUnsignedByte());
+ position.set(Position.KEY_SATELLITES, record.readUnsignedByte());
+
+ position.setCourse(record.readUnsignedShortLE());
+ position.setAltitude(record.readShortLE());
+
+ } else {
+
+ String key = getKey(sensorId);
+ Object value = readValue(record, sensorType);
+ if (key != null && value != null) {
+ position.getAttributes().put(key, value);
+ }
+
+ }
+ }
+
+ positions.add(position);
+
+ } else {
+ buf.skipBytes(length);
+ }
+ }
+
+ buf.readUnsignedByte(); // checksum
- return null;
+ return positions.isEmpty() ? null : positions;
}
diff --git a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java
index 65fdb82e8..1c783b355 100644
--- a/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/IotmProtocolDecoderTest.java
@@ -1,5 +1,7 @@
package org.traccar.protocol;
+import io.netty.handler.codec.mqtt.MqttMessageBuilders;
+import io.netty.handler.codec.mqtt.MqttQoS;
import org.junit.Test;
import org.traccar.ProtocolTest;
@@ -10,6 +12,15 @@ public class IotmProtocolDecoderTest extends ProtocolTest {
IotmProtocolDecoder decoder = new IotmProtocolDecoder(null);
+ verifyNull(decoder, MqttMessageBuilders.connect().clientId(
+ "123456789012345").build());
+
+ verifyPositions(decoder, false, MqttMessageBuilders.publish().payload(binary(
+ "020208009188752DE7120300013A002000AD59050030B135030340030C300301A00302A00E00D0B9AB5B420334C04100001F060000320004072064008C000162002000C004476F6F440109002100AD59050030BA359B")).qos(MqttQoS.EXACTLY_ONCE).build());
+
+ verifyPositions(decoder, false, MqttMessageBuilders.publish().payload(binary(
+ "020208009188752DE71203000109002000AD590500309635F3")).qos(MqttQoS.EXACTLY_ONCE).build());
+
}
}