blob: b42d135a9b29efbce5aec4af41cefd91cb5a229d [file] [log] [blame]
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -07001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.pcepio.types;
17
18import java.util.LinkedList;
19import java.util.ListIterator;
20
21import org.jboss.netty.buffer.ChannelBuffer;
22import org.onosproject.pcepio.exceptions.PcepParseException;
23import org.onosproject.pcepio.protocol.PcepVersion;
24
25import com.google.common.base.MoreObjects;
26
27/**
28 * Provides Pcep Rsvp User Error Spec.
29 */
30public class PcepRsvpUserErrorSpec implements PcepRsvpErrorSpec {
31
32 /*
33 RSVP error spec object header.
34 0 1 2 3
35 +-------------+-------------+-------------+-------------+
36 | Length (bytes) | Class-Num | C-Type |
37 +-------------+-------------+-------------+-------------+
38 | |
39 // (Object contents) //
40 | |
41 +-------------+-------------+-------------+-------------+
42
43 Ref : USER_ERROR_SPEC @ RFC5284.
44 USER_ERROR_SPEC object: Class = 194, C-Type = 1
45
46 0 1 2 3
47 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
48 +---------------+---------------+---------------+---------------+
49 | Enterprise Number |
50 +---------------+---------------+---------------+---------------+
51 | Sub Org | Err Desc Len | User Error Value |
52 +---------------+---------------+---------------+---------------+
53 | |
54 ~ Error Description ~
55 | |
56 +---------------+---------------+---------------+---------------+
57 | |
58 ~ User-Defined Subobjects ~
59 | |
60 +---------------+---------------+---------------+---------------+
61 */
62
63 public static final byte CLASS_NUM = (byte) 0xc2;
64 public static final byte CLASS_TYPE = 0x01;
65
66 private PcepRsvpSpecObjHeader objHeader;
67 private int enterpriseNum;
68 private byte subOrg;
69 private byte errDescLen;
70 private short userErrorValue;
71 private byte[] errDesc;
72 private LinkedList<PcepValueType> llRsvpUserSpecSubObj;
73
74 /**
75 * Default constructor.
76 *
77 * @param objHeader pcep rsvp spec object header
78 * @param enterpriseNum enterprise number
79 * @param subOrg organization identifier value
80 * @param errDescLen error description length
81 * @param userErrorValue user error value
82 * @param errDesc error description
83 * @param llRsvpUserSpecSubObj list of subobjects
84 */
85 public PcepRsvpUserErrorSpec(PcepRsvpSpecObjHeader objHeader, int enterpriseNum, byte subOrg, byte errDescLen,
86 short userErrorValue, byte[] errDesc, LinkedList<PcepValueType> llRsvpUserSpecSubObj) {
87 this.objHeader = objHeader;
88 this.enterpriseNum = enterpriseNum;
89 this.subOrg = subOrg;
90 this.errDescLen = errDescLen;
91 this.userErrorValue = userErrorValue;
92 this.errDesc = errDesc;
93 this.llRsvpUserSpecSubObj = llRsvpUserSpecSubObj;
94 }
95
96 @Override
97 public int write(ChannelBuffer cb) {
98 int objLenIndex = objHeader.write(cb);
99 cb.writeInt(enterpriseNum);
100 cb.writeByte(subOrg);
101 cb.writeByte(errDescLen);
102 cb.writeShort(userErrorValue);
103 cb.writeBytes(errDesc);
104
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700105 if (llRsvpUserSpecSubObj != null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700106
107 ListIterator<PcepValueType> listIterator = llRsvpUserSpecSubObj.listIterator();
108
109 while (listIterator.hasNext()) {
110 PcepValueType tlv = listIterator.next();
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700111 if (tlv == null) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700112 continue;
113 }
114 tlv.write(cb);
115 // need to take care of padding
116 int pad = tlv.getLength() % 4;
117 if (0 != pad) {
118 pad = 4 - pad;
119 for (int i = 0; i < pad; ++i) {
120 cb.writeByte((byte) 0);
121 }
122 }
123 }
124 }
125 short objLen = (short) (cb.writerIndex() - objLenIndex);
126 cb.setShort(objLenIndex, objLen);
127 return objLen;
128 }
129
130 /**
131 * Reads the channel buffer and returns object of PcepRsvpErrorSpec.
132 *
133 * @param cb of type channel buffer
134 * @return object of PcepRsvpErrorSpec
135 * @throws PcepParseException when expected object is not received
136 */
137 public static PcepRsvpErrorSpec read(ChannelBuffer cb) throws PcepParseException {
138 PcepRsvpSpecObjHeader objHeader;
139 int enterpriseNum;
140 byte subOrg;
141 byte errDescLen;
142 short userErrorValue;
143 byte[] errDesc;
144 LinkedList<PcepValueType> llRsvpUserSpecSubObj = null;
145
146 objHeader = PcepRsvpSpecObjHeader.read(cb);
147
Sho SHIMIZUde09fa02015-09-03 09:39:52 -0700148 if (objHeader.getObjClassNum() != CLASS_NUM || objHeader.getObjClassType() != CLASS_TYPE) {
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700149 throw new PcepParseException("Expected PcepRsvpUserErrorSpec object.");
150 }
151 enterpriseNum = cb.readInt();
152 subOrg = cb.readByte();
153 errDescLen = cb.readByte();
154 userErrorValue = cb.readShort();
155 errDesc = new byte[errDescLen];
156 cb.readBytes(errDesc, 0, errDescLen);
157
158 llRsvpUserSpecSubObj = parseErrSpecSubObj(cb);
159
160 return new PcepRsvpUserErrorSpec(objHeader, enterpriseNum, subOrg, errDescLen, userErrorValue, errDesc,
161 llRsvpUserSpecSubObj);
162 }
163
164 private static LinkedList<PcepValueType> parseErrSpecSubObj(ChannelBuffer cb) throws PcepParseException {
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700165 LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<>();
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700166 while (0 < cb.readableBytes()) {
167 PcepValueType tlv = null;
168 short hType = cb.readShort();
169 int iValue = 0;
170 //short hLength = cb.readShort();
171 switch (hType) {
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530172 case AutonomousSystemSubTlv.TYPE:
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700173 iValue = cb.readInt();
Mahesh Poojary Sf1bbd362016-02-25 18:19:59 +0530174 tlv = new AutonomousSystemSubTlv(iValue);
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700175 break;
176 default:
177 throw new PcepParseException("Unsupported Sub TLV type :" + hType);
178 }
179 llRsvpUserSpecSubObj.add(tlv);
180 }
181 return llRsvpUserSpecSubObj;
182 }
183
184 @Override
185 public PcepVersion getVersion() {
186 return PcepVersion.PCEP_1;
187 }
188
189 @Override
190 public short getType() {
191 return StatefulRsvpErrorSpecTlv.TYPE;
192 }
193
194 @Override
195 public short getLength() {
196 return objHeader.getObjLen();
197 }
198
199 @Override
200 public byte getClassNum() {
201 return CLASS_NUM;
202 }
203
204 @Override
205 public byte getClassType() {
206 return CLASS_TYPE;
207 }
208
209 @Override
210 public String toString() {
211 return MoreObjects.toStringHelper(getClass())
Sho SHIMIZU7cdbcf72015-09-03 14:43:05 -0700212 .add("enterpriseNumber", enterpriseNum)
213 .add("subOrganization", subOrg)
214 .add("errDescLength", errDescLen)
215 .add("userErrorValue", userErrorValue)
216 .add("errDesc", errDesc)
217 .add("RsvpUserSpecSubObject", llRsvpUserSpecSubObj)
Sho SHIMIZUe81e4db2015-09-03 09:44:38 -0700218 .toString();
219 }
220}