X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=pcep%2Fimpl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fpcep%2Fimpl%2Fobject%2FPCEPRequestParameterObjectParser.java;h=b9fc394d8dc438ffd910b462d7ceae9f3bdbbf1e;hb=e4f0738f33ad5a5203434fe52b9949a38b458f7d;hp=680a4ab8e4222d029a0ad94131a661ea90a81bb9;hpb=b7985ae58fb4050cccbe361f11d195b9b37a0357;p=bgpcep.git diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/PCEPRequestParameterObjectParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/PCEPRequestParameterObjectParser.java index 680a4ab8e4..b9fc394d8d 100644 --- a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/PCEPRequestParameterObjectParser.java +++ b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/object/PCEPRequestParameterObjectParser.java @@ -8,186 +8,179 @@ package org.opendaylight.protocol.pcep.impl.object; -import java.util.Arrays; -import java.util.BitSet; +import static org.opendaylight.protocol.util.ByteBufWriteUtil.writeUnsignedInt; +import com.google.common.base.Preconditions; +import com.google.common.primitives.UnsignedBytes; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import java.util.List; import org.opendaylight.protocol.pcep.spi.AbstractObjectWithTlvsParser; import org.opendaylight.protocol.pcep.spi.ObjectUtil; import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException; -import org.opendaylight.protocol.pcep.spi.TlvHandlerRegistry; -import org.opendaylight.protocol.util.ByteArray; +import org.opendaylight.protocol.pcep.spi.TlvRegistry; +import org.opendaylight.protocol.pcep.spi.VendorInformationTlvRegistry; +import org.opendaylight.protocol.util.BitArray; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Object; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.ObjectHeader; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.RequestId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.order.tlv.Order; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.path.setup.type.tlv.PathSetupType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.Rp; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.RpBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.rp.Tlvs; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.rp.object.rp.TlvsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.vendor.information.tlvs.VendorInformationTlv; /** * Parser for {@link Rp} */ -public class PCEPRequestParameterObjectParser extends AbstractObjectWithTlvsParser { - - public static final int CLASS = 2; - - public static final int TYPE = 1; - - /* - * lengths of fields in bytes - */ - private static final int FLAGS_PRI_MF_LENGTH = 4; - private static final int RID_F_LENGTH = 4; - - /* - * lengths of subfields inside multi-field in bits - */ - private static final int FLAGS_SF_LENGTH = 29; - - /* - * offsets of field in bytes - */ - - private static final int FLAGS_PRI_MF_OFFSET = 0; - private static final int RID_F_OFFSET = FLAGS_PRI_MF_OFFSET + FLAGS_PRI_MF_LENGTH; - private static final int TLVS_OFFSET = RID_F_OFFSET + RID_F_LENGTH; - - /* - * offsets of subfields inside multi-field in bits - */ - - private static final int FLAGS_SF_OFFSET = 0; - private static final int PRI_SF_OFFSET = FLAGS_SF_OFFSET + FLAGS_SF_LENGTH; - - /* - * flags offsets inside flags sub-field in bits - */ - - private static final int O_FLAG_OFFSET = 26; - private static final int B_FLAG_OFFSET = 27; - private static final int R_FLAG_OFFSET = 28; - - /* - * GCO extension flags offsets inside flags sub-field in bits - */ - private static final int M_FLAG_OFFSET = 21; - private static final int D_FLAG_OFFSET = 22; - - /* - * Path-key bit (RFC5520) - */ - private static final int P_FLAG_OFFSET = 23; - /* - * OF extension flags offsets inside flags sub.field in bits - */ - private static final int S_FLAG_OFFSET = 24; - /* - * RFC6006 flags - */ - private static final int F_FLAG_OFFSET = 18; - - private static final int N_FLAG_OFFSET = 19; - - private static final int E_FLAG_OFFSET = 20; - - public PCEPRequestParameterObjectParser(final TlvHandlerRegistry tlvReg) { - super(tlvReg); - } - - @Override - public Object parseObject(final ObjectHeader header, final byte[] bytes) throws PCEPDeserializerException { - if (bytes == null || bytes.length == 0) { - throw new IllegalArgumentException("Array of bytes is mandatory. Can't be null or empty."); - } - - final BitSet flags = ByteArray.bytesToBitSet(Arrays.copyOfRange(bytes, FLAGS_PRI_MF_OFFSET, FLAGS_PRI_MF_OFFSET - + FLAGS_PRI_MF_LENGTH)); - short priority = 0; - priority |= flags.get(PRI_SF_OFFSET + 2) ? 1 : 0; - priority |= (flags.get(PRI_SF_OFFSET + 1) ? 1 : 0) << 1; - priority |= (flags.get(PRI_SF_OFFSET) ? 1 : 0) << 2; - - final RpBuilder builder = new RpBuilder(); - builder.setIgnore(header.isIgnore()); - builder.setProcessingRule(header.isProcessingRule()); - - builder.setPriority(priority); - builder.setFragmentation(flags.get(F_FLAG_OFFSET)); - builder.setP2mp(flags.get(N_FLAG_OFFSET)); - builder.setEroCompression(flags.get(E_FLAG_OFFSET)); - builder.setMakeBeforeBreak(flags.get(M_FLAG_OFFSET)); - builder.setOrder(flags.get(D_FLAG_OFFSET)); - builder.setPathKey(flags.get(P_FLAG_OFFSET)); - builder.setSupplyOf(flags.get(S_FLAG_OFFSET)); - builder.setLoose(flags.get(O_FLAG_OFFSET)); - builder.setBiDirectional(flags.get(B_FLAG_OFFSET)); - builder.setReoptimization(flags.get(R_FLAG_OFFSET)); - - builder.setRequestId(new RequestId(ByteArray.bytesToLong(Arrays.copyOfRange(bytes, RID_F_OFFSET, RID_F_OFFSET + RID_F_LENGTH)))); - parseTlvs(builder, ByteArray.cutBytes(bytes, TLVS_OFFSET)); - - return builder.build(); - } - - @Override - public void addTlv(final RpBuilder builder, final Tlv tlv) { - if (tlv instanceof Order) { - builder.setTlvs(new TlvsBuilder().setOrder((Order) tlv).build()); - } - } - - @Override - public byte[] serializeObject(final Object object) { - if (!(object instanceof Rp)) { - throw new IllegalArgumentException("Wrong instance of PCEPObject. Passed " + object.getClass() + ". Needed RpObject."); - } - final Rp rPObj = (Rp) object; - final BitSet flags = new BitSet(FLAGS_PRI_MF_LENGTH * Byte.SIZE); - - flags.set(R_FLAG_OFFSET, rPObj.isReoptimization()); - flags.set(B_FLAG_OFFSET, rPObj.isBiDirectional()); - flags.set(O_FLAG_OFFSET, rPObj.isLoose()); - flags.set(M_FLAG_OFFSET, rPObj.isMakeBeforeBreak()); - flags.set(D_FLAG_OFFSET, rPObj.isOrder()); - flags.set(P_FLAG_OFFSET, rPObj.isPathKey()); - flags.set(S_FLAG_OFFSET, rPObj.isSupplyOf()); - flags.set(F_FLAG_OFFSET, rPObj.isFragmentation()); - flags.set(N_FLAG_OFFSET, rPObj.isP2mp()); - flags.set(E_FLAG_OFFSET, rPObj.isEroCompression()); - - flags.set(PRI_SF_OFFSET, (rPObj.getPriority() & 1 << 2) != 0); - flags.set(PRI_SF_OFFSET + 1, (rPObj.getPriority() & 1 << 1) != 0); - flags.set(PRI_SF_OFFSET + 2, (rPObj.getPriority() & 1) != 0); - - final byte[] tlvs = serializeTlvs(rPObj.getTlvs()); - final byte[] retBytes = new byte[TLVS_OFFSET + tlvs.length + getPadding(TLVS_OFFSET + tlvs.length, PADDED_TO)]; - - ByteArray.copyWhole(ByteArray.bitSetToBytes(flags, FLAGS_PRI_MF_LENGTH), retBytes, FLAGS_PRI_MF_OFFSET); - ByteArray.copyWhole(ByteArray.longToBytes(rPObj.getRequestId().getValue(), RID_F_LENGTH), retBytes, RID_F_OFFSET); - if (tlvs.length != 0) { - ByteArray.copyWhole(tlvs, retBytes, TLVS_OFFSET); - } - return ObjectUtil.formatSubobject(TYPE, CLASS, object.isProcessingRule(), object.isIgnore(), retBytes); - } - - public byte[] serializeTlvs(final Tlvs tlvs) { - if (tlvs == null) { - return new byte[0]; - } else if (tlvs.getOrder() != null) { - return serializeTlv(tlvs.getOrder()); - } - return new byte[0]; - } - - @Override - public int getObjectType() { - return TYPE; - } - - @Override - public int getObjectClass() { - return CLASS; - } +public class PCEPRequestParameterObjectParser extends AbstractObjectWithTlvsParser { + + public static final int CLASS = 2; + + public static final int TYPE = 1; + + /* + * lengths of fields in bytes + */ + private static final int FLAGS_SIZE = 32; + + /* + * lengths of subfields inside multi-field in bits + */ + private static final int FLAGS_SF_LENGTH = 29; + + /* + * offsets of subfields inside multi-field in bits + */ + + private static final int FLAGS_SF_OFFSET = 0; + private static final int PRI_SF_OFFSET = FLAGS_SF_OFFSET + FLAGS_SF_LENGTH; + + /* + * flags offsets inside flags sub-field in bits + */ + + private static final int O_FLAG_OFFSET = 26; + private static final int B_FLAG_OFFSET = 27; + private static final int R_FLAG_OFFSET = 28; + + /* + * GCO extension flags offsets inside flags sub-field in bits + */ + private static final int M_FLAG_OFFSET = 21; + private static final int D_FLAG_OFFSET = 22; + + /* + * Path-key bit (RFC5520) + */ + private static final int P_FLAG_OFFSET = 23; + /* + * OF extension flags offsets inside flags sub.field in bits + */ + private static final int S_FLAG_OFFSET = 24; + /* + * RFC6006 flags + */ + private static final int F_FLAG_OFFSET = 18; + + private static final int N_FLAG_OFFSET = 19; + + private static final int E_FLAG_OFFSET = 20; + + public PCEPRequestParameterObjectParser(final TlvRegistry tlvReg, final VendorInformationTlvRegistry viTlvReg) { + super(tlvReg, viTlvReg); + } + + @Override + public Object parseObject(final ObjectHeader header, final ByteBuf bytes) throws PCEPDeserializerException { + Preconditions.checkArgument(bytes != null && bytes.isReadable(), "Array of bytes is mandatory. Can't be null or empty."); + final BitArray flags = BitArray.valueOf(bytes, FLAGS_SIZE); + + final RpBuilder builder = new RpBuilder(); + builder.setIgnore(header.isIgnore()); + builder.setProcessingRule(header.isProcessingRule()); + + short priority = 0; + priority |= flags.get(PRI_SF_OFFSET + 2) ? 1 : 0; + priority |= (flags.get(PRI_SF_OFFSET + 1) ? 1 : 0) << 1; + priority |= (flags.get(PRI_SF_OFFSET) ? 1 : 0) << 2; + builder.setPriority(priority); + builder.setFragmentation(flags.get(F_FLAG_OFFSET)); + builder.setP2mp(flags.get(N_FLAG_OFFSET)); + builder.setEroCompression(flags.get(E_FLAG_OFFSET)); + builder.setMakeBeforeBreak(flags.get(M_FLAG_OFFSET)); + builder.setOrder(flags.get(D_FLAG_OFFSET)); + builder.setPathKey(flags.get(P_FLAG_OFFSET)); + builder.setSupplyOf(flags.get(S_FLAG_OFFSET)); + builder.setLoose(flags.get(O_FLAG_OFFSET)); + builder.setBiDirectional(flags.get(B_FLAG_OFFSET)); + builder.setReoptimization(flags.get(R_FLAG_OFFSET)); + + builder.setRequestId(new RequestId(bytes.readUnsignedInt())); + final TlvsBuilder tlvsBuilder = new TlvsBuilder(); + parseTlvs(tlvsBuilder, bytes.slice()); + builder.setTlvs(tlvsBuilder.build()); + return builder.build(); + } + + @Override + public void addTlv(final TlvsBuilder builder, final Tlv tlv) { + if (tlv instanceof Order) { + builder.setOrder((Order) tlv); + } + if (tlv instanceof PathSetupType) { + builder.setPathSetupType((PathSetupType) tlv); + } + } + + @Override + public void serializeObject(final Object object, final ByteBuf buffer) { + Preconditions.checkArgument(object instanceof Rp, "Wrong instance of PCEPObject. Passed %s. Needed RPObject.", object.getClass()); + final ByteBuf body = Unpooled.buffer(); + final Rp rpObj = (Rp) object; + final BitArray flags = new BitArray(FLAGS_SIZE); + flags.set(R_FLAG_OFFSET, rpObj.isReoptimization()); + flags.set(B_FLAG_OFFSET, rpObj.isBiDirectional()); + flags.set(O_FLAG_OFFSET, rpObj.isLoose()); + flags.set(M_FLAG_OFFSET, rpObj.isMakeBeforeBreak()); + flags.set(D_FLAG_OFFSET, rpObj.isOrder()); + flags.set(P_FLAG_OFFSET, rpObj.isPathKey()); + flags.set(S_FLAG_OFFSET, rpObj.isSupplyOf()); + flags.set(F_FLAG_OFFSET, rpObj.isFragmentation()); + flags.set(N_FLAG_OFFSET, rpObj.isP2mp()); + flags.set(E_FLAG_OFFSET, rpObj.isEroCompression()); + final byte[] res = flags.array(); + if (rpObj.getPriority() != null) { + final byte p = UnsignedBytes.checkedCast(rpObj.getPriority().shortValue()); + res[res.length -1] = (byte) (res[res.length -1] | p); + } + body.writeBytes(res); + Preconditions.checkArgument(rpObj.getRequestId() != null, "RequestId is mandatory"); + writeUnsignedInt(rpObj.getRequestId().getValue(), body); + serializeTlvs(rpObj.getTlvs(), body); + ObjectUtil.formatSubobject(TYPE, CLASS, object.isProcessingRule(), object.isIgnore(), body, buffer); + } + + public void serializeTlvs(final Tlvs tlvs, final ByteBuf body) { + if (tlvs == null) { + return; + } + if (tlvs.getOrder() != null) { + serializeTlv(tlvs.getOrder(), body); + } + if (tlvs.getPathSetupType() != null) { + serializeTlv(tlvs.getPathSetupType(), body); + } + serializeVendorInformationTlvs(tlvs.getVendorInformationTlv(), body); + } + + @Override + protected final void addVendorInformationTlvs(final TlvsBuilder builder, final List tlvs) { + if (!tlvs.isEmpty()) { + builder.setVendorInformationTlv(tlvs); + } + } }