aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/org/traccar/protocol/MegastekProtocolDecoder.java203
-rw-r--r--test/org/traccar/protocol/MegastekProtocolDecoderTest.java10
2 files changed, 161 insertions, 52 deletions
diff --git a/src/org/traccar/protocol/MegastekProtocolDecoder.java b/src/org/traccar/protocol/MegastekProtocolDecoder.java
index f863df153..d014869d8 100644
--- a/src/org/traccar/protocol/MegastekProtocolDecoder.java
+++ b/src/org/traccar/protocol/MegastekProtocolDecoder.java
@@ -33,9 +33,7 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
super(serverManager);
}
- static private Pattern pattern = Pattern.compile(
- "STX," +
- "[^,]+," + // Identifier (not IMEI)
+ static private Pattern patternGPRMC = Pattern.compile(
"\\$GPRMC," +
"(\\d{2})(\\d{2})(\\d{2})\\.\\d+," + // Time (HHMMSS.SSS)
"([AV])," + // Validity
@@ -43,10 +41,12 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
"([NS])," +
"(\\d+)(\\d{2}\\.\\d+)," + // Longitude (DDDMM.MMMM)
"([EW])," +
- "(\\d+\\.\\d{2})?," + // Speed
- "(\\d+\\.\\d{2})?," + // Course
+ "(\\d+\\.\\d+)?," + // Speed
+ "(\\d+\\.\\d+)?," + // Course
"(\\d{2})(\\d{2})(\\d{2})" + // Date (DDMMYY)
- "[^\\*]+\\*[0-9a-fA-F]{2}," + // Checksumm
+ "[^\\*]+\\*[0-9a-fA-F]{2}"); // Checksum
+
+ static private Pattern patternSimple = Pattern.compile(
"[FL]," + // Flag
"([^,]*)," + // Alarm
"imei:(\\d+)," + // IMEI
@@ -56,25 +56,32 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
"(\\d)?," + // Charger
"(\\d+)," + // MCC
"(\\d+)," + // MNC
- "([0-9a-fA-F]+,[0-9a-fA-F]+);" + // Location code
- ".+"); // Checksumm
-
- @Override
- protected Object decode(
- ChannelHandlerContext ctx, Channel channel, Object msg)
- throws Exception {
+ "(\\p{XDigit}{4},\\p{XDigit}{4});" + // Location code
+ ".+"); // Checksum
- String sentence = (String) msg;
+ static private Pattern patternAlternative = Pattern.compile(
+ "(\\d+)," + // MCC
+ "(\\d+)," + // MNC
+ "(\\p{XDigit}{4},\\p{XDigit}{4})," + // Location code
+ "(\\d+)," + // GSM signal
+ "(\\d+)," + // Battery
+ "(\\d+)," + // Flags
+ "(\\d+)," + // Inputs
+ "(\\d+)," + // Outputs
+ "(\\d\\.\\d{2})," + // ADC 1
+ "(\\d\\.\\d{2})," + // ADC 2
+ "(\\d\\.\\d{2})," + // ADC 3
+ "([^;]+);" + // Alarm
+ ".+"); // Checksum
+ private boolean parseGPRMC(String gprmc, Position position) {
+
// Parse message
- Matcher parser = pattern.matcher(sentence);
+ Matcher parser = patternGPRMC.matcher(gprmc);
if (!parser.matches()) {
- return null;
+ return false;
}
- // Create new position
- Position position = new Position();
- ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("megastek");
int index = 1;
// Time
@@ -119,50 +126,146 @@ public class MegastekProtocolDecoder extends BaseProtocolDecoder {
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());
+ position.setTime(time.getTime());
- // Alarm
- extendedInfo.set("alarm", parser.group(index++));
+ return true;
+ }
+
+ @Override
+ protected Object decode(
+ ChannelHandlerContext ctx, Channel channel, Object msg)
+ throws Exception {
- // IMEI
- String imei = parser.group(index++);
- try {
- position.setDeviceId(getDataManager().getDeviceByImei(imei).getId());
- } catch(Exception error) {
- Log.warning("Unknown device - " + imei);
- return null;
+ String sentence = (String) msg;
+
+ // Detect type
+ boolean simple = (sentence.charAt(3) == ',');
+
+ // Split message
+ String id;
+ String gprmc;
+ String status;
+ if (simple) {
+
+ int beginIndex = 4;
+ int endIndex = sentence.indexOf(',', beginIndex);
+ id = sentence.substring(beginIndex, endIndex);
+
+ beginIndex = endIndex + 1;
+ endIndex = sentence.indexOf('*', beginIndex) + 3;
+ gprmc = sentence.substring(beginIndex, endIndex);
+
+ beginIndex = endIndex + 1;
+ status = sentence.substring(beginIndex);
+
+ } else {
+
+ int beginIndex = 3;
+ int endIndex = beginIndex + 16;
+ id = sentence.substring(beginIndex, endIndex).trim();
+
+ beginIndex = endIndex + 2;
+ endIndex = sentence.indexOf('*', beginIndex) + 3;
+ gprmc = sentence.substring(beginIndex, endIndex);
+
+ beginIndex = endIndex + 1;
+ status = sentence.substring(beginIndex);
+
}
- // Satellites
- String satellites = parser.group(index++);
- if (satellites != null) {
- extendedInfo.set("satellites", satellites);
+ // Create new position
+ Position position = new Position();
+ ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("megastek");
+
+ // Parse location data
+ if (!parseGPRMC(gprmc, position)) {
+ return null;
}
+
+ if (simple) {
- // Altitude
- position.setAltitude(Double.valueOf(parser.group(index++)));
+ // Parse status
+ Matcher parser = patternSimple.matcher(status);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ int index = 1;
- // Battery
- position.setPower(Double.valueOf(parser.group(index++)));
+ // Alarm
+ extendedInfo.set("alarm", parser.group(index++));
- // Charger
- String charger = parser.group(index++);
- if (charger != null) {
- extendedInfo.set("charger", Integer.valueOf(charger) == 1);
- }
+ // IMEI
+ String imei = parser.group(index++);
+ try {
+ position.setDeviceId(getDataManager().getDeviceByImei(imei).getId());
+ } catch(Exception firstError) {
+ try {
+ position.setDeviceId(getDataManager().getDeviceByImei(id).getId());
+ } catch(Exception secondError) {
+ Log.warning("Unknown device - " + imei + "(id - " + id + ")");
+ return null;
+ }
+ }
- // MCC
- extendedInfo.set("mcc", parser.group(index++));
+ // Satellites
+ String satellites = parser.group(index++);
+ if (satellites != null) {
+ extendedInfo.set("satellites", satellites);
+ }
- // MNC
- extendedInfo.set("mnc", parser.group(index++));
+ // Altitude
+ position.setAltitude(Double.valueOf(parser.group(index++)));
- // LAC
- extendedInfo.set("lac", parser.group(index++));
+ // Battery
+ position.setPower(Double.valueOf(parser.group(index++)));
- // Extended info
- position.setExtendedInfo(extendedInfo.toString());
+ // Charger
+ String charger = parser.group(index++);
+ if (charger != null) {
+ extendedInfo.set("charger", Integer.valueOf(charger) == 1);
+ }
+
+ extendedInfo.set("mcc", parser.group(index++));
+ extendedInfo.set("mnc", parser.group(index++));
+ extendedInfo.set("lac", parser.group(index++));
+
+ } else {
+ // Parse status
+ Matcher parser = patternAlternative.matcher(status);
+ if (!parser.matches()) {
+ return null;
+ }
+
+ int index = 1;
+
+ try {
+ position.setDeviceId(getDataManager().getDeviceByImei(id).getId());
+ } catch(Exception error) {
+ Log.warning("Unknown device - " + id);
+ return null;
+ }
+
+ extendedInfo.set("mcc", parser.group(index++));
+ extendedInfo.set("mnc", parser.group(index++));
+ extendedInfo.set("lac", parser.group(index++));
+ extendedInfo.set("gsm", parser.group(index++));
+
+ // Battery
+ position.setPower(Double.valueOf(parser.group(index++)));
+
+ extendedInfo.set("flags", parser.group(index++));
+ extendedInfo.set("input", parser.group(index++));
+ extendedInfo.set("output", parser.group(index++));
+ extendedInfo.set("adc1", parser.group(index++));
+ extendedInfo.set("adc2", parser.group(index++));
+ extendedInfo.set("adc3", parser.group(index++));
+ extendedInfo.set("alarm", parser.group(index++));
+
+ }
+
+ position.setExtendedInfo(extendedInfo.toString());
return position;
}
diff --git a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
index f4998d3f9..33ef6fe40 100644
--- a/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MegastekProtocolDecoderTest.java
@@ -10,16 +10,22 @@ public class MegastekProtocolDecoderTest {
MegastekProtocolDecoder decoder = new MegastekProtocolDecoder(null);
decoder.setDataManager(new TestDataManager());
-
+
assertNotNull(decoder.decode(null, null,
"STX,GerAL22,$GPRMC,174752.000,A,3637.060059,S,6416.2354,W,0.00,0.00,030812,,,A*55,F,,imei:861785000249353,05,180.6,Battery=100%,,1,722,310,0FA6,39D0;8F"));
-
+
assertNotNull(decoder.decode(null, null,
"STX,GerAL22,$GPRMC,000051.000,A,3637.079590,S,6416.2148,W,1.72,332.98,010109,,,A*52,L,,imei:861785000249353,03,275.3,Battery=68%,,1,722,07,0515,1413;41"));
assertNotNull(decoder.decode(null, null,
"STX,102110830074542,$GPRMC,114229.000,A,2238.2024,N,11401.9619,E,0.00,0.00,310811,,,A*64,F,LowBattery,imei:012207005553885,03,113.1,Battery=24%,,1,460,01,2531,647E;57"));
+ assertNotNull(decoder.decode(null, null,
+ "STX863070014949464 $GPRMC,215942.290,A,4200.1831,N,02128.5904,E,003.1,079.8,090813,,,A*6E,294,02,0064,0F3D,18,17,0000,000000,0000,0.00,0.02,0.00,Store;D8"));
+
+ assertNotNull(decoder.decode(null, null,
+ "STX123456 $GPRMC,063709.000,A,2238.1998,N,11401.9670,E,0.00,,250313,,,A*7F,460,01,2531,647E,11,87,1000,001001,0000,0.00,0.02,0.00,Timer;4A"));
+
}
}