public final class PcepImplBundleTest extends AbstractBundleTest {
@Override
protected Collection<String> prerequisiteBundles() {
- return Lists.newArrayList("concepts", "pcep-api", "pcep-spi", "rsvp-api", "util");
+ return Lists.newArrayList("concepts", "pcep-api", "pcep-spi", "pcep-ietf-stateful02", "rsvp-api", "util");
}
@Override
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>pcep-ietf-stateful02</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+ <tag>HEAD</tag>
+ </scm>
+ <parent>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>pcep-parent</artifactId>
+ <version>0.3.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>pcep-ietf-stateful02</artifactId>
+ <description>PCE IETF Stateful model plugin</description>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>concepts</artifactId>
+ </dependency>
+
+ <!--
+ FIXME: this is in support of the generated code. This should not
+ be here, but the plugin should bring it in.
+ -->
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ </dependency>
+
+ <!--
+ FIXME: these are IETF models which are pre-generated in SAL infra.
+ This should not be here, but rather should somehow be
+ discovered by the plugin.
+ -->
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+ module draft-crabbe-pce-pce-initiated-lsp-00 {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:pcep:crabbe:initiated:00";
+ prefix "initiated00";
+
+ import pcep-types { prefix pcep; revision-date 2013-10-05; }
+ import pcep-message { prefix msg; revision-date 2013-10-07; }
+ import draft-crabbe-pce-stateful-pce-02 { prefix stateful02; revision-date 2014-01-10 ;}
+
+ organization "Cisco Systems, Inc.";
+ contact "Dana Kutenicsova <dkutenic@cisco.com>";
+
+ description
+ "This module contains the data model of PCEP extensions defined
+ in draft-crabbe-pce-pce-initiated-lsp-00.
+
+ Copyright (c)2014 Cisco Systems, Inc. All rights reserved.
+
+ This program and the accompanying materials are made available
+ under the terms of the Eclipse Public License v1.0 which
+ accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html";
+
+ revision "2014-01-13" {
+ description
+ "Initial revision.";
+ reference "https://tools.ietf.org/html/draft-crabbe-pce-pce-initiated-lsp-00";
+ }
+
+ grouping pcinitiate-message {
+ uses pcep:message;
+
+ container pcinitiate-message {
+ description "LSP Initiate Message";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-pce-initiated-lsp-00#section-5.1";
+
+ uses pcep:message-header;
+
+ list requests {
+ uses pcep:endpoints-object;
+
+ uses pcep:explicit-route-object;
+
+ uses pcep:lsp-attributes;
+ }
+ }
+ }
+
+ grouping lsp-cleanup-tlv {
+ description "LSP Cleanup TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-pce-initiated-lsp-00#section-6.2.1";
+ container lsp-cleanup {
+ uses pcep:tlv;
+ leaf timeout {
+ type uint32 {
+ range 0..4294967295;
+ }
+ mandatory true;
+ }
+ }
+ }
+
+ augment "/msg:open/msg:open-message/msg:open/msg:tlvs/stateful02:stateful" {
+ leaf initiation {
+ type boolean;
+ default false;
+ }
+ }
+
+ notification pcinitiate {
+ uses pcinitiate-message;
+ }
+}
--- /dev/null
+module draft-crabbe-pce-stateful-pce-02 {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:pcep:crabbe:stateful:02";
+ prefix "stateful02";
+
+ import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
+ import pcep-types { prefix pcep; revision-date 2013-10-05; }
+ import pcep-message { prefix msg; revision-date 2013-10-07; }
+ import rsvp { prefix rsvp; revision-date 2013-08-20; }
+
+ organization "Cisco Systems, Inc.";
+ contact "Dana Kutenicsova <dkutenic@cisco.com>";
+
+ description
+ "This module contains the data model of PCEP extensions defined
+ in draft-crabbe-pce-stateful-pce.
+
+ Copyright (c)2014 Cisco Systems, Inc. All rights reserved.
+
+ This program and the accompanying materials are made available
+ under the terms of the Eclipse Public License v1.0 which
+ accompanies this distribution, and is available at
+ http://www.eclipse.org/legal/epl-v10.html";
+
+ revision "2014-01-10" {
+ description
+ "Initial revision.";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02";
+ }
+
+ typedef plsp-id {
+ type uint32 {
+ range 0..1048576;
+ }
+ }
+
+ typedef symbolic-path-name {
+ type binary {
+ length 1..65535;
+ }
+ }
+
+ grouping lsp-db-version-tlv {
+ description "LSP State Database Version TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.1.2";
+
+ container lsp-db-version {
+ uses pcep:tlv;
+ leaf version {
+ type uint64;
+ mandatory true;
+ }
+ }
+ }
+
+ grouping lsp-identifiers-tlv {
+ description "LSP Identifiers TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.2.2";
+ container lsp-identifiers {
+ uses pcep:tlv;
+ leaf lsp-id {
+ type rsvp:lsp-id;
+ mandatory true;
+ }
+
+ leaf tunnel-id {
+ type rsvp:tunnel-id;
+ mandatory true;
+ }
+
+ choice address-family {
+ case ipv4-case {
+ container ipv4 {
+ leaf ipv4-tunnel-sender-address {
+ type inet:ipv4-address;
+ mandatory true;
+ }
+ leaf ipv4-extended-tunnel-id {
+ type rsvp:ipv4-extended-tunnel-id;
+ mandatory true;
+ }
+ }
+ }
+ case ipv6-case {
+ container ipv6 {
+ leaf ipv6-tunnel-sender-address {
+ type inet:ipv6-address;
+ mandatory true;
+ }
+ leaf ipv6-extended-tunnel-id {
+ type rsvp:ipv6-extended-tunnel-id;
+ mandatory true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ grouping lsp-error-code-tlv {
+ description "LSP Error Code TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.2.3";
+ container lsp-error-code {
+ uses pcep:tlv;
+ leaf error-code {
+ type uint32;
+ mandatory true;
+ }
+ }
+ }
+
+ grouping rsvp-error-spec-tlv {
+ description "RSVP Error Spec TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.2.4";
+ container rsvp-error-spec {
+ uses pcep:tlv;
+ choice error-type {
+ case rsvp-case {
+ container rsvp-error {
+ uses rsvp:error-spec;
+ }
+ }
+ case user-case {
+ container user-error {
+ uses rsvp:user-error-spec;
+ }
+ }
+ }
+ }
+ }
+
+ grouping stateful-capability-tlv {
+ description "Stateful PCE Capability TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.1.1";
+
+ container stateful {
+ uses pcep:tlv;
+
+ leaf lsp-update-capability {
+ type boolean;
+ default false;
+ }
+ leaf include-db-version {
+ type boolean;
+ default false;
+ }
+ }
+ }
+
+ grouping symbolic-path-name-tlv {
+ description "Symbolic Path Name TLV";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.2.1";
+ container symbolic-path-name {
+ uses pcep:tlv;
+ leaf path-name {
+ type symbolic-path-name;
+ mandatory true;
+ }
+ }
+ }
+
+ grouping lsp-object {
+ description "LSP Object";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-7.2";
+
+ container lsp {
+ uses pcep:object;
+ container "tlvs" {
+ uses lsp-db-version-tlv;
+
+ uses lsp-error-code-tlv;
+
+ uses lsp-identifiers-tlv;
+
+ uses rsvp-error-spec-tlv;
+
+ uses symbolic-path-name-tlv;
+ }
+
+ leaf plsp-id {
+ type plsp-id;
+ mandatory true;
+ }
+
+ leaf delegate {
+ type boolean;
+ default false;
+ }
+
+ leaf sync {
+ type boolean;
+ default false;
+ }
+
+ leaf remove {
+ type boolean;
+ default false;
+ }
+
+ leaf operational {
+ type boolean;
+ default false;
+ }
+ }
+ }
+
+ grouping pcupd-message {
+ uses pcep:message;
+
+ container pcupd-message {
+ description "State Update Request Message";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-6.2";
+
+ uses pcep:message-header;
+
+ list updates {
+ uses lsp-object;
+
+ container path {
+ uses pcep:path-definition;
+ }
+ }
+ }
+ }
+
+ grouping pcrpt-message {
+ uses pcep:message;
+
+ container pcrpt-message {
+ description "State Report Message";
+ reference "http://tools.ietf.org/html/draft-crabbe-pce-stateful-pce-02#section-6.1";
+
+ uses pcep:message-header;
+
+ list reports {
+ uses lsp-object;
+
+ container path {
+ uses pcep:path-definition;
+ }
+ }
+ }
+ }
+
+ notification pcupd {
+ uses pcupd-message;
+ }
+
+ notification pcrpt {
+ uses pcrpt-message;
+ }
+
+ augment "/msg:open/msg:open-message/msg:open/msg:tlvs" {
+ uses stateful-capability-tlv;
+
+ uses lsp-db-version-tlv;
+ }
+
+ augment "/msg:pcerr/msg:pcerr-message/msg:error-type/msg:session-case/msg:session/msg:open/msg:tlvs" {
+ uses stateful-capability-tlv;
+
+ uses lsp-db-version-tlv;
+ }
+
+ augment "/msg:pcreq/msg:pcreq-message/msg:requests/msg:segment-computation/msg:p2p" {
+ uses lsp-object;
+ }
+
+ augment "/msg:pcrep/msg:pcrep-message/msg:replies" {
+ uses lsp-object;
+ }
+}
<groupId>${project.groupId}</groupId>
<artifactId>pcep-spi</artifactId>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-ietf-stateful02</artifactId>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.initiated00;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.pojo.AbstractPCEPExtensionProviderActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Pcinitiate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.lsp.cleanup.tlv.LspCleanup;
+
+public class InitiatedActivator extends AbstractPCEPExtensionProviderActivator {
+ @Override
+ protected List<AutoCloseable> startImpl(final PCEPExtensionProviderContext context) {
+ final List<AutoCloseable> regs = new ArrayList<>();
+
+ regs.add(context.registerMessageParser(PcinitiateMessageParser.TYPE,
+ new PcinitiateMessageParser(context.getObjectHandlerRegistry())));
+ regs.add(context.registerMessageSerializer(Pcinitiate.class, new PcinitiateMessageParser(context.getObjectHandlerRegistry())));
+
+ regs.add(context.registerTlvParser(LSPCleanupTlvParser.TYPE, new LSPCleanupTlvParser()));
+ regs.add(context.registerTlvSerializer(LspCleanup.class, new LSPCleanupTlvParser()));
+
+ regs.add(context.registerTlvParser(PCEStatefulCapabilityTlvParser.TYPE, new PCEStatefulCapabilityTlvParser()));
+ // regs.add(context.registerTlvSerializer(Stateful.class, new PCEStatefulCapabilityTlvParser()));
+
+ return regs;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.initiated00;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.lsp.cleanup.tlv.LspCleanup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.lsp.cleanup.tlv.LspCleanupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+public class LSPCleanupTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 26;
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ return ByteArray.intToBytes(((LspCleanup) tlv).getTimeout().intValue());
+ }
+
+ @Override
+ public Tlv parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ return new LspCleanupBuilder().setTimeout(ByteArray.bytesToLong(buffer)).build();
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.initiated00;
+
+import java.util.BitSet;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Stateful1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Stateful1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.StatefulBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+/**
+ * Parser for {@link Stateful}
+ */
+public final class PCEStatefulCapabilityTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 16;
+
+ private static final int FLAGS_F_LENGTH = 4;
+
+ private static final int I_FLAG_OFFSET = 29;
+ private static final int S_FLAG_OFFSET = 30;
+ private static final int U_FLAG_OFFSET = 31;
+
+ @Override
+ public Stateful parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ if (buffer == null || buffer.length == 0) {
+ throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
+ }
+ if (buffer.length < FLAGS_F_LENGTH) {
+ throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + buffer.length + "; Expected: >= "
+ + FLAGS_F_LENGTH + ".");
+ }
+
+ final BitSet flags = ByteArray.bytesToBitSet(ByteArray.subByte(buffer, 0, FLAGS_F_LENGTH));
+
+ final StatefulBuilder sb = new StatefulBuilder();
+ sb.setIncludeDbVersion(flags.get(S_FLAG_OFFSET));
+ sb.setLspUpdateCapability(flags.get(U_FLAG_OFFSET));
+
+ if (flags.get(I_FLAG_OFFSET)) {
+ sb.addAugmentation(Stateful1.class, new Stateful1Builder().setInitiation(Boolean.TRUE).build());
+ }
+
+ return sb.build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("StatefulCapabilityTlv is mandatory.");
+ }
+ final Stateful sct = (Stateful) tlv;
+
+ final BitSet flags = new BitSet(FLAGS_F_LENGTH * Byte.SIZE);
+
+ final Stateful1 sfi = sct.getAugmentation(Stateful1.class);
+ if (sfi != null) {
+ flags.set(I_FLAG_OFFSET, sfi.isInitiation());
+ }
+
+ flags.set(U_FLAG_OFFSET, sct.isLspUpdateCapability());
+ flags.set(S_FLAG_OFFSET, sct.isIncludeDbVersion());
+
+ return ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.initiated00;
+
+import io.netty.buffer.ByteBuf;
+
+import java.util.List;
+
+import org.opendaylight.protocol.pcep.impl.message.AbstractMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectHandlerRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Pcinitiate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.PcinitiateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.PcinitiateMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.pcinitiate.message.Requests;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.pcinitiate.message.RequestsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+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.bandwidth.object.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.object.EndpointsObj;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Parser for {@link Pcinitiate}
+ */
+public class PcinitiateMessageParser extends AbstractMessageParser {
+ public static final int TYPE = 12;
+
+ public PcinitiateMessageParser(final ObjectHandlerRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void serializeMessage(final Message message, final ByteBuf buffer) {
+ if (!(message instanceof Pcinitiate)) {
+ throw new IllegalArgumentException("Wrong instance of Message. Passed instance of " + message.getClass()
+ + ". Needed PcinitiateMessage.");
+ }
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.PcinitiateMessage init = ((Pcinitiate) message).getPcinitiateMessage();
+ for (final Requests req : init.getRequests()) {
+ buffer.writeBytes(serializeObject(req.getEndpointsObj()));
+ buffer.writeBytes(serializeObject(req.getLspa()));
+ if (req.getEro() != null) {
+ buffer.writeBytes(serializeObject(req.getEro()));
+ }
+ if (req.getBandwidth() != null) {
+ buffer.writeBytes(serializeObject(req.getBandwidth()));
+ }
+ if (req.getMetrics() != null && !req.getMetrics().isEmpty()) {
+ for (final Metrics m : req.getMetrics()) {
+ buffer.writeBytes(serializeObject(m.getMetric()));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+ if (objects == null) {
+ throw new IllegalArgumentException("Passed list can't be null.");
+ }
+ final PcinitiateMessageBuilder builder = new PcinitiateMessageBuilder();
+ final List<Requests> reqs = Lists.newArrayList();
+ Requests req = null;
+ while (!objects.isEmpty()) {
+ req = this.getValidRequest(objects);
+ if (req == null) {
+ break;
+ }
+ reqs.add(req);
+ }
+ builder.setRequests(reqs);
+ return new PcinitiateBuilder().setPcinitiateMessage(builder.build()).build();
+ }
+
+ private Requests getValidRequest(final List<Object> objects) {
+ final RequestsBuilder builder = new RequestsBuilder();
+ builder.setEndpointsObj((EndpointsObj) objects.get(0));
+ objects.remove(0);
+
+ builder.setLspa((Lspa) objects.get(0));
+ objects.remove(0);
+ final List<Metrics> metrics = Lists.newArrayList();
+
+ Object obj;
+ State state = State.Init;
+ while (!objects.isEmpty() && !state.equals(State.End)) {
+ obj = objects.get(0);
+
+ switch (state) {
+ case Init:
+ state = State.EroIn;
+ if (obj instanceof Ero) {
+ builder.setEro((Ero) obj);
+ break;
+ }
+ case EroIn:
+ state = State.BandwidthIn;
+ if (obj instanceof Bandwidth) {
+ builder.setBandwidth((Bandwidth) obj);
+ break;
+ }
+ case BandwidthIn:
+ state = State.MetricIn;
+ if (obj instanceof Metric) {
+ metrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
+ state = State.BandwidthIn;
+ break;
+ }
+ case MetricIn:
+ state = State.End;
+ break;
+ case End:
+ break;
+ }
+ if (!state.equals(State.End)) {
+ objects.remove(0);
+ }
+ }
+ builder.setMetrics(metrics);
+ return builder.build();
+ }
+
+ private enum State {
+ Init, EroIn, BandwidthIn, MetricIn, End
+ }
+
+ @Override
+ public int getMessageType() {
+ return TYPE;
+ }
+}
import com.google.common.collect.Lists;
import com.google.common.primitives.UnsignedBytes;
-abstract class AbstractMessageParser implements MessageParser, MessageSerializer {
+public abstract class AbstractMessageParser implements MessageParser, MessageSerializer {
private static final int COMMON_OBJECT_HEADER_LENGTH = 4;
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import java.util.Arrays;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.db.version.tlv.LspDbVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.db.version.tlv.LspDbVersionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+import com.google.common.primitives.UnsignedLong;
+
+/**
+ * Parser for {@link LspDbVersion}
+ */
+public class LspDbVersionTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 23;
+
+ private static final int DBV_F_LENGTH = 8;
+
+ @Override
+ public LspDbVersion parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ return new LspDbVersionBuilder().setVersion(
+ UnsignedLong.fromLongBits(ByteArray.bytesToLong(ByteArray.subByte(buffer, 0, DBV_F_LENGTH))).bigIntegerValue()).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("LspDbVersionTlv is mandatory.");
+ }
+ final LspDbVersion lsp = (LspDbVersion) tlv;
+ final byte[] array = ByteArray.longToBytes(UnsignedLong.valueOf(lsp.getVersion()).longValue(), DBV_F_LENGTH);
+ if (array.length > DBV_F_LENGTH) {
+ throw new IllegalArgumentException("LspDBVersion too big.");
+ }
+ final byte[] result = new byte[DBV_F_LENGTH];
+ Arrays.fill(result, (byte) 0);
+ int j = 7;
+ for (int i = array.length - 1; i >= 0; i--) {
+ result[j] |= array[i];
+ j--;
+ }
+ return result;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv4Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv4CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv4._case.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv4._case.Ipv4Builder;
+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.rsvp.rev130820.Ipv4ExtendedTunnelId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.TunnelId;
+
+/**
+ * Parser for {@link LspIdentifiers}
+ */
+public class LspIdentifierIpv4TlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 18;
+
+ private static final int IP4_F_LENGTH = 4;
+ private static final int EX_TUNNEL_ID4_F_LENGTH = 4;
+
+ private static final int LSP_ID_F_LENGTH = 2;
+ private static final int TUNNEL_ID_F_LENGTH = 2;
+
+ private static final int V4_LENGTH = 12;
+
+ @Override
+ public LspIdentifiers parseTlv(final byte[] valueBytes) throws PCEPDeserializerException {
+ if (valueBytes == null || valueBytes.length == 0) {
+ throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
+ }
+ if (valueBytes.length != V4_LENGTH) {
+ throw new IllegalArgumentException("Length " + valueBytes.length + " does not match LSP Identifiers Ipv4 tlv length.");
+ }
+ int position = 0;
+ final Ipv4Builder builder = new Ipv4Builder();
+ builder.setIpv4TunnelSenderAddress(Ipv4Util.addressForBytes(ByteArray.subByte(valueBytes, position, IP4_F_LENGTH)));
+ position = IP4_F_LENGTH;
+ final LspId lspId = new LspId(ByteArray.bytesToLong(ByteArray.subByte(valueBytes, position, LSP_ID_F_LENGTH)));
+ position += LSP_ID_F_LENGTH;
+ final TunnelId tunnelId = new TunnelId(ByteArray.bytesToInt(ByteArray.subByte(valueBytes, position, TUNNEL_ID_F_LENGTH)));
+ position += TUNNEL_ID_F_LENGTH;
+ builder.setIpv4ExtendedTunnelId(new Ipv4ExtendedTunnelId(Ipv4Util.addressForBytes(ByteArray.subByte(valueBytes, position,
+ EX_TUNNEL_ID4_F_LENGTH))));
+ final AddressFamily afi = new Ipv4CaseBuilder().setIpv4(builder.build()).build();
+ position += EX_TUNNEL_ID4_F_LENGTH;
+ return new LspIdentifiersBuilder().setAddressFamily(afi).setLspId(lspId).setTunnelId(tunnelId).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("LspIdentifiersTlv is mandatory.");
+ }
+ final LspIdentifiers lsp = (LspIdentifiers) tlv;
+ final AddressFamily afi = lsp.getAddressFamily();
+
+ if (afi.getImplementedInterface().equals(Ipv6Case.class)) {
+ return new LspIdentifierIpv6TlvParser().serializeTlv(tlv);
+ }
+
+ final byte[] bytes = new byte[V4_LENGTH];
+ int offset = 0;
+ final Ipv4 ipv4 = ((Ipv4Case) afi).getIpv4();
+ ByteArray.copyWhole(Ipv4Util.bytesForAddress(ipv4.getIpv4TunnelSenderAddress()), bytes, offset);
+ offset += IP4_F_LENGTH;
+ ByteArray.copyWhole(ByteArray.longToBytes(lsp.getLspId().getValue(), LSP_ID_F_LENGTH), bytes, offset);
+ offset += LSP_ID_F_LENGTH;
+ ByteArray.copyWhole(ByteArray.intToBytes(lsp.getTunnelId().getValue(), TUNNEL_ID_F_LENGTH), bytes, offset);
+ offset += TUNNEL_ID_F_LENGTH;
+ ByteArray.copyWhole(Ipv4Util.bytesForAddress(ipv4.getIpv4ExtendedTunnelId()), bytes, offset);
+ return bytes;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import org.opendaylight.protocol.concepts.Ipv6Util;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv6Case;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.Ipv6CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv6._case.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.lsp.identifiers.address.family.ipv6._case.Ipv6Builder;
+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.rsvp.rev130820.Ipv6ExtendedTunnelId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.LspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.TunnelId;
+
+/**
+ * Parser for {@link LspIdentifiers}
+ */
+public class LspIdentifierIpv6TlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 19;
+
+ private static final int IP6_F_LENGTH = 16;
+ private static final int EX_TUNNEL_ID6_F_LENGTH = 16;
+
+ private static final int LSP_ID_F_LENGTH = 2;
+ private static final int TUNNEL_ID_F_LENGTH = 2;
+
+ private static final int V6_LENGTH = 36;
+
+ @Override
+ public LspIdentifiers parseTlv(final byte[] valueBytes) throws PCEPDeserializerException {
+ if (valueBytes == null || valueBytes.length == 0) {
+ throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
+ }
+ if (valueBytes.length != V6_LENGTH) {
+ throw new IllegalArgumentException("Length " + valueBytes.length + " does not match LSP Identifiers Ipv6 tlv length.");
+ }
+ int position = 0;
+ final Ipv6Builder builder = new Ipv6Builder();
+ builder.setIpv6TunnelSenderAddress(Ipv6Util.addressForBytes(ByteArray.subByte(valueBytes, position, IP6_F_LENGTH)));
+ position += IP6_F_LENGTH;
+ final LspId lspId = new LspId(ByteArray.bytesToLong(ByteArray.subByte(valueBytes, position, LSP_ID_F_LENGTH)));
+ position += LSP_ID_F_LENGTH;
+ final TunnelId tunnelId = new TunnelId(ByteArray.bytesToInt(ByteArray.subByte(valueBytes, position, TUNNEL_ID_F_LENGTH)));
+ position += TUNNEL_ID_F_LENGTH;
+ builder.setIpv6ExtendedTunnelId(new Ipv6ExtendedTunnelId(Ipv6Util.addressForBytes(ByteArray.subByte(valueBytes, position,
+ EX_TUNNEL_ID6_F_LENGTH))));
+ final AddressFamily afi = new Ipv6CaseBuilder().setIpv6(builder.build()).build();
+ position += EX_TUNNEL_ID6_F_LENGTH;
+ return new LspIdentifiersBuilder().setAddressFamily(afi).setLspId(lspId).setTunnelId(tunnelId).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("LspIdentifiersTlv is mandatory.");
+ }
+ final byte[] bytes = new byte[V6_LENGTH];
+ int offset = 0;
+ final LspIdentifiers lsp = (LspIdentifiers) tlv;
+ final Ipv6 ipv6 = ((Ipv6Case) lsp.getAddressFamily()).getIpv6();
+ ByteArray.copyWhole(Ipv6Util.bytesForAddress(ipv6.getIpv6TunnelSenderAddress()), bytes, offset);
+ offset += IP6_F_LENGTH;
+ ByteArray.copyWhole(ByteArray.longToBytes(lsp.getLspId().getValue(), LSP_ID_F_LENGTH), bytes, offset);
+ offset += LSP_ID_F_LENGTH;
+ ByteArray.copyWhole(ByteArray.intToBytes(lsp.getTunnelId().getValue(), TUNNEL_ID_F_LENGTH), bytes, offset);
+ offset += TUNNEL_ID_F_LENGTH;
+ ByteArray.copyWhole(Ipv6Util.bytesForAddress(ipv6.getIpv6ExtendedTunnelId()), bytes, offset);
+ return bytes;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.symbolic.path.name.tlv.SymbolicPathName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.symbolic.path.name.tlv.SymbolicPathNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+/**
+ * Parser for {@link SymbolicPathName}
+ */
+public class LspSymbolicNameTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 17;
+
+ @Override
+ public SymbolicPathName parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ return new SymbolicPathNameBuilder().setPathName(
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.SymbolicPathName(buffer)).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("SymbolicPathNameTlv is mandatory.");
+ }
+ final SymbolicPathName spn = (SymbolicPathName) tlv;
+ return spn.getPathName().getValue();
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.error.code.tlv.LspErrorCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.error.code.tlv.LspErrorCodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+/**
+ * Parser for {@link LspErrorCode}
+ */
+public class LspUpdateErrorTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 20;
+
+ private static final int UPDATE_ERR_CODE_LENGTH = 4;
+
+ @Override
+ public LspErrorCode parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ return new LspErrorCodeBuilder().setErrorCode(ByteArray.bytesToLong(buffer)).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("LspErrorCodeTlv is mandatory.");
+ }
+ final LspErrorCode lsp = (LspErrorCode) tlv;
+ return ByteArray.longToBytes(lsp.getErrorCode(), UPDATE_ERR_CODE_LENGTH);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import java.util.BitSet;
+
+import org.opendaylight.protocol.pcep.impl.object.AbstractObjectWithTlvsParser;
+import org.opendaylight.protocol.pcep.impl.object.ObjectUtil;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvHandlerRegistry;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PlspId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.db.version.tlv.LspDbVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.error.code.tlv.LspErrorCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.LspBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.lsp.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.lsp.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.symbolic.path.name.tlv.SymbolicPathName;
+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.Tlv;
+
+/**
+ * Parser for {@link Lsp}
+ */
+public class PCEPLspObjectParser extends AbstractObjectWithTlvsParser<TlvsBuilder> {
+
+ public static final int CLASS = 32;
+
+ public static final int TYPE = 1;
+
+ /*
+ * offset of TLVs offset of other fields are not defined as constants
+ * because of non-standard mapping of bits
+ */
+ private static final int TLVS_OFFSET = 4;
+
+ /*
+ * 12b extended to 16b so first 4b are restricted (belongs to LSP ID)
+ */
+ private static final int DELEGATE_FLAG_OFFSET = 15;
+ private static final int SYNC_FLAG_OFFSET = 14;
+ private static final int REMOVE_FLAG_OFFSET = 12;
+ private static final int OPERATIONAL_FLAG_OFFSET = 13;
+
+ public PCEPLspObjectParser(final TlvHandlerRegistry tlvReg) {
+ super(tlvReg);
+ }
+
+ @Override
+ public Lsp 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(ByteArray.subByte(bytes, 2, 2));
+
+ final LspBuilder builder = new LspBuilder();
+ builder.setIgnore(header.isIgnore());
+ builder.setProcessingRule(header.isProcessingRule());
+
+ builder.setPlspId(new PlspId((ByteArray.bytesToLong(ByteArray.subByte(bytes, 0, 2)) & 0xFFFF) << 4 | (bytes[2] & 0xFF) >> 4));
+ builder.setDelegate(flags.get(DELEGATE_FLAG_OFFSET));
+ builder.setSync(flags.get(SYNC_FLAG_OFFSET));
+ builder.setRemove(flags.get(REMOVE_FLAG_OFFSET));
+ builder.setOperational(flags.get(OPERATIONAL_FLAG_OFFSET));
+ final TlvsBuilder b = new TlvsBuilder();
+ parseTlvs(b, ByteArray.cutBytes(bytes, TLVS_OFFSET));
+ builder.setTlvs(b.build());
+ return builder.build();
+ }
+
+ @Override
+ public void addTlv(final TlvsBuilder builder, final Tlv tlv) {
+ if (tlv instanceof LspErrorCode) {
+ builder.setLspErrorCode((LspErrorCode) tlv);
+ } else if (tlv instanceof LspIdentifiers) {
+ builder.setLspIdentifiers((LspIdentifiers) tlv);
+ } else if (tlv instanceof RsvpErrorSpec) {
+ builder.setRsvpErrorSpec((RsvpErrorSpec) tlv);
+ } else if (tlv instanceof SymbolicPathName) {
+ builder.setSymbolicPathName((SymbolicPathName) tlv);
+ } else if (tlv instanceof LspDbVersion) {
+ builder.setLspDbVersion((LspDbVersion) tlv);
+ }
+ }
+
+ @Override
+ public byte[] serializeObject(final Object object) {
+ if (!(object instanceof Lsp)) {
+ throw new IllegalArgumentException("Wrong instance of PCEPObject. Passed " + object.getClass() + ". Needed LspObject.");
+ }
+ final Lsp specObj = (Lsp) object;
+
+ final byte[] tlvs = serializeTlvs(specObj.getTlvs());
+ final byte[] retBytes = new byte[TLVS_OFFSET + tlvs.length + getPadding(TLVS_OFFSET + tlvs.length, PADDED_TO)];
+
+ final int lspID = specObj.getPlspId().getValue().intValue();
+ retBytes[0] = (byte) (lspID >> 12);
+ retBytes[1] = (byte) (lspID >> 4);
+ retBytes[2] = (byte) (lspID << 4);
+ if (specObj.isDelegate()) {
+ retBytes[3] |= 1 << (Byte.SIZE - (DELEGATE_FLAG_OFFSET - Byte.SIZE) - 1);
+ }
+ if (specObj.isRemove()) {
+ retBytes[3] |= 1 << (Byte.SIZE - (REMOVE_FLAG_OFFSET - Byte.SIZE) - 1);
+ }
+ if (specObj.isSync()) {
+ retBytes[3] |= 1 << (Byte.SIZE - (SYNC_FLAG_OFFSET - Byte.SIZE) - 1);
+ }
+ if (specObj.isOperational()) {
+ retBytes[3] |= 1 << (Byte.SIZE - (OPERATIONAL_FLAG_OFFSET - Byte.SIZE) - 1);
+ }
+ 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];
+ }
+ int finalLength = 0;
+ byte[] lspErrBytes = null;
+ byte[] lspIdBytes = null;
+ byte[] rsvpErrBytes = null;
+ byte[] symbBytes = null;
+ byte[] dbvBytes = null;
+ if (tlvs.getLspErrorCode() != null) {
+ lspErrBytes = serializeTlv(tlvs.getLspErrorCode());
+ finalLength += lspErrBytes.length;
+ }
+ if (tlvs.getLspIdentifiers() != null) {
+ lspIdBytes = serializeTlv(tlvs.getLspIdentifiers());
+ finalLength += lspIdBytes.length;
+ }
+ if (tlvs.getRsvpErrorSpec() != null) {
+ rsvpErrBytes = serializeTlv(tlvs.getRsvpErrorSpec());
+ finalLength += rsvpErrBytes.length;
+ }
+ if (tlvs.getSymbolicPathName() != null) {
+ symbBytes = serializeTlv(tlvs.getSymbolicPathName());
+ finalLength += symbBytes.length;
+ }
+ if (tlvs.getLspDbVersion() != null) {
+ dbvBytes = serializeTlv(tlvs.getLspDbVersion());
+ finalLength += dbvBytes.length;
+ }
+ int offset = 0;
+ final byte[] result = new byte[finalLength];
+ if (lspErrBytes != null) {
+ ByteArray.copyWhole(lspErrBytes, result, offset);
+ offset += lspErrBytes.length;
+ }
+ if (lspIdBytes != null) {
+ ByteArray.copyWhole(lspIdBytes, result, offset);
+ offset += lspIdBytes.length;
+ }
+ if (rsvpErrBytes != null) {
+ ByteArray.copyWhole(rsvpErrBytes, result, offset);
+ offset += rsvpErrBytes.length;
+ }
+ if (symbBytes != null) {
+ ByteArray.copyWhole(symbBytes, result, offset);
+ offset += symbBytes.length;
+ }
+ if (dbvBytes != null) {
+ ByteArray.copyWhole(dbvBytes, result, offset);
+ offset += dbvBytes.length;
+ }
+ return result;
+ }
+
+ @Override
+ public int getObjectType() {
+ return TYPE;
+ }
+
+ @Override
+ public int getObjectClass() {
+ return CLASS;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import io.netty.buffer.ByteBuf;
+
+import java.util.List;
+
+import org.opendaylight.protocol.pcep.impl.message.AbstractMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectHandlerRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PcrptBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.PcrptMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.pcrpt.message.Reports;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.pcrpt.message.ReportsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.pcrpt.message.reports.Path;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.pcrpt.message.reports.PathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+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.bandwidth.object.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.Rro;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Parser for {@link Pcrpt}
+ */
+public class PCEPReportMessageParser extends AbstractMessageParser {
+
+ public static final int TYPE = 10;
+
+ public PCEPReportMessageParser(final ObjectHandlerRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void serializeMessage(final Message message, final ByteBuf buffer) {
+ if (!(message instanceof Pcrpt)) {
+ throw new IllegalArgumentException("Wrong instance of Message. Passed instance of " + message.getClass()
+ + ". Nedded PcrptMessage.");
+ }
+ final Pcrpt msg = (Pcrpt) message;
+ final List<Reports> reports = msg.getPcrptMessage().getReports();
+ for (final Reports report : reports) {
+ buffer.writeBytes(serializeObject(report.getLsp()));
+ final Path p = report.getPath();
+ if (p != null) {
+ if (p.getEro() != null) {
+ buffer.writeBytes(serializeObject(p.getEro()));
+ }
+ if (p.getLspa() != null) {
+ buffer.writeBytes(serializeObject(p.getLspa()));
+ }
+ if (p.getBandwidth() != null) {
+ buffer.writeBytes(serializeObject(p.getBandwidth()));
+ }
+ if (p.getRro() != null) {
+ buffer.writeBytes(serializeObject(p.getRro()));
+ }
+ if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+ for (final Metrics m : p.getMetrics()) {
+ buffer.writeBytes(serializeObject(m.getMetric()));
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+ if (objects == null) {
+ throw new IllegalArgumentException("Passed list can't be null.");
+ }
+ if (objects.isEmpty()) {
+ throw new PCEPDeserializerException("Pcrpt message cannot be empty.");
+ }
+
+ final List<Reports> reports = Lists.newArrayList();
+
+ while (!objects.isEmpty()) {
+ final Reports report = getValidReports(objects, errors);
+ if (reports != null) {
+ reports.add(report);
+ }
+ }
+ return new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build()).build();
+ }
+
+ private Reports getValidReports(final List<Object> objects, final List<Message> errors) {
+ final ReportsBuilder builder = new ReportsBuilder();
+ if (objects.get(0) instanceof Lsp) {
+ builder.setLsp((Lsp) objects.get(0));
+ objects.remove(0);
+ } else {
+ errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+ return null;
+ }
+ if (!objects.isEmpty()) {
+ final PathBuilder pBuilder = new PathBuilder();
+ parsePath(objects, pBuilder);
+ builder.setPath(pBuilder.build());
+ }
+ return builder.build();
+ }
+
+ private void parsePath(final List<Object> objects, final PathBuilder builder) {
+ final List<Metrics> pathMetrics = Lists.newArrayList();
+ Object obj;
+ State state = State.Init;
+ while (!objects.isEmpty() && !state.equals(State.End)) {
+ obj = objects.get(0);
+ switch (state) {
+ case Init:
+ state = State.EroIn;
+ if (obj instanceof Ero) {
+ builder.setEro((Ero) obj);
+ break;
+ }
+ case EroIn:
+ state = State.LspaIn;
+ if (obj instanceof Lspa) {
+ builder.setLspa((Lspa) obj);
+ break;
+ }
+ case LspaIn:
+ state = State.BandwidthIn;
+ if (obj instanceof Bandwidth) {
+ builder.setBandwidth((Bandwidth) obj);
+ break;
+ }
+ case BandwidthIn:
+ state = State.RroIn;
+ if (obj instanceof Rro) {
+ builder.setRro((Rro) obj);
+ break;
+ }
+ case RroIn:
+ state = State.MetricIn;
+ if (obj instanceof Metric) {
+ pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
+ state = State.RroIn;
+ break;
+ }
+ case MetricIn:
+ state = State.End;
+ break;
+ case End:
+ break;
+ }
+ if (!state.equals(State.End)) {
+ objects.remove(0);
+ }
+ }
+ if (!pathMetrics.isEmpty()) {
+ builder.setMetrics(pathMetrics);
+ }
+ }
+
+ private enum State {
+ Init, EroIn, LspaIn, BandwidthIn, RroIn, MetricIn, End
+ }
+
+ @Override
+ public int getMessageType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import io.netty.buffer.ByteBuf;
+
+import java.util.List;
+
+import org.opendaylight.protocol.pcep.impl.message.AbstractMessageParser;
+import org.opendaylight.protocol.pcep.spi.ObjectHandlerRegistry;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.PCEPErrors;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.PcupdBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.PcupdMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.Updates;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.UpdatesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.updates.Path;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcupd.message.pcupd.message.updates.PathBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+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.bandwidth.object.Bandwidth;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.explicit.route.object.Ero;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.include.route.object.Iro;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.Metrics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lsp.attributes.MetricsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.lspa.object.Lspa;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.metric.object.Metric;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Parser for {@link Pcupd}
+ */
+public class PCEPUpdateRequestMessageParser extends AbstractMessageParser {
+
+ public static final int TYPE = 11;
+
+ public PCEPUpdateRequestMessageParser(final ObjectHandlerRegistry registry) {
+ super(registry);
+ }
+
+ @Override
+ public void serializeMessage(final Message message, final ByteBuf buffer) {
+ if (!(message instanceof Pcupd)) {
+ throw new IllegalArgumentException("Wrong instance of PCEPMessage. Passed instance of " + message.getClass()
+ + ". Nedded PcupdMessage.");
+ }
+ final Pcupd msg = (Pcupd) message;
+ final List<Updates> updates = msg.getPcupdMessage().getUpdates();
+ for (final Updates update : updates) {
+ buffer.writeBytes(serializeObject(update.getLsp()));
+ final Path p = update.getPath();
+ if (p != null) {
+ buffer.writeBytes(serializeObject(p.getEro()));
+ if (p.getLspa() != null) {
+ buffer.writeBytes(serializeObject(p.getLspa()));
+ }
+ if (p.getBandwidth() != null) {
+ buffer.writeBytes(serializeObject(p.getBandwidth()));
+ }
+ if (p.getMetrics() != null && !p.getMetrics().isEmpty()) {
+ for (final Metrics m : p.getMetrics()) {
+ buffer.writeBytes(serializeObject(m.getMetric()));
+ }
+ }
+ if (p.getIro() != null) {
+ buffer.writeBytes(serializeObject(p.getIro()));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Message validate(final List<Object> objects, final List<Message> errors) throws PCEPDeserializerException {
+ if (objects == null) {
+ throw new IllegalArgumentException("Passed list can't be null.");
+ }
+ if (objects.isEmpty()) {
+ throw new PCEPDeserializerException("Pcup message cannot be empty.");
+ }
+
+ final List<Updates> updateRequests = Lists.newArrayList();
+
+ while (!objects.isEmpty()) {
+ final Updates update = getValidUpdates(objects, errors);
+ if (update != null) {
+ updateRequests.add(update);
+ }
+ }
+ if (!objects.isEmpty()) {
+ throw new PCEPDeserializerException("Unprocessed Objects: " + objects);
+ }
+ return new PcupdBuilder().setPcupdMessage(new PcupdMessageBuilder().setUpdates(updateRequests).build()).build();
+ }
+
+ private Updates getValidUpdates(final List<Object> objects, final List<Message> errors) {
+ final UpdatesBuilder builder = new UpdatesBuilder();
+ if (objects.get(0) instanceof Lsp) {
+ builder.setLsp((Lsp) objects.get(0));
+ objects.remove(0);
+ } else {
+ errors.add(createErrorMsg(PCEPErrors.LSP_MISSING));
+ return null;
+ }
+ if (!objects.isEmpty()) {
+ final PathBuilder pBuilder = new PathBuilder();
+ if (objects.get(0) instanceof Ero) {
+ pBuilder.setEro((Ero) objects.get(0));
+ objects.remove(0);
+ } else {
+ errors.add(createErrorMsg(PCEPErrors.ERO_MISSING));
+ return null;
+ }
+ parsePath(objects, pBuilder);
+ builder.setPath(pBuilder.build());
+ }
+ return builder.build();
+ }
+
+ private void parsePath(final List<Object> objects, final PathBuilder pBuilder) {
+ final List<Metrics> pathMetrics = Lists.newArrayList();
+ Object obj;
+ State state = State.Init;
+ while (!objects.isEmpty() && !state.equals(State.End)) {
+ obj = objects.get(0);
+ switch (state) {
+ case Init:
+ state = State.LspaIn;
+ if (obj instanceof Lspa) {
+ pBuilder.setLspa((Lspa) obj);
+ break;
+ }
+ case LspaIn:
+ state = State.BandwidthIn;
+ if (obj instanceof Bandwidth) {
+ pBuilder.setBandwidth((Bandwidth) obj);
+ break;
+ }
+ case BandwidthIn:
+ state = State.MetricIn;
+ if (obj instanceof Metric) {
+ pathMetrics.add(new MetricsBuilder().setMetric((Metric) obj).build());
+ state = State.BandwidthIn;
+ break;
+ }
+ case MetricIn:
+ state = State.IroIn;
+ if (obj instanceof Iro) {
+ pBuilder.setIro((Iro) obj);
+ break;
+ }
+ case IroIn:
+ state = State.End;
+ break;
+ case End:
+ break;
+ }
+ if (!state.equals(State.End)) {
+ objects.remove(0);
+ }
+ }
+ if (!pathMetrics.isEmpty()) {
+ pBuilder.setMetrics(pathMetrics);
+ }
+ }
+
+ private enum State {
+ Init, LspaIn, BandwidthIn, MetricIn, IroIn, End
+ }
+
+ @Override
+ public int getMessageType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import java.util.BitSet;
+
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.StatefulBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
+
+public final class PCEStatefulCapabilityTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 16;
+
+ private static final int FLAGS_F_LENGTH = 4;
+
+ private static final int S_FLAG_OFFSET = 30;
+ private static final int U_FLAG_OFFSET = 31;
+
+ @Override
+ public Stateful parseTlv(final byte[] buffer) throws PCEPDeserializerException {
+ if (buffer == null || buffer.length == 0) {
+ throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
+ }
+ if (buffer.length < FLAGS_F_LENGTH) {
+ throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + buffer.length + "; Expected: >= "
+ + FLAGS_F_LENGTH + ".");
+ }
+
+ final BitSet flags = ByteArray.bytesToBitSet(ByteArray.subByte(buffer, 0, FLAGS_F_LENGTH));
+
+ final StatefulBuilder sb = new StatefulBuilder();
+ sb.setIncludeDbVersion(flags.get(S_FLAG_OFFSET));
+ sb.setLspUpdateCapability(flags.get(U_FLAG_OFFSET));
+ return sb.build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("StatefulCapabilityTlv is mandatory.");
+ }
+ final Stateful sct = (Stateful) tlv;
+ final BitSet flags = new BitSet(FLAGS_F_LENGTH * Byte.SIZE);
+ flags.set(U_FLAG_OFFSET, sct.isLspUpdateCapability());
+ flags.set(S_FLAG_OFFSET, sct.isIncludeDbVersion());
+ return ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import java.util.BitSet;
+
+import org.opendaylight.protocol.concepts.Ipv4Util;
+import org.opendaylight.protocol.concepts.Ipv6Util;
+import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
+import org.opendaylight.protocol.pcep.spi.TlvParser;
+import org.opendaylight.protocol.pcep.spi.TlvSerializer;
+import org.opendaylight.protocol.util.ByteArray;
+import org.opendaylight.protocol.util.Values;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.iana.rev130816.EnterpriseNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpecBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.ErrorType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.RsvpCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.RsvpCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.UserCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.UserCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.rsvp._case.RsvpError;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.rsvp._case.RsvpErrorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.user._case.UserError;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.error.type.user._case.UserErrorBuilder;
+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.rsvp.rev130820.ErrorSpec.Flags;
+
+import com.google.common.primitives.UnsignedBytes;
+
+/**
+ * Parser for {@link RsvpErrorSpec}
+ */
+public final class RSVPErrorSpecTlvParser implements TlvParser, TlvSerializer {
+
+ public static final int TYPE = 21;
+
+ private static final int IP4_F_LENGTH = 4;
+ private static final int IP6_F_LENGTH = 16;
+ private static final int FLAGS_F_LENGTH = 1;
+ private static final int ERROR_CODE_F_LENGTH = 1;
+ private static final int ERROR_VALUE_F_LENGTH = 2;
+
+ private static final int ENTERPRISE_F_LENGTH = 4;
+ private static final int SUB_ORG_F_LENGTH = 1;
+ private static final int ERR_DESCR_LENGTH_F_LENGTH = 1;
+ private static final int USER_VALUE_F_LENGTH = 2;
+
+ private static final int RSVP_ERROR_CLASS_NUM = 6;
+ private static final int RSVP_IPV4_ERROR_CLASS_TYPE = 1;
+ private static final int RSVP_IPV6_ERROR_CLASS_TYPE = 2;
+
+ private static final int USER_ERROR_CLASS_NUM = 194;
+ private static final int USER_ERROR_CLASS_TYPE = 1;
+
+ private static final int IN_PLACE_FLAG_OFFSET = 7;
+ private static final int NOT_GUILTY_FLAGS_OFFSET = 6;
+
+ private static final int V4_RSVP_LENGTH = 10;
+ private static final int V6_RSVP_LENGTH = 22;
+
+ @Override
+ public RsvpErrorSpec parseTlv(final byte[] valueBytes) throws PCEPDeserializerException {
+ if (valueBytes == null || valueBytes.length == 0) {
+ throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
+ }
+
+ final int classNum = ByteArray.bytesToInt(ByteArray.subByte(valueBytes, 0, 1));
+ final int classType = ByteArray.bytesToInt(ByteArray.subByte(valueBytes, 1, 1));
+
+ ErrorType errorType = null;
+ final int byteOffset = 2;
+
+ if (classNum == RSVP_ERROR_CLASS_NUM) {
+ errorType = parseRsvp(classType, ByteArray.cutBytes(valueBytes, byteOffset));
+ } else if (classNum == USER_ERROR_CLASS_NUM && classType == USER_ERROR_CLASS_TYPE) {
+ errorType = parseUserError(ByteArray.cutBytes(valueBytes, byteOffset));
+ }
+ return new RsvpErrorSpecBuilder().setErrorType(errorType).build();
+ }
+
+ @Override
+ public byte[] serializeTlv(final Tlv tlv) {
+ if (tlv == null) {
+ throw new IllegalArgumentException("RSVPErrorSpecTlv is mandatory.");
+ }
+ final RsvpErrorSpec rsvp = (RsvpErrorSpec) tlv;
+
+ if (rsvp.getErrorType().getImplementedInterface().equals(RsvpCase.class)) {
+ final RsvpCase r = (RsvpCase) rsvp.getErrorType();
+ return serializeRsvp(r.getRsvpError());
+ } else {
+ final UserCase u = (UserCase) rsvp.getErrorType();
+ return serializerUserError(u.getUserError());
+ }
+ }
+
+ private UserCase parseUserError(final byte[] valueBytes) {
+ final UserErrorBuilder error = new UserErrorBuilder();
+ int byteOffset = 0;
+ error.setEnterprise(new EnterpriseNumber(ByteArray.bytesToLong(ByteArray.subByte(valueBytes, byteOffset, ENTERPRISE_F_LENGTH))));
+ byteOffset += ENTERPRISE_F_LENGTH;
+ error.setSubOrg((short) UnsignedBytes.toInt(valueBytes[byteOffset]));
+ byteOffset += SUB_ORG_F_LENGTH;
+ final int errDescrLength = UnsignedBytes.toInt(valueBytes[byteOffset]);
+ byteOffset += ERR_DESCR_LENGTH_F_LENGTH;
+ error.setValue(ByteArray.bytesToInt(ByteArray.subByte(valueBytes, byteOffset, USER_VALUE_F_LENGTH)));
+ byteOffset += USER_VALUE_F_LENGTH;
+ error.setDescription(ByteArray.bytesToHRString(ByteArray.subByte(valueBytes, byteOffset, errDescrLength)));
+ byteOffset += errDescrLength;
+ // if we have any subobjects, place the implementation here
+ return new UserCaseBuilder().setUserError(error.build()).build();
+ }
+
+ private byte[] serializerUserError(final UserError ue) {
+ final byte[] enterprise = ByteArray.longToBytes(ue.getEnterprise().getValue(), ENTERPRISE_F_LENGTH);
+ final byte suborg = UnsignedBytes.checkedCast(ue.getSubOrg());
+ final byte[] value = ByteArray.intToBytes(ue.getValue(), USER_VALUE_F_LENGTH);
+ final byte[] desc = (ue.getDescription() == null) ? new byte[0] : ue.getDescription().getBytes();
+ final byte descLen = UnsignedBytes.checkedCast(desc.length);
+ // if we have any subobjects, place the implementation here
+ final byte[] bytes = new byte[2 + ENTERPRISE_F_LENGTH + SUB_ORG_F_LENGTH + USER_VALUE_F_LENGTH + ERR_DESCR_LENGTH_F_LENGTH
+ + desc.length];
+ bytes[0] = UnsignedBytes.checkedCast(USER_ERROR_CLASS_NUM);
+ bytes[1] = UnsignedBytes.checkedCast(USER_ERROR_CLASS_TYPE);
+ int offset = 2;
+ ByteArray.copyWhole(enterprise, bytes, offset);
+ offset += ENTERPRISE_F_LENGTH;
+ bytes[offset] = suborg;
+ offset += SUB_ORG_F_LENGTH;
+ bytes[offset] = descLen;
+ offset += ERR_DESCR_LENGTH_F_LENGTH;
+ ByteArray.copyWhole(value, bytes, offset);
+ offset += USER_VALUE_F_LENGTH;
+ ByteArray.copyWhole(desc, bytes, offset);
+ return bytes;
+ }
+
+ private RsvpCase parseRsvp(final int classType, final byte[] valueBytes) {
+ int byteOffset = 0;
+ final RsvpErrorBuilder builder = new RsvpErrorBuilder();
+ if (classType == RSVP_IPV4_ERROR_CLASS_TYPE) {
+ builder.setNode(new IpAddress(Ipv4Util.addressForBytes(ByteArray.subByte(valueBytes, byteOffset, IP4_F_LENGTH))));
+ byteOffset += IP4_F_LENGTH;
+ } else if (classType == RSVP_IPV6_ERROR_CLASS_TYPE) {
+ builder.setNode(new IpAddress(Ipv6Util.addressForBytes(ByteArray.subByte(valueBytes, byteOffset, IP6_F_LENGTH))));
+ byteOffset += IP6_F_LENGTH;
+ }
+ final BitSet flags = ByteArray.bytesToBitSet(ByteArray.subByte(valueBytes, byteOffset, FLAGS_F_LENGTH));
+ byteOffset += FLAGS_F_LENGTH;
+ builder.setFlags(new Flags(flags.get(IN_PLACE_FLAG_OFFSET), flags.get(NOT_GUILTY_FLAGS_OFFSET)));
+ final short errorCode = (short) (valueBytes[byteOffset] & Values.BYTE_MAX_VALUE_BYTES);
+ byteOffset += ERROR_CODE_F_LENGTH;
+ builder.setCode(errorCode);
+ final int errorValue = (ByteArray.bytesToShort(ByteArray.subByte(valueBytes, byteOffset, ERROR_VALUE_F_LENGTH)) & 0xFFFF);
+ builder.setValue(errorValue);
+ return new RsvpCaseBuilder().setRsvpError(builder.build()).build();
+ }
+
+ private byte[] serializeRsvp(final RsvpError rsvp) {
+ final BitSet flags = new BitSet(FLAGS_F_LENGTH * Byte.SIZE);
+ flags.set(IN_PLACE_FLAG_OFFSET, rsvp.getFlags().isInPlace());
+ flags.set(NOT_GUILTY_FLAGS_OFFSET, rsvp.getFlags().isNotGuilty());
+ int offset = 0;
+ final IpAddress node = rsvp.getNode();
+ byte[] bytes;
+ if (node.getIpv4Address() != null) {
+ bytes = new byte[V4_RSVP_LENGTH];
+ bytes[0] = RSVP_ERROR_CLASS_NUM;
+ bytes[1] = RSVP_IPV4_ERROR_CLASS_TYPE;
+ offset += 2;
+ ByteArray.copyWhole(Ipv4Util.bytesForAddress(node.getIpv4Address()), bytes, offset);
+ offset += IP4_F_LENGTH;
+ } else {
+ bytes = new byte[V6_RSVP_LENGTH];
+ bytes[0] = RSVP_ERROR_CLASS_NUM;
+ bytes[1] = RSVP_IPV6_ERROR_CLASS_TYPE;
+ offset += 2;
+ ByteArray.copyWhole(Ipv6Util.bytesForAddress(node.getIpv6Address()), bytes, offset);
+ offset += IP6_F_LENGTH;
+ }
+ bytes[offset] = ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH)[0];
+ offset += FLAGS_F_LENGTH;
+ bytes[offset] = UnsignedBytes.checkedCast(rsvp.getCode());
+ offset += ERROR_CODE_F_LENGTH;
+ final byte[] value = ByteArray.intToBytes(rsvp.getValue().intValue(), ERROR_VALUE_F_LENGTH);
+ ByteArray.copyWhole(value, bytes, offset);
+ return bytes;
+ }
+
+ @Override
+ public int getType() {
+ return TYPE;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.protocol.pcep.impl.stateful02;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.protocol.pcep.spi.PCEPExtensionProviderContext;
+import org.opendaylight.protocol.pcep.spi.pojo.AbstractPCEPExtensionProviderActivator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcrpt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.db.version.tlv.LspDbVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.error.code.tlv.LspErrorCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.identifiers.tlv.LspIdentifiers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.lsp.object.Lsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpec;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.stateful.capability.tlv.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.symbolic.path.name.tlv.SymbolicPathName;
+
+public class StatefulActivator extends AbstractPCEPExtensionProviderActivator {
+ @Override
+ protected List<AutoCloseable> startImpl(final PCEPExtensionProviderContext context) {
+ final List<AutoCloseable> regs = new ArrayList<>();
+
+ regs.add(context.registerMessageParser(PCEPUpdateRequestMessageParser.TYPE,
+ new PCEPUpdateRequestMessageParser(context.getObjectHandlerRegistry())));
+ regs.add(context.registerMessageSerializer(Pcupd.class, new PCEPUpdateRequestMessageParser(context.getObjectHandlerRegistry())));
+
+ regs.add(context.registerMessageParser(PCEPReportMessageParser.TYPE,
+ new PCEPReportMessageParser(context.getObjectHandlerRegistry())));
+ regs.add(context.registerMessageSerializer(Pcrpt.class, new PCEPReportMessageParser(context.getObjectHandlerRegistry())));
+
+ regs.add(context.registerObjectParser(PCEPLspObjectParser.TYPE, PCEPLspObjectParser.CLASS,
+ new PCEPLspObjectParser(context.getTlvHandlerRegistry())));
+ regs.add(context.registerObjectSerializer(Lsp.class, new PCEPLspObjectParser(context.getTlvHandlerRegistry())));
+
+ regs.add(context.registerTlvParser(PCEStatefulCapabilityTlvParser.TYPE, new PCEStatefulCapabilityTlvParser()));
+ regs.add(context.registerTlvSerializer(Stateful.class, new PCEStatefulCapabilityTlvParser()));
+
+ regs.add(context.registerTlvParser(LspDbVersionTlvParser.TYPE, new LspDbVersionTlvParser()));
+ regs.add(context.registerTlvSerializer(LspDbVersion.class, new LspDbVersionTlvParser()));
+
+ regs.add(context.registerTlvParser(LspUpdateErrorTlvParser.TYPE, new LspUpdateErrorTlvParser()));
+ regs.add(context.registerTlvSerializer(LspErrorCode.class, new LspUpdateErrorTlvParser()));
+
+ regs.add(context.registerTlvParser(LspSymbolicNameTlvParser.TYPE, new LspSymbolicNameTlvParser()));
+ regs.add(context.registerTlvSerializer(SymbolicPathName.class, new LspSymbolicNameTlvParser()));
+
+ regs.add(context.registerTlvParser(LspIdentifierIpv4TlvParser.TYPE, new LspIdentifierIpv4TlvParser()));
+ regs.add(context.registerTlvSerializer(LspIdentifiers.class, new LspIdentifierIpv4TlvParser()));
+
+ regs.add(context.registerTlvParser(LspIdentifierIpv6TlvParser.TYPE, new LspIdentifierIpv6TlvParser()));
+
+ regs.add(context.registerTlvParser(RSVPErrorSpecTlvParser.TYPE, new RSVPErrorSpecTlvParser()));
+ regs.add(context.registerTlvSerializer(RsvpErrorSpec.class, new RSVPErrorSpecTlvParser()));
+
+ return regs;
+ }
+}
<modules>
<module>api</module>
<module>api-config</module>
+ <module>ietf-stateful02</module>
<module>impl</module>
<module>impl-config</module>
<module>spi</module>
<groupId>${project.groupId}</groupId>
<artifactId>pcep-spi-config</artifactId>
<version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-ietf-stateful02</artifactId>
+ <version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>