package com.globalLock.location;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.ProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderAdapter;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import android.util.Log;
public class UniguardCodecFilter extends ProtocolCodecFilter {
// 鎵撳寘
public static IoBuffer makePacket(byte[] deviceNo, short command,
IoBuffer content) {
IoBuffer buffer = IoBuffer.allocate(2 + 2 + 6 + 2
+ (content == null ? 0 : content.remaining()) + 1);
buffer.put((byte) '&')
.put((byte) '&')
.putShort(
(short) (6 + 2 + (content == null ? 0 : content
.remaining()) + 1)).put(deviceNo)
.putShort(command);
if (content != null) {
buffer.put(content);
content.rewind();
}
return buffer.put(checksum(buffer, 4, buffer.position() - 1)).flip();
}
public static IoBuffer makePacket(Command command) {
return makePacket(command.getDeviceNoBuffer(), command.getCmd(),
command.getContent());
}
// 姹傚拰鏍¢獙
private static byte checksum(IoBuffer buffer, int startPos, int endPos) {
// System.out.println(String.format("from %d to %d", startPos, endPos
// ));
int sum = 0;
for (int i = startPos; i <= endPos; i++)
sum ^= buffer.get(i);
return (byte) (sum & 0xff);
}
// 瑙e寘
public static Command parsePacket(IoBuffer buff) {
// move to @, the head char
while (buff.hasRemaining() && buff.get() != (byte) '&')
;
while (buff.hasRemaining() && buff.get() != (byte) '&')
;
if (buff.limit() - buff.position() < 11) {// 鍖呬笉瀹屾暣
// System.err.println("鍖呬笉瀹屾暣1");
buff.position(buff.position() - 1);
return null;
}
int oldPos = buff.position() - 2;
// String s = buff.ToString();
int len = buff.getShort();
Command command = null;
byte[] bs = new byte[6];
buff.get(bs);
IoBuffer buffer = IoBuffer.allocate(8).putShort((short) 0).put(bs)
.rewind();
command = new Command(0, buffer.getLong(), buff.getShort());
if (len > 0) {
int oldLimit = buff.limit();
if (buff.position() - 6 - 2 + len > buff.limit()) { // 鍖呬笉瀹屾暣
// System.err.println("鍖呬笉瀹屾暣2 "
// + s
// +
// String.format("锟�s + %s + 2 > %s",
// buff.position(),
// len,
// buff.limit()));
buff.position(oldPos);
return null;
}
// System.out.println(buff.getHexDump());
buff.limit(buff.position() - 6 - 2 + len - 1);
command.setContent(buff.slice());
buff.position(buff.limit());
buff.limit(oldLimit);
// System.out.println(buff.getHexDump());
}
command.setBad(true);
if (checksum(buff, oldPos + 4, buff.position() - 1) != buff.get()) {
// System.err.println("鏍¢獙閿欒" + s);
}
else {
command.setBad(false);
}
return command;
}
// 杞箟
private static IoBuffer TranSend(IoBuffer in) {
IoBuffer out = IoBuffer.allocate(2048);
out.put(in.get());
out.put(in.get());
while (in.hasRemaining()) {
byte b = in.get();
if (b == 0x24) {
out.put((byte) 0x24);
out.put((byte) 0);
} else if (b == 0x26) {
out.put((byte) 0x24);
out.put((byte) 0x2);
} else
out.put(b);
}
out.flip();
return out;
}
public static IoBuffer TranRecv(IoBuffer in) {
IoBuffer out = IoBuffer.allocate(4096);
for (int i = 0; i < in.limit(); i++) {
if (in.get(i) == 0x24)
if (in.get(i + 1) == 0x00)
out.put(in.get(i++));
else if (in.get(i + 1) == 0x02) {
out.put((byte) 0x26);
i++;
} else
out.put(in.get(i));
else
out.put(in.get(i));
}
out.flip();
in.rewind();
in.put(out.slice()).flip();
return in;
}
public UniguardCodecFilter() {
super(new ProtocolCodecFactory() {
public ProtocolEncoder getEncoder(IoSession session)
throws Exception {
return new ProtocolEncoderAdapter() {
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
IoBuffer buffer = makePacket((Command) message);
Log.i("", "SEND HEX " + buffer.getHexDump());
out.write(TranSend(buffer));
}
};
}
public ProtocolDecoder getDecoder(IoSession session)
throws Exception {
return new ProtocolDecoderAdapter() {
public void decode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
Log.i("", session.getAttribute("userId") + " RECV HEX "
+ in.getHexDump());
// String s = in.getHexDump();
TranRecv(in);
Log.i("", session.getAttribute("userId")
+ " RECV HEX Tran " + in.getHexDump());
IoBuffer buff = in;
boolean continuous = session.getAttachment() != null;
if (continuous) {
// 濡備笂娆℃湁锟� 鍜屼笂娆$殑鍖呮帴璧锋潵瑙e寘
byte[] prevData = (byte[]) session.getAttachment();
IoBuffer newBuff = IoBuffer
.allocate(prevData.length + in.remaining());
newBuff.put(prevData).put(in).flip();
// System.err.println(session.getAttribute("userId")
// + " 鎺ヤ笂娆$殑锟�" + newBuff.getHexDump());
buff = newBuff;
}
// 瑙e寘
while (buff.hasRemaining()) {
Command cmd = parsePacket(buff);
if (cmd != null) {
out.write(cmd);
// if (cmd.isBad()) {
// System.err.println(session.getAttribute("userId")
// + " 鏀跺埌鍧忓寘");
// }
} else {
break;
}
}
// ...
if (continuous) {
if (!buff.hasRemaining()) {
// buff.release();
session.setAttachment(null);
} else {
byte[] remain = new byte[buff.remaining()];
buff.get(remain);
session.setAttachment(remain);
}
} else {
if (buff.hasRemaining()) {
// System.err.println(session.getAttribute("userId")
// + " 娌℃湁瑙e畬 " + s);
byte[] remain = new byte[in.remaining()];
in.get(remain);
session.setAttachment(remain);
}
}
}
};
}
});
}
}