Merge "Fixed write of uptodate to explicitly set routes."
[bgpcep.git] / pcep / ietf-stateful02 / src / main / java / org / opendaylight / protocol / pcep / ietf / stateful02 / Stateful02RSVPErrorSpecTlvParser.java
1 /*
2  * Copyright (c) 2014 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.ietf.stateful02;
9
10 import java.util.BitSet;
11
12 import org.opendaylight.protocol.concepts.Ipv4Util;
13 import org.opendaylight.protocol.concepts.Ipv6Util;
14 import org.opendaylight.protocol.pcep.impl.tlv.TlvUtil;
15 import org.opendaylight.protocol.pcep.spi.PCEPDeserializerException;
16 import org.opendaylight.protocol.pcep.spi.TlvParser;
17 import org.opendaylight.protocol.pcep.spi.TlvSerializer;
18 import org.opendaylight.protocol.util.ByteArray;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpec;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.RsvpErrorSpecBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.RsvpError;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.rsvp.error.spec.tlv.rsvp.error.spec.RsvpErrorBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Tlv;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev130820.ErrorSpec.Flags;
26
27 import com.google.common.primitives.UnsignedBytes;
28
29 /**
30  * Parser for {@link RsvpErrorSpec}
31  */
32 public final class Stateful02RSVPErrorSpecTlvParser implements TlvParser, TlvSerializer {
33
34         public static final int TYPE = 21;
35
36         private static final int IP4_F_LENGTH = 4;
37         private static final int IP6_F_LENGTH = 16;
38         private static final int FLAGS_F_LENGTH = 1;
39         private static final int ERROR_CODE_F_LENGTH = 1;
40         private static final int ERROR_VALUE_F_LENGTH = 2;
41
42         private static final int IN_PLACE_FLAG_OFFSET = 7;
43         private static final int NOT_GUILTY_FLAGS_OFFSET = 6;
44
45         private static final int V4_RSVP_LENGTH = 8;
46         private static final int V6_RSVP_LENGTH = 20;
47
48         @Override
49         public RsvpErrorSpec parseTlv(final byte[] valueBytes) throws PCEPDeserializerException {
50                 if (valueBytes == null || valueBytes.length == 0) {
51                         throw new IllegalArgumentException("Value bytes array is mandatory. Can't be null or empty.");
52                 }
53                 int byteOffset = 0;
54                 final RsvpErrorBuilder builder = new RsvpErrorBuilder();
55                 if (valueBytes.length == V4_RSVP_LENGTH) {
56                         builder.setNode(new IpAddress(Ipv4Util.addressForBytes(ByteArray.subByte(valueBytes, byteOffset, IP4_F_LENGTH))));
57                         byteOffset += IP4_F_LENGTH;
58                 } else if (valueBytes.length == V6_RSVP_LENGTH) {
59                         builder.setNode(new IpAddress(Ipv6Util.addressForBytes(ByteArray.subByte(valueBytes, byteOffset, IP6_F_LENGTH))));
60                         byteOffset += IP6_F_LENGTH;
61                 }
62                 final BitSet flags = ByteArray.bytesToBitSet(ByteArray.subByte(valueBytes, byteOffset, FLAGS_F_LENGTH));
63                 byteOffset += FLAGS_F_LENGTH;
64                 builder.setFlags(new Flags(flags.get(IN_PLACE_FLAG_OFFSET), flags.get(NOT_GUILTY_FLAGS_OFFSET)));
65                 final short errorCode = (short) UnsignedBytes.toInt(valueBytes[byteOffset]);
66                 byteOffset += ERROR_CODE_F_LENGTH;
67                 builder.setCode(errorCode);
68                 final int errorValue = (ByteArray.bytesToShort(ByteArray.subByte(valueBytes, byteOffset, ERROR_VALUE_F_LENGTH)) & 0xFFFF);
69                 builder.setValue(errorValue);
70                 return new RsvpErrorSpecBuilder().setRsvpError(builder.build()).build();
71         }
72
73         @Override
74         public byte[] serializeTlv(final Tlv tlv) {
75                 if (tlv == null) {
76                         throw new IllegalArgumentException("RSVPErrorSpecTlv is mandatory.");
77                 }
78                 final RsvpErrorSpec rsvpTlv = (RsvpErrorSpec) tlv;
79                 final RsvpError rsvp = rsvpTlv.getRsvpError();
80                 final BitSet flags = new BitSet(FLAGS_F_LENGTH * Byte.SIZE);
81                 flags.set(IN_PLACE_FLAG_OFFSET, rsvp.getFlags().isInPlace());
82                 flags.set(NOT_GUILTY_FLAGS_OFFSET, rsvp.getFlags().isNotGuilty());
83                 int offset = 0;
84                 final IpAddress node = rsvp.getNode();
85                 byte[] bytes;
86                 if (node.getIpv4Address() != null) {
87                         bytes = new byte[V4_RSVP_LENGTH];
88                         ByteArray.copyWhole(Ipv4Util.bytesForAddress(node.getIpv4Address()), bytes, offset);
89                         offset += IP4_F_LENGTH;
90                 } else {
91                         bytes = new byte[V6_RSVP_LENGTH];
92                         ByteArray.copyWhole(Ipv6Util.bytesForAddress(node.getIpv6Address()), bytes, offset);
93                         offset += IP6_F_LENGTH;
94                 }
95                 bytes[offset] = ByteArray.bitSetToBytes(flags, FLAGS_F_LENGTH)[0];
96                 offset += FLAGS_F_LENGTH;
97                 bytes[offset] = UnsignedBytes.checkedCast(rsvp.getCode());
98                 offset += ERROR_CODE_F_LENGTH;
99                 final byte[] value = ByteArray.intToBytes(rsvp.getValue().intValue(), ERROR_VALUE_F_LENGTH);
100                 ByteArray.copyWhole(value, bytes, offset);
101                 return TlvUtil.formatTlv(TYPE, bytes);
102         }
103
104         @Override
105         public int getType() {
106                 return TYPE;
107         }
108 }