aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/helper/Crc.java30
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java72
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java2
-rw-r--r--test/org/traccar/helper/CrcTest.java15
4 files changed, 57 insertions, 62 deletions
diff --git a/src/org/traccar/helper/Crc.java b/src/org/traccar/helper/Crc.java
index 213d1192a..418ec3132 100644
--- a/src/org/traccar/helper/Crc.java
+++ b/src/org/traccar/helper/Crc.java
@@ -154,21 +154,25 @@ public class Crc {
return String.format("*%02x", checksum).toUpperCase();
}
- public static String luhnChecksum(String s) {
- int sum = 0;
- boolean evenPosition = true;
- for (int i = s.length() - 1; i >= 0; i--) {
- int n = Integer.parseInt(s.substring(i, i + 1));
- if (evenPosition) {
- n *= 2;
- if (n > 9) {
- n = (n % 10) + 1;
+ public static long luhnChecksum(long imei) {
+ long checksum = 0;
+ long remain = imei;
+
+ for (int i = 0; remain != 0; i++) {
+ long digit = remain % 10;
+
+ if ((i % 2) == 0) {
+ digit *= 2;
+ if (digit >= 10) {
+ digit = 1 + (digit % 10);
}
}
- sum += n;
- evenPosition = !evenPosition;
+
+ checksum += digit;
+ remain /= 10;
}
- return String.valueOf(10 - sum % 10);
- }
+
+ return 10 - (checksum % 10);
+ }
}
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index 045eb2adc..573cccecf 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -26,6 +26,7 @@ import org.jboss.netty.channel.ChannelHandlerContext;
import org.traccar.BaseProtocolDecoder;
import org.traccar.Context;
import org.traccar.helper.ChannelBufferTools;
+import org.traccar.helper.Crc;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Event;
import org.traccar.model.Position;
@@ -40,68 +41,41 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
private static final long IMEI_BASE_TC65_V28 = 358244010000000L;
private static final long IMEI_BASE_TC65I_V11 = 0x14143B4000000L;
+ private static boolean validateImei(long imei) {
+ return Crc.luhnChecksum(imei / 10) == imei % 10;
+ }
+
private static long imeiFromUnitId(long unitId) {
- if(unitId == 0) {
- return 0L;
- } else if(unitId < 0x1000000) {
- // Assume TC65i.
+
+ if (unitId == 0) {
+
+ return 0;
+
+ } else {
+
+ // Try TC65i
long imei = IMEI_BASE_TC65I_V11 + unitId;
- if(validateImei(imei)) {
+ if (validateImei(imei)) {
return imei;
}
- // No? Maybe it's TC65 v2.8?
+ // Try TC65 v2.8
imei = IMEI_BASE_TC65_V28 + ((unitId + 0xA8180) & 0xFFFFFF);
- if(validateImei(imei)) {
+ if (validateImei(imei)) {
return imei;
}
- // Still no match? How about TC65 v2.0?
+ // Try TC65 v2.0
imei = IMEI_BASE_TC65_V20 + unitId;
- if(validateImei(imei)) {
+ if (validateImei(imei)) {
return imei;
}
- } else {
- // Unit ID is full IMEI, just check it.
- if(validateImei(unitId)) {
- return unitId;
- }
+
}
return unitId;
}
-
- private static boolean validateImei(long imei2) {
-
- int checksum = 0;
- long remain = imei2;
-
- // Iterate through all meaningful digits.
- for (int i = 0; remain != 0; i++) {
- // Extract the rightmost digit, that is, compute
- // imei modulo 10 (or remainder of imei / 10).
- int digit = (int) (remain % 10);
-
- // For each even-positioned digit, calculate the value
- // to be added to sum: Double the digit and then sum up
- // the digits of the result.
- // Example: 7 -> 2*7 = 14 -> 1 + 4 = 5
- if (0 != (i % 2)) {
- digit = digit * 2;
- if (digit >= 10) {
- digit = digit - 9;
- }
- }
- checksum = checksum + digit;
-
- // Remove the rightmost digit as it's already processed.
- remain = remain / 10;
- }
- // The IMEI is valid if the calculated checksum is dividable by 10.
- return 0 == (checksum % 10);
- }
-
private static final int DEFAULT_SELECTOR = 0x0002FC;
private static final int EVENT_DATA = 119;
@@ -115,12 +89,14 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
buf.readUnsignedByte(); // marker
int version = buf.readUnsignedByte();
+
+ String imei;
if ((version & 0x80) != 0) {
- buf.skipBytes(4); // unit id high
+ imei = String.valueOf((buf.readUnsignedInt() << (3 * 8)) | buf.readUnsignedMedium());
+ } else {
+ imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
}
- String imei = String.valueOf(imeiFromUnitId(buf.readUnsignedMedium()));
-
buf.readUnsignedShort(); // length
// Selector
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index f17d2e168..faa2f122e 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -89,7 +89,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
if (id.length() == 14) {
- id += Crc.luhnChecksum(id); // IMEI checksum
+ id += Crc.luhnChecksum(Long.valueOf(id)); // IMEI checksum
}
return id;
}
diff --git a/test/org/traccar/helper/CrcTest.java b/test/org/traccar/helper/CrcTest.java
new file mode 100644
index 000000000..46e7dfc79
--- /dev/null
+++ b/test/org/traccar/helper/CrcTest.java
@@ -0,0 +1,15 @@
+package org.traccar.helper;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CrcTest {
+
+ @Test
+ public void testLuhnChecksum() {
+
+ Assert.assertEquals(7, Crc.luhnChecksum(12345678901234L));
+
+ }
+
+}