aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2014-05-24 17:53:11 +1200
committerAnton Tananaev <anton.tananaev@gmail.com>2014-05-24 17:53:11 +1200
commitc93e2764fa214a58196561af93aba0037debb92e (patch)
treec7c1cd9d60deaa05f02ce1c04b0c2e0a0cdc2336
parentae84a13424be6bd55ddc12182554ba859b5dc786 (diff)
downloadtraccar-server-c93e2764fa214a58196561af93aba0037debb92e.tar.gz
traccar-server-c93e2764fa214a58196561af93aba0037debb92e.tar.bz2
traccar-server-c93e2764fa214a58196561af93aba0037debb92e.zip
Support XY006 extension (fix #709)
-rw-r--r--default.cfg1
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java125
-rw-r--r--test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java3
3 files changed, 85 insertions, 44 deletions
diff --git a/default.cfg b/default.cfg
index c0fe6cd1b..11f7d32e5 100644
--- a/default.cfg
+++ b/default.cfg
@@ -100,6 +100,7 @@
<!-- Meiligao server configuration -->
<entry key='meiligao.enable'>true</entry>
<entry key='meiligao.port'>5009</entry>
+ <!--<entry key='meiligao.server'>127.0.0.1:5009</entry>-->
<!-- Maxon server configuration -->
<entry key='maxon.enable'>true</entry>
diff --git a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
index c20dd53cf..aee6f8e1c 100644
--- a/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
+++ b/src/org/traccar/protocol/MeiligaoProtocolDecoder.java
@@ -15,14 +15,14 @@
*/
package org.traccar.protocol;
+import java.net.InetSocketAddress;
import java.nio.charset.Charset;
-import java.text.ParseException;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.HeapChannelBufferFactory;
+import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.traccar.BaseProtocolDecoder;
@@ -60,11 +60,21 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
"(?:\\|([0-9a-fA-F]+))?" + // Milage
".*"); // TODO: parse ADC
+
+ private static final int MSG_HEARTBEAT = 0x0001;
+ private static final int MSG_SERVER = 0x0002;
+ private static final int MSG_LOGIN = 0x5000;
+ private static final int MSG_LOGIN_RESPONSE = 0x5000;
+
+ private static final int MSG_POSITION = 0x9955;
+ private static final int MSG_POSITION_LOGGED = 0x9016;
+ private static final int MSG_ALARM = 0x9999;
+
private String getImei(ChannelBuffer buf) {
String id = "";
- for (int i = 4; i < 4 + 7; i++) {
- int b = buf.getUnsignedByte(i);
+ for (int i = 0; i < 7; i++) {
+ int b = buf.readUnsignedByte();
// First digit
int d1 = (b & 0xf0) >> 4;
@@ -82,6 +92,38 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
return id;
}
+
+ private static void sendResponse(
+ Channel channel, ChannelBuffer id, int type, ChannelBuffer msg) {
+
+ if (channel != null) {
+ ChannelBuffer buf = ChannelBuffers.buffer(
+ 2 + 2 + id.readableBytes() + 2 + msg.readableBytes() + 2 + 2);
+
+ buf.writeByte('@');
+ buf.writeByte('@');
+ buf.writeShort(buf.capacity());
+ buf.writeBytes(id);
+ buf.writeShort(type);
+ buf.writeBytes(msg);
+ buf.writeShort(Crc.crc16X25Ccitt(buf.toByteBuffer()));
+ buf.writeByte('\r');
+ buf.writeByte('\n');
+
+ channel.write(buf);
+ }
+ }
+
+ private String getMeiligaoServer(Channel channel) {
+
+ if (getServerManager() != null &&
+ getServerManager().getProperties().contains("meiligao.server")) {
+ return getServerManager().getProperties().getProperty("meiligao.server");
+ } else {
+ InetSocketAddress address = (InetSocketAddress) channel.getLocalAddress();
+ return address.getAddress().getHostAddress() + ":" + address.getPort();
+ }
+ }
@Override
protected Object decode(
@@ -89,53 +131,47 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
throws Exception {
ChannelBuffer buf = (ChannelBuffer) msg;
- int command = buf.getUnsignedShort(4 + 7);
-
- // Login confirmation
- if (command == 0x5000) {
- ChannelBuffer sendBuf = HeapChannelBufferFactory.getInstance().getBuffer(18);
- sendBuf.writeByte('@');
- sendBuf.writeByte('@');
- sendBuf.writeShort(sendBuf.capacity());
- byte[] array = new byte[7];
- buf.getBytes(0, array);
- sendBuf.writeBytes(array);
- sendBuf.writeShort(0x4000);
- sendBuf.writeByte(0x01);
- sendBuf.writeShort(Crc.crc16X25Ccitt(sendBuf.toByteBuffer()));
- sendBuf.writeByte('\r');
- sendBuf.writeByte('\n');
- if (channel != null) {
- channel.write(sendBuf);
- }
- return null;
+ buf.skipBytes(2); // header
+ buf.readShort(); // length
+ ChannelBuffer id = buf.readBytes(7);
+ int command = buf.readUnsignedShort();
+ ChannelBuffer response;
+
+ switch (command) {
+ case MSG_LOGIN:
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, id, MSG_LOGIN_RESPONSE, response);
+ break;
+ case MSG_HEARTBEAT:
+ response = ChannelBuffers.wrappedBuffer(new byte[] {0x01});
+ sendResponse(channel, id, MSG_HEARTBEAT, response);
+ break;
+ case MSG_SERVER:
+ response = ChannelBuffers.copiedBuffer(
+ getMeiligaoServer(channel), Charset.defaultCharset());
+ sendResponse(channel, id, MSG_SERVER, response);
+ break;
+ case MSG_POSITION:
+ case MSG_POSITION_LOGGED:
+ case MSG_ALARM:
+ break;
+ default:
+ return null;
}
- // Payload offset
- int offset = 4 + 7 + 2;
-
// Create new position
Position position = new Position();
ExtendedInfoFormatter extendedInfo = new ExtendedInfoFormatter("meiligao");
- // Alarm
- if (command == 0x9999) {
- extendedInfo.set("alarm", buf.getUnsignedByte(offset));
- }
-
- // Data offset
- if (command == 0x9955) {
- offset += 0;
- } else if (command == 0x9016) {
- offset += 6;
- } else if (command == 0x9999) {
- offset += 1;
- } else {
- return null;
+ // Custom data
+ if (command == MSG_ALARM) {
+ extendedInfo.set("alarm", buf.readUnsignedByte());
+ } else if (command == MSG_POSITION_LOGGED) {
+ buf.skipBytes(6);
}
// Get device by id
- String imei = getImei(buf);
+ String imei = getImei(id);
try {
position.setDeviceId(getDataManager().getDeviceByImei(imei).getId());
} catch(Exception error) {
@@ -144,10 +180,11 @@ public class MeiligaoProtocolDecoder extends BaseProtocolDecoder {
}
// Parse message
- String sentence = buf.toString(offset, buf.readableBytes() - offset - 4, Charset.defaultCharset());
+ String sentence = buf.toString(
+ buf.readerIndex(), buf.readableBytes() - 4, Charset.defaultCharset());
Matcher parser = pattern.matcher(sentence);
if (!parser.matches()) {
- throw new ParseException(null, 0);
+ return null;
}
Integer index = 1;
diff --git a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
index df08ece77..71f9289f2 100644
--- a/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
+++ b/test/org/traccar/protocol/MeiligaoProtocolDecoderTest.java
@@ -59,6 +59,9 @@ public class MeiligaoProtocolDecoderTest {
int[] buf15 = {0x24,0x24,0x00,0x50,0x35,0x78,0x42,0x51,0xff,0xff,0xff,0x99,0x55,0x30,0x30,0x30,0x30,0x33,0x36,0x2e,0x39,0x38,0x31,0x2c,0x56,0x2c,0x30,0x39,0x33,0x31,0x2e,0x33,0x34,0x37,0x31,0x2c,0x4e,0x2c,0x30,0x36,0x39,0x31,0x31,0x2e,0x38,0x34,0x31,0x32,0x2c,0x57,0x2c,0x2c,0x2c,0x32,0x38,0x30,0x31,0x31,0x34,0x2c,0x2c,0x2c,0x4e,0x2a,0x36,0x35,0x7c,0x7c,0x31,0x36,0x38,0x7c,0x32,0x30,0x30,0x30,0x5e,0x42,0x0d,0x0a};
verify(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(buf15))));
+
+ //assertNull(decoder.decode(null, null, ChannelBuffers.wrappedBuffer(ChannelBufferTools.convertArray(
+ // new int[] {0x24,0x24,0x00,0x11,0x30,0x06,0x00,0x00,0x00,0x46,0x09,0x00,0x02,0x84,0x9a,0x0d,0x0a}))));
}