aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol
diff options
context:
space:
mode:
authorShinryuken <watertext@hotmail.it>2017-11-19 11:22:31 +0100
committerGitHub <noreply@github.com>2017-11-19 11:22:31 +0100
commita5b273f8f8afd1a67613517c6487642601070456 (patch)
treebabc63f5d50977fc91b3946b1da2e86ec74c51a5 /src/org/traccar/protocol
parentc7928ef4a722cb40e9911c8e76e308fc48c85567 (diff)
parentfb9cbb2b74dc0060bd0dc5d0b3bfeb958ed6f3b5 (diff)
downloadtraccar-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.java4
-rw-r--r--src/org/traccar/protocol/GenxProtocolDecoder.java1
-rw-r--r--src/org/traccar/protocol/Gl200TextProtocolDecoder.java134
-rw-r--r--src/org/traccar/protocol/Ivt401Protocol.java45
-rw-r--r--src/org/traccar/protocol/Ivt401ProtocolDecoder.java97
-rw-r--r--src/org/traccar/protocol/Jt600ProtocolDecoder.java14
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java40
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java3
-rw-r--r--src/org/traccar/protocol/OkoProtocol.java45
-rw-r--r--src/org/traccar/protocol/OkoProtocolDecoder.java100
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;
+ }
+
+}