package packet; import component.*; import encoding.*; /* * @Author: Wang Feng * @Description: * @Version: 1.0.0 * @Date: 10:25 2021/3/16 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ // // 表示一个MIN拉取式数据包 // // @Description: // 1. 包格式的定义如下 // Data = 7 TLV-LENGTH // { DataIdentifier } => 标识区 // { Signature } => 签名区 // { => 只读区 // [FreshnessPeriod] // [NackHeader] // // } // { => 可变区 // { => 受保护区 // [CongestionMark] // } // { => 非受保护区 // "Empty" // } // } // public class Data implements IEncodingAble, InteractWithField { private MINPacket minPacket=new MINPacket(); public FreshnessPeriod freshnessPeriod=new FreshnessPeriod(); public Payload payload=new Payload(); public CongestionMark congestionMark=new CongestionMark(); public NackHeader nackHeader=new NackHeader(); public Identifier name=new Identifier(); public Data(){ } public Data(Identifier name,Payload payload,FreshnessPeriod freshnessPeriod, CongestionMark congestionMark,NackHeader nackHeader){ this.name=name; this.payload=payload; this.freshnessPeriod=freshnessPeriod; this.congestionMark=congestionMark; this.nackHeader=nackHeader; } /** * 展示数据包的 URI * * @return */ public String toUri() throws ComponentException { if (this.name == null) { return ""; } return this.name.toUri(); } /** * 获取内容数据包的名字 * * @return */ public Identifier getName() { return this.name; } public void setName(Identifier name) { this.name = name; } /** * 将 Data 的各项属性填充到 MINPacket 中定义的对应分区当中 * * @return */ @Override public boolean fillDataToFields() throws PacketException { ///////////////////////////////////////////////////////////// //// 填充可变区 // { => 可变区 // { => 受保护区 // [CongestionMark] // } // { => 非受保护区 // "Empty" // } // } /////////////////////////////////////////////////////////////\ try { // 填充可变受保护区 this.minPacket.mutableField.mutableProtectField.clearBlocks(); // CongestionMark Block block = new SelfEncodingBase().selfWireEncode(this.congestionMark); if (block == null) { return false; } this.minPacket.mutableField.mutableProtectField.addBlock(block); // 填充可变非受保护区(无) ///////////////////////////////////////////////////////////// //// 填充只读区 // { => 只读区 // [FreshnessPeriod] // [NackHeader] // // } ///////////////////////////////////////////////////////////// this.minPacket.readOnlyField.clearBlocks(); // FreshnessPeriod if (this.freshnessPeriod.isInitial()) { block = new SelfEncodingBase().selfWireEncode(this.freshnessPeriod); if (block == null) { return false; } this.minPacket.readOnlyField.addBlock(block); } // NackHeader if (this.nackHeader.isInitial()) { block = new SelfEncodingBase().selfWireEncode(this.nackHeader); if (block == null) { return false; } this.minPacket.readOnlyField.addBlock(block); } // Payload block = new SelfEncodingBase().selfWireEncode(this.payload); if (block == null) { return false; } this.minPacket.readOnlyField.addBlock(block); ///////////////////////////////////////////////////////////// //// 填充标识区 ///////////////////////////////////////////////////////////// this.minPacket.identifierField.clearIdentifiers(); IdentifierWrapper identifierWrapper = new IdentifierWrapper().createContentInterestIdentifierByComponents(this.name.getComponents()); if (identifierWrapper == null) { return false; } this.minPacket.identifierField.addIdentifier(identifierWrapper); return true; } catch (EncoderException | BlockException | ComponentException e) { throw new PacketException("Data.fillDataToFields: " + e.getMessage()); } } /** * 从 MINPacket 的分区中提取出 Data 的各项属性 * * @return */ @Override public boolean extraDataFromFields() throws PacketException { try { ///////////////////////////////////////////////////////////// //// 解析可变区 // { => 可变区 // { => 受保护区 // [CongestionMark] // } // { => 非受保护区 // "Empty" // } // } ///////////////////////////////////////////////////////////// Block block = this.minPacket.mutableField.mutableProtectField.getBlockByType(new VlInt(TLV.TlvCongestionMark)); if (block != null) { if (!this.congestionMark.wireDecode(block)) { return false; } } ///////////////////////////////////////////////////////////// //// 解析只读区 // { => 只读区 // [FreshnessPeriod] // // } ///////////////////////////////////////////////////////////// ElementContainer elementContainer = this.minPacket.readOnlyField.getBlocks(); int len = elementContainer.length(); for (int i = 0; i < len; i++) { Block newblock = elementContainer.getBlock(i); int type = newblock.getType().getVlIntValue2Int(); switch (type) { case TLV.TlvFreshnessPeriod: if (!this.freshnessPeriod.wireDecode(newblock)) { return false; } break; case TLV.TlvPayload: if (!this.payload.wireDecode(newblock)) { return false; } break; default: // TODO: 这边可以规定哪些范围是自定义的,哪些是预留的,然后根据需要这边抛出错误 } } ///////////////////////////////////////////////////////////// //// 解析标识区 ///////////////////////////////////////////////////////////// IdentifierWrapper interestIdentifierWrapper = this.minPacket.identifierField.getIdentifierByType(new VlInt(TLV.TlvIdentifierContentInterest)); if (interestIdentifierWrapper == null) { return false; } this.setName(interestIdentifierWrapper.getIdentifier()); return true; } catch (ComponentException | VlIntException | BlockException e) { throw new PacketException("Data.extraDataFromFields: " + e.getMessage()); } } /** * 将 Data 线速编码为一个 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 中解码出一个 Data * * @param block * @return */ @Override public boolean wireDecode(Block block) throws PacketException { if (!this.minPacket.wireDecode(block)) { return false; } return this.extraDataFromFields(); } }