Files
min-dev-java/src/main/java/packet/CPacket.java
T
2021-03-24 11:22:23 +08:00

210 lines
5.9 KiB
Java

package packet;
import component.ComponentException;
import component.IdentifierWrapper;
import component.Payload;
import component.TTL;
import encoding.*;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 22:07 2021/3/13
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
//
// 表示一个通用的MIN推式包
//
// @Description:
// 1. 包格式定义如下:
// CPacket = 5 TLV-LENGTH
// { CommonIdentifier } => 标识区
// { Signature } => 签名区
// { => 只读区
// <Payload>
// }
// { => 可变区
// { => 受保护区
// "Empty"
// }
// { => 非受保护区
// [TTL]
// }
// }
//
public class CPacket implements InteractWithField, IEncodingAble {
private MINPacket minPacket;
private TTL ttl;
private Payload payload;
private String flatIdentifier; // 推式包拥有一个扁平的标识
public CPacket(){
minPacket=new MINPacket();
ttl=new TTL();
payload=new Payload();
}
/**
* 将 CPacket 的各项属性填充到 MINPacket 中定义的对应分区当中
* @Description:
* // 1. 主要填充标识区、只读区和可变区
* @return
*/
@Override
public boolean fillDataToFields() throws PacketException {
// 可变区 => 受保护区(无)
// 填充可变区 => 非受保护区
// 首先清除所有的Block
this.minPacket.mutableField.mutableDangerousField.clearBlocks();
Block block= null;
try {
block = new SelfEncodingBase().selfWireEncode(this.ttl);
} catch (EncoderException | BlockException | ComponentException e) {
throw new PacketException("CPacket.fillDataToFields: "+e.getMessage());
}
if(block==null){
return false;
}
this.minPacket.mutableField.mutableDangerousField.addBlock(block);
// 填充只读区
// 首先清除所有的Block
this.minPacket.readOnlyField.clearBlocks();
try {
block=new SelfEncodingBase().selfWireEncode(this.payload);
} catch (EncoderException | BlockException | ComponentException e) {
throw new PacketException("CPacket.fillDataToFields: "+e.getMessage());
}
if(block==null){
return false;
}
this.minPacket.readOnlyField.addBlock(block);
// 填充标识区
// 首先清除所有的标识
this.minPacket.identifierField.clearIdentifiers();
IdentifierWrapper identifierWrapper=
new IdentifierWrapper().createCommonIdentifierByString(this.flatIdentifier);
if(identifierWrapper==null){
return false;
}
this.minPacket.identifierField.addIdentifier(identifierWrapper);
return true;
}
/**
* 从 MINPacket 的分区当中提取出 CPacket 的各项属性
* @return
*/
@Override
public boolean extraDataFromFields() throws PacketException {
// 提取 Payload
Block payloadBlock=this.minPacket.readOnlyField.getBlockByType(new VlInt(TLV.TlvPayload));
if(payloadBlock==null){
return false;
}
if(this.payload.wireDecode(payloadBlock)){
return false;
}
// 提取 TTL
Block ttlBlock=this.minPacket.mutableField.mutableDangerousField.getBlockByType(new VlInt(TLV.TlvTTL));
if(ttlBlock==null){
return false;
}
try {
if(this.ttl.wireDecode(ttlBlock)){
return false;
}
} catch (ComponentException e) {
throw new PacketException("CPacket.extraDataFromFields: "+e.getMessage());
}
// 提取标识
IdentifierWrapper commonIdentifier=this.minPacket.identifierField.getIdentifierByType(new VlInt(TLV.TlvIdentifierCommon));
if(commonIdentifier==null){
return false;
}
String identifierString=commonIdentifier.toUri();
if((identifierString.length()>0)&&(identifierString.startsWith("/"))){
this.flatIdentifier=identifierString.substring(1);
}
return true;
}
/**
* 将 CPacket 编码成 TLV
* @param encoder
* @return
*/
@Override
public int wireEncode(Encoder encoder) throws PacketException {
// 首先将属性填充到分区当中
if(!this.fillDataToFields()){
return 0;
}
// 指定包类型
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();
}
/**
* 展示平面标识
* @return
*/
public String toUri(){
return this.flatIdentifier;
}
/**
* 设置推式包的平面标识,eg: asdfsvnjweivnjsdcs
* @param identifier
*/
public void setIdentifier(String identifier){
this.flatIdentifier=identifier;
}
/**
* 获取推式包的平面标识
* @return
*/
public String getIdentifier(){
return this.flatIdentifier;
}
/**
* 得到 TTL
* @return
*/
public TTL getTtl() {
return ttl;
}
/**
* 设置 TTL
* @param ttl
*/
public void setTtl(TTL ttl) {
this.ttl = ttl;
}
}