package com.tianze.jmsn.gps;
//import org.apache.log4j.Logger;
import org.apache.log4j.Logger;
import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;
/**
*
* @author wjp // 解码器
*/
public class AppliedServerDecoder implements MessageDecoder{
static Logger logger = Logger.getLogger(AppliedServerDecoder.class.getName());
//通过版本号与命令ID区分要用该解码器解析socket数据
public AppliedServerDecoder (){
}
/*
* 1 消息长度 2 消息的总长度(字节数),从第一个字节到最后一个字节。
3 协议版本号 1 当前为10H
4 IP 4 监控终端的IP地址
8 Port 2 监控终端的端口号
10 关键字 8 协议关键字(用户名)
18 点数 2 追踪的点数
20 预留 2 预留
22 车机类型 1 包括厂家和GSM/GPRS类型
23 命令序号 2 从0开始循环累加
25 命令ID 1
26 信息内容 — 不定长
*
(信息内容)1 消息长度 2 消息的总长度(字节数),从第一个字节到最后一个字节。
3 车载终端ID 5 第一个字节是车载终端的厂家编号(从20H~FFH),后四个字节是SIM卡号码(去掉第一个数字1)。
8 协议版本号 1 版本号为2
9 命令序号 2 从0开始循环累加
11 命令ID 1
12 信息内容 — 不定长
*/
public MessageDecoderResult decodable(IoSession session, ByteBuffer in) {
in.mark();
byte[] len = new byte[2];
in.get(len);
//数据包长度
int datalen = this.getNonSign(len[0])*256
+ this.getNonSign(len[1]) ;
in.reset();
if (in.remaining()>=datalen){ // 接收到足够的长度
return MessageDecoderResult.OK;
}
// 其他的情况认为不完整,需要继续接收数据
return MessageDecoderResult.NEED_DATA;
}
//真正解析socket数据
public MessageDecoderResult decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception {
while (true) {
in.mark();
byte[] len = new byte[2];
//数据包长度
int datalen =0;
if (in.remaining()>=2) {
in.get(len);
datalen = this.getNonSign(len[0])*256
+ this.getNonSign(len[1]);
if(datalen==0) {
throw new Exception("包长度为零错误");
}
in.reset();
}else if(in.remaining()==0) {
return MessageDecoderResult.OK;
}else {
return MessageDecoderResult.NEED_DATA;
}
if(datalen==0) {
throw new Exception("包长度为零错误");
}
if (in.remaining()>=datalen){ // 接收到足够的长度
byte[] data=new byte[datalen];
in.get(data);
ByteBuffer bf=ByteBuffer.wrap(data);
out.write(bf);
}else {
return MessageDecoderResult.NEED_DATA;
}
}
}
protected int getNonSign(byte Sign) {
if (Sign < 0) {
return (Sign + 256);
} else {
return Sign;
}
}
public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception {
logger.debug("完成解码");
}
}