aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/MeiligaoProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java155
1 files changed, 107 insertions, 48 deletions
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 9f7b8abf7..30905076e 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2012 - 2018 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.
@@ -15,12 +15,14 @@
*/
package org.traccar.protocol;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.DeviceSession;
+import org.traccar.NetworkMessage;
+import org.traccar.helper.BitUtil;
import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.Parser;
@@ -30,12 +32,16 @@ import org.traccar.model.Position;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.regex.Pattern;
public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
+ private Map<Byte, ByteBuf> photos = new HashMap<>();
+
public MeiligaoProtocolDecoder(MeiligaoProtocol protocol) {
super(protocol);
}
@@ -135,7 +141,20 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
public static final int MSG_OBD_RT = 0x9901;
public static final int MSG_OBD_RTA = 0x9902;
- private DeviceSession identify(ChannelBuffer buf, Channel channel, SocketAddress remoteAddress) {
+ public static final int MSG_TRACK_ON_DEMAND = 0x4101;
+ public static final int MSG_TRACK_BY_INTERVAL = 0x4102;
+ public static final int MSG_MOVEMENT_ALARM = 0x4106;
+ public static final int MSG_OUTPUT_CONTROL = 0x4115;
+ public static final int MSG_TIME_ZONE = 0x4132;
+ public static final int MSG_TAKE_PHOTO = 0x4151;
+ public static final int MSG_UPLOAD_PHOTO = 0x0800;
+ public static final int MSG_UPLOAD_PHOTO_RESPONSE = 0x8801;
+ public static final int MSG_DATA_PHOTO = 0x9988;
+ public static final int MSG_POSITION_IMAGE = 0x9977;
+ public static final int MSG_UPLOAD_COMPLETE = 0x0f80;
+ public static final int MSG_REBOOT_GPS = 0x4902;
+
+ private DeviceSession identify(ByteBuf buf, Channel channel, SocketAddress remoteAddress) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 7; i++) {
@@ -166,10 +185,10 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
private static void sendResponse(
- Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int type, ChannelBuffer msg) {
+ Channel channel, SocketAddress remoteAddress, ByteBuf id, int type, ByteBuf msg) {
if (channel != null) {
- ChannelBuffer buf = ChannelBuffers.buffer(
+ ByteBuf buf = Unpooled.buffer(
2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2);
buf.writeByte('@');
@@ -178,18 +197,19 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
buf.writeBytes(id);
buf.writeShort(type);
buf.writeBytes(msg);
- buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.toByteBuffer()));
+ msg.release();
+ buf.writeShort(Checksum.crc16(Checksum.CRC16_CCITT_FALSE, buf.nioBuffer()));
buf.writeByte('\r');
buf.writeByte('\n');
- channel.write(buf, remoteAddress);
+ channel.writeAndFlush(new NetworkMessage(buf, remoteAddress));
}
}
private String getServer(Channel channel) {
String server = Context.getConfig().getString(getProtocolName() + ".server");
- if (server == null) {
- InetSocketAddress address = (InetSocketAddress) channel.getLocalAddress();
+ if (server == null && channel != null) {
+ InetSocketAddress address = (InetSocketAddress) channel.localAddress();
server = address.getAddress().getHostAddress() + ":" + address.getPort();
}
return server;
@@ -252,7 +272,15 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
position.setAltitude(parser.nextDouble(0));
}
- position.set(Position.KEY_STATUS, parser.next());
+ if (parser.hasNext()) {
+ int status = parser.nextHexInt();
+ for (int i = 1; i <= 5; i++) {
+ position.set(Position.PREFIX_OUT + i, BitUtil.check(status, i - 1));
+ }
+ for (int i = 1; i <= 5; i++) {
+ position.set(Position.PREFIX_IN + i, BitUtil.check(status, i - 1 + 8));
+ }
+ }
for (int i = 1; i <= 8; i++) {
position.set(Position.PREFIX_ADC + i, parser.nextHexInt());
@@ -302,7 +330,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
position.set("drivingRange", parser.nextDouble());
position.set(Position.KEY_ODOMETER, parser.nextDouble());
position.set("singleFuelConsumption", parser.nextDouble());
- position.set("totalFuelConsumption", parser.nextDouble());
+ position.set(Position.KEY_FUEL_USED, parser.nextDouble());
position.set(Position.KEY_DTCS, parser.nextInt());
position.set("hardAccelerationCount", parser.nextInt());
position.set("hardBrakingCount", parser.nextInt());
@@ -331,7 +359,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
return position;
}
- private List<Position> decodeRetransmission(ChannelBuffer buf, DeviceSession deviceSession) {
+ private List<Position> decodeRetransmission(ByteBuf buf, DeviceSession deviceSession) {
List<Position> positions = new LinkedList<>();
int count = buf.readUnsignedByte();
@@ -344,7 +372,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
endIndex = buf.writerIndex() - 4;
}
- String sentence = buf.readBytes(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII);
+ String sentence = buf.readSlice(endIndex - buf.readerIndex()).toString(StandardCharsets.US_ASCII);
Position position = new Position(getProtocolName());
position.setDeviceId(deviceSession.getDeviceId());
@@ -368,27 +396,35 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
- ChannelBuffer buf = (ChannelBuffer) msg;
+ ByteBuf buf = (ByteBuf) msg;
buf.skipBytes(2); // header
buf.readShort(); // length
- ChannelBuffer id = buf.readBytes(7);
+ ByteBuf id = buf.readSlice(7);
int command = buf.readUnsignedShort();
- ChannelBuffer response;
- if (channel != null) {
- if (command == MSG_LOGIN) {
- response = ChannelBuffers.wrappedBuffer(new byte[]{0x01});
- sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
- return null;
- } else if (command == MSG_HEARTBEAT) {
- response = ChannelBuffers.wrappedBuffer(new byte[]{0x01});
- sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
- return null;
- } else if (command == MSG_SERVER) {
- response = ChannelBuffers.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
- sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
- return null;
- }
+ if (command == MSG_LOGIN) {
+ ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01});
+ sendResponse(channel, remoteAddress, id, MSG_LOGIN_RESPONSE, response);
+ return null;
+ } else if (command == MSG_HEARTBEAT) {
+ ByteBuf response = Unpooled.wrappedBuffer(new byte[]{0x01});
+ sendResponse(channel, remoteAddress, id, MSG_HEARTBEAT, response);
+ return null;
+ } else if (command == MSG_SERVER) {
+ ByteBuf response = Unpooled.copiedBuffer(getServer(channel), StandardCharsets.US_ASCII);
+ sendResponse(channel, remoteAddress, id, MSG_SERVER, response);
+ return null;
+ } else if (command == MSG_UPLOAD_PHOTO) {
+ byte imageIndex = buf.readByte();
+ photos.put(imageIndex, Unpooled.buffer());
+ ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex});
+ sendResponse(channel, remoteAddress, id, MSG_UPLOAD_PHOTO_RESPONSE, response);
+ return null;
+ } else if (command == MSG_UPLOAD_COMPLETE) {
+ byte imageIndex = buf.readByte();
+ ByteBuf response = Unpooled.copiedBuffer(new byte[]{imageIndex, 0, 0});
+ sendResponse(channel, remoteAddress, id, MSG_RETRANSMISSION, response);
+ return null;
}
DeviceSession deviceSession = identify(id, channel, remoteAddress);
@@ -396,7 +432,18 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
return null;
}
- if (command == MSG_RETRANSMISSION) {
+ if (command == MSG_DATA_PHOTO) {
+
+ byte imageIndex = buf.readByte();
+ buf.readUnsignedShort(); // image footage
+ buf.readUnsignedByte(); // total packets
+ buf.readUnsignedByte(); // packet index
+
+ photos.get(imageIndex).writeBytes(buf, buf.readableBytes() - 2 - 2);
+
+ return null;
+
+ } else if (command == MSG_RETRANSMISSION) {
return decodeRetransmission(buf, deviceSession);
@@ -404,6 +451,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
+ position.setDeviceId(deviceSession.getDeviceId());
+
if (command == MSG_ALARM) {
short alarmCode = buf.readUnsignedByte();
position.set(Position.KEY_ALARM, decodeAlarm(alarmCode));
@@ -414,11 +463,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
} else if (command == MSG_POSITION_LOGGED) {
buf.skipBytes(6);
- }
-
- position.setDeviceId(deviceSession.getDeviceId());
-
- if (command == MSG_RFID) {
+ } else if (command == MSG_RFID) {
for (int i = 0; i < 15; i++) {
long rfid = buf.readUnsignedInt();
if (rfid != 0) {
@@ -427,23 +472,37 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
position.set(Position.KEY_DRIVER_UNIQUE_ID, card);
}
}
+ } else if (command == MSG_POSITION_IMAGE) {
+ byte imageIndex = buf.readByte();
+ buf.readUnsignedByte(); // image upload type
+ String uniqueId = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId();
+ ByteBuf photo = photos.remove(imageIndex);
+ try {
+ position.set(Position.KEY_IMAGE, Context.getMediaManager().writeFile(uniqueId, photo, "jpg"));
+ } finally {
+ photo.release();
+ }
}
String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, StandardCharsets.US_ASCII);
- if (command == MSG_POSITION || command == MSG_POSITION_LOGGED || command == MSG_ALARM) {
- return decodeRegular(position, sentence);
- } else if (command == MSG_RFID) {
- return decodeRfid(position, sentence);
- } else if (command == MSG_OBD_RT) {
- return decodeObd(position, sentence);
- } else if (command == MSG_OBD_RTA) {
- return decodeObdA(position, sentence);
+ switch (command) {
+ case MSG_POSITION:
+ case MSG_POSITION_LOGGED:
+ case MSG_ALARM:
+ case MSG_POSITION_IMAGE:
+ return decodeRegular(position, sentence);
+ case MSG_RFID:
+ return decodeRfid(position, sentence);
+ case MSG_OBD_RT:
+ return decodeObd(position, sentence);
+ case MSG_OBD_RTA:
+ return decodeObdA(position, sentence);
+ default:
+ return null;
}
}
-
- return null;
}
}