Bug-2064: Implementation of RFC5492 Error handling.
[bgpcep.git] / bgp / parser-impl / src / main / java / org / opendaylight / protocol / bgp / parser / impl / message / open / CapabilityParameterParser.java
index 254d63e42c01d3e4f4781a80995bc80350acee83..ddedab068a28fa9c05d35b0cc0867b554380d617 100644 (file)
@@ -8,13 +8,12 @@
 package org.opendaylight.protocol.bgp.parser.impl.message.open;
 
 import com.google.common.base.Preconditions;
-
+import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.Unpooled;
-
 import java.util.Arrays;
-
+import java.util.List;
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.CapabilityRegistry;
@@ -24,7 +23,9 @@ import org.opendaylight.protocol.bgp.parser.spi.ParameterUtil;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.CParameters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.OptionalCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.bgp.parameters.optional.capabilities.CParameters;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -44,30 +45,52 @@ public final class CapabilityParameterParser implements ParameterParser, Paramet
     @Override
     public BgpParameters parseParameter(final ByteBuf buffer) throws BGPParsingException, BGPDocumentedException {
         Preconditions.checkArgument(buffer != null && buffer.readableBytes() != 0, "Byte array cannot be null or empty.");
-        LOG.trace("Started parsing of BGP Capability: {}", Arrays.toString(ByteArray.getAllBytes(buffer)));
+        LOG.trace("Started parsing of BGP Capabilities: {}", Arrays.toString(ByteArray.getAllBytes(buffer)));
+        final List<OptionalCapabilities> optionalCapas = Lists.newArrayList();
+        while (buffer.isReadable()) {
+            final OptionalCapabilities optionalCapa = parseOptionalCapability(buffer);
+            if (optionalCapa != null) {
+                optionalCapas.add(optionalCapa);
+            }
+        }
+        return new BgpParametersBuilder().setOptionalCapabilities(optionalCapas).build();
+    }
+
+    private OptionalCapabilities parseOptionalCapability(final ByteBuf buffer) throws BGPDocumentedException, BGPParsingException {
         final int capCode = buffer.readUnsignedByte();
         final int capLength = buffer.readUnsignedByte();
         final ByteBuf paramBody = buffer.slice(buffer.readerIndex(), capLength);
+        buffer.skipBytes(capLength);
         final CParameters ret = this.reg.parseCapability(capCode, paramBody);
         if (ret == null) {
             LOG.debug("Ignoring unsupported capability {}", capCode);
             return null;
         }
-        return new BgpParametersBuilder().setCParameters(ret).build();
+        return new OptionalCapabilitiesBuilder().setCParameters(ret).build();
     }
 
     @Override
     public void serializeParameter(final BgpParameters parameter, ByteBuf byteAggregator) {
-        final CParameters cap = parameter.getCParameters();
-
-        LOG.trace("Started serializing BGP Capability: {}", cap);
+        if (parameter.getOptionalCapabilities() != null && !parameter.getOptionalCapabilities().isEmpty()) {
+            LOG.trace("Started serializing BGP Capability: {}", parameter.getOptionalCapabilities());
+            final ByteBuf buffer = Unpooled.buffer();
+            for (final OptionalCapabilities optionalCapa : parameter.getOptionalCapabilities()) {
+                serializeOptionalCapability(optionalCapa, buffer);
+            }
+            ParameterUtil.formatParameter(TYPE, buffer, byteAggregator);
+        }
+    }
 
-        final ByteBuf bytes = Unpooled.buffer();
-        this.reg.serializeCapability(cap,bytes);
-        if (bytes == null) {
-            throw new IllegalArgumentException("Unhandled capability class" + cap.getImplementedInterface());
+    private void serializeOptionalCapability(final OptionalCapabilities optionalCapa, final ByteBuf byteAggregator) {
+        if (optionalCapa.getCParameters() != null) {
+            final CParameters cap = optionalCapa.getCParameters();
+            final ByteBuf bytes = Unpooled.buffer();
+            this.reg.serializeCapability(cap, bytes);
+            if (bytes == null) {
+                throw new IllegalArgumentException("Unhandled capability class" + cap.getImplementedInterface());
+            }
+            LOG.trace("BGP capability serialized to: {}", ByteBufUtil.hexDump(bytes));
+            byteAggregator.writeBytes(bytes);
         }
-        LOG.trace("BGP capability serialized to: {}", ByteBufUtil.hexDump(bytes));
-        ParameterUtil.formatParameter(TYPE, bytes,byteAggregator);
     }
 }