Use IetfYangUtil.hexStringBytes()/hexStringFor()
[bgpcep.git] / bgp / extensions / mvpn / src / main / java / org / opendaylight / protocol / bgp / mvpn / impl / attributes / OpaqueUtil.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.mvpn.impl.attributes;
9
10 import io.netty.buffer.ByteBuf;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.opendaylight.protocol.util.ByteArray;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pmsi.tunnel.rev180329.Opaque;
17 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;
18 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;
19 import org.opendaylight.yangtools.yang.common.Uint16;
20 import org.opendaylight.yangtools.yang.common.Uint8;
21 import org.opendaylight.yangtools.yang.common.netty.ByteBufUtils;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24
25 public final class OpaqueUtil {
26     public static final short GENERIC_LSP_IDENTIFIER = 1;
27     public static final short EXTENDED_TYPE = 255;
28     private static final Logger LOG = LoggerFactory.getLogger(OpaqueUtil.class);
29
30     private OpaqueUtil() {
31         // Hidden on purpose
32     }
33
34     public static boolean serializeOpaque(final Opaque opaque, final ByteBuf byteBuf) {
35         final Uint8 type = opaque.getOpaqueType();
36         switch (type.toJava()) {
37             case GENERIC_LSP_IDENTIFIER:
38                 ByteBufUtils.write(byteBuf, type);
39                 writeGeneric(opaque.getOpaque(), byteBuf);
40                 break;
41             case EXTENDED_TYPE:
42                 ByteBufUtils.write(byteBuf, type);
43                 writeExtended(opaque.getOpaque(), opaque.getOpaqueExtendedType(), byteBuf);
44                 break;
45             default:
46                 LOG.debug("Skipping serialization of Opaque Value {}", opaque);
47                 return false;
48         }
49         return true;
50     }
51
52     private static void writeExtended(final HexString opaque, final Uint16 opaqueExtendedType, final ByteBuf byteBuf) {
53         final byte[] output = writeOpaqueValue(opaque);
54         ByteBufUtils.writeOrZero(byteBuf, opaqueExtendedType);
55         byteBuf.writeShort(output.length);
56         byteBuf.writeBytes(output);
57     }
58
59     private static void writeGeneric(final HexString opaque, final ByteBuf byteBuf) {
60         final byte[] output = writeOpaqueValue(opaque);
61         byteBuf.writeShort(output.length);
62         byteBuf.writeBytes(output);
63     }
64
65     private static byte[] writeOpaqueValue(final HexString opaque) {
66         return IetfYangUtil.INSTANCE.hexStringBytes(opaque);
67     }
68
69     public static Opaque parseOpaque(final ByteBuf buffer) {
70         final Uint8 type = ByteBufUtils.readUint8(buffer);
71         final OpaqueValueBuilder builder = new OpaqueValueBuilder();
72         switch (type.toJava()) {
73             case GENERIC_LSP_IDENTIFIER:
74                 builder.setOpaque(buildOpaqueValue(buffer));
75                 break;
76             case EXTENDED_TYPE:
77                 buildExtended(builder, buffer);
78                 break;
79             default:
80                 final int length = buffer.readUnsignedShort();
81                 buffer.skipBytes(length);
82                 LOG.debug("Skipping parsing of Opaque Value {}", buffer);
83                 return null;
84         }
85         return builder.setOpaqueType(type).build();
86     }
87
88     private static void buildExtended(final OpaqueValueBuilder builder, final ByteBuf buffer) {
89         final Uint16 extendedType = ByteBufUtils.readUint16(buffer);
90         final HexString opaqueValue = buildOpaqueValue(buffer);
91         builder.setOpaqueExtendedType(extendedType).setOpaque(opaqueValue);
92     }
93
94     private static HexString buildOpaqueValue(final ByteBuf buffer) {
95         final int length = buffer.readUnsignedShort();
96         return IetfYangUtil.INSTANCE.hexStringFor(ByteArray.readBytes(buffer, length));
97     }
98
99     public static List<OpaqueValue> parseOpaqueList(final ByteBuf byteBuf) {
100         final List<OpaqueValue> opaqueValues = new ArrayList<>();
101         while (byteBuf.isReadable()) {
102             final Opaque opaque = parseOpaque(byteBuf);
103             if (opaque != null) {
104                 opaqueValues.add((OpaqueValue) opaque);
105             }
106         }
107         return opaqueValues;
108     }
109
110     public static boolean serializeOpaqueList(final List<OpaqueValue> mldpP2mpLsp, final ByteBuf buffer) {
111         boolean parsed = false;
112         for (final OpaqueValue opaque : mldpP2mpLsp) {
113             if (serializeOpaque(opaque, buffer)) {
114                 parsed = true;
115             }
116         }
117         return parsed;
118     }
119 }