package com.example.agvcontroller.protocol;
|
|
|
import static com.example.agvcontroller.utils.DateUtils.formatDate;
|
|
import android.util.Log;
|
|
import com.example.agvcontroller.AGVApplication;
|
import com.example.agvcontroller.socket.RadixTools;
|
|
import org.greenrobot.eventbus.EventBus;
|
|
import java.net.InetSocketAddress;
|
import java.util.Date;
|
import java.util.logging.Logger;
|
|
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBufUtil;
|
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.handler.codec.MessageToByteEncoder;
|
|
/**
|
* 编码器
|
* 此解码器将会生成校验码
|
* 处理方式: 异或和
|
* Created by vincent on 2019-04-02
|
*/
|
//@Component
|
@ChannelHandler.Sharable
|
public class ProtocolEncoder extends MessageToByteEncoder<Object> {
|
|
//private static final Logger log = LoggerFactory.getLogger(ProtocolEncoder.class);
|
|
//@Autowired
|
private SystemProperties systemProperties;
|
|
@Override
|
protected void encode(ChannelHandlerContext ctx, Object obj, ByteBuf out) {
|
InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
|
String ip = remoteAddress.getAddress().getHostAddress();
|
|
if (obj instanceof ByteBuf){
|
out.writeBytes((ByteBuf) obj);
|
|
} else if (obj instanceof byte[]){
|
// out.writeBytes((byte[]) obj);
|
|
out.writeBytes((byte[]) new byte[]{
|
0x0D, 0x0A
|
});
|
} else if (obj instanceof AgvAction<?>){
|
|
|
AgvAction action = (AgvAction)obj;
|
|
String uniqueNo = action.getAgvNo();
|
|
byte[] uniqueNoBytes = RadixTools.intToBytes(Integer.parseInt(uniqueNo)); // uniqueno
|
|
byte[] bodyBytes = action.writeToBytes();
|
|
|
int len = PackagePart.UNIQUENO.getLen() // len
|
+ PackagePart.TIMESTAMP.getLen()
|
+ PackagePart.COMMAND_MARK.getLen()
|
+ bodyBytes.length;
|
|
out.writeByte((byte)0xEE) // symbol
|
.writeShortLE(len)
|
.writeBytes(Utils.reverse(uniqueNoBytes)) // uniqueno
|
.writeIntLE((int) (System.currentTimeMillis() / 1000)) // timestamp
|
.writeByte(ProtocolPojoType.ACTION_COMMAND.protocolType.getCode()) // type
|
.writeBytes(bodyBytes) // body
|
.writeShort((short)0) // valid
|
;
|
|
int validCode = ValidUtil.calculateValidByteFromBuff(out);
|
out.resetReaderIndex();
|
|
out.writerIndex(out.readableBytes() - 2);
|
out.writeShortLE(validCode);
|
// 生成整个报文的字节数组
|
byte[] buffer = new byte[out.readableBytes()];
|
out.getBytes(out.readerIndex(), buffer);
|
|
// 将字节数组转换为 16 进制字符串
|
String hexMessage = bytesToHex(buffer);
|
String log = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss") + " 下行: " + ip + "[" + action.getHandleCmdType().getDesc() + "]>>>" + hexMessage;
|
Log.d("updown", log);
|
AGVApplication.addLog(log);
|
// EventBus.getDefault().post(log);
|
} else if (obj instanceof AgvPackage){
|
|
AgvPackage pac = (AgvPackage)obj;
|
|
|
|
byte[] bodyBytes = pac.getBody().getMessageBody().writeToBytes(); // body
|
|
//String uniqueNo = pac.getHeader().getUniqueNo();
|
|
byte[] uniquenoBytes = RadixTools.intToBytes(Integer.parseInt(pac.getHeader().getUniqueNo())); // uniqueno
|
|
|
int len = PackagePart.UNIQUENO.getLen() // len
|
+ PackagePart.TIMESTAMP.getLen()
|
+ PackagePart.COMMAND_MARK.getLen()
|
+ bodyBytes.length;
|
|
out.writeByte(pac.getHeader().getStartSymbol()) // symbol
|
.writeShortLE(len)
|
.writeBytes(Utils.reverse(uniquenoBytes)) // uniqueno
|
.writeIntLE((int) (System.currentTimeMillis() / 1000)) // timestamp
|
.writeByte(pac.getHeader().getProtocolType().getCode()) // type
|
.writeBytes(bodyBytes) // body
|
.writeShort(pac.getValidCode()) // valid
|
;
|
|
pac.setValidCode(ValidUtil.calculateValidByteFromBuff(out));
|
out.resetReaderIndex();
|
|
out.writerIndex(out.readableBytes() - 2);
|
out.writeShortLE(pac.getValidCode());
|
// 生成整个报文的字节数组
|
byte[] buffer = new byte[out.readableBytes()];
|
out.getBytes(out.readerIndex(), buffer);
|
|
// 将字节数组转换为 16 进制字符串
|
String hexMessage = bytesToHex(buffer);
|
String log = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss") + " 下行: " + ip + "[" + pac.getHeader().getProtocolType().getDes() + "]>>>" + hexMessage;
|
Log.d("updown", log);
|
AGVApplication.addLog(log);
|
// EventBus.getDefault().post(log);
|
}
|
|
|
}
|
|
private String bytesToHex(byte[] bytes) {
|
StringBuilder sb = new StringBuilder();
|
for (byte b : bytes) {
|
sb.append(String.format("%02X", b));
|
}
|
return sb.toString();
|
}
|
|
// 将十六进制字符串转换为字节数组
|
private byte[] hexStringToByteArray(String s) {
|
int len = s.length();
|
byte[] data = new byte[len / 2];
|
for (int i = 0; i < len; i += 2) {
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
+ Character.digit(s.charAt(i+1), 16));
|
}
|
return data;
|
}
|
|
// EE | 11 00 | 01 00 00 00 | 0C AB 12 64 | F0 | 01 00 | 01 01 | 00 00 00 00 | 4C F7
|
// # | len | uniqueno | timestamp | cmd | content | crc
|
|
}
|