mirror of
https://gitee.com/willfree/min-dev-java.git
synced 2026-10-04 19:42:01 +08:00
284 lines
8.3 KiB
Java
284 lines
8.3 KiB
Java
package packet;
|
|
|
|
import com.sun.xml.internal.ws.api.message.Packet;
|
|
import component.*;
|
|
import encoding.*;
|
|
import mgmt.MgmtException;
|
|
|
|
/*
|
|
* @Author: Wang Feng
|
|
* @Description:
|
|
* @Version: 1.0.0
|
|
* @Date: 22:07 2021/3/13
|
|
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
*/
|
|
//
|
|
// 表示一个通用的MIN推式包
|
|
//
|
|
// @Description:
|
|
// 1. 包格式定义如下:
|
|
// CPacket = 5 TLV-LENGTH
|
|
// { => 标识区
|
|
// SrcIdentifier => 源标识
|
|
// DstIdentifier => 目的标识
|
|
// }
|
|
// { Signature } => 签名区
|
|
// { => 只读区
|
|
// <Payload>
|
|
// }
|
|
// { => 可变区
|
|
// { => 受保护区
|
|
// "Empty"
|
|
// }
|
|
// { => 非受保护区
|
|
// [TTL]
|
|
// }
|
|
// }
|
|
//
|
|
public class CPacket implements InteractWithField, IEncodingAble {
|
|
public MINPacket minPacket=new MINPacket();
|
|
public TTL ttl=new TTL();
|
|
public Payload payload=new Payload();
|
|
public Identifier srcIdentifier=new Identifier();
|
|
public Identifier dstIdentifier=new Identifier();
|
|
|
|
public CPacket(){
|
|
}
|
|
|
|
public CPacket(Identifier srcIdentifier,Identifier dstIdentifier,
|
|
Payload payload,TTL ttl){
|
|
this.srcIdentifier=srcIdentifier;
|
|
this.dstIdentifier=dstIdentifier;
|
|
this.payload=payload;
|
|
this.ttl=ttl;
|
|
}
|
|
|
|
public CPacket createCPacketByMINPacket(MINPacket minPacket) throws PacketException {
|
|
try {
|
|
CPacket cPacket=new CPacket();
|
|
if(!cPacket.doExtraDataFromFields(minPacket)){
|
|
return null;
|
|
}
|
|
return cPacket;
|
|
} catch (PacketException e) {
|
|
throw new PacketException("CPacket.createCPacketByMINPacket: "+e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取源标识
|
|
* @return
|
|
*/
|
|
public Identifier getSrcIdentifier() {
|
|
return srcIdentifier;
|
|
}
|
|
|
|
/**
|
|
* 设置源标识
|
|
* @param srcIdentifier
|
|
*/
|
|
public void setSrcIdentifier(Identifier srcIdentifier) {
|
|
this.srcIdentifier = srcIdentifier;
|
|
}
|
|
|
|
/**
|
|
* 获取目的标识
|
|
* @return
|
|
*/
|
|
public Identifier getDstIdentifier() {
|
|
return dstIdentifier;
|
|
}
|
|
|
|
/**
|
|
* 设置目的标识
|
|
* @param dstIdentifier
|
|
*/
|
|
public void setDstIdentifier(Identifier dstIdentifier) {
|
|
this.dstIdentifier = dstIdentifier;
|
|
}
|
|
|
|
/**
|
|
* 得到 TTL
|
|
*
|
|
* @return
|
|
*/
|
|
public TTL getTtl() {
|
|
return ttl;
|
|
}
|
|
|
|
/**
|
|
* 设置 TTL
|
|
*
|
|
* @param ttl
|
|
*/
|
|
public void setTtl(TTL ttl) {
|
|
this.ttl = ttl;
|
|
}
|
|
|
|
/**
|
|
* 展示目的标识
|
|
*
|
|
* @return
|
|
*/
|
|
public String toUri() throws PacketException {
|
|
try {
|
|
return this.dstIdentifier.toUri();
|
|
} catch (ComponentException e) {
|
|
throw new PacketException("CPacket.toUri() :"+e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取payload中的value
|
|
* @return
|
|
*/
|
|
public byte[] getValue(){
|
|
return this.payload.getValue();
|
|
}
|
|
|
|
/**
|
|
* 将 CPacket 的各项属性填充到目标 MINPacket 中定义的对应分区当中
|
|
*
|
|
* @return
|
|
* @Description: // 1. 主要填充标识区、只读区和可变区
|
|
*/
|
|
public boolean doFillDataToFields(MINPacket minPacket) throws PacketException {
|
|
try {
|
|
// 可变区 => 受保护区(无)
|
|
|
|
// 填充可变区 => 非受保护区
|
|
// 首先清除所有的Block
|
|
minPacket.mutableField.mutableDangerousField.clearBlocks();
|
|
Block block = new SelfEncodingBase().selfWireEncode(this.ttl);
|
|
if (block == null) {
|
|
return false;
|
|
}
|
|
minPacket.mutableField.mutableDangerousField.addBlock(block);
|
|
|
|
// 填充只读区
|
|
// 首先清除所有的Block
|
|
if (this.payload.getValue() != null){
|
|
minPacket.readOnlyField.clearBlocks();
|
|
block = new SelfEncodingBase().selfWireEncode(this.payload);
|
|
if (block == null) {
|
|
return false;
|
|
}
|
|
minPacket.readOnlyField.addBlock(block);
|
|
}
|
|
|
|
|
|
// 填充标识区
|
|
// 首先清除所有的标识
|
|
if((this.srcIdentifier==null)||(this.dstIdentifier==null)){
|
|
throw new PacketException("CPacket.fillDataToFields: SrcIdentifier or DstIdentifier is null.");
|
|
}
|
|
minPacket.identifierField.clearIdentifiers();
|
|
IdentifierWrapper srcIdentifierWrapper =
|
|
new IdentifierWrapper(new VlInt(TLV.TlvIdentifierCommon),this.srcIdentifier);
|
|
IdentifierWrapper dstIdentifierWrapper =
|
|
new IdentifierWrapper(new VlInt(TLV.TlvIdentifierCommon),this.dstIdentifier);
|
|
minPacket.identifierField.addIdentifier(srcIdentifierWrapper);
|
|
minPacket.identifierField.addIdentifier(dstIdentifierWrapper);
|
|
|
|
return true;
|
|
} catch (EncoderException | BlockException | ComponentException | MgmtException e) {
|
|
throw new PacketException("CPacket.fillDataToFields: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将 CPacket 的各项属性填充到 MINPacket 中定义的对应分区当中
|
|
* @return
|
|
* @throws PacketException
|
|
*/
|
|
public boolean fillDataToFields() throws PacketException {
|
|
return this.doFillDataToFields(this.minPacket);
|
|
}
|
|
|
|
/**
|
|
* 从指定的 MINPacket 的分区当中提取出 CPacket 的各项属性
|
|
*
|
|
* @return
|
|
*/
|
|
public boolean doExtraDataFromFields(MINPacket minPacket) throws PacketException {
|
|
try {
|
|
// 提取 Payload
|
|
Block payloadBlock = minPacket.readOnlyField.getBlockByType(new VlInt(TLV.TlvPayload));
|
|
if (payloadBlock == null) {
|
|
return false;
|
|
}
|
|
if (!this.payload.wireDecode(payloadBlock)) {
|
|
return false;
|
|
}
|
|
|
|
// 提取 TTL
|
|
Block ttlBlock = minPacket.mutableField.mutableDangerousField.getBlockByType(new VlInt(TLV.TlvTTL));
|
|
if (ttlBlock == null) {
|
|
return false;
|
|
}
|
|
if (!this.ttl.wireDecode(ttlBlock)) {
|
|
return false;
|
|
}
|
|
|
|
// 提取标识
|
|
IdentifierWrapper srcIdentifierWrapper = minPacket.identifierField.getIdentifier(0);
|
|
if (srcIdentifierWrapper == null) {
|
|
return false;
|
|
}
|
|
IdentifierWrapper dstIdentifierWrapper = minPacket.identifierField.getIdentifier(1);
|
|
if (dstIdentifierWrapper == null) {
|
|
return false;
|
|
}
|
|
this.srcIdentifier=srcIdentifierWrapper.getIdentifier();
|
|
this.dstIdentifier=dstIdentifierWrapper.getIdentifier();
|
|
|
|
return true;
|
|
} catch (ComponentException e) {
|
|
throw new PacketException("CPacket.extraDataFromFields: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 从 MINPacket 的分区当中提取出 CPacket 的各项属性
|
|
* @return
|
|
*/
|
|
@Override
|
|
public boolean extraDataFromFields() throws PacketException {
|
|
return this.doExtraDataFromFields(this.minPacket);
|
|
}
|
|
|
|
/**
|
|
* 将 CPacket 编码成 TLV
|
|
*
|
|
* @param encoder
|
|
* @return
|
|
*/
|
|
@Override
|
|
public int wireEncode(Encoder encoder) throws PacketException {
|
|
// 首先将属性填充到分区当中
|
|
if (!this.fillDataToFields()) {
|
|
return -1;
|
|
}
|
|
|
|
// 指定包类型
|
|
this.minPacket.packetType = new VlInt(TLV.TlvPacketMINCommon);
|
|
|
|
return this.minPacket.wireEncode(encoder);
|
|
}
|
|
|
|
/**
|
|
* 从 TLV Block 中解码出一个 CPacket
|
|
*
|
|
* @param block
|
|
* @return
|
|
*/
|
|
@Override
|
|
public boolean wireDecode(Block block) throws PacketException {
|
|
if (!this.minPacket.wireDecode(block)) {
|
|
return false;
|
|
}
|
|
return this.extraDataFromFields();
|
|
}
|
|
|
|
}
|