aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java164
-rw-r--r--src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java20
-rw-r--r--src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java12
3 files changed, 83 insertions, 113 deletions
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
index 17298c6f3..544f1dc80 100644
--- a/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
+++ b/src/main/java/org/traccar/protocol/LaipacProtocolDecoder.java
@@ -30,11 +30,9 @@ import org.traccar.model.Device;
import org.traccar.model.Command;
import org.traccar.model.Network;
import org.traccar.model.Position;
-import org.traccar.database.ConnectionManager;
import java.net.SocketAddress;
import java.util.regex.Pattern;
-import java.util.Date;
public class LaipacProtocolDecoder extends BaseProtocolDecoder {
@@ -72,9 +70,11 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
.number(",(d)") // gps status
.number(",(d+)") // adc1
.number(",(d+)") // adc2
- .number(",(x{1}|x{8})") // lac+cid
- .number(",(d{1}|d{6})") // mcc+mnc
- .optional(2)
+ .number(",(x{4}|x{1})") // lac | lac+cid = 0
+ .number("(x{4})") // cid | nothing
+ .number(",(d{3}|d{1})") // mcc | mcc+mnc = 0
+ .number("(d{3})") // mnc | nothing
+ .optional(4)
.expression(",([^*]*)") // anything remaining (be forward compatible)
.optional(1)
.text("*")
@@ -140,28 +140,64 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
return devicePassword;
}
+ private String getEventResponse(String event, String devicePassword) {
+
+ String responseCode = null;
+
+ switch (event) {
+ case "3":
+ responseCode = "d";
+ break;
+ case "S":
+ case "T":
+ responseCode = "t";
+ break;
+ case "X":
+ case "4":
+ responseCode = "x";
+ break;
+ case "Y":
+ responseCode = "y";
+ break;
+ case "Z":
+ responseCode = "z";
+ break;
+ default:
+ break;
+ }
+
+ if (responseCode != null) {
+ String response = "$AVCFG," + devicePassword + "," + responseCode;
+ response += Checksum.nmea(response) + "\r\n";
+ return response;
+ }
+
+ return null;
+ }
+
+ private String getStatusResponse(String status, String event, String checksum) {
+
+ if (Character.isLowerCase(status.charAt(0))) {
+ String response = "$EAVACK," + event + "," + checksum;
+ response += Checksum.nmea(response) + "\r\n";
+ return response;
+ }
+
+ return null;
+ }
+
private Object handleEchk(
- String sentence, int checksum, Parser parser, Channel channel, SocketAddress remoteAddress) {
+ String sentence, Parser parser, Channel channel, SocketAddress remoteAddress) {
if (channel != null) {
channel.writeAndFlush(new NetworkMessage(sentence + "\r\n", remoteAddress));
}
- DeviceSession deviceSession =
- getDeviceSession(channel, remoteAddress, parser.next());
- if (deviceSession != null) {
- ConnectionManager cm = Context.getConnectionManager();
- if (cm != null) {
- cm.updateDevice(deviceSession.getDeviceId(),
- Device.STATUS_ONLINE, new Date());
- }
- }
-
return null;
}
protected Object handleAvrmc(
- String sentence, int checksum, Parser parser, Channel channel, SocketAddress remoteAddress) {
+ String sentence, Parser parser, Channel channel, SocketAddress remoteAddress) {
DeviceSession deviceSession =
getDeviceSession(channel, remoteAddress, parser.next());
@@ -171,97 +207,55 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
Position position = new Position(getProtocolName());
- // Device ID
position.setDeviceId(deviceSession.getDeviceId());
-
- // Time
DateBuilder dateBuilder = new DateBuilder()
.setTime(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
- // Status [ V: Invalid | A: Valid | R: Not realtime | P: Parked ]
String status = parser.next();
String upperCaseStatus = status.toUpperCase();
- position.setValid(upperCaseStatus.equals("A"));
+ position.setValid(upperCaseStatus.equals("A") || upperCaseStatus.equals("R") || upperCaseStatus.equals("P"));
position.set(Position.KEY_STATUS, status);
- // Position
position.setLatitude(parser.nextCoordinate());
position.setLongitude(parser.nextCoordinate());
-
- // Speed
position.setSpeed(parser.nextDouble(0));
-
- // Course
position.setCourse(parser.nextDouble(0));
- // Date
dateBuilder.setDateReverse(parser.nextInt(0), parser.nextInt(0), parser.nextInt(0));
position.setTime(dateBuilder.getDate());
- // Alarm / Event
String event = parser.next();
position.set(Position.KEY_ALARM, decodeAlarm(event));
position.set(Position.KEY_EVENT, decodeEvent(event, position));
-
- // Battery
position.set(Position.KEY_BATTERY, Double.parseDouble(parser.next().replaceAll("\\.", "")) * 0.001);
-
- // Odometer
position.set(Position.KEY_ODOMETER, parser.nextDouble());
-
- // GPS status
position.set(Position.KEY_GPS, parser.nextInt());
-
- // ADC1 / ADC2
position.set(Position.PREFIX_ADC + 1, parser.nextDouble() * 0.001);
position.set(Position.PREFIX_ADC + 2, parser.nextDouble() * 0.001);
- // LAC, CID, MCC, MNC
- Integer laccid = parser.nextHexInt();
- Integer mccmnc = parser.nextInt();
- if (laccid != null && laccid != 0 && mccmnc != null && mccmnc != 0) {
- Integer lac = (laccid >> 16) & 0xFFFF;
- Integer cid = laccid & 0xFFFF;
- Integer mcc = mccmnc / 10000;
- Integer mnc = mccmnc % 100;
+ Integer lac = parser.nextHexInt();
+ Integer cid = parser.nextHexInt();
+ Integer mcc = parser.nextInt();
+ Integer mnc = parser.nextInt();
+ if (lac != null && cid != null && mcc != null && mnc != null) {
position.setNetwork(new Network(CellTower.from(mcc, mnc, lac, cid)));
}
- // Skip remaining parameters
String unused = parser.next();
- // Checksum
- String checksumStr = parser.next();
- if (checksum != Integer.parseInt(checksumStr, 16)) {
- return null;
- }
+ String checksum = parser.next();
if (channel != null) {
- if (Character.isLowerCase(status.charAt(0))) {
- String ack = "$EAVACK," + event + "," + checksumStr;
- ack += Checksum.nmea(ack) + "\r\n";
- channel.writeAndFlush(new NetworkMessage(ack, remoteAddress));
+ String statusResponse = getStatusResponse(status, event, checksum);
+ if (statusResponse != null) {
+ channel.writeAndFlush(new NetworkMessage(statusResponse, remoteAddress));
}
- String response = "";
String devicePassword = getDevicePassword(deviceSession);
-
- if (event.equals("3")) {
- response = "$AVCFG," + devicePassword + ",d";
- } else if (event.equals("S") || event.equals("T")) {
- response = "$AVCFG," + devicePassword + ",t";
- } else if (event.equals("X") || event.equals("4")) {
- response = "$AVCFG," + devicePassword + ",x";
- } else if (event.equals("Y")) {
- response = "$AVCFG," + devicePassword + ",y";
- } else if (event.equals("Z")) {
- response = "$AVCFG," + devicePassword + ",z";
- }
-
- if (response.length() > 0) {
- response += Checksum.nmea(response) + "\r\n";
- channel.writeAndFlush(new NetworkMessage(response, remoteAddress));
+ String eventResponse = getEventResponse(event, devicePassword);
+ if (eventResponse != null) {
+ channel.writeAndFlush(new NetworkMessage(eventResponse, remoteAddress));
}
}
@@ -274,36 +268,14 @@ public class LaipacProtocolDecoder extends BaseProtocolDecoder {
String sentence = (String) msg;
- // Validate sentence length
- int slen = sentence.length();
- if (slen <= 5) {
- return null;
- }
-
- // Validate sentence format
- if (sentence.charAt(0) != '$') {
- return null;
- }
- if (sentence.charAt(slen - 3) != '*') {
- return null;
- }
-
- // Verify sentence checksum
- int checksum = Integer.parseInt(sentence.substring(slen - 2), 16);
- if (checksum != Checksum.xor(sentence.substring(1, slen - 3))) {
- return null;
- }
-
- // Handle ECHK sentences
Parser parser = new Parser(PATTERN_ECHK, sentence);
if (parser.matches()) {
- return handleEchk(sentence, checksum, parser, channel, remoteAddress);
+ return handleEchk(sentence, parser, channel, remoteAddress);
}
- // Handle AVRMC sentences
parser = new Parser(PATTERN_AVRMC, sentence);
if (parser.matches()) {
- return handleAvrmc(sentence, checksum, parser, channel, remoteAddress);
+ return handleAvrmc(sentence, parser, channel, remoteAddress);
}
return null;
diff --git a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
index 090203806..fac82d2fd 100644
--- a/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
+++ b/src/main/java/org/traccar/protocol/LaipacProtocolEncoder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015 - 2019 Anton Tananaev (anton@traccar.org)
+ * Copyright 2019 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.
@@ -15,7 +15,6 @@
*/
package org.traccar.protocol;
-import org.traccar.Context;
import org.traccar.Protocol;
import org.traccar.StringProtocolEncoder;
import org.traccar.model.Command;
@@ -28,8 +27,7 @@ public class LaipacProtocolEncoder extends StringProtocolEncoder {
public LaipacProtocolEncoder(Protocol protocol) {
this.protocol = protocol;
- defaultDevicePassword = Context.getConfig().getString(
- getProtocolName() + ".defaultPassword", "00000000");
+ defaultDevicePassword = "00000000";
}
protected String getProtocolName() {
@@ -41,28 +39,28 @@ public class LaipacProtocolEncoder extends StringProtocolEncoder {
initDevicePassword(command, defaultDevicePassword);
- String cmd = "";
+ String commandSentence = null;
switch (command.getType()) {
case Command.TYPE_CUSTOM:
- cmd = formatCommand(command, "${%s}",
+ commandSentence = formatCommand(command, "${%s}",
Command.KEY_DATA);
break;
case Command.TYPE_POSITION_SINGLE:
- cmd = formatCommand(command, "$AVREQ,{%s},1",
+ commandSentence = formatCommand(command, "$AVREQ,{%s},1",
Command.KEY_DEVICE_PASSWORD);
break;
case Command.TYPE_REBOOT_DEVICE:
- cmd = formatCommand(command, "$AVRESET,{%s},{%s}",
+ commandSentence = formatCommand(command, "$AVRESET,{%s},{%s}",
Command.KEY_UNIQUE_ID, Command.KEY_DEVICE_PASSWORD);
break;
default:
break;
}
- if (cmd.length() > 0) {
- cmd += Checksum.nmea(cmd) + "\r\n";
- return cmd;
+ if (commandSentence != null) {
+ commandSentence += Checksum.nmea(commandSentence) + "\r\n";
+ return commandSentence;
}
return null;
diff --git a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
index 1426e5c35..0bbb58490 100644
--- a/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
+++ b/src/test/java/org/traccar/protocol/LaipacProtocolDecoderTest.java
@@ -104,27 +104,27 @@ public class LaipacProtocolDecoderTest extends ProtocolTest {
verifyPosition(decoder, text(
"$AVRMC,999999999999999,084514,r,5050.1314,N,00419.9719,E,0.68,306.39,120318,0,3882,84,1,0,0,3EE4A617,020610*4D"));
- //Alarm button
+ // Alarm button
verifyPosition(decoder, text(
"$AVRMC,358174067149865,142945,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,3,3455,119,1,0,0,3EE4A617,020610*53"));
- //G-Sensor
+ // G-Sensor
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143407,R,5050.1254,N,00420.0490,E,0.00,0.00,190318,8,3455,119,1,0,0,3EE4A617,020610*52"));
- //Powered off
+ // Powered off
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143648,A,5050.1141,N,00420.0525,E,1.24,174.38,190318,H,3455,119,1,0,0,3EE4A617,020610*3E"));
- //No network
+ // No network
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143747,R,5050.1124,N,00420.0542,E,1.34,161.96,190318,a,3416,119,1,0,0*7D"));
- //Zero LAC, CID, MCC, MNC
+ // Zero LAC, CID, MCC, MNC
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0*5F"));
- //New unknown parameters
+ // New unknown parameters
verifyPosition(decoder, text(
"$AVRMC,358174067149865,143747,P,5050.1124,N,00420.0542,E,1.34,161.96,190318,A,3416,119,1,0,0,0,0,0,0*5F"));
}