diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/org/traccar/database/GroupTree.java | 8 | ||||
-rw-r--r-- | src/org/traccar/model/Command.java | 1 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gt06ProtocolDecoder.java | 165 | ||||
-rw-r--r-- | src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 6 | ||||
-rw-r--r-- | src/org/traccar/protocol/Pt502Protocol.java | 8 | ||||
-rw-r--r-- | src/org/traccar/protocol/Pt502ProtocolEncoder.java | 38 | ||||
-rw-r--r-- | src/org/traccar/protocol/UlbotechProtocolDecoder.java | 21 | ||||
-rw-r--r-- | src/org/traccar/protocol/V680Protocol.java | 10 |
8 files changed, 181 insertions, 76 deletions
diff --git a/src/org/traccar/database/GroupTree.java b/src/org/traccar/database/GroupTree.java index 4a2321f58..9062e7aa8 100644 --- a/src/org/traccar/database/GroupTree.java +++ b/src/org/traccar/database/GroupTree.java @@ -140,9 +140,11 @@ public class GroupTree { } private void getNodes(Set<TreeNode> results, TreeNode node) { - for (TreeNode child : node.getChildren()) { - results.add(child); - getNodes(results, child); + if (node != null) { + for (TreeNode child : node.getChildren()) { + results.add(child); + getNodes(results, child); + } } } diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java index 69172ecee..0a1a62216 100644 --- a/src/org/traccar/model/Command.java +++ b/src/org/traccar/model/Command.java @@ -36,6 +36,7 @@ public class Command extends Message { public static final String TYPE_SILENCE_TIME = "silenceTime"; public static final String TYPE_SET_PHONEBOOK = "setPhonebook"; public static final String TYPE_VOICE_MESSAGE = "voiceMessage"; + public static final String TYPE_OUTPUT_CONTROL = "outputControl"; public static final String TYPE_ALARM_GEOFENCE = "movementAlarm"; public static final String TYPE_ALARM_BATTERY = "alarmBattery"; diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index e9799c1b0..00444b61b 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2012 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,6 +63,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { public static final int MSG_COMMAND_0 = 0x80; public static final int MSG_COMMAND_1 = 0x81; public static final int MSG_COMMAND_2 = 0x82; + public static final int MSG_INFO = 0x94; private static boolean isSupported(int type) { return hasGps(type) || hasLbs(type) || hasStatus(type); @@ -168,102 +169,132 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { ChannelBuffer buf = (ChannelBuffer) msg; - if (buf.readByte() != 0x78 || buf.readByte() != 0x78) { - return null; - } + int header = buf.readShort(); + + if (header == 0x7878) { - int length = buf.readUnsignedByte(); // size - int dataLength = length - 5; + int length = buf.readUnsignedByte(); + int dataLength = length - 5; - int type = buf.readUnsignedByte(); + int type = buf.readUnsignedByte(); - if (type == MSG_LOGIN) { + if (type == MSG_LOGIN) { - String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); - buf.readUnsignedShort(); // type + String imei = ChannelBuffers.hexDump(buf.readBytes(8)).substring(1); + buf.readUnsignedShort(); // type - // Timezone offset - if (dataLength > 10) { - int extensionBits = buf.readUnsignedShort(); - int hours = (extensionBits >> 4) / 100; - int minutes = (extensionBits >> 4) % 100; - int offset = (hours * 60 + minutes) * 60; - if ((extensionBits & 0x8) != 0) { - offset = -offset; + // Timezone offset + if (dataLength > 10) { + int extensionBits = buf.readUnsignedShort(); + int hours = (extensionBits >> 4) / 100; + int minutes = (extensionBits >> 4) % 100; + int offset = (hours * 60 + minutes) * 60; + if ((extensionBits & 0x8) != 0) { + offset = -offset; + } + if (!forceTimeZone) { + timeZone.setRawOffset(offset * 1000); + } } - if (!forceTimeZone) { - timeZone.setRawOffset(offset * 1000); + + if (identify(imei, channel, remoteAddress)) { + buf.skipBytes(buf.readableBytes() - 6); + sendResponse(channel, type, buf.readUnsignedShort()); } - } - if (identify(imei, channel, remoteAddress)) { - buf.skipBytes(buf.readableBytes() - 6); - sendResponse(channel, type, buf.readUnsignedShort()); - } + } else if (hasDeviceId()) { + + if (type == MSG_STRING) { - } else if (hasDeviceId()) { + Position position = new Position(); + position.setDeviceId(getDeviceId()); + position.setProtocol(getProtocolName()); - if (type == MSG_STRING) { + getLastLocation(position, null); - Position position = new Position(); - position.setDeviceId(getDeviceId()); - position.setProtocol(getProtocolName()); + int commandLength = buf.readUnsignedByte(); - getLastLocation(position, null); + if (commandLength > 0) { + buf.readUnsignedByte(); // server flag (reserved) + position.set("command", buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); + } - int commandLength = buf.readUnsignedByte(); + buf.readUnsignedShort(); // language - if (commandLength > 0) { - buf.readUnsignedByte(); // server flag (reserved) - position.set("command", buf.readBytes(commandLength - 1).toString(StandardCharsets.US_ASCII)); - } + sendResponse(channel, type, buf.readUnsignedShort()); + + return position; - buf.readUnsignedShort(); // language + } else if (isSupported(type)) { - sendResponse(channel, type, buf.readUnsignedShort()); + Position position = new Position(); + position.setDeviceId(getDeviceId()); + position.setProtocol(getProtocolName()); - return position; + if (hasGps(type)) { + decodeGps(position, buf); + } else { + getLastLocation(position, null); + } - } else if (isSupported(type)) { + if (hasLbs(type)) { + decodeLbs(position, buf, hasStatus(type)); + } - Position position = new Position(); - position.setDeviceId(getDeviceId()); - position.setProtocol(getProtocolName()); + if (hasStatus(type)) { + decodeStatus(position, buf); + } + + if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { + position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); + } + + if (buf.readableBytes() > 6) { + buf.skipBytes(buf.readableBytes() - 6); + } + int index = buf.readUnsignedShort(); + position.set(Position.KEY_INDEX, index); + sendResponse(channel, type, index); + + return position; - if (hasGps(type)) { - decodeGps(position, buf); } else { - getLastLocation(position, null); - } - if (hasLbs(type)) { - decodeLbs(position, buf, hasStatus(type)); - } + buf.skipBytes(dataLength); + if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { + sendResponse(channel, type, buf.readUnsignedShort()); + } - if (hasStatus(type)) { - decodeStatus(position, buf); } - if (type == MSG_GPS_LBS_1 && buf.readableBytes() == 4 + 6) { - position.set(Position.KEY_ODOMETER, buf.readUnsignedInt()); - } + } - if (buf.readableBytes() > 6) { - buf.skipBytes(buf.readableBytes() - 6); - } - int index = buf.readUnsignedShort(); - position.set(Position.KEY_INDEX, index); - sendResponse(channel, type, index); + } else if (header == 0x7979) { - return position; + int length = buf.readUnsignedShort(); + int dataLength = length - 6; - } else { + int type = buf.readUnsignedByte(); - buf.skipBytes(dataLength); - if (type != MSG_COMMAND_0 && type != MSG_COMMAND_1 && type != MSG_COMMAND_2) { - sendResponse(channel, type, buf.readUnsignedShort()); - } + if (type == MSG_INFO) { + int subType = buf.readUnsignedByte(); + if (subType == 0x05) { + + Position position = new Position(); + position.setDeviceId(getDeviceId()); + position.setProtocol(getProtocolName()); + + getLastLocation(position, null); + + int flags = buf.readUnsignedByte(); + + position.set("door", BitUtil.check(flags, 0)); + position.set(Position.PREFIX_IO + 1, BitUtil.check(flags, 2)); + + return position; + + } } } diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index 48ee95c13..cdbf3850a 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2012 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -284,10 +284,10 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { } if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextInt(16)); + position.set(Position.KEY_ODOMETER, parser.nextLong(16)); } if (parser.hasNext()) { - position.set(Position.KEY_ODOMETER, parser.nextInt(16)); + position.set(Position.KEY_ODOMETER, parser.nextLong(16)); } if (parser.hasNext()) { diff --git a/src/org/traccar/protocol/Pt502Protocol.java b/src/org/traccar/protocol/Pt502Protocol.java index 165d53c2d..04c758b22 100644 --- a/src/org/traccar/protocol/Pt502Protocol.java +++ b/src/org/traccar/protocol/Pt502Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * 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.string.StringDecoder; +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,8 @@ public class Pt502Protocol extends BaseProtocol { public Pt502Protocol() { super("pt502"); + setSupportedCommands( + Command.TYPE_OUTPUT_CONTROL); } @Override @@ -36,7 +40,9 @@ public class Pt502Protocol extends BaseProtocol { @Override protected void addSpecificHandlers(ChannelPipeline pipeline) { pipeline.addLast("frameDecoder", new Pt502FrameDecoder()); + pipeline.addLast("stringEncoder", new StringEncoder()); pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectEncoder", new Pt502ProtocolEncoder()); pipeline.addLast("objectDecoder", new Pt502ProtocolDecoder(Pt502Protocol.this)); } }; diff --git a/src/org/traccar/protocol/Pt502ProtocolEncoder.java b/src/org/traccar/protocol/Pt502ProtocolEncoder.java new file mode 100644 index 000000000..86c6703d4 --- /dev/null +++ b/src/org/traccar/protocol/Pt502ProtocolEncoder.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Anton Tananaev (anton.tananaev@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 Pt502ProtocolEncoder extends StringProtocolEncoder { + + @Override + protected Object encodeCommand(Command command) { + + switch (command.getType()) { + case Command.TYPE_OUTPUT_CONTROL: + return formatCommand(command, "000000OPC{%s},{%s}", Command.KEY_INDEX, Command.KEY_DATA); + default: + Log.warning(new UnsupportedOperationException(command.getType())); + break; + } + + return null; + } + +} diff --git a/src/org/traccar/protocol/UlbotechProtocolDecoder.java b/src/org/traccar/protocol/UlbotechProtocolDecoder.java index 9cbaadfb4..2fd7d8f74 100644 --- a/src/org/traccar/protocol/UlbotechProtocolDecoder.java +++ b/src/org/traccar/protocol/UlbotechProtocolDecoder.java @@ -65,6 +65,25 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { } } + private void decodeJ1708(Position position, ChannelBuffer buf, short length) { + + int end = buf.readerIndex() + length; + + while (buf.readerIndex() < end) { + int mark = buf.readUnsignedByte(); + int len = BitUtil.between(mark, 0, 6); + int type = BitUtil.between(mark, 6, 8); + int id = buf.readUnsignedByte(); + if (type == 3) { + id += 256; + } + String value = ChannelBuffers.hexDump(buf.readBytes(len - 1)); + if (type == 2 || type == 3) { + position.set("pid" + id, value); + } + } + } + private void decodeDriverBehavior(Position position, ChannelBuffer buf) { int value = buf.readUnsignedByte(); @@ -200,7 +219,7 @@ public class UlbotechProtocolDecoder extends BaseProtocolDecoder { break; case DATA_J1708: - position.set("j1708", ChannelBuffers.hexDump(buf.readBytes(length))); + decodeJ1708(position, buf, length); break; case DATA_VIN: diff --git a/src/org/traccar/protocol/V680Protocol.java b/src/org/traccar/protocol/V680Protocol.java index a89f77edd..d2ceb207b 100644 --- a/src/org/traccar/protocol/V680Protocol.java +++ b/src/org/traccar/protocol/V680Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2015 - 2016 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ */ package org.traccar.protocol; +import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.handler.codec.string.StringDecoder; @@ -40,6 +41,13 @@ public class V680Protocol extends BaseProtocol { pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this)); } }); + serverList.add(new TrackerServer(new ConnectionlessBootstrap(), this.getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new V680ProtocolDecoder(V680Protocol.this)); + } + }); } } |