diff options
Diffstat (limited to 'src/org/traccar/protocol/MeiligaoProtocolDecoder.java')
-rw-r--r-- | src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 155 |
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; } } |