aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol/Gl200TextProtocolDecoder.java')
-rw-r--r--src/org/traccar/protocol/Gl200TextProtocolDecoder.java1266
1 files changed, 0 insertions, 1266 deletions
diff --git a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java b/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
deleted file mode 100644
index aeb57a116..000000000
--- a/src/org/traccar/protocol/Gl200TextProtocolDecoder.java
+++ /dev/null
@@ -1,1266 +0,0 @@
-/*
- * 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.
- * 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.BaseProtocolDecoder;
-import org.traccar.Context;
-import org.traccar.DeviceSession;
-import org.traccar.NetworkMessage;
-import org.traccar.Protocol;
-import org.traccar.helper.BitUtil;
-import org.traccar.helper.Parser;
-import org.traccar.helper.PatternBuilder;
-import org.traccar.helper.UnitsConverter;
-import org.traccar.model.CellTower;
-import org.traccar.model.Network;
-import org.traccar.model.Position;
-import org.traccar.model.WifiAccessPoint;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.Channel;
-
-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;
-
-public class Gl200TextProtocolDecoder extends BaseProtocolDecoder {
-
- private boolean ignoreFixTime;
-
- public Gl200TextProtocolDecoder(Protocol protocol) {
- super(protocol);
-
- ignoreFixTime = Context.getConfig().getBoolean(getProtocolName() + ".ignoreFixTime");
- }
-
- private static final Pattern PATTERN_ACK = new PatternBuilder()
- .text("+ACK:GT")
- .expression("...,") // type
- .number("([0-9A-Z]{2}xxxx),") // protocol version
- .number("(d{15}|x{14}),") // imei
- .any().text(",")
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .number("(xxxx)") // counter
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_INF = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GTINF,")
- .number("[0-9A-Z]{2}xxxx,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("(?:[0-9A-Z]{17},)?") // vin
- .expression("(?:[^,]+)?,") // device name
- .number("(xx),") // state
- .expression("(?:[0-9Ff]{20})?,") // iccid
- .number("(d{1,2}),") // rssi
- .number("d{1,2},")
- .expression("[01],") // external power
- .number("([d.]+)?,") // odometer or external power
- .number("d*,") // backup battery or lightness
- .number("(d+.d+),") // battery
- .expression("([01]),") // charging
- .number("(?:d),") // led
- .number("(?:d)?,") // gps on need
- .number("(?:d)?,") // gps antenna type
- .number("(?:d)?,").optional() // gps antenna state
- .number("d{14},") // last fix time
- .groupBegin()
- .number("(d+),") // battery percentage
- .number("[d.]*,") // flash type / power
- .number("(-?[d.]+)?,,,") // temperature
- .or()
- .expression("(?:[01])?,").optional() // pin15 mode
- .number("(d+)?,") // adc1
- .number("(d+)?,").optional() // adc2
- .number("(xx)?,") // digital input
- .number("(xx)?,") // digital output
- .number("[-+]dddd,") // timezone
- .expression("[01],") // daylight saving
- .groupEnd()
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .number("(xxxx)") // counter
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_VER = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GTVER,")
- .number("[0-9A-Z]{2}xxxx,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .expression("([^,]*),") // device type
- .number("(xxxx),") // firmware version
- .number("(xxxx),") // hardware version
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd),") // time (hhmmss)
- .number("(xxxx)") // counter
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_LOCATION = new PatternBuilder()
- .number("(d{1,2})?,") // hdop
- .number("(d{1,3}.d)?,") // speed
- .number("(d{1,3})?,") // course
- .number("(-?d{1,5}.d)?,") // altitude
- .number("(-?d{1,3}.d{6})?,") // longitude
- .number("(-?d{1,2}.d{6})?,") // latitude
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(d+)?,") // mcc
- .number("(d+)?,") // mnc
- .groupBegin()
- .number("(d+),") // lac
- .number("(d+),") // cid
- .or()
- .number("(x+)?,") // lac
- .number("(x+)?,") // cid
- .groupEnd()
- .number("(?:d+|(d+.d))?,") // odometer
- .compile();
-
- private static final Pattern PATTERN_OBD = new PatternBuilder()
- .text("+RESP:GTOBD,")
- .number("[0-9A-Z]{2}xxxx,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("(?:[0-9A-Z]{17})?,") // vin
- .expression("[^,]{0,20},") // device name
- .expression("[01],") // report type
- .number("x{1,8},") // report mask
- .expression("(?:[0-9A-Z]{17})?,") // vin
- .number("[01],") // obd connect
- .number("(?:d{1,5})?,") // obd voltage
- .number("(?:x{8})?,") // support pids
- .number("(d{1,5})?,") // engine rpm
- .number("(d{1,3})?,") // speed
- .number("(-?d{1,3})?,") // coolant temp
- .number("(d+.?d*|Inf|NaN)?,") // fuel consumption
- .number("(d{1,5})?,") // dtcs cleared distance
- .number("(?:d{1,5})?,")
- .expression("([01])?,") // obd connect
- .number("(d{1,3})?,") // number of dtcs
- .number("(x*),") // dtcs
- .number("(d{1,3})?,") // throttle
- .number("(?:d{1,3})?,") // engine load
- .number("(d{1,3})?,") // fuel level
- .expression("(?:[0-9A],)?") // obd protocol
- .number("(d+),") // odometer
- .expression(PATTERN_LOCATION.pattern())
- .number("(d{1,7}.d)?,") // odometer
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_FRI = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GT...,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("(?:([0-9A-Z]{17}),)?") // vin
- .expression("[^,]*,") // device name
- .number("(d+)?,") // power
- .number("d{1,2},").optional() // report type
- .number("d{1,2},").optional() // count
- .number(",").optional() // reserved
- .number("(d+),").optional() // battery
- .expression("((?:")
- .expression(PATTERN_LOCATION.pattern())
- .expression(")+)")
- .groupBegin()
- .number("(d{1,7}.d)?,") // odometer
- .number("(d{5}:dd:dd)?,") // hour meter
- .number("(x+)?,") // adc 1
- .number("(x+)?,") // adc 2
- .number("(d{1,3})?,") // battery
- .number("(?:(xx)(xx)(xx))?,") // device status
- .number("(d+)?,") // rpm
- .number("(?:d+.?d*|Inf|NaN)?,") // fuel consumption
- .number("(d+)?,") // fuel level
- .or()
- .number("(d{1,7}.d)?,").optional() // odometer
- .number("(d{1,3})?,") // battery
- .groupEnd()
- .any()
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_ERI = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GTERI,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("(x{8}),") // mask
- .number("(d+)?,") // power
- .number("d{1,2},") // report type
- .number("d{1,2},") // count
- .expression("((?:")
- .expression(PATTERN_LOCATION.pattern())
- .expression(")+)")
- .number("(d{1,7}.d)?,") // odometer
- .number("(d{5}:dd:dd)?,") // hour meter
- .number("(x+)?,") // adc 1
- .number("(x+)?,").optional() // adc 2
- .number("(d{1,3})?,") // battery
- .number("(?:(xx)(xx)(xx))?,") // device status
- .expression("(.*)") // additional data
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_IGN = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GTIG[NF],")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("d+,") // ignition off duration
- .expression(PATTERN_LOCATION.pattern())
- .number("(d{5}:dd:dd)?,") // hour meter
- .number("(d{1,7}.d)?,") // odometer
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_LSW = new PatternBuilder()
- .text("+RESP:").expression("GT[LT]SW,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("[01],") // type
- .number("([01]),") // state
- .expression(PATTERN_LOCATION.pattern())
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_IDA = new PatternBuilder()
- .text("+RESP:GTIDA,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,,") // device name
- .number("([^,]+),") // rfid
- .expression("[01],") // report type
- .number("1,") // count
- .expression(PATTERN_LOCATION.pattern())
- .number("(d+.d),") // odometer
- .text(",,,,")
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_WIF = new PatternBuilder()
- .text("+RESP:GTWIF,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("(d+),") // count
- .number("((?:x{12},-?d+,,,,)+),,,,") // wifi
- .number("(d{1,3}),") // battery
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_GSM = new PatternBuilder()
- .text("+RESP:GTGSM,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("(?:STR|CTN|NMR|RTL),") // fix type
- .expression("(.*)") // cells
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_PNA = new PatternBuilder()
- .text("+RESP:GT").expression("P[NF]A,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF):GT...,")
- .number("(?:[0-9A-Z]{2}xxxx)?,") // protocol version
- .number("(d{15}|x{14}),") // imei
- .expression("[^,]*,") // device name
- .number("d*,")
- .number("(x{1,2}),") // report type
- .number("d{1,2},") // count
- .expression(PATTERN_LOCATION.pattern())
- .groupBegin()
- .number("(d{1,7}.d)?,").optional() // odometer
- .number("(d{1,3})?,") // battery
- .or()
- .number("(d{1,7}.d)?,") // odometer
- .groupEnd()
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)") // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private static final Pattern PATTERN_BASIC = new PatternBuilder()
- .text("+").expression("(?:RESP|BUFF)").text(":")
- .expression("GT...,")
- .number("(?:[0-9A-Z]{2}xxxx)?,").optional() // protocol version
- .number("(d{15}|x{14}),") // imei
- .any()
- .number("(d{1,2})?,") // hdop
- .number("(d{1,3}.d)?,") // speed
- .number("(d{1,3})?,") // course
- .number("(-?d{1,5}.d)?,") // altitude
- .number("(-?d{1,3}.d{6})?,") // longitude
- .number("(-?d{1,2}.d{6})?,") // latitude
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(d+),") // mcc
- .number("(d+),") // mnc
- .number("(x+),") // lac
- .number("(x+),").optional(4) // cell
- .any()
- .number("(dddd)(dd)(dd)") // date (yyyymmdd)
- .number("(dd)(dd)(dd)").optional(2) // time (hhmmss)
- .text(",")
- .number("(xxxx)") // count number
- .text("$").optional()
- .compile();
-
- private Object decodeAck(Channel channel, SocketAddress remoteAddress, String sentence, String type) {
- Parser parser = new Parser(PATTERN_ACK, sentence);
- if (parser.matches()) {
- String protocolVersion = parser.next();
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
- if (type.equals("HBD")) {
- if (channel != null) {
- parser.skip(6);
- channel.writeAndFlush(new NetworkMessage(
- "+SACK:GTHBD," + protocolVersion + "," + parser.next() + "$", remoteAddress));
- }
- } else {
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
- getLastLocation(position, parser.nextDateTime());
- position.setValid(false);
- position.set(Position.KEY_RESULT, "Command " + type + " accepted");
- return position;
- }
- }
- return null;
- }
-
- private Position initPosition(Parser parser, Channel channel, SocketAddress remoteAddress) {
- if (parser.matches()) {
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession != null) {
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
- return position;
- }
- }
- return null;
- }
-
- private void decodeDeviceTime(Position position, Parser parser) {
- if (parser.hasNext(6)) {
- if (ignoreFixTime) {
- position.setTime(parser.nextDateTime());
- } else {
- position.setDeviceTime(parser.nextDateTime());
- }
- }
- }
-
- private Long parseHours(String hoursString) {
- if (hoursString != null) {
- String[] hours = hoursString.split(":");
- return (long) (Integer.parseInt(hours[0]) * 3600
- + (hours.length > 1 ? Integer.parseInt(hours[1]) * 60 : 0)
- + (hours.length > 2 ? Integer.parseInt(hours[2]) : 0)) * 1000;
- }
- return null;
- }
-
- private Object decodeInf(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_INF, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- switch (parser.nextHexInt()) {
- case 0x16:
- case 0x1A:
- case 0x12:
- position.set(Position.KEY_IGNITION, false);
- position.set(Position.KEY_MOTION, true);
- break;
- case 0x11:
- position.set(Position.KEY_IGNITION, false);
- position.set(Position.KEY_MOTION, false);
- break;
- case 0x21:
- position.set(Position.KEY_IGNITION, true);
- position.set(Position.KEY_MOTION, false);
- break;
- case 0x22:
- position.set(Position.KEY_IGNITION, true);
- position.set(Position.KEY_MOTION, true);
- break;
- case 0x41:
- position.set(Position.KEY_MOTION, false);
- break;
- case 0x42:
- position.set(Position.KEY_MOTION, true);
- break;
- default:
- break;
- }
-
- position.set(Position.KEY_RSSI, parser.nextInt());
-
- parser.next(); // odometer or external power
-
- position.set(Position.KEY_BATTERY, parser.nextDouble());
- position.set(Position.KEY_CHARGE, parser.nextInt() == 1);
-
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- position.set(Position.PREFIX_TEMP + 1, parser.next());
-
- position.set(Position.PREFIX_ADC + 1, parser.next());
- position.set(Position.PREFIX_ADC + 2, parser.next());
-
- position.set(Position.KEY_INPUT, parser.next());
- position.set(Position.KEY_OUTPUT, parser.next());
-
- getLastLocation(position, parser.nextDateTime());
-
- position.set(Position.KEY_INDEX, parser.nextHexInt());
-
- return position;
- }
-
- private Object decodeVer(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_VER, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- position.set("deviceType", parser.next());
- position.set(Position.KEY_VERSION_FW, parser.nextHexInt());
- position.set(Position.KEY_VERSION_HW, parser.nextHexInt());
-
- getLastLocation(position, parser.nextDateTime());
-
- return position;
- }
-
- private void skipLocation(Parser parser) {
- parser.skip(19);
- }
-
- private void decodeLocation(Position position, Parser parser) {
- Integer hdop = parser.nextInt();
- position.setValid(hdop == null || hdop > 0);
- position.set(Position.KEY_HDOP, hdop);
-
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
- position.setAltitude(parser.nextDouble(0));
-
- if (parser.hasNext(8)) {
- position.setValid(true);
- position.setLongitude(parser.nextDouble());
- position.setLatitude(parser.nextDouble());
- position.setTime(parser.nextDateTime());
- } else {
- getLastLocation(position, null);
- }
-
- if (parser.hasNext(6)) {
- int mcc = parser.nextInt();
- int mnc = parser.nextInt();
- if (parser.hasNext(2)) {
- position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextInt(), parser.nextInt())));
- }
- if (parser.hasNext(2)) {
- position.setNetwork(new Network(CellTower.from(mcc, mnc, parser.nextHexInt(), parser.nextHexInt())));
- }
- }
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- }
- }
-
- private Object decodeObd(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_OBD, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- position.set(Position.KEY_RPM, parser.nextInt());
- position.set(Position.KEY_OBD_SPEED, parser.nextInt());
- position.set(Position.PREFIX_TEMP + 1, parser.nextInt());
- position.set(Position.KEY_FUEL_CONSUMPTION, parser.next());
- position.set("dtcsClearedDistance", parser.nextInt());
- if (parser.hasNext()) {
- position.set("odbConnect", parser.nextInt() == 1);
- }
- position.set("dtcsNumber", parser.nextInt());
- position.set("dtcsCodes", parser.next());
- position.set(Position.KEY_THROTTLE, parser.nextInt());
- position.set(Position.KEY_FUEL_LEVEL, parser.nextInt());
- if (parser.hasNext()) {
- position.set(Position.KEY_OBD_ODOMETER, parser.nextInt() * 1000);
- }
-
- decodeLocation(position, parser);
-
- if (parser.hasNext()) {
- position.set(Position.KEY_OBD_ODOMETER, (int) (parser.nextDouble() * 1000));
- }
-
- decodeDeviceTime(position, parser);
-
- return position;
- }
-
- private Object decodeCan(Channel channel, SocketAddress remoteAddress, String sentence) throws ParseException {
- Position position = new Position(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);
- long reportMaskExt = 0;
-
- 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)) {
- position.set(Position.KEY_OBD_ODOMETER, values[index++]);
- }
- if (BitUtil.check(reportMask, 3) && !values[index++].isEmpty()) {
- position.set(Position.KEY_FUEL_USED, Double.parseDouble(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 5) && !values[index++].isEmpty()) {
- position.set(Position.KEY_RPM, Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 4) && !values[index++].isEmpty()) {
- position.set(Position.KEY_OBD_SPEED, UnitsConverter.knotsFromKph(Integer.parseInt(values[index - 1])));
- }
- if (BitUtil.check(reportMask, 6) && !values[index++].isEmpty()) {
- position.set(Position.KEY_COOLANT_TEMP, Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 7) && !values[index++].isEmpty()) {
- position.set(Position.KEY_FUEL_CONSUMPTION, Double.parseDouble(values[index - 1].substring(1)));
- }
- if (BitUtil.check(reportMask, 8) && !values[index++].isEmpty()) {
- position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(values[index - 1].substring(1)));
- }
- if (BitUtil.check(reportMask, 9) && !values[index++].isEmpty()) {
- position.set("range", Long.parseLong(values[index - 1]) * 100);
- }
- if (BitUtil.check(reportMask, 10) && !values[index++].isEmpty()) {
- position.set(Position.KEY_THROTTLE, Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 11) && !values[index++].isEmpty()) {
- position.set(Position.KEY_HOURS, UnitsConverter.msFromHours(Double.parseDouble(values[index - 1])));
- }
- if (BitUtil.check(reportMask, 12)) {
- position.set("drivingHours", Double.parseDouble(values[index++]));
- }
- if (BitUtil.check(reportMask, 13)) {
- position.set("idleHours", Double.parseDouble(values[index++]));
- }
- if (BitUtil.check(reportMask, 14) && !values[index++].isEmpty()) {
- position.set("idleFuelConsumption", Double.parseDouble(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 15) && !values[index++].isEmpty()) {
- position.set(Position.KEY_AXLE_WEIGHT, Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 16) && !values[index++].isEmpty()) {
- position.set("tachographInfo", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 17) && !values[index++].isEmpty()) {
- position.set("indicators", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 18) && !values[index++].isEmpty()) {
- position.set("lights", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 19) && !values[index++].isEmpty()) {
- position.set("doors", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 20) && !values[index++].isEmpty()) {
- position.set("vehicleOverspeed", Double.parseDouble(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 21) && !values[index++].isEmpty()) {
- position.set("engineOverspeed", Double.parseDouble(values[index - 1]));
- }
- if (BitUtil.check(reportMask, 29)) {
- reportMaskExt = Long.parseLong(values[index++], 16);
- }
- if (BitUtil.check(reportMaskExt, 0) && !values[index++].isEmpty()) {
- position.set("adBlueLevel", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMaskExt, 1) && !values[index++].isEmpty()) {
- position.set("axleWeight1", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMaskExt, 2) && !values[index++].isEmpty()) {
- position.set("axleWeight3", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMaskExt, 3) && !values[index++].isEmpty()) {
- position.set("axleWeight4", Integer.parseInt(values[index - 1]));
- }
- if (BitUtil.check(reportMaskExt, 4)) {
- index += 1; // tachograph overspeed
- }
- if (BitUtil.check(reportMaskExt, 5)) {
- index += 1; // tachograph motion
- }
- if (BitUtil.check(reportMaskExt, 6)) {
- index += 1; // tachograph direction
- }
- if (BitUtil.check(reportMaskExt, 7) && !values[index++].isEmpty()) {
- position.set(Position.PREFIX_ADC + 1, Integer.parseInt(values[index - 1]) * 0.001);
- }
- if (BitUtil.check(reportMaskExt, 8)) {
- index += 1; // pedal breaking factor
- }
- if (BitUtil.check(reportMaskExt, 9)) {
- index += 1; // engine breaking factor
- }
- if (BitUtil.check(reportMaskExt, 10)) {
- index += 1; // total accelerator kick-downs
- }
- if (BitUtil.check(reportMaskExt, 11)) {
- index += 1; // total effective engine speed
- }
- if (BitUtil.check(reportMaskExt, 12)) {
- index += 1; // total cruise control time
- }
- if (BitUtil.check(reportMaskExt, 13)) {
- index += 1; // total accelerator kick-down time
- }
- if (BitUtil.check(reportMaskExt, 14)) {
- index += 1; // total brake application
- }
- if (BitUtil.check(reportMaskExt, 15) && !values[index++].isEmpty()) {
- position.set("driver1Card", values[index - 1]);
- }
- if (BitUtil.check(reportMaskExt, 16) && !values[index++].isEmpty()) {
- position.set("driver2Card", values[index - 1]);
- }
- if (BitUtil.check(reportMaskExt, 17) && !values[index++].isEmpty()) {
- position.set("driver1Name", values[index - 1]);
- }
- if (BitUtil.check(reportMaskExt, 18) && !values[index++].isEmpty()) {
- position.set("driver2Name", values[index - 1]);
- }
- if (BitUtil.check(reportMaskExt, 19) && !values[index++].isEmpty()) {
- position.set("registration", values[index - 1]);
- }
- if (BitUtil.check(reportMaskExt, 20)) {
- index += 1; // expansion information
- }
- if (BitUtil.check(reportMaskExt, 21)) {
- index += 1; // rapid brakings
- }
- if (BitUtil.check(reportMaskExt, 22)) {
- index += 1; // rapid accelerations
- }
- if (BitUtil.check(reportMaskExt, 23)) {
- index += 1; // engine torque
- }
-
- DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
- dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
-
- if (BitUtil.check(reportMask, 30)) {
- while (values[index].isEmpty()) {
- index += 1;
- }
- 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();
- if (BitUtil.check(ignition, 4)) {
- position.set(Position.KEY_IGNITION, false);
- } else if (BitUtil.check(ignition, 5)) {
- position.set(Position.KEY_IGNITION, true);
- }
- position.set(Position.KEY_INPUT, parser.nextHexInt());
- position.set(Position.KEY_OUTPUT, parser.nextHexInt());
- }
- }
-
- private Object decodeFri(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_FRI, sentence);
- if (!parser.matches()) {
- return null;
- }
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
-
- LinkedList<Position> positions = new LinkedList<>();
-
- String vin = parser.next();
- Integer power = parser.nextInt();
- Integer battery = parser.nextInt();
-
- Parser itemParser = new Parser(PATTERN_LOCATION, parser.next());
- while (itemParser.find()) {
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
-
- position.set(Position.KEY_VIN, vin);
-
- decodeLocation(position, itemParser);
-
- positions.add(position);
- }
-
- Position position = positions.getLast();
-
- skipLocation(parser);
-
- if (power != null && power > 10) {
- position.set(Position.KEY_POWER, power * 0.001); // only on some devices
- }
- if (battery != null) {
- position.set(Position.KEY_BATTERY_LEVEL, battery);
- }
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- }
- position.set(Position.KEY_HOURS, parseHours(parser.next()));
- position.set(Position.PREFIX_ADC + 1, parser.next());
- position.set(Position.PREFIX_ADC + 2, parser.next());
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- decodeStatus(position, parser);
-
- position.set(Position.KEY_RPM, parser.nextInt());
- position.set(Position.KEY_FUEL_LEVEL, parser.nextInt());
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- }
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- decodeDeviceTime(position, parser);
- if (ignoreFixTime) {
- positions.clear();
- positions.add(position);
- }
-
- return positions;
- }
-
- private Object decodeEri(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_ERI, sentence);
- if (!parser.matches()) {
- return null;
- }
-
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession == null) {
- return null;
- }
-
- long mask = parser.nextHexLong();
-
- LinkedList<Position> positions = new LinkedList<>();
-
- Integer power = parser.nextInt();
-
- Parser itemParser = new Parser(PATTERN_LOCATION, parser.next());
- while (itemParser.find()) {
- Position position = new Position(getProtocolName());
- position.setDeviceId(deviceSession.getDeviceId());
-
- decodeLocation(position, itemParser);
-
- positions.add(position);
- }
-
- Position position = positions.getLast();
-
- skipLocation(parser);
-
- if (power != null) {
- position.set(Position.KEY_POWER, power * 0.001);
- }
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- position.set(Position.KEY_HOURS, parseHours(parser.next()));
- position.set(Position.PREFIX_ADC + 1, parser.next());
- position.set(Position.PREFIX_ADC + 2, parser.next());
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- decodeStatus(position, parser);
-
- int index = 0;
- String[] data = parser.next().split(",");
-
- index += 1; // device type
-
- if (BitUtil.check(mask, 0)) {
- index += 1; // digital fuel sensor data
- }
-
- if (BitUtil.check(mask, 1)) {
- int deviceCount = Integer.parseInt(data[index++]);
- for (int i = 1; i <= deviceCount; i++) {
- index += 1; // id
- index += 1; // type
- if (!data[index++].isEmpty()) {
- position.set(Position.PREFIX_TEMP + i, (short) Integer.parseInt(data[index - 1], 16) * 0.0625);
- }
- }
- }
-
- if (BitUtil.check(mask, 2)) {
- index += 1; // can data
- }
-
- if (BitUtil.check(mask, 3) || BitUtil.check(mask, 4)) {
- int deviceCount = Integer.parseInt(data[index++]);
- for (int i = 1; i <= deviceCount; i++) {
- index += 1; // type
- if (BitUtil.check(mask, 3)) {
- position.set(Position.KEY_FUEL_LEVEL, Double.parseDouble(data[index++]));
- }
- if (BitUtil.check(mask, 4)) {
- index += 1; // volume
- }
- }
- }
-
- decodeDeviceTime(position, parser);
- if (ignoreFixTime) {
- positions.clear();
- positions.add(position);
- }
-
- return positions;
- }
-
- private Object decodeIgn(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_IGN, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- decodeLocation(position, parser);
-
- position.set(Position.KEY_IGNITION, sentence.contains("IGN"));
- position.set(Position.KEY_HOURS, parseHours(parser.next()));
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
-
- decodeDeviceTime(position, parser);
-
- return position;
- }
-
- private Object decodeLsw(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_LSW, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- position.set(Position.PREFIX_IN + (sentence.contains("LSW") ? 1 : 2), parser.nextInt() == 1);
-
- decodeLocation(position, parser);
-
- decodeDeviceTime(position, parser);
-
- return position;
- }
-
- private Object decodeIda(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_IDA, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- position.set(Position.KEY_DRIVER_UNIQUE_ID, parser.next());
-
- decodeLocation(position, parser);
-
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
-
- decodeDeviceTime(position, parser);
-
- return position;
- }
-
- private Object decodeWif(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_WIF, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- getLastLocation(position, null);
-
- Network network = new Network();
-
- parser.nextInt(); // count
- Matcher matcher = Pattern.compile("([0-9a-fA-F]{12}),(-?\\d+),,,,").matcher(parser.next());
- while (matcher.find()) {
- String mac = matcher.group(1).replaceAll("(..)", "$1:");
- network.addWifiAccessPoint(WifiAccessPoint.from(
- mac.substring(0, mac.length() - 1), Integer.parseInt(matcher.group(2))));
- }
-
- position.setNetwork(network);
-
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- return position;
- }
-
- private Object decodeGsm(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_GSM, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- getLastLocation(position, null);
-
- Network network = new Network();
-
- String[] data = parser.next().split(",");
- for (int i = 0; i < 6; i++) {
- if (!data[i * 6].isEmpty()) {
- network.addCellTower(CellTower.from(
- Integer.parseInt(data[i * 6]), Integer.parseInt(data[i * 6 + 1]),
- Integer.parseInt(data[i * 6 + 2], 16), Integer.parseInt(data[i * 6 + 3], 16),
- Integer.parseInt(data[i * 6 + 4])));
- }
- }
-
- position.setNetwork(network);
-
- return position;
- }
-
- private Object decodePna(Channel channel, SocketAddress remoteAddress, String sentence) {
- Parser parser = new Parser(PATTERN_PNA, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- getLastLocation(position, null);
-
- position.set(Position.KEY_ALARM, sentence.contains("PNA") ? Position.ALARM_POWER_ON : Position.ALARM_POWER_OFF);
-
- return position;
- }
-
- private Object decodeOther(Channel channel, SocketAddress remoteAddress, String sentence, String type) {
- Parser parser = new Parser(PATTERN, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- int reportType = parser.nextHexInt();
- if (type.equals("NMR")) {
- position.set(Position.KEY_MOTION, reportType == 1);
- } else if (type.equals("SOS")) {
- position.set(Position.KEY_ALARM, Position.ALARM_SOS);
- } else if (type.equals("DIS")) {
- position.set(Position.PREFIX_IN + reportType / 0x10, reportType % 0x10 == 1);
- } else if (type.equals("IGL")) {
- position.set(Position.KEY_IGNITION, reportType % 0x10 == 1);
- }
-
- decodeLocation(position, parser);
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- }
- position.set(Position.KEY_BATTERY_LEVEL, parser.nextInt());
-
- if (parser.hasNext()) {
- position.set(Position.KEY_ODOMETER, parser.nextDouble() * 1000);
- }
-
- decodeDeviceTime(position, parser);
-
- if (Context.getConfig().getBoolean(getProtocolName() + ".ack") && channel != null) {
- channel.writeAndFlush(new NetworkMessage("+SACK:" + parser.next() + "$", remoteAddress));
- }
-
- return position;
- }
-
- private Object decodeBasic(Channel channel, SocketAddress remoteAddress, String sentence, String type) {
- Parser parser = new Parser(PATTERN_BASIC, sentence);
- Position position = initPosition(parser, channel, remoteAddress);
- if (position == null) {
- return null;
- }
-
- if (parser.hasNext()) {
- int hdop = parser.nextInt();
- position.setValid(hdop > 0);
- position.set(Position.KEY_HDOP, hdop);
- }
-
- position.setSpeed(UnitsConverter.knotsFromKph(parser.nextDouble(0)));
- position.setCourse(parser.nextDouble(0));
- position.setAltitude(parser.nextDouble(0));
-
- if (parser.hasNext(2)) {
- position.setLongitude(parser.nextDouble());
- position.setLatitude(parser.nextDouble());
- } else {
- getLastLocation(position, null);
- }
-
- if (parser.hasNext(6)) {
- position.setTime(parser.nextDateTime());
- }
-
- if (parser.hasNext(4)) {
- position.setNetwork(new Network(CellTower.from(
- parser.nextInt(), parser.nextInt(), parser.nextHexInt(), parser.nextHexInt())));
- }
-
- decodeDeviceTime(position, parser);
-
- switch (type) {
- case "TOW":
- position.set(Position.KEY_ALARM, Position.ALARM_TOW);
- break;
- case "IDL":
- position.set(Position.KEY_ALARM, Position.ALARM_IDLE);
- break;
- case "PNA":
- position.set(Position.KEY_ALARM, Position.ALARM_POWER_ON);
- break;
- case "PFA":
- position.set(Position.KEY_ALARM, Position.ALARM_POWER_OFF);
- break;
- case "EPN":
- case "MPN":
- position.set(Position.KEY_ALARM, Position.ALARM_POWER_RESTORED);
- break;
- case "EPF":
- case "MPF":
- position.set(Position.KEY_ALARM, Position.ALARM_POWER_CUT);
- break;
- case "BPL":
- position.set(Position.KEY_ALARM, Position.ALARM_LOW_BATTERY);
- break;
- case "STT":
- position.set(Position.KEY_ALARM, Position.ALARM_MOVEMENT);
- break;
- case "SWG":
- position.set(Position.KEY_ALARM, Position.ALARM_GEOFENCE);
- break;
- case "TMP":
- case "TEM":
- position.set(Position.KEY_ALARM, Position.ALARM_TEMPERATURE);
- break;
- case "JDR":
- case "JDS":
- position.set(Position.KEY_ALARM, Position.ALARM_JAMMING);
- break;
- default:
- break;
- }
-
- return position;
- }
-
- @Override
- protected Object decode(
- Channel channel, SocketAddress remoteAddress, Object msg) throws Exception {
-
- String sentence = ((ByteBuf) msg).toString(StandardCharsets.US_ASCII);
-
- int typeIndex = sentence.indexOf(":GT");
- if (typeIndex < 0) {
- return null;
- }
-
- Object result;
- String type = sentence.substring(typeIndex + 3, typeIndex + 6);
- if (sentence.startsWith("+ACK")) {
- result = decodeAck(channel, remoteAddress, sentence, type);
- } else {
- switch (type) {
- case "INF":
- result = decodeInf(channel, remoteAddress, sentence);
- break;
- case "OBD":
- result = decodeObd(channel, remoteAddress, sentence);
- break;
- case "CAN":
- result = decodeCan(channel, remoteAddress, sentence);
- break;
- case "FRI":
- case "GEO":
- case "STR":
- result = decodeFri(channel, remoteAddress, sentence);
- break;
- case "ERI":
- result = decodeEri(channel, remoteAddress, sentence);
- break;
- case "IGN":
- case "IGF":
- result = decodeIgn(channel, remoteAddress, sentence);
- break;
- case "LSW":
- case "TSW":
- result = decodeLsw(channel, remoteAddress, sentence);
- break;
- case "IDA":
- result = decodeIda(channel, remoteAddress, sentence);
- break;
- case "WIF":
- result = decodeWif(channel, remoteAddress, sentence);
- break;
- case "GSM":
- result = decodeGsm(channel, remoteAddress, sentence);
- break;
- case "VER":
- result = decodeVer(channel, remoteAddress, sentence);
- break;
- case "PNA":
- case "PFA":
- result = decodePna(channel, remoteAddress, sentence);
- break;
- default:
- result = decodeOther(channel, remoteAddress, sentence, type);
- break;
- }
-
- if (result == null) {
- result = decodeBasic(channel, remoteAddress, sentence, type);
- }
-
- if (result != null) {
- if (result instanceof Position) {
- ((Position) result).set(Position.KEY_TYPE, type);
- } else {
- for (Position p : (List<Position>) result) {
- p.set(Position.KEY_TYPE, type);
- }
- }
- }
- }
-
- return result;
- }
-
-}