aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/traccar/database/GroupTree.java8
-rw-r--r--src/org/traccar/model/Command.java1
-rw-r--r--src/org/traccar/protocol/Gt06ProtocolDecoder.java165
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java6
-rw-r--r--src/org/traccar/protocol/Pt502Protocol.java8
-rw-r--r--src/org/traccar/protocol/Pt502ProtocolEncoder.java38
-rw-r--r--src/org/traccar/protocol/UlbotechProtocolDecoder.java21
-rw-r--r--src/org/traccar/protocol/V680Protocol.java10
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));
+ }
+ });
}
}