2 * Copyright (c) 2013 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.pcep.impl;
10 import java.util.ArrayList;
11 import java.util.List;
13 import org.opendaylight.protocol.concepts.IPv4Prefix;
14 import org.opendaylight.protocol.concepts.IPv6Prefix;
15 import org.opendaylight.protocol.pcep.PCEPDeserializerException;
16 import org.opendaylight.protocol.pcep.impl.subobject.EROExplicitExclusionRouteSubobjectParser;
17 import org.opendaylight.protocol.pcep.impl.subobject.EROLabelSubobjectParser;
18 import org.opendaylight.protocol.pcep.impl.subobject.EROPathKeyWith128PCEIDSubobjectParser;
19 import org.opendaylight.protocol.pcep.impl.subobject.EROPathKeyWith32PCEIDSubobjectParser;
20 import org.opendaylight.protocol.pcep.impl.subobject.EROProtectionSubobjectParser;
21 import org.opendaylight.protocol.pcep.impl.subobject.EROUnnumberedInterfaceSubobjectParser;
22 import org.opendaylight.protocol.pcep.subobject.EROAsNumberSubobject;
23 import org.opendaylight.protocol.pcep.subobject.EROExplicitExclusionRouteSubobject;
24 import org.opendaylight.protocol.pcep.subobject.EROIPPrefixSubobject;
25 import org.opendaylight.protocol.pcep.subobject.EROLabelSubobject;
26 import org.opendaylight.protocol.pcep.subobject.EROPathKeyWith128PCEIDSubobject;
27 import org.opendaylight.protocol.pcep.subobject.EROPathKeyWith32PCEIDSubobject;
28 import org.opendaylight.protocol.pcep.subobject.EROProtectionSubobject;
29 import org.opendaylight.protocol.pcep.subobject.EROUnnumberedInterfaceSubobject;
30 import org.opendaylight.protocol.pcep.subobject.ExplicitRouteSubobject;
31 import org.opendaylight.protocol.util.ByteArray;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * Parser for {@link org.opendaylight.protocol.pcep.PCEPSubobject PCEPSubobject}
38 public class PCEPEROSubobjectParser {
40 private static final Logger logger = LoggerFactory.getLogger(PCEPEROSubobjectParser.class);
43 * Type identifier for {@link org.opendaylight.protocol.pcep.PCEPSubobject PCEPSubobject}
45 public enum PCEPSubobjectType {
46 IPv4_PREFIX(1), IPv6_PREFIX(2), LABEL(3), UNNUMBERED_INTERFACE_ID(4), AS_NUMBER(32), EXRS(33), PROTECTION(37), PK_32(64), PK_128(65);
48 private final int indicator;
50 PCEPSubobjectType(final int indicator) {
51 this.indicator = indicator;
54 public int getIndicator() {
55 return this.indicator;
58 public static PCEPSubobjectType getFromInt(final int type) throws PCEPDeserializerException {
60 for (final PCEPSubobjectType type_e : PCEPSubobjectType.values()) {
61 if (type_e.getIndicator() == type)
65 throw new PCEPDeserializerException("Unknown Subobject type. Passed: " + type + "; Known: " + PCEPSubobjectType.values() + ".");
70 * Fields lengths in Bytes
72 public static final int TYPE_FLAG_F_LENGTH = 1;
73 public static final int LENGTH_F_LENGTH = 1;
76 * Fields offsets in Bytes
78 public static final int TYPE_FLAG_F_OFFSET = 0;
79 public static final int LENGTH_F_OFFSET = TYPE_FLAG_F_OFFSET + TYPE_FLAG_F_LENGTH;
80 public static final int SO_CONTENTS_OFFSET = LENGTH_F_OFFSET + LENGTH_F_LENGTH;
82 public static List<ExplicitRouteSubobject> parse(final byte[] bytes) throws PCEPDeserializerException {
84 throw new IllegalArgumentException("Byte array is mandatory.");
86 final List<ExplicitRouteSubobject> subobjsList = new ArrayList<ExplicitRouteSubobject>();
88 PCEPSubobjectType type;
89 byte[] soContentsBytes;
93 while (offset < bytes.length) {
95 loose_flag = ((bytes[offset + TYPE_FLAG_F_OFFSET] & (1 << 7)) != 0) ? true : false;
96 length = ByteArray.bytesToInt(ByteArray.subByte(bytes, offset + LENGTH_F_OFFSET, LENGTH_F_LENGTH));
98 type = PCEPSubobjectType.getFromInt((bytes[offset + TYPE_FLAG_F_OFFSET] & 0xff) & ~(1 << 7));
100 if (length > bytes.length - offset)
101 throw new PCEPDeserializerException("Wrong length specified. Passed: " + length + "; Expected: <= "
102 + (bytes.length - offset));
104 soContentsBytes = new byte[length - SO_CONTENTS_OFFSET];
105 System.arraycopy(bytes, offset + SO_CONTENTS_OFFSET, soContentsBytes, 0, length - SO_CONTENTS_OFFSET);
107 logger.debug("Attempt to parse subobject from bytes: {}", ByteArray.bytesToHexString(soContentsBytes));
108 final ExplicitRouteSubobject subObj = parseSpecificSubobject(type, soContentsBytes, loose_flag);
109 logger.debug("Subobject was parsed. {}", subObj);
111 subobjsList.add(subObj);
119 public static byte[] put(final List<ExplicitRouteSubobject> objsToSerialize) {
120 final List<byte[]> bytesList = new ArrayList<byte[]>(objsToSerialize.size());
123 for (final ExplicitRouteSubobject obj : objsToSerialize) {
124 final byte[] bytes = put(obj);
125 length += bytes.length;
126 bytesList.add(bytes);
129 final byte[] retBytes = new byte[length];
132 for (final byte[] bytes : bytesList) {
133 System.arraycopy(bytes, 0, retBytes, offset, bytes.length);
134 offset += bytes.length;
140 public static byte[] put(final ExplicitRouteSubobject objToSerialize) {
141 int typeIndicator = 0;
143 byte[] soContentsBytes = null;
145 if (objToSerialize instanceof EROIPPrefixSubobject<?>
146 && ((EROIPPrefixSubobject<?>) objToSerialize).getPrefix() instanceof IPv4Prefix) {
147 typeIndicator = PCEPSubobjectType.IPv4_PREFIX.getIndicator();
148 // soContentsBytes = EROIpPrefixSubobjectParser.put(objToSerialize);
149 } else if (objToSerialize instanceof EROIPPrefixSubobject<?>
150 && ((EROIPPrefixSubobject<?>) objToSerialize).getPrefix() instanceof IPv6Prefix) {
151 typeIndicator = PCEPSubobjectType.IPv6_PREFIX.getIndicator();
152 // soContentsBytes = EROIPv6PrefixSubobjectParser.put(objToSerialize);
153 } else if (objToSerialize instanceof EROAsNumberSubobject) {
154 typeIndicator = PCEPSubobjectType.AS_NUMBER.getIndicator();
155 // soContentsBytes = EROAsNumberSubobjectParser.put(objToSerialize);
156 } else if (objToSerialize instanceof EROUnnumberedInterfaceSubobject) {
157 typeIndicator = PCEPSubobjectType.UNNUMBERED_INTERFACE_ID.getIndicator();
158 soContentsBytes = EROUnnumberedInterfaceSubobjectParser.put(objToSerialize);
159 } else if (objToSerialize instanceof EROLabelSubobject) {
160 typeIndicator = PCEPSubobjectType.LABEL.getIndicator();
161 soContentsBytes = EROLabelSubobjectParser.put((EROLabelSubobject) objToSerialize);
162 } else if (objToSerialize instanceof EROExplicitExclusionRouteSubobject) {
163 typeIndicator = PCEPSubobjectType.EXRS.getIndicator();
164 soContentsBytes = EROExplicitExclusionRouteSubobjectParser.put((EROExplicitExclusionRouteSubobject) objToSerialize);
165 } else if (objToSerialize instanceof EROPathKeyWith32PCEIDSubobject) {
166 typeIndicator = PCEPSubobjectType.PK_32.getIndicator();
167 soContentsBytes = EROPathKeyWith32PCEIDSubobjectParser.put((EROPathKeyWith32PCEIDSubobject) objToSerialize);
168 } else if (objToSerialize instanceof EROPathKeyWith128PCEIDSubobject) {
169 typeIndicator = PCEPSubobjectType.PK_128.getIndicator();
170 soContentsBytes = EROPathKeyWith128PCEIDSubobjectParser.put((EROPathKeyWith128PCEIDSubobject) objToSerialize);
171 } else if (objToSerialize instanceof EROProtectionSubobject) {
172 typeIndicator = PCEPSubobjectType.PROTECTION.getIndicator();
173 soContentsBytes = EROProtectionSubobjectParser.put((EROProtectionSubobject) objToSerialize);
175 throw new IllegalArgumentException("Unknown instance of PCEPSubobject. Passed: " + objToSerialize.getClass() + ".");
177 final byte[] bytes = new byte[SO_CONTENTS_OFFSET + soContentsBytes.length];
179 bytes[TYPE_FLAG_F_OFFSET] = (byte) (ByteArray.cutBytes(ByteArray.intToBytes(typeIndicator), (Integer.SIZE / 8) - TYPE_FLAG_F_LENGTH)[0] | (objToSerialize.isLoose() ? 1 << 7
181 bytes[LENGTH_F_OFFSET] = ByteArray.cutBytes(ByteArray.intToBytes(soContentsBytes.length + SO_CONTENTS_OFFSET), (Integer.SIZE / 8)
182 - LENGTH_F_LENGTH)[0];
184 System.arraycopy(soContentsBytes, 0, bytes, SO_CONTENTS_OFFSET, soContentsBytes.length);
189 private static ExplicitRouteSubobject parseSpecificSubobject(final PCEPSubobjectType type, final byte[] soContentsBytes,
190 final boolean loose_flag) throws PCEPDeserializerException {
194 // return EROIpPrefixSubobjectParser.parse(soContentsBytes, loose_flag);
196 // return EROIPv6PrefixSubobjectParser.parse(soContentsBytes, loose_flag);
197 case UNNUMBERED_INTERFACE_ID:
198 return EROUnnumberedInterfaceSubobjectParser.parse(soContentsBytes, loose_flag);
200 // return EROAsNumberSubobjectParser.parse(soContentsBytes, loose_flag);
202 return EROLabelSubobjectParser.parse(soContentsBytes, loose_flag);
204 return EROExplicitExclusionRouteSubobjectParser.parse(soContentsBytes, loose_flag);
206 return EROPathKeyWith32PCEIDSubobjectParser.parse(soContentsBytes, loose_flag);
208 return EROPathKeyWith128PCEIDSubobjectParser.parse(soContentsBytes, loose_flag);
210 return EROProtectionSubobjectParser.parse(soContentsBytes, loose_flag);
212 throw new PCEPDeserializerException("Unknown Subobject type. Passed: " + type + ".");