8a70dec5c40d0d55488d2174fa7342368a621bf4
[bgpcep.git] / pcep / impl / src / main / java / org / opendaylight / protocol / pcep / impl / subobject / RROIpPrefixSubobjectParser.java
1 /*
2  * Copyright (c) 2013 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.pcep.impl.subobject;
9
10 import java.util.Arrays;
11 import java.util.BitSet;
12
13 import org.opendaylight.protocol.concepts.Ipv4Util;
14 import org.opendaylight.protocol.concepts.Ipv6Util;
15 import org.opendaylight.protocol.pcep.PCEPDeserializerException;
16 import org.opendaylight.protocol.pcep.spi.RROSubobjectParser;
17 import org.opendaylight.protocol.pcep.spi.RROSubobjectSerializer;
18 import org.opendaylight.protocol.util.ByteArray;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.Subobjects;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.reported.route.object.SubobjectsBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.IpPrefixSubobject;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.record.route.subobjects.subobject.type.IpPrefixBuilder;
24
25 import com.google.common.primitives.UnsignedBytes;
26
27 /**
28  * Parser for {@link org.opendaylight.protocol.pcep.subobject.RROIPAddressSubobject RROIPAddressSubobject<IPv4Prefix>}
29  */
30 public class RROIpPrefixSubobjectParser implements RROSubobjectParser, RROSubobjectSerializer {
31
32         public static final int TYPE = 1;
33
34         public static final int TYPE6 = 2;
35
36         private static final int IP4_F_LENGTH = 4;
37         private static final int IP_F_LENGTH = 16;
38
39         private static final int PREFIX_F_LENGTH = 1;
40         private static final int FLAGS_F_LENGTH = 1;
41
42         private static final int IP_F_OFFSET = 0;
43
44         private static final int PREFIX4_F_OFFSET = IP_F_OFFSET + IP4_F_LENGTH;
45         private static final int FLAGS4_F_OFFSET = PREFIX4_F_OFFSET + PREFIX_F_LENGTH;
46
47         private static final int CONTENT4_LENGTH = IP4_F_LENGTH + PREFIX_F_LENGTH + FLAGS_F_LENGTH;
48
49         private static final int PREFIX_F_OFFSET = IP_F_OFFSET + IP_F_LENGTH;
50         private static final int FLAGS_F_OFFSET = PREFIX_F_OFFSET + PREFIX_F_LENGTH;
51
52         private static final int CONTENT_LENGTH = IP_F_LENGTH + PREFIX_F_LENGTH + FLAGS_F_LENGTH;
53
54         private static final int LPA_F_OFFSET = 7;
55         private static final int LPIU_F_OFFSET = 6;
56
57         @Override
58         public Subobjects parseSubobject(final byte[] buffer) throws PCEPDeserializerException {
59                 if (buffer == null || buffer.length == 0) {
60                         throw new IllegalArgumentException("Array of bytes is mandatory. Can't be null or empty.");
61                 }
62                 final SubobjectsBuilder builder = new SubobjectsBuilder();
63                 if (buffer.length == CONTENT4_LENGTH) {
64                         final int length = UnsignedBytes.toInt(buffer[PREFIX4_F_OFFSET]);
65                         final BitSet flags = ByteArray.bytesToBitSet(Arrays.copyOfRange(buffer, FLAGS4_F_OFFSET, FLAGS4_F_OFFSET + FLAGS_F_LENGTH));
66                         builder.setProtectionAvailable(flags.get(LPA_F_OFFSET));
67                         builder.setProtectionInUse(flags.get(LPIU_F_OFFSET));
68                         builder.setSubobjectType(new IpPrefixBuilder().setIpPrefix(
69                                         new IpPrefix(Ipv4Util.prefixForBytes(ByteArray.subByte(buffer, IP_F_OFFSET, IP4_F_LENGTH), length))).build());
70                 } else if (buffer.length == CONTENT_LENGTH) {
71                         final int length = UnsignedBytes.toInt(buffer[PREFIX_F_OFFSET]);
72                         final BitSet flags = ByteArray.bytesToBitSet(Arrays.copyOfRange(buffer, FLAGS_F_OFFSET, FLAGS_F_OFFSET + FLAGS_F_LENGTH));
73                         builder.setProtectionAvailable(flags.get(LPA_F_OFFSET));
74                         builder.setProtectionInUse(flags.get(LPIU_F_OFFSET));
75                         builder.setSubobjectType(new IpPrefixBuilder().setIpPrefix(
76                                         new IpPrefix(Ipv6Util.prefixForBytes(ByteArray.subByte(buffer, IP_F_OFFSET, IP_F_LENGTH), length))).build());
77                 } else {
78                         throw new PCEPDeserializerException("Wrong length of array of bytes. Passed: " + buffer.length + ";");
79                 }
80                 return builder.build();
81         }
82
83         @Override
84         public byte[] serializeSubobject(final Subobjects subobject) {
85                 if (!(subobject.getSubobjectType() instanceof IpPrefixSubobject)) {
86                         throw new IllegalArgumentException("Unknown ReportedRouteSubobject instance. Passed " + subobject.getClass()
87                                         + ". Needed RROIPAddressSubobject.");
88                 }
89
90                 final IpPrefixSubobject specObj = (IpPrefixSubobject) subobject.getSubobjectType();
91                 final IpPrefix prefix = specObj.getIpPrefix();
92
93                 if (prefix.getIpv4Prefix() == null && prefix.getIpv6Prefix() == null) {
94                         throw new IllegalArgumentException("Unknown AbstractPrefix instance. Passed " + prefix.getClass() + ".");
95                 }
96
97                 final BitSet flags = new BitSet(FLAGS_F_LENGTH * Byte.SIZE);
98                 flags.set(LPA_F_OFFSET, subobject.isProtectionAvailable());
99                 flags.set(LPIU_F_OFFSET, subobject.isProtectionInUse());
100
101                 if (prefix.getIpv4Prefix() != null) {
102                         final byte[] retBytes = new byte[CONTENT4_LENGTH];
103                         ByteArray.copyWhole(Ipv4Util.bytesForPrefix(prefix.getIpv4Prefix()), retBytes, IP_F_OFFSET);
104                         retBytes[PREFIX4_F_OFFSET] = UnsignedBytes.checkedCast(Ipv4Util.getPrefixLength(prefix));
105                         ByteArray.copyWhole(ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH), retBytes, FLAGS4_F_OFFSET);
106                         return retBytes;
107                 } else {
108                         final byte[] retBytes = new byte[CONTENT_LENGTH];
109                         ByteArray.copyWhole(Ipv6Util.bytesForPrefix(prefix.getIpv6Prefix()), retBytes, IP_F_OFFSET);
110                         retBytes[PREFIX_F_OFFSET] = UnsignedBytes.checkedCast(Ipv4Util.getPrefixLength(prefix));
111                         ByteArray.copyWhole(ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH), retBytes, FLAGS_F_OFFSET);
112                         return retBytes;
113                 }
114         }
115
116         @Override
117         public int getType() {
118                 return TYPE;
119         }
120
121         public int getType6() {
122                 return TYPE6;
123         }
124 }