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
8 package org.opendaylight.protocol.bgp.mvpn.impl.attributes;
10 import com.google.common.base.Joiner;
11 import com.google.common.base.Splitter;
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.ByteBufUtil;
14 import java.util.ArrayList;
15 import java.util.List;
16 import javax.xml.bind.DatatypeConverter;
17 import org.opendaylight.protocol.util.ByteArray;
18 import org.opendaylight.protocol.util.ByteBufWriteUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.Opaque;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValue;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.pmsi.tunnel.pmsi.tunnel.tunnel.identifier.mldp.p2mp.lsp.mldp.p2mp.lsp.OpaqueValueBuilder;
23 import org.opendaylight.yangtools.yang.common.Uint16;
24 import org.opendaylight.yangtools.yang.common.Uint8;
25 import org.opendaylight.yangtools.yang.common.netty.ByteBufUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
29 public final class OpaqueUtil {
30 public static final short GENERIC_LSP_IDENTIFIER = 1;
31 public static final short EXTENDED_TYPE = 255;
32 private static final Logger LOG = LoggerFactory.getLogger(OpaqueUtil.class);
33 private static final String SEPARATOR = ":";
34 private static final String EMPTY_SEPARATOR = "";
36 private OpaqueUtil() {
40 public static boolean serializeOpaque(final Opaque opaque, final ByteBuf byteBuf) {
41 final Uint8 type = opaque.getOpaqueType();
42 switch (type.toJava()) {
43 case GENERIC_LSP_IDENTIFIER:
44 ByteBufWriteUtil.writeUnsignedByte(type, byteBuf);
45 writeGeneric(opaque.getOpaque(), byteBuf);
48 ByteBufWriteUtil.writeUnsignedByte(type, byteBuf);
49 writeExtended(opaque.getOpaque(), opaque.getOpaqueExtendedType(), byteBuf);
52 LOG.debug("Skipping serialization of Opaque Value {}", opaque);
58 private static void writeExtended(final HexString opaque, final Uint16 opaqueExtendedType, final ByteBuf byteBuf) {
59 final byte[] output = writeOpaqueValue(opaque.getValue());
60 ByteBufWriteUtil.writeUnsignedShort(opaqueExtendedType, byteBuf);
61 byteBuf.writeShort(output.length);
62 byteBuf.writeBytes(output);
65 private static void writeGeneric(final HexString opaque, final ByteBuf byteBuf) {
66 final byte[] output = writeOpaqueValue(opaque.getValue());
67 byteBuf.writeShort(output.length);
68 byteBuf.writeBytes(output);
71 private static byte[] writeOpaqueValue(final String opaque) {
72 final String joined = opaque.replace(SEPARATOR, EMPTY_SEPARATOR);
73 return DatatypeConverter.parseHexBinary(joined);
76 public static Opaque parseOpaque(final ByteBuf buffer) {
77 final Uint8 type = ByteBufUtils.readUint8(buffer);
78 final OpaqueValueBuilder builder = new OpaqueValueBuilder();
79 switch (type.toJava()) {
80 case GENERIC_LSP_IDENTIFIER:
81 builder.setOpaque(buildOpaqueValue(buffer));
84 buildExtended(builder, buffer);
87 final int length = buffer.readUnsignedShort();
88 buffer.skipBytes(length);
89 LOG.debug("Skipping parsing of Opaque Value {}", buffer);
92 builder.setOpaqueType(type);
93 return builder.build();
96 private static void buildExtended(final OpaqueValueBuilder builder, final ByteBuf buffer) {
97 final Uint16 extendedType = ByteBufUtils.readUint16(buffer);
98 final HexString opaqueValue = buildOpaqueValue(buffer);
99 builder.setOpaqueExtendedType(extendedType).setOpaque(opaqueValue);
102 private static HexString buildOpaqueValue(final ByteBuf buffer) {
103 final int length = buffer.readUnsignedShort();
104 final byte[] value = ByteArray.readBytes(buffer, length);
105 final String hexDump = ByteBufUtil.hexDump(value);
106 final Iterable<String> splitted = Splitter.fixedLength(2).split(hexDump);
107 return new HexString(Joiner.on(SEPARATOR).join(splitted));
110 public static List<OpaqueValue> parseOpaqueList(final ByteBuf byteBuf) {
111 final List<OpaqueValue> opaqueValues = new ArrayList<>();
112 while (byteBuf.isReadable()) {
113 final Opaque opaque = parseOpaque(byteBuf);
114 if (opaque != null) {
115 opaqueValues.add((OpaqueValue) opaque);
121 public static boolean serializeOpaqueList(final List<OpaqueValue> mldpP2mpLsp, final ByteBuf buffer) {
122 boolean parsed = false;
123 for (final OpaqueValue opaque : mldpP2mpLsp) {
124 if (serializeOpaque(opaque, buffer)) {