Created separated project for stateful-02. 32/4432/3
authorDana Kutenicsova <dkutenic@cisco.com>
Mon, 20 Jan 2014 10:15:39 +0000 (11:15 +0100)
committerDana Kutenicsova <dkutenic@cisco.com>
Mon, 20 Jan 2014 12:24:41 +0000 (13:24 +0100)
Change-Id: I1914920cd7006d272eaed260d868018a871cf663
Signed-off-by: Dana Kutenicsova <dkutenic@cisco.com>
23 files changed:
integration-tests/src/test/java/org/opendaylight/protocol/integration/PcepImplBundleTest.java
pcep/ietf-stateful02/.project [new file with mode: 0644]
pcep/ietf-stateful02/pom.xml [new file with mode: 0644]
pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-pce-initiated-lsp-00.yang [new file with mode: 0644]
pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-stateful-pce-02.yang [new file with mode: 0644]
pcep/impl/pom.xml
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/InitiatedActivator.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/LSPCleanupTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PCEStatefulCapabilityTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PcinitiateMessageParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/message/AbstractMessageParser.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspDbVersionTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv4TlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv6TlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspSymbolicNameTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspUpdateErrorTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPLspObjectParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPReportMessageParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPUpdateRequestMessageParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEStatefulCapabilityTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/RSVPErrorSpecTlvParser.java [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/StatefulActivator.java [new file with mode: 0644]
pcep/pom.xml

index e01f538c0542a2249e23b9b5eda52444e453187e..517c744502ff3c33deb86f4084701b943fd88b37 100644 (file)
@@ -14,7 +14,7 @@ import com.google.common.collect.Lists;
 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
diff --git a/pcep/ietf-stateful02/.project b/pcep/ietf-stateful02/.project
new file mode 100644 (file)
index 0000000..4e0dbfd
--- /dev/null
@@ -0,0 +1,24 @@
+<?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>
diff --git a/pcep/ietf-stateful02/pom.xml b/pcep/ietf-stateful02/pom.xml
new file mode 100644 (file)
index 0000000..c4383a6
--- /dev/null
@@ -0,0 +1,79 @@
+<?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>
diff --git a/pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-pce-initiated-lsp-00.yang b/pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-pce-initiated-lsp-00.yang
new file mode 100644 (file)
index 0000000..d766cfe
--- /dev/null
@@ -0,0 +1,73 @@
+ 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;
+       }
+}
diff --git a/pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-stateful-pce-02.yang b/pcep/ietf-stateful02/src/main/yang/draft-crabbe-pce-stateful-pce-02.yang
new file mode 100644 (file)
index 0000000..9e8a92a
--- /dev/null
@@ -0,0 +1,272 @@
+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;
+       }
+}
index 87702a002e26f1b5103fb33ea402e55733f9883a..14959b471ca7ae588aa494d23e99479e1e5059c3 100644 (file)
             <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>
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/InitiatedActivator.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/InitiatedActivator.java
new file mode 100644 (file)
index 0000000..7fa2aba
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/LSPCleanupTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/LSPCleanupTlvParser.java
new file mode 100644 (file)
index 0000000..6317439
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PCEStatefulCapabilityTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PCEStatefulCapabilityTlvParser.java
new file mode 100644 (file)
index 0000000..c3dd740
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * 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
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PcinitiateMessageParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/initiated00/PcinitiateMessageParser.java
new file mode 100644 (file)
index 0000000..764b1f0
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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;
+       }
+}
index 6452e555512d6031d8db3ca538af7fe018fcf7b2..0acbec114d2a2ea7003db6280109a6e48d996476 100644 (file)
@@ -36,7 +36,7 @@ import com.google.common.base.Preconditions;
 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;
 
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspDbVersionTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspDbVersionTlvParser.java
new file mode 100644 (file)
index 0000000..3934d83
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv4TlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv4TlvParser.java
new file mode 100644 (file)
index 0000000..f48fc69
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv6TlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspIdentifierIpv6TlvParser.java
new file mode 100644 (file)
index 0000000..4e09734
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspSymbolicNameTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspSymbolicNameTlvParser.java
new file mode 100644 (file)
index 0000000..740f97f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspUpdateErrorTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/LspUpdateErrorTlvParser.java
new file mode 100644 (file)
index 0000000..b6a7c05
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPLspObjectParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPLspObjectParser.java
new file mode 100644 (file)
index 0000000..84aa786
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPReportMessageParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPReportMessageParser.java
new file mode 100644 (file)
index 0000000..1de8cac
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPUpdateRequestMessageParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEPUpdateRequestMessageParser.java
new file mode 100644 (file)
index 0000000..67231db
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEStatefulCapabilityTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/PCEStatefulCapabilityTlvParser.java
new file mode 100644 (file)
index 0000000..5600034
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/RSVPErrorSpecTlvParser.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/RSVPErrorSpecTlvParser.java
new file mode 100644 (file)
index 0000000..513f99d
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * 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;
+       }
+}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/StatefulActivator.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/stateful02/StatefulActivator.java
new file mode 100644 (file)
index 0000000..75aac32
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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;
+       }
+}
index 35c656eebce9cce8c39218a9071418e8b62b503b..43c946aaa8ffccfe2ef1c5cf062e3a6d5ca585a0 100644 (file)
@@ -27,6 +27,7 @@
     <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>