aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar/protocol')
-rw-r--r--src/org/traccar/protocol/MeiligaoProtocolDecoder.java125
1 files changed, 81 insertions, 44 deletions
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;