package com.ifish.socketNew.codeFactory; import java.nio.charset.Charset; import com.ifish.socketNew.model.receive.BackFunctionCodeHeater; import org.apache.log4j.Logger; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.AttributeKey; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.codec.ProtocolDecoder; import org.apache.mina.filter.codec.ProtocolDecoderOutput; import com.ifish.socketNew.model.send.OrderFunctionCode0; import com.ifish.socketNew.model.send.OrderFunctionCode1; import com.ifish.socketNew.model.send.OrderFunctionCode16; import com.ifish.socketNew.model.send.OrderFunctionCode17; import com.ifish.socketNew.model.send.OrderFunctionCode5; import com.ifish.socketNew.model.send.OrderFunctionCode9; /** * 解码 * * @author */ public class ServerDecode implements ProtocolDecoder { private final AttributeKey CONTEXT = new AttributeKey(getClass(), "context"); private final Charset charset; private static Logger log = Logger.getLogger(ServerDecode.class); public ServerDecode() { this(Charset.defaultCharset()); } public ServerDecode(Charset charset) { this.charset = charset; } private Context getContext(IoSession session) { Context ctx = (Context) session.getAttribute(CONTEXT); if (ctx == null) { ctx = new Context(charset); session.setAttribute(CONTEXT, ctx); } return ctx; } @Override public void decode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception { // 小端模式 //in.order(ByteOrder.LITTLE_ENDIAN); // 先获取上次的处理上下文,其中可能有未处理完的数据 Context ctx = getContext(session); // 先把当前buffer中的数据追加到Context的buffer当中 ctx.append(in); IoBuffer buf = ctx.getBuffer(); buf.flip(); //验证 getValid(session, buf, out); } /** * 验证协议 * @param session * @param buf * @param out */ private void getValid(IoSession session, IoBuffer buf, ProtocolDecoderOutput out){ int limit = buf.remaining(); int check_code = buf.position(1).get() & 0xff; int length = buf.position(14).get() & 0xff; buf.position(0); //计算包长度 if (buf.hasRemaining() && limit == length && length >= 17) { //字节转成对象 doDecode(buf, out, length ,check_code); } else{ // log.info(String.format("length error:length:【%s】,limit:【%s】,HexDump:【%s】",length,limit,buf.getHexDump())); // log.info("length error:length:【{}】,limit:【{}】,HexDump:【{}】",length,limit,buf.getHexDump()); } buf.position(0); buf.clear(); } /** * 解码成对象 * @param buf * @param out * @param length */ private void doDecode(IoBuffer buf, ProtocolDecoderOutput out, int length, int check_code) { //字节 byte[] bytes = new byte[length]; buf.get(bytes); buf.flip(); // log.info("lengthth:【{}】;limit:【{}】,HexDump:【{}】",length,buf.limit(),buf.getHexDump()); //crc16校验 //boolean bln = CRC16.calcCrc16(ByteUtil.hexStringToBytes(hexDump)); switch (length) { case 31: { functionBackHeater(bytes,buf, out); break; }//长度为22 case 22:{ //设置报警温度 if(check_code==5){ functionCode5(buf, out); } //设备报警 else if(check_code==9){ functionCode9(buf, out); } //模块版本指令 else if(check_code==16){ functionCode16(buf, out); } else{ out.write(bytes); } break; } //长度为24,设备发登录请求 case 24:{ if(check_code==1){ functionCode1(buf, out); } else { out.write(bytes); } break; } //长度为25,手机发登录请求 case 25:{ if(check_code==0){ functionCode0(buf, out); } else { out.write(bytes); } break; } //模块版本指令 case 42:{ if(check_code==17){ functionCode17(buf, out); } else { out.write(bytes); } break; } default:{ out.write(bytes); } } } /** * 设备登陆服务器 * @param buf * @param out */ private void functionCode1(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode1 model = new OrderFunctionCode1(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //登陆信息 model.setVendor(buf.get()); model.setHardware_type(buf.get()); model.setVersion(buf.get()); byte[] login_ip = model.getLogin_ip(); for (int i = 0; i < login_ip.length; i++) { login_ip[i] = buf.get(); } model.setLogin_ip(login_ip); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } /** * APP登陆服务器 * @param buf * @param out */ private void functionCode0(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode0 model = new OrderFunctionCode0(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //时间 model.setLongtime(buf.getLong()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } /** * 设置报警温度 * @param buf * @param out */ private void functionCode5(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode5 model = new OrderFunctionCode5(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //开启关闭报警,00关,01开,02设置温度 model.setOnoff(buf.get()); //低温报警温度 model.setLow_wendu(buf.getShort()); //高温报警温度 model.setHight_wendu(buf.getShort()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } /** * 模块版本号 * @param buf * @param out */ private void functionCode16(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode16 model = new OrderFunctionCode16(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //版本 model.setVersion(buf.get()); //年 model.setYear(buf.getShort()); //月 model.setMonth(buf.get()); //日 model.setDay(buf.get()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } /** * 模块版本号 * @param buf * @param out */ private void functionCode17(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode17 model = new OrderFunctionCode17(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //版本 model.setVersion(buf.get()); //年 model.setYear(buf.getShort()); //月 model.setMonth(buf.get()); //日 model.setDay(buf.get()); //MCU启动次数 model.setNumber1(buf.getInt()); //模块启动次数 model.setNumber2(buf.getInt()); //连接路由器次数 model.setNumber3(buf.getInt()); //成功连接服务器次数 model.setNumber4(buf.getInt()); //尝试连接服务器次数 model.setNumber5(buf.getInt()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } /** * 设备温度报警 * @param buf * @param out */ private void functionCode9(IoBuffer buf, ProtocolDecoderOutput out) { OrderFunctionCode9 model = new OrderFunctionCode9(); //15字节数据包头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); //报警温度类型,0是低温报警,1是高温报警 model.setWarn_type(buf.get()); //当前设备温度 model.setWendu(buf.getShort()); //报警温度 model.setWarn_wendu(buf.getShort()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } private void functionBackHeater(byte[] bytes,IoBuffer buf, ProtocolDecoderOutput out){ BackFunctionCodeHeater model = new BackFunctionCodeHeater(); model.setByteMessage(bytes); buf.getHexDump(); //15字节头 model.setType(buf.get()); model.setCheck_code(buf.get()); byte[] src = model.getSrc(); for (int i = 0; i < src.length; i++) { src[i] = buf.get(); } model.setSrc(src); byte[] dest = model.getDest(); for (int i = 0; i < dest.length; i++) { dest[i] = buf.get(); } model.setDest(dest); model.setRemote_len(buf.get()); model.setMainNumber(buf.get()); model.setMainSwitch(buf.get()); model.setControlState(buf.get()); model.setWaterTemperature(buf.getShort()); model.setHeatingTemperature(buf.getShort()); model.setAlarmSwitch(buf.get()); model.setPh(buf.getShort()); model.setLowTemperature(buf.getShort()); model.setHighTemperature(buf.getShort()); byte[] crc16_code = model.getCrc16_code(); for (int i = 0; i < crc16_code.length; i++) { crc16_code[i] = buf.get(); } out.write(model); } @Override public void dispose(IoSession session) throws Exception { Context ctx = (Context) session.getAttribute(CONTEXT); if (ctx != null) { session.removeAttribute(CONTEXT); } } @Override public void finishDecode(IoSession session, ProtocolDecoderOutput out) throws Exception { } }