diff options
author | Shinryuken <watertext@hotmail.it> | 2017-11-19 11:22:31 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-19 11:22:31 +0100 |
commit | a5b273f8f8afd1a67613517c6487642601070456 (patch) | |
tree | babc63f5d50977fc91b3946b1da2e86ec74c51a5 /src/org/traccar/protocol | |
parent | c7928ef4a722cb40e9911c8e76e308fc48c85567 (diff) | |
parent | fb9cbb2b74dc0060bd0dc5d0b3bfeb958ed6f3b5 (diff) | |
download | traccar-server-a5b273f8f8afd1a67613517c6487642601070456.tar.gz traccar-server-a5b273f8f8afd1a67613517c6487642601070456.tar.bz2 traccar-server-a5b273f8f8afd1a67613517c6487642601070456.zip |
Merge branch 'master' into payload-as-form-param
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r-- | src/org/traccar/protocol/DwayProtocolDecoder.java | 4 | ||||
-rw-r--r-- | src/org/traccar/protocol/GenxProtocolDecoder.java | 1 | ||||
-rw-r--r-- | src/org/traccar/protocol/Gl200TextProtocolDecoder.java | 134 | ||||
-rw-r--r-- | src/org/traccar/protocol/Ivt401Protocol.java | 45 | ||||
-rw-r--r-- | src/org/traccar/protocol/Ivt401ProtocolDecoder.java | 97 | ||||
-rw-r--r-- | src/org/traccar/protocol/Jt600ProtocolDecoder.java | 14 | ||||
-rw-r--r-- | src/org/traccar/protocol/MegastekProtocolDecoder.java | 40 | ||||
-rw-r--r-- | src/org/traccar/protocol/MeiligaoProtocolDecoder.java | 3 | ||||
-rw-r--r-- | src/org/traccar/protocol/OkoProtocol.java | 45 | ||||
-rw-r--r-- | src/org/traccar/protocol/OkoProtocolDecoder.java | 100 |
10 files changed, 464 insertions, 19 deletions
diff --git a/src/org/traccar/protocol/DwayProtocolDecoder.java b/src/org/traccar/protocol/DwayProtocolDecoder.java index 767b35c72..121681588 100644 --- a/src/org/traccar/protocol/DwayProtocolDecoder.java +++ b/src/org/traccar/protocol/DwayProtocolDecoder.java @@ -59,9 +59,9 @@ public class DwayProtocolDecoder extends BaseProtocolDecoder { Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { String sentence = (String) msg; - if (sentence.startsWith(">H")) { + if (sentence.equals("AA55,HB")) { if (channel != null) { - channel.write(">ALIVE\r\n"); + channel.write("55AA,HB,OK\r\n"); } return null; } diff --git a/src/org/traccar/protocol/GenxProtocolDecoder.java b/src/org/traccar/protocol/GenxProtocolDecoder.java index ebf6f2b53..3b38227dc 100644 --- a/src/org/traccar/protocol/GenxProtocolDecoder.java +++ b/src/org/traccar/protocol/GenxProtocolDecoder.java @@ -55,6 +55,7 @@ public class GenxProtocolDecoder extends BaseProtocolDecoder { for (int i = 0; i < Math.min(values.length, reportColumns.length); i++) { switch (reportColumns[i]) { case 1: + case 28: DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[i]); if (deviceSession != null) { position.setDeviceId(deviceSession.getDeviceId()); diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java index 2f03cbb8f..fb0023dba 100644 --- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java +++ b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java @@ -31,8 +31,12 @@ import org.traccar.model.WifiAccessPoint; import java.net.SocketAddress; import java.nio.charset.StandardCharsets; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.LinkedList; import java.util.List; +import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -216,7 +220,7 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { .number("(d{1,7}.d)?,") // odometer .number("(d{5}:dd:dd)?,") // hour meter .number("(x+)?,") // adc 1 - .number("(x+)?,") // adc 2 + .number("(x+)?,").optional() // adc 2 .number("(d{1,3})?,") // battery .number("(?:(xx)(xx)(xx))?,") // device status .expression("(.*)") // additional data @@ -523,6 +527,131 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { return position; } + private Object decodeCan(Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException { + Position position = new Position(); + position.setProtocol(getProtocolName()); + + int index = 0; + String[] values = sentence.split(","); + + index += 1; // header + index += 1; // protocol version + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, values[index++]); + position.setDeviceId(deviceSession.getDeviceId()); + + index += 1; // device name + index += 1; // report type + index += 1; // canbus state + long reportMask = Long.parseLong(values[index++], 16); + + if (BitUtil.check(reportMask, 0)) { + position.set(Position.KEY_VIN, values[index++]); + } + if (BitUtil.check(reportMask, 1)) { + position.set(Position.KEY_IGNITION, Integer.parseInt(values[index++]) > 0); + } + if (BitUtil.check(reportMask, 2)) { + index += 1; // total distance + } + if (BitUtil.check(reportMask, 3)) { + position.set("totalFuelConsumption", Double.parseDouble(values[index++])); + } + if (BitUtil.check(reportMask, 5)) { + position.set(Position.KEY_RPM, Integer.parseInt(values[index++])); + } + if (BitUtil.check(reportMask, 4)) { + position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index++]))); + } + if (BitUtil.check(reportMask, 6)) { + position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index++])); + } + if (BitUtil.check(reportMask, 7)) { + index += 1; // fuel consumption + } + if (BitUtil.check(reportMask, 8)) { + index += 1; // fuel level + } + if (BitUtil.check(reportMask, 9)) { + index += 1; // range + } + if (BitUtil.check(reportMask, 10)) { + if (!values[index++].isEmpty()) { + position.set(Position.KEY_THROTTLE, Integer.parseInt(values[index - 1])); + } + } + if (BitUtil.check(reportMask, 11)) { + position.set(Position.KEY_HOURS, Double.parseDouble(values[index++])); + } + if (BitUtil.check(reportMask, 12)) { + index += 1; // driving time + } + if (BitUtil.check(reportMask, 13)) { + index += 1; // idle time + } + if (BitUtil.check(reportMask, 14)) { + index += 1; // idle fuel + } + if (BitUtil.check(reportMask, 15)) { + index += 1; // axle weight + } + if (BitUtil.check(reportMask, 16)) { + index += 1; // tachograph info + } + if (BitUtil.check(reportMask, 17)) { + index += 1; // indicators + } + if (BitUtil.check(reportMask, 18)) { + index += 1; // lights + } + if (BitUtil.check(reportMask, 19)) { + index += 1; // doors + } + if (BitUtil.check(reportMask, 20)) { + index += 1; // total vehicle overspeed time + } + if (BitUtil.check(reportMask, 21)) { + index += 1; // total engine overspeed time + } + if (BitUtil.check(reportMask, 29)) { + index += 1; // expansion + } + + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + + if (BitUtil.check(reportMask, 30)) { + position.setValid(Integer.parseInt(values[index++]) > 0); + if (!values[index].isEmpty()) { + position.setSpeed(UnitsConverter.knotsFromKph(Double.parseDouble(values[index++]))); + position.setCourse(Integer.parseInt(values[index++])); + position.setAltitude(Double.parseDouble(values[index++])); + position.setLongitude(Double.parseDouble(values[index++])); + position.setLatitude(Double.parseDouble(values[index++])); + position.setTime(dateFormat.parse(values[index++])); + } else { + index += 6; // no location + getLastLocation(position, null); + } + } else { + getLastLocation(position, null); + } + + if (BitUtil.check(reportMask, 31)) { + index += 4; // cell + } + + index += 1; // reserved + + if (ignoreFixTime) { + position.setTime(dateFormat.parse(values[index])); + } else { + position.setDeviceTime(dateFormat.parse(values[index])); + } + + return position; + } + private void decodeStatus(Position position, Parser parser) { if (parser.hasNext(3)) { int ignition = parser.nextHexInt(0); @@ -869,6 +998,9 @@ public class Gl200TextProtocolDecoder extends BaseProtocolDecoder { case "OBD": result = decodeObd(channel, remoteAddress, sentence); break; + case "CAN": + result = decodeCan(channel, remoteAddress, sentence); + break; case "FRI": result = decodeFri(channel, remoteAddress, sentence); break; diff --git a/src/org/traccar/protocol/Ivt401Protocol.java b/src/org/traccar/protocol/Ivt401Protocol.java new file mode 100644 index 000000000..b58601ba1 --- /dev/null +++ b/src/org/traccar/protocol/Ivt401Protocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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. + * 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.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class Ivt401Protocol extends BaseProtocol { + + public Ivt401Protocol() { + super("ivt401"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, ';')); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new Ivt401ProtocolDecoder(Ivt401Protocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/Ivt401ProtocolDecoder.java b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java new file mode 100644 index 000000000..f209ee09e --- /dev/null +++ b/src/org/traccar/protocol/Ivt401ProtocolDecoder.java @@ -0,0 +1,97 @@ +/* + * Copyright 2017 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. + * 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.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.helper.UnitsConverter; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class Ivt401ProtocolDecoder extends BaseProtocolDecoder { + + public Ivt401ProtocolDecoder(Ivt401Protocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("(") + .expression("TL[ABLN],") // header + .number("(d+),") // imei + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(dd)(dd)(dd),") // time (hhmmss) + .number("([-+]d+.d+),") // latitude + .number("([-+]d+.d+),") // longitude + .number("(d+),") // speed + .number("(d+),") // course + .number("(-?d+.?d*),") // altitude + .number("(d+),") // satellites + .number("(d),") // gps status + .number("(d+),") // rssi + .number("(d+),") // input + .number("(d+),") // output + .number("(d+.d+),") // adc + .number("(d+.d+),") // power + .number("(d+.d+),") // battery + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + position.setTime(parser.nextDateTime(Parser.DateTimeFormat.DMY_HMS)); + + position.setLatitude(parser.nextDouble()); + position.setLongitude(parser.nextDouble()); + position.setSpeed(UnitsConverter.knotsFromKph(parser.nextInt())); + position.setCourse(parser.nextInt()); + position.setAltitude(parser.nextDouble()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + + position.setValid(parser.nextInt() > 0); + + position.set(Position.KEY_RSSI, parser.nextInt()); + position.set(Position.KEY_INPUT, parser.nextBinInt()); + position.set(Position.KEY_OUTPUT, parser.nextBinInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_BATTERY, parser.nextDouble()); + + return position; + } + +} diff --git a/src/org/traccar/protocol/Jt600ProtocolDecoder.java b/src/org/traccar/protocol/Jt600ProtocolDecoder.java index f76fd8069..58835c7d6 100644 --- a/src/org/traccar/protocol/Jt600ProtocolDecoder.java +++ b/src/org/traccar/protocol/Jt600ProtocolDecoder.java @@ -21,6 +21,7 @@ import org.jboss.netty.channel.Channel; import org.traccar.BaseProtocolDecoder; import org.traccar.DeviceSession; import org.traccar.helper.BcdUtil; +import org.traccar.helper.BitBuffer; import org.traccar.helper.BitUtil; import org.traccar.helper.DateBuilder; import org.traccar.helper.Parser; @@ -152,6 +153,19 @@ public class Jt600ProtocolDecoder extends BaseProtocolDecoder { fuel += buf.readUnsignedByte(); position.set(Position.KEY_FUEL_LEVEL, fuel); + } else if (version == 3) { + + BitBuffer bitBuffer = new BitBuffer(buf); + + position.set("fuel1", bitBuffer.readUnsigned(12)); + position.set("fuel2", bitBuffer.readUnsigned(12)); + position.set("fuel3", bitBuffer.readUnsigned(12)); + position.set(Position.KEY_ODOMETER, bitBuffer.readUnsigned(20) * 1000); + + int status = bitBuffer.readUnsigned(24); + position.set(Position.KEY_IGNITION, BitUtil.check(status, 0)); + position.set(Position.KEY_STATUS, status); + } positions.add(position); diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java index 3ef52acd1..ad0f20a24 100644 --- a/src/org/traccar/protocol/MegastekProtocolDecoder.java +++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java @@ -340,30 +340,38 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder { } private String decodeAlarm(String value) { + value = value.toLowerCase(); + if (value.startsWith("geo")) { + if (value.endsWith("in")) { + return Position.ALARM_GEOFENCE_ENTER; + } else if (value.endsWith("out")) { + return Position.ALARM_GEOFENCE_EXIT; + } + } switch (value) { - case "SOS": - case "Help": + case "poweron": + return Position.ALARM_POWER_ON; + case "poweroff": + return Position.ALARM_POWER_ON; + case "sos": + case "help": return Position.ALARM_SOS; - case "Over Speed": - case "OverSpeed": + case "over speed": + case "overspeed": return Position.ALARM_OVERSPEED; - case "LowSpeed": + case "lowspeed": return Position.ALARM_LOW_SPEED; - case "Low Battery": - case "LowBattery": + case "low battery": + case "lowbattery": return Position.ALARM_LOW_BATTERY; - case "VIB": + case "vib": return Position.ALARM_VIBRATION; - case "Move in": - case "Geo in": - case "Geo1 in": - case "Geo2 in": + case "move in": return Position.ALARM_GEOFENCE_ENTER; - case "Move out": - case "Geo out": - case "Geo1 out": - case "Geo2 out": + case "move out": return Position.ALARM_GEOFENCE_EXIT; + case "error": + return Position.ALARM_FAULT; default: return null; } diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java index b0793037f..bc7a0b71a 100644 --- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java +++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java @@ -69,6 +69,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { .number("|(x{8})") // odometer .groupBegin() .number("|(xx)") // satellites + .text("|") + .expression("(.*)") // driver .groupEnd("?") .or() .number("|(x{9})") // odometer @@ -259,6 +261,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder { position.set(Position.KEY_RSSI, parser.nextHexInt()); position.set(Position.KEY_ODOMETER, parser.nextHexLong()); position.set(Position.KEY_SATELLITES, parser.nextHexInt()); + position.set("driverLicense", parser.next()); position.set(Position.KEY_ODOMETER, parser.nextHexLong()); position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next()); diff --git a/src/org/traccar/protocol/OkoProtocol.java b/src/org/traccar/protocol/OkoProtocol.java new file mode 100644 index 000000000..0b38741e5 --- /dev/null +++ b/src/org/traccar/protocol/OkoProtocol.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 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. + * 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.jboss.netty.bootstrap.ServerBootstrap; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.handler.codec.string.StringDecoder; +import org.traccar.BaseProtocol; +import org.traccar.CharacterDelimiterFrameDecoder; +import org.traccar.TrackerServer; + +import java.util.List; + +public class OkoProtocol extends BaseProtocol { + + public OkoProtocol() { + super("oko"); + } + + @Override + public void initTrackerServers(List<TrackerServer> serverList) { + serverList.add(new TrackerServer(new ServerBootstrap(), getName()) { + @Override + protected void addSpecificHandlers(ChannelPipeline pipeline) { + pipeline.addLast("frameDecoder", new CharacterDelimiterFrameDecoder(1024, '}')); + pipeline.addLast("stringDecoder", new StringDecoder()); + pipeline.addLast("objectDecoder", new OkoProtocolDecoder(OkoProtocol.this)); + } + }); + } + +} diff --git a/src/org/traccar/protocol/OkoProtocolDecoder.java b/src/org/traccar/protocol/OkoProtocolDecoder.java new file mode 100644 index 000000000..e86acf0b8 --- /dev/null +++ b/src/org/traccar/protocol/OkoProtocolDecoder.java @@ -0,0 +1,100 @@ +/* + * Copyright 2017 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. + * 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.jboss.netty.channel.Channel; +import org.traccar.BaseProtocolDecoder; +import org.traccar.DeviceSession; +import org.traccar.helper.DateBuilder; +import org.traccar.helper.Parser; +import org.traccar.helper.PatternBuilder; +import org.traccar.model.Position; + +import java.net.SocketAddress; +import java.util.regex.Pattern; + +public class OkoProtocolDecoder extends BaseProtocolDecoder { + + public OkoProtocolDecoder(OkoProtocol protocol) { + super(protocol); + } + + private static final Pattern PATTERN = new PatternBuilder() + .text("{") + .number("(d{15}),").optional() // imei + .number("(dd)(dd)(dd).d+,") // time + .expression("([AV]),") // validity + .number("(dd)(dd.d+),") // latitude + .expression("([NS]),") + .number("(ddd)(dd.d+),") // longitude + .expression("([EW]),") + .number("(d+.?d*)?,") // speed + .number("(d+.?d*)?,") // course + .number("(dd)(dd)(dd),") // date (ddmmyy) + .number("(d+),") // satellites + .number("(d+.d+),") // adc + .number("(xx),") // event + .number("(d+.d+),") // power + .number("d,") // memory status + .number("(xx)") // io + .any() + .compile(); + + @Override + protected Object decode( + Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { + + Parser parser = new Parser(PATTERN, (String) msg); + if (!parser.matches()) { + return null; + } + + DeviceSession deviceSession; + if (parser.hasNext()) { + deviceSession = getDeviceSession(channel, remoteAddress, parser.next()); + } else { + deviceSession = getDeviceSession(channel, remoteAddress); + } + if (deviceSession == null) { + return null; + } + + Position position = new Position(); + position.setProtocol(getProtocolName()); + position.setDeviceId(deviceSession.getDeviceId()); + + DateBuilder dateBuilder = new DateBuilder() + .setTime(parser.nextInt(), parser.nextInt(), parser.nextInt()); + + position.setValid(parser.next().equals("A")); + position.setLatitude(parser.nextCoordinate()); + position.setLongitude(parser.nextCoordinate()); + position.setSpeed(parser.nextDouble(0)); + position.setCourse(parser.nextDouble(0)); + + dateBuilder.setDateReverse(parser.nextInt(), parser.nextInt(), parser.nextInt()); + position.setTime(dateBuilder.getDate()); + + position.set(Position.KEY_SATELLITES, parser.nextInt()); + position.set(Position.PREFIX_ADC + 1, parser.nextDouble()); + position.set(Position.KEY_EVENT, parser.next()); + position.set(Position.KEY_POWER, parser.nextDouble()); + position.set(Position.KEY_INPUT, parser.nextHexInt()); + + return position; + } + +} |