aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java238
-rw-r--r--test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java6
2 files changed, 161 insertions, 83 deletions
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index 4df757d22..97cafa172 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -60,7 +60,15 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
"(\\p{XDigit}{9})" + // Odometer
"(?:\\|(\\p{XDigit}{5,}))?)?)?)?)?" + // RFID
".*");
-
+
+ private static final Pattern rfidPattern = Pattern.compile(
+ "\\|(\\d{2})(\\d{2})(\\d{2})," + // Time (HHMMSS)
+ "(\\d{2})(\\d{2})(\\d{2})," + // Date (DDMMYY)
+ "(\\d+)(\\d{2}\\.\\d+)," + // Latitude (DDMM.MMMM)
+ "([NS])," +
+ "(\\d+)(\\d{2}\\.\\d+)," + // Longitude (DDDMM.MMMM)
+ "([EW])");
+
private static final int MSG_HEARTBEAT = 0x0001;
private static final int MSG_SERVER = 0x0002;
private static final int MSG_LOGIN = 0x5000;
@@ -69,6 +77,8 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
private static final int MSG_POSITION = 0x9955;
private static final int MSG_POSITION_LOGGED = 0x9016;
private static final int MSG_ALARM = 0x9999;
+
+ private static final int MSG_RFID = 0x9966;
private String getImei(ChannelBuffer buf) {
String id = "";
@@ -90,6 +100,9 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
if (id.length() == 14) {
id += Crc.luhnChecksum(Long.valueOf(id)); // IMEI checksum
}
+ if (id.length() > 15) {
+ id = id.substring(0, 15);
+ }
return id;
}
@@ -123,6 +136,27 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
return server;
}
+ private Position decodeRfid(Position position, ChannelBuffer buf) {
+
+ for (int i = 0; i < 15; i++) {
+ long rfid = buf.readUnsignedInt();
+ if (rfid != 0) {
+ position.set(Event.KEY_RFID, String.format("%010d", rfid));
+ }
+ }
+
+ // Parse message
+ String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, Charset.defaultCharset());
+ Matcher parser = pattern.matcher(sentence);
+ if (!parser.matches()) {
+ return null;
+ }
+ Integer index = 1;
+
+
+ return position;
+ }
+
@Override
protected Object decode(
Channel channel, SocketAddress remoteAddress, Object msg)
@@ -158,6 +192,7 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
case MSG_POSITION:
case MSG_POSITION_LOGGED:
case MSG_ALARM:
+ case MSG_RFID:
break;
default:
return null;
@@ -180,105 +215,142 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
position.setDeviceId(getDeviceId());
+ // RFID
+ if (command == MSG_RFID) {
+ for (int i = 0; i < 15; i++) {
+ long rfid = buf.readUnsignedInt();
+ if (rfid != 0) {
+ position.set(Event.KEY_RFID, String.format("%010d", rfid));
+ }
+ }
+ }
+
// Parse message
- String sentence = buf.toString(
- buf.readerIndex(), buf.readableBytes() - 4, Charset.defaultCharset());
- Matcher parser = pattern.matcher(sentence);
+ String sentence = buf.toString(buf.readerIndex(), buf.readableBytes() - 4, Charset.defaultCharset());
+ Matcher parser = (command == MSG_RFID ? rfidPattern : pattern).matcher(sentence);
if (!parser.matches()) {
return null;
}
-
Integer index = 1;
- // Time
- Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- time.clear();
- time.set(Calendar.HOUR_OF_DAY, Integer.valueOf(parser.group(index++)));
- time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++)));
- time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++)));
- String mseconds = parser.group(index++);
- if (mseconds != null) {
- time.set(Calendar.MILLISECOND, Integer.valueOf(mseconds));
- }
+ if (command == MSG_RFID) {
- // Validity
- position.setValid(parser.group(index++).compareTo("A") == 0);
-
- // Latitude
- Double latitude = Double.valueOf(parser.group(index++));
- latitude += Double.valueOf(parser.group(index++)) / 60;
- if (parser.group(index++).compareTo("S") == 0) latitude = -latitude;
- position.setLatitude(latitude);
-
- // Longitude
- Double longitude = Double.valueOf(parser.group(index++));
- longitude += Double.valueOf(parser.group(index++)) / 60;
- if (parser.group(index++).compareTo("W") == 0) longitude = -longitude;
- position.setLongitude(longitude);
-
- // Speed
- String speed = parser.group(index++);
- if (speed != null) {
- position.setSpeed(Double.valueOf(speed));
- }
+ // Time and date
+ Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ time.clear();
+ time.set(Calendar.HOUR_OF_DAY, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1);
+ time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++)));
+ position.setTime(time.getTime());
- // Course
- String course = parser.group(index++);
- if (course != null) {
- position.setCourse(Double.valueOf(course));
- }
+ // Latitude
+ Double latitude = Double.valueOf(parser.group(index++));
+ latitude += Double.valueOf(parser.group(index++)) / 60;
+ if (parser.group(index++).compareTo("S") == 0) latitude = -latitude;
+ position.setLatitude(latitude);
- // Date
- time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++)));
- time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1);
- time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++)));
- position.setTime(time.getTime());
+ // Longitude
+ Double longitude = Double.valueOf(parser.group(index++));
+ longitude += Double.valueOf(parser.group(index++)) / 60;
+ if (parser.group(index++).compareTo("W") == 0) longitude = -longitude;
+ position.setLongitude(longitude);
- // HDOP
- position.set(Event.KEY_HDOP, parser.group(index++));
+ } else {
- // Altitude
- String altitude = parser.group(index++);
- if (altitude != null) {
- position.setAltitude(Double.valueOf(altitude));
- }
+ // Time
+ Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ time.clear();
+ time.set(Calendar.HOUR_OF_DAY, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.MINUTE, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.SECOND, Integer.valueOf(parser.group(index++)));
+ String mseconds = parser.group(index++);
+ if (mseconds != null) {
+ time.set(Calendar.MILLISECOND, Integer.valueOf(mseconds));
+ }
- // State
- String state = parser.group(index++);
- if (state != null) {
- position.set(Event.KEY_STATUS, state);
- }
+ // Validity
+ position.setValid(parser.group(index++).compareTo("A") == 0);
+
+ // Latitude
+ Double latitude = Double.valueOf(parser.group(index++));
+ latitude += Double.valueOf(parser.group(index++)) / 60;
+ if (parser.group(index++).compareTo("S") == 0) latitude = -latitude;
+ position.setLatitude(latitude);
- // ADC
- for (int i = 1; i <= 8; i++) {
- String adc = parser.group(index++);
- if (adc != null) {
- position.set(Event.PREFIX_ADC + i, Integer.parseInt(adc, 16));
+ // Longitude
+ Double longitude = Double.valueOf(parser.group(index++));
+ longitude += Double.valueOf(parser.group(index++)) / 60;
+ if (parser.group(index++).compareTo("W") == 0) longitude = -longitude;
+ position.setLongitude(longitude);
+
+ // Speed
+ String speed = parser.group(index++);
+ if (speed != null) {
+ position.setSpeed(Double.valueOf(speed));
}
- }
- // Cell identifier
- position.set(Event.KEY_CELL, parser.group(index++));
+ // Course
+ String course = parser.group(index++);
+ if (course != null) {
+ position.setCourse(Double.valueOf(course));
+ }
- // GSM signal
- String gsm = parser.group(index++);
- if (gsm != null) {
- position.set(Event.KEY_GSM, Integer.parseInt(gsm, 16));
- }
+ // Date
+ time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(parser.group(index++)));
+ time.set(Calendar.MONTH, Integer.valueOf(parser.group(index++)) - 1);
+ time.set(Calendar.YEAR, 2000 + Integer.valueOf(parser.group(index++)));
+ position.setTime(time.getTime());
+
+ // HDOP
+ position.set(Event.KEY_HDOP, parser.group(index++));
+
+ // Altitude
+ String altitude = parser.group(index++);
+ if (altitude != null) {
+ position.setAltitude(Double.valueOf(altitude));
+ }
+
+ // State
+ String state = parser.group(index++);
+ if (state != null) {
+ position.set(Event.KEY_STATUS, state);
+ }
+
+ // ADC
+ for (int i = 1; i <= 8; i++) {
+ String adc = parser.group(index++);
+ if (adc != null) {
+ position.set(Event.PREFIX_ADC + i, Integer.parseInt(adc, 16));
+ }
+ }
+
+ // Cell identifier
+ position.set(Event.KEY_CELL, parser.group(index++));
+
+ // GSM signal
+ String gsm = parser.group(index++);
+ if (gsm != null) {
+ position.set(Event.KEY_GSM, Integer.parseInt(gsm, 16));
+ }
+
+ // Odometer
+ String odometer = parser.group(index++);
+ if (odometer == null) {
+ odometer = parser.group(index++);
+ }
+ if (odometer != null) {
+ position.set(Event.KEY_ODOMETER, Integer.parseInt(odometer, 16));
+ }
+
+ // RFID
+ String rfid = parser.group(index++);
+ if (rfid != null) {
+ position.set(Event.KEY_RFID, Integer.parseInt(rfid, 16));
+ }
- // Odometer
- String odometer = parser.group(index++);
- if (odometer == null) {
- odometer = parser.group(index++);
- }
- if (odometer != null) {
- position.set(Event.KEY_ODOMETER, Integer.parseInt(odometer, 16));
- }
-
- // RFID
- String rfid = parser.group(index++);
- if (rfid != null) {
- position.set(Event.KEY_RFID, Integer.parseInt(rfid, 16));
}
return position;
diff --git a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
index d0fdebc03..1c4252c0f 100644
--- a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
@@ -13,6 +13,12 @@ public class MeiligaoProtocolDecoderTest extends ProtocolDecoderTest {
MeiligaoProtocolDecoder decoder = new MeiligaoProtocolDecoder(new MeiligaoProtocol());
+ verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString(
+ "24240074630700194707719966009E1F7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007C3132303334302C3238303630362C323430302E303030302C4E2C31323130302E303030302C458F7E0D0A"))));
+
+ verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString(
+ "24240076220720151fffff99660012b3ab00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007c3135303634382c3233303731352c313931352e37323835362c4e2c30373235322e35333034342c456dd00d0a"))));
+
assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertHexString(
"24240000123456FFFFFFFF50008B9B0D0A"))));