4a9357de8e50c1b064dd991c94fb4f653cabdceb
[onosfw.git] /
1 /*
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  */
16 package org.onosproject.pcepio.types;
17
18 import java.util.LinkedList;
19 import java.util.ListIterator;
20
21 import org.jboss.netty.buffer.ChannelBuffer;
22 import org.onosproject.pcepio.exceptions.PcepParseException;
23 import org.onosproject.pcepio.protocol.PcepVersion;
24
25 import com.google.common.base.MoreObjects;
26
27 /**
28  * Provides Pcep Rsvp User Error Spec.
29  */
30 public 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
105         if (llRsvpUserSpecSubObj != null) {
106
107             ListIterator<PcepValueType> listIterator = llRsvpUserSpecSubObj.listIterator();
108
109             while (listIterator.hasNext()) {
110                 PcepValueType tlv = listIterator.next();
111                 if (tlv == null) {
112                     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
148         if (objHeader.getObjClassNum() != CLASS_NUM || objHeader.getObjClassType() != CLASS_TYPE) {
149             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 {
165         LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<>();
166         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) {
172             case AutonomousSystemTlv.TYPE:
173                 iValue = cb.readInt();
174                 tlv = new AutonomousSystemTlv(iValue);
175                 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())
212                 .add("enterpriseNumber", enterpriseNum)
213                 .add("subOrganization", subOrg)
214                 .add("errDescLength", errDescLen)
215                 .add("userErrorValue", userErrorValue)
216                 .add("errDesc", errDesc)
217                 .add("RsvpUserSpecSubObject", llRsvpUserSpecSubObj)
218                 .toString();
219     }
220 }