2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.protocol.bgp.evpn.impl.attributes.tunnel.identifier;
11 import com.google.common.base.Joiner;
12 import com.google.common.base.Splitter;
13 import io.netty.buffer.ByteBuf;
14 import io.netty.buffer.ByteBufUtil;
15 import java.util.ArrayList;
16 import java.util.List;
17 import javax.xml.bind.DatatypeConverter;
18 import org.opendaylight.protocol.util.ByteArray;
19 import org.opendaylight.protocol.util.ByteBufWriteUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev160812.Opaque;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev160812.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValue;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev160812.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValueBuilder;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 final class OpaqueUtil {
28 static final short GENERIC_LSP_IDENTIFIER = 1;
29 static final short EXTENDED_TYPE = 255;
30 private static final Logger LOG = LoggerFactory.getLogger(OpaqueUtil.class);
31 private static final String SEPARATOR = ":";
32 private static final String EMPTY_SEPARATOR = "";
34 private OpaqueUtil() {
35 throw new UnsupportedOperationException();
38 static boolean serializeOpaque(final Opaque opaque, final ByteBuf byteBuf) {
39 final Short type = opaque.getOpaqueType();
41 case GENERIC_LSP_IDENTIFIER:
42 ByteBufWriteUtil.writeUnsignedByte(type, byteBuf);
43 writeGeneric(opaque.getOpaque(), byteBuf);
46 ByteBufWriteUtil.writeUnsignedByte(type, byteBuf);
47 writeExtended(opaque.getOpaque(), opaque.getOpaqueExtendedType(), byteBuf);
50 LOG.debug("Skipping serialization of Opaque Value {}", opaque);
56 private static void writeExtended(final HexString opaque, final Integer opaqueExtendedType, final ByteBuf byteBuf) {
57 final byte[] output = writeOpaqueValue(opaque.getValue());
58 ByteBufWriteUtil.writeUnsignedShort(opaqueExtendedType, byteBuf);
59 ByteBufWriteUtil.writeUnsignedShort(output.length, byteBuf);
60 byteBuf.writeBytes(output);
63 private static void writeGeneric(final HexString opaque, final ByteBuf byteBuf) {
64 final byte[] output = writeOpaqueValue(opaque.getValue());
65 ByteBufWriteUtil.writeUnsignedShort(output.length, byteBuf);
66 byteBuf.writeBytes(output);
69 private static byte[] writeOpaqueValue(final String opaque) {
70 final String joined = opaque.replace(SEPARATOR, EMPTY_SEPARATOR);
71 return DatatypeConverter.parseHexBinary(joined);
74 static Opaque parseOpaque(final ByteBuf buffer) {
75 final short type = buffer.readUnsignedByte();
76 final OpaqueValueBuilder builder = new OpaqueValueBuilder();
78 case GENERIC_LSP_IDENTIFIER:
79 builder.setOpaque(buildOpaqueValue(buffer));
82 buildExtended(builder, buffer);
85 final int length = buffer.readUnsignedShort();
86 buffer.skipBytes(length);
87 LOG.debug("Skipping parsing of Opaque Value {}", buffer);
90 builder.setOpaqueType(type);
91 return builder.build();
94 private static void buildExtended(final OpaqueValueBuilder builder, final ByteBuf buffer) {
95 final int extendedType = buffer.readUnsignedShort();
96 final HexString opaqueValue = buildOpaqueValue(buffer);
97 builder.setOpaqueExtendedType(extendedType).setOpaque(opaqueValue);
100 private static HexString buildOpaqueValue(final ByteBuf buffer) {
101 final int length = buffer.readUnsignedShort();
102 final byte[] value = ByteArray.readBytes(buffer, length);
103 final String hexDump = ByteBufUtil.hexDump(value);
104 final Iterable<String> splitted = Splitter.fixedLength(2).split(hexDump);
105 return new HexString(Joiner.on(SEPARATOR).join(splitted));
108 static List<OpaqueValue> parseOpaqueList(final ByteBuf byteBuf) {
109 final List<OpaqueValue> opaqueValues = new ArrayList<>();
110 while (byteBuf.isReadable()) {
111 final Opaque opaque = parseOpaque(byteBuf);
112 if (opaque != null) {
113 opaqueValues.add((OpaqueValue) opaque);
119 static boolean serializeOpaqueList(final List<OpaqueValue> mldpP2mpLsp, final ByteBuf buffer) {
120 boolean parsed = false;
121 for (final OpaqueValue opaque : mldpP2mpLsp) {
122 if (serializeOpaque(opaque, buffer)) {