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.pcep.PCEPDeserializerException;
14 import org.opendaylight.protocol.pcep.impl.subobject.XROAsNumberSubobjectParser;
15 import org.opendaylight.protocol.pcep.impl.subobject.XROIPv4PrefixSubobjectParser;
16 import org.opendaylight.protocol.pcep.impl.subobject.XROIPv6PrefixSubobjectParser;
17 import org.opendaylight.protocol.pcep.impl.subobject.XROSRLGSubobjectParser;
18 import org.opendaylight.protocol.pcep.impl.subobject.XROUnnumberedInterfaceSubobjectParser;
19 import org.opendaylight.protocol.pcep.subobject.ExcludeRouteSubobject;
20 import org.opendaylight.protocol.pcep.subobject.XROAsNumberSubobject;
21 import org.opendaylight.protocol.pcep.subobject.XROIPPrefixSubobject;
22 import org.opendaylight.protocol.pcep.subobject.XROSRLGSubobject;
23 import org.opendaylight.protocol.pcep.subobject.XROUnnumberedInterfaceSubobject;
24 import org.opendaylight.protocol.util.ByteArray;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * Parser for {@link org.opendaylight.protocol.pcep.PCEPXROSubobject PCEPXROSubobject}
31 public class PCEPXROSubobjectParser {
33 private static final Logger logger = LoggerFactory.getLogger(PCEPXROSubobjectParser.class);
36 * Type identifier for {@link org.opendaylight.protocol.pcep.PCEPXROSubobject PCEPXROSubobject}
38 public enum PCEPXROSubobjectType {
39 IPv4_PREFIX(1), IPv6_PREFIX(2), UNNUMBERED_INTERFACE_ID(4), AS_NUMBER(32), SRLG(34);
41 private final int indicator;
43 PCEPXROSubobjectType(final int indicator) {
44 this.indicator = indicator;
47 public int getIndicator() {
48 return this.indicator;
51 public static PCEPXROSubobjectType getFromInt(final int type) throws PCEPDeserializerException {
53 for (final PCEPXROSubobjectType type_e : PCEPXROSubobjectType.values()) {
54 if (type_e.getIndicator() == type)
58 throw new PCEPDeserializerException("Unknown Subobject type. Passed: " + type + "; Known: " + PCEPXROSubobjectType.values()
64 * Fields lengths in Bytes
66 public static final int TYPE_FLAG_F_LENGTH = 1;
67 public static final int LENGTH_F_LENGTH = 1;
70 * Fields offsets in Bytes
72 public static final int TYPE_FLAG_F_OFFSET = 0;
73 public static final int LENGTH_F_OFFSET = TYPE_FLAG_F_OFFSET + TYPE_FLAG_F_LENGTH;
74 public static final int SO_CONTENTS_OFFSET = LENGTH_F_OFFSET + LENGTH_F_LENGTH;
76 public static List<ExcludeRouteSubobject> parse(final byte[] bytes) throws PCEPDeserializerException {
78 throw new IllegalArgumentException("Byte array is mandatory.");
80 final List<ExcludeRouteSubobject> subobjsList = new ArrayList<ExcludeRouteSubobject>();
81 boolean mandatoryFlag;
82 PCEPXROSubobjectType type;
83 byte[] soContentsBytes;
87 while (offset < bytes.length) {
89 mandatoryFlag = ((bytes[offset + TYPE_FLAG_F_OFFSET] & (1 << 7)) != 0);
90 length = ByteArray.bytesToInt(ByteArray.subByte(bytes, offset + LENGTH_F_OFFSET, LENGTH_F_LENGTH));
92 type = PCEPXROSubobjectType.getFromInt((bytes[offset + TYPE_FLAG_F_OFFSET] & 0xff) & ~(1 << 7));
94 if (length > bytes.length - offset)
95 throw new PCEPDeserializerException("Wrong length specified. Passed: " + length + "; Expected: <= "
96 + (bytes.length - offset));
98 soContentsBytes = new byte[length - SO_CONTENTS_OFFSET];
99 System.arraycopy(bytes, offset + SO_CONTENTS_OFFSET, soContentsBytes, 0, length - SO_CONTENTS_OFFSET);
101 logger.debug("Attempt to parse exclude route objects subobject from bytes: {}", ByteArray.bytesToHexString(soContentsBytes));
102 final ExcludeRouteSubobject subObj = parseSpecificSubobject(type, soContentsBytes, mandatoryFlag);
103 logger.debug("Subobject was parsed. {}", subObj);
105 subobjsList.add(subObj);
113 public static byte[] put(final List<ExcludeRouteSubobject> objsToSerialize) {
114 final List<byte[]> bytesList = new ArrayList<byte[]>(objsToSerialize.size());
117 for (final ExcludeRouteSubobject obj : objsToSerialize) {
118 final byte[] bytes = put(obj);
119 length += bytes.length;
120 bytesList.add(bytes);
123 final byte[] retBytes = new byte[length];
126 for (final byte[] bytes : bytesList) {
127 System.arraycopy(bytes, 0, retBytes, offset, bytes.length);
128 offset += bytes.length;
134 public static byte[] put(final ExcludeRouteSubobject objToSerialize) {
135 int typeIndicator = 0;
137 final byte[] soContentsBytes;
139 if (objToSerialize instanceof XROIPPrefixSubobject && ((XROIPPrefixSubobject) objToSerialize).getPrefix().getIpv4Prefix() != null) {
140 typeIndicator = PCEPXROSubobjectType.IPv4_PREFIX.getIndicator();
141 soContentsBytes = XROIPv4PrefixSubobjectParser.put(objToSerialize);
142 } else if (objToSerialize instanceof XROIPPrefixSubobject
143 && ((XROIPPrefixSubobject) objToSerialize).getPrefix().getIpv6Prefix() != null) {
144 typeIndicator = PCEPXROSubobjectType.IPv6_PREFIX.getIndicator();
145 soContentsBytes = XROIPv6PrefixSubobjectParser.put(objToSerialize);
146 } else if (objToSerialize instanceof XROAsNumberSubobject) {
147 typeIndicator = PCEPXROSubobjectType.AS_NUMBER.getIndicator();
148 soContentsBytes = XROAsNumberSubobjectParser.put(objToSerialize);
149 } else if (objToSerialize instanceof XROUnnumberedInterfaceSubobject) {
150 typeIndicator = PCEPXROSubobjectType.UNNUMBERED_INTERFACE_ID.getIndicator();
151 soContentsBytes = XROUnnumberedInterfaceSubobjectParser.put(objToSerialize);
152 } else if (objToSerialize instanceof XROSRLGSubobject) {
153 typeIndicator = PCEPXROSubobjectType.SRLG.getIndicator();
154 soContentsBytes = XROSRLGSubobjectParser.put(objToSerialize);
156 throw new IllegalArgumentException("Unknown instance of PCEPXROSubobject. Passed: " + objToSerialize.getClass() + ".");
158 final byte[] bytes = new byte[SO_CONTENTS_OFFSET + soContentsBytes.length];
160 bytes[TYPE_FLAG_F_OFFSET] = (byte) (ByteArray.cutBytes(ByteArray.intToBytes(typeIndicator), (Integer.SIZE / 8) - TYPE_FLAG_F_LENGTH)[0] | (objToSerialize.isMandatory() ? 1 << 7
162 bytes[LENGTH_F_OFFSET] = ByteArray.cutBytes(ByteArray.intToBytes(soContentsBytes.length + SO_CONTENTS_OFFSET), (Integer.SIZE / 8)
163 - LENGTH_F_LENGTH)[0];
165 System.arraycopy(soContentsBytes, 0, bytes, SO_CONTENTS_OFFSET, soContentsBytes.length);
170 private static ExcludeRouteSubobject parseSpecificSubobject(final PCEPXROSubobjectType type, final byte[] soContentsBytes,
171 final boolean mandatory) throws PCEPDeserializerException {
175 return XROIPv4PrefixSubobjectParser.parse(soContentsBytes, mandatory);
177 return XROIPv6PrefixSubobjectParser.parse(soContentsBytes, mandatory);
178 case UNNUMBERED_INTERFACE_ID:
179 return XROUnnumberedInterfaceSubobjectParser.parse(soContentsBytes, mandatory);
181 return XROAsNumberSubobjectParser.parse(soContentsBytes, mandatory);
183 return XROSRLGSubobjectParser.parse(soContentsBytes, mandatory);
185 throw new PCEPDeserializerException("Unknown Subobject type. Passed: " + type + ".");