Finish Huabao protocol implementation

This commit is contained in:
Anton Tananaev
2015-11-17 11:36:08 +13:00
parent e4f936e973
commit 3471e62b0f
3 changed files with 118 additions and 5 deletions

View File

@@ -21,7 +21,6 @@ import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
import org.jboss.netty.handler.timeout.IdleStateEvent;
import org.traccar.helper.Log;

View File

@@ -16,10 +16,20 @@
package org.traccar.protocol;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.traccar.BaseProtocolDecoder;
import org.traccar.helper.BitUtil;
import org.traccar.helper.ChannelBufferTools;
import org.traccar.helper.Checksum;
import org.traccar.helper.DateBuilder;
import org.traccar.helper.UnitsConverter;
import org.traccar.model.Event;
import org.traccar.model.Position;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.util.TimeZone;
public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
@@ -27,7 +37,38 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
super(protocol);
}
public static final int MSG_GENERAL_RESPONSE = 0x8001;
public static final int MSG_TERMINAL_REGISTER = 0x0100;
public static final int MSG_TERMINAL_REGISTER_RESPONSE = 0x8100;
public static final int MSG_TERMINAL_AUTH = 0x0102;
public static final int MSG_LOCATION_REPORT = 0x0200;
public static final int RESULT_SUCCESS = 0;
private void sendResponse(
Channel channel, SocketAddress remoteAddress, int type, ChannelBuffer id, ChannelBuffer data) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
response.writeByte(0x7e);
response.writeShort(type);
response.writeShort(data.readableBytes());
response.writeBytes(id);
response.writeShort(1); // index
response.writeBytes(data);
response.writeByte(Checksum.xor(response.toByteBuffer(1, response.readableBytes() - 1)));
response.writeByte(0x7e);
if (channel != null) {
channel.write(response, remoteAddress);
}
}
private void sendGeneralResponse(
Channel channel, SocketAddress remoteAddress, ChannelBuffer id, int type, int index) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
response.writeShort(index);
response.writeShort(type);
response.writeByte(RESULT_SUCCESS);
sendResponse(channel, remoteAddress, MSG_GENERAL_RESPONSE, id, response);
}
@Override
protected Object decode(
@@ -36,10 +77,74 @@ public class HuabaoProtocolDecoder extends BaseProtocolDecoder {
ChannelBuffer buf = (ChannelBuffer) msg;
buf.readUnsignedByte(); // start marker
//int type = buf.readUnsignedShort();
//int flags = buf.readUnsignedShort();
buf.skipBytes(6); // phone number
buf.readUnsignedShort(); // index
int type = buf.readUnsignedShort();
buf.readUnsignedShort(); // body length
ChannelBuffer id = buf.readBytes(6); // phone number
int index = buf.readUnsignedShort();
if (!identify(id.toString(Charset.defaultCharset()), channel, remoteAddress)) {
return null;
}
if (type == MSG_TERMINAL_REGISTER) {
ChannelBuffer response = ChannelBuffers.dynamicBuffer();
response.writeShort(index);
response.writeByte(RESULT_SUCCESS);
response.writeBytes("authentication".getBytes(Charset.defaultCharset()));
sendResponse(channel, remoteAddress, MSG_TERMINAL_REGISTER_RESPONSE, id, response);
} else if (type == MSG_TERMINAL_AUTH) {
sendGeneralResponse(channel, remoteAddress, id, type, index);
} else if (type == MSG_LOCATION_REPORT) {
Position position = new Position();
position.setProtocol(getProtocolName());
position.setDeviceId(getDeviceId());
position.set(Event.KEY_ALARM, buf.readUnsignedInt());
int flags = buf.readInt();
position.set(Event.KEY_IGNITION, BitUtil.check(flags, 0));
position.setValid(BitUtil.check(flags, 1));
double lat = buf.readUnsignedInt() * 0.000001;
double lon = buf.readUnsignedInt() * 0.000001;
if (BitUtil.check(flags, 2)) {
position.setLatitude(-lat);
} else {
position.setLatitude(lat);
}
if (BitUtil.check(flags, 3)) {
position.setLongitude(-lon);
} else {
position.setLongitude(lon);
}
position.setAltitude(buf.readShort());
position.setSpeed(UnitsConverter.knotsFromKph(buf.readUnsignedShort() * 0.1));
position.setCourse(buf.readUnsignedShort());
DateBuilder dateBuilder = new DateBuilder(TimeZone.getTimeZone("GMT+8"))
.setYear(ChannelBufferTools.readHexInteger(buf, 2))
.setMonth(ChannelBufferTools.readHexInteger(buf, 2))
.setDay(ChannelBufferTools.readHexInteger(buf, 2))
.setHour(ChannelBufferTools.readHexInteger(buf, 2))
.setMinute(ChannelBufferTools.readHexInteger(buf, 2))
.setSecond(ChannelBufferTools.readHexInteger(buf, 2));
position.setTime(dateBuilder.getDate());
// additional information
return position;
}
return null;
}

View File

@@ -10,9 +10,18 @@ public class HuabaoProtocolDecoderTest extends ProtocolDecoderTest {
HuabaoProtocolDecoder decoder = new HuabaoProtocolDecoder(new HuabaoProtocol());
verifyNothing(decoder, binary(
"7E0100002D013511221122000500000000373031303748422D52303347424400000000000000000000003233363631303402CBD5424136383630387E"));
verifyNothing(decoder, binary(
"7e0100002d007089994489002800000000000000000048422d523033474244000000000000000000000031393036373531024142433030303030d17e"));
verifyNothing(decoder, binary(
"7E0102000E013511221122000661757468656E7469636174696F6E3F7E"));
verifyPosition(decoder, binary(
"7E02000032013511221122000700000000000C000301578CC006CA3A5C00470000000014072317201501040000000030011631010BD07E"));
}
}