blob: 744731fc60c0affacfb80f4164554a4cbc607cc8 [file] [log] [blame]
SureshBR25058b72015-08-13 13:05:06 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
SureshBR25058b72015-08-13 13:05:06 +05303 *
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
17package org.onosproject.pcep.controller.impl;
18
19import java.io.IOException;
20import java.net.InetSocketAddress;
21import java.net.SocketAddress;
22import java.nio.channels.ClosedChannelException;
23import java.util.Collections;
24import java.util.Date;
25import java.util.LinkedList;
26import java.util.List;
27import java.util.ListIterator;
28import java.util.concurrent.RejectedExecutionException;
29
30import org.jboss.netty.channel.Channel;
31import org.jboss.netty.channel.ChannelHandlerContext;
32import org.jboss.netty.channel.ChannelStateEvent;
33import org.jboss.netty.channel.ExceptionEvent;
34import org.jboss.netty.channel.MessageEvent;
35import org.jboss.netty.handler.timeout.IdleState;
36import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler;
37import org.jboss.netty.handler.timeout.IdleStateEvent;
38import org.jboss.netty.handler.timeout.IdleStateHandler;
39import org.jboss.netty.handler.timeout.ReadTimeoutException;
40import org.onlab.packet.IpAddress;
Priyanka Bd2b28882016-04-04 16:57:04 +053041import org.onosproject.pcep.controller.ClientCapability;
SureshBR25058b72015-08-13 13:05:06 +053042import org.onosproject.pcep.controller.PccId;
43import org.onosproject.pcep.controller.driver.PcepClientDriver;
44import org.onosproject.pcepio.exceptions.PcepParseException;
45import org.onosproject.pcepio.protocol.PcepError;
46import org.onosproject.pcepio.protocol.PcepErrorInfo;
47import org.onosproject.pcepio.protocol.PcepErrorMsg;
48import org.onosproject.pcepio.protocol.PcepErrorObject;
49import org.onosproject.pcepio.protocol.PcepFactory;
50import org.onosproject.pcepio.protocol.PcepMessage;
51import org.onosproject.pcepio.protocol.PcepOpenMsg;
52import org.onosproject.pcepio.protocol.PcepOpenObject;
53import org.onosproject.pcepio.protocol.PcepType;
54import org.onosproject.pcepio.protocol.PcepVersion;
Avantika-Huawei56c11842016-04-28 00:56:56 +053055import org.onosproject.pcepio.types.IPv4RouterIdOfLocalNodeSubTlv;
56import org.onosproject.pcepio.types.NodeAttributesTlv;
SureshBR25058b72015-08-13 13:05:06 +053057import org.onosproject.pcepio.types.PceccCapabilityTlv;
58import org.onosproject.pcepio.types.StatefulPceCapabilityTlv;
59import org.onosproject.pcepio.types.PcepErrorDetailInfo;
60import org.onosproject.pcepio.types.PcepValueType;
61import org.slf4j.Logger;
62import org.slf4j.LoggerFactory;
63
64/**
65 * Channel handler deals with the pcc client connection and dispatches
66 * messages from client to the appropriate locations.
67 */
68class PcepChannelHandler extends IdleStateAwareChannelHandler {
69 static final byte DEADTIMER_MAXIMUM_VALUE = (byte) 0xFF;
70 static final byte KEEPALIVE_MULTIPLE_FOR_DEADTIMER = 4;
71 private static final Logger log = LoggerFactory.getLogger(PcepChannelHandler.class);
72 private final Controller controller;
73 private PcepClientDriver pc;
74 private PccId thispccId;
75 private Channel channel;
76 private byte sessionId = 0;
77 private byte keepAliveTime;
78 private byte deadTime;
Priyanka Bd2b28882016-04-04 16:57:04 +053079 private ClientCapability capability;
SureshBR25058b72015-08-13 13:05:06 +053080 private PcepPacketStatsImpl pcepPacketStats;
81 static final int MAX_WRONG_COUNT_PACKET = 5;
82 static final int BYTE_MASK = 0xFF;
83
84 // State needs to be volatile because the HandshakeTimeoutHandler
85 // needs to check if the handshake is complete
86 private volatile ChannelState state;
87
88 // When a pcc client with a ip addresss is found (i.e we already have a
89 // connected client with the same ip), the new client is immediately
90 // disconnected. At that point netty callsback channelDisconnected() which
91 // proceeds to cleaup client state - we need to ensure that it does not cleanup
92 // client state for the older (still connected) client
93 private volatile Boolean duplicatePccIdFound;
94
95 //Indicates the pcep version used by this pcc client
96 protected PcepVersion pcepVersion;
97 protected PcepFactory factory1;
98
99 /**
100 * Create a new unconnected PcepChannelHandler.
101 * @param controller parent controller
102 */
103 PcepChannelHandler(Controller controller) {
104 this.controller = controller;
105 this.state = ChannelState.INIT;
106 factory1 = controller.getPcepMessageFactory1();
107 duplicatePccIdFound = Boolean.FALSE;
108 pcepPacketStats = new PcepPacketStatsImpl();
109 }
110
111 /**
112 * To disconnect a PCC.
113 */
114 public void disconnectClient() {
115 pc.disconnectClient();
116 }
117
118 //*************************
119 // Channel State Machine
120 //*************************
121
122 /**
123 * The state machine for handling the client/channel state. All state
124 * transitions should happen from within the state machine (and not from other
125 * parts of the code)
126 */
127 enum ChannelState {
128 /**
129 * Initial state before channel is connected.
130 */
131 INIT(false) {
132
133 },
134 /**
135 * Once the session is established, wait for open message.
136 */
137 OPENWAIT(false) {
138 @Override
139 void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
140
Avantika-Huawei56c11842016-04-28 00:56:56 +0530141 log.info("Message received in OPEN WAIT State");
SureshBR25058b72015-08-13 13:05:06 +0530142
143 //check for open message
144 if (m.getType() != PcepType.OPEN) {
145 // When the message type is not open message increment the wrong packet statistics
146 h.processUnknownMsg();
147 log.debug("message is not OPEN message");
148 } else {
149
150 h.pcepPacketStats.addInPacket();
151 PcepOpenMsg pOpenmsg = (PcepOpenMsg) m;
Priyanka Bd2b28882016-04-04 16:57:04 +0530152 //Do Capability negotiation.
153 h.capabilityNegotiation(pOpenmsg);
SureshBR25058b72015-08-13 13:05:06 +0530154 log.debug("Sending handshake OPEN message");
155 h.sessionId = pOpenmsg.getPcepOpenObject().getSessionId();
156 h.pcepVersion = pOpenmsg.getPcepOpenObject().getVersion();
157
158 //setting keepalive and deadTimer
159 byte yKeepalive = pOpenmsg.getPcepOpenObject().getKeepAliveTime();
160 byte yDeadTimer = pOpenmsg.getPcepOpenObject().getDeadTime();
161 h.keepAliveTime = yKeepalive;
162 if (yKeepalive < yDeadTimer) {
163 h.deadTime = yDeadTimer;
164 } else {
165 if (DEADTIMER_MAXIMUM_VALUE > (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER)) {
166 h.deadTime = (byte) (yKeepalive * KEEPALIVE_MULTIPLE_FOR_DEADTIMER);
167 } else {
168 h.deadTime = DEADTIMER_MAXIMUM_VALUE;
169 }
170 }
Avantika-Huawei56c11842016-04-28 00:56:56 +0530171
Avantika-Huawei7f7376a2016-05-11 17:07:50 +0530172 /*
173 * If MPLS LSR id and PCEP session socket IP addresses are not same,
174 * the MPLS LSR id will be encoded in separate TLV.
175 * We always maintain session information based on LSR ids.
176 * The socket IP is stored in channel.
177 */
Avantika-Huawei56c11842016-04-28 00:56:56 +0530178 LinkedList<PcepValueType> optionalTlvs = pOpenmsg.getPcepOpenObject().getOptionalTlv();
179 for (PcepValueType optionalTlv : optionalTlvs) {
180 if (optionalTlv instanceof NodeAttributesTlv) {
181 List<PcepValueType> subTlvs = ((NodeAttributesTlv) optionalTlv)
182 .getllNodeAttributesSubTLVs();
183 for (PcepValueType subTlv : subTlvs) {
184 if (subTlv instanceof IPv4RouterIdOfLocalNodeSubTlv) {
185 h.thispccId = PccId.pccId(IpAddress
186 .valueOf(((IPv4RouterIdOfLocalNodeSubTlv) subTlv).getInt()));
187 break;
188 }
189 }
190 break;
191 }
192 }
193
194 if (h.thispccId == null) {
195 final SocketAddress address = h.channel.getRemoteAddress();
196 if (!(address instanceof InetSocketAddress)) {
197 throw new IOException("Invalid client connection. Pcc is indentifed based on IP");
198 }
199
200 final InetSocketAddress inetAddress = (InetSocketAddress) address;
201 h.thispccId = PccId.pccId(IpAddress.valueOf(inetAddress.getAddress()));
202 }
203
SureshBR25058b72015-08-13 13:05:06 +0530204 h.sendHandshakeOpenMessage();
205 h.pcepPacketStats.addOutPacket();
206 h.setState(KEEPWAIT);
SureshBR25058b72015-08-13 13:05:06 +0530207 }
208 }
209 },
210 /**
211 * Once the open messages are exchanged, wait for keep alive message.
212 */
213 KEEPWAIT(false) {
214 @Override
215 void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
Avantika-Huawei56c11842016-04-28 00:56:56 +0530216 log.info("message received in KEEPWAIT state");
SureshBR25058b72015-08-13 13:05:06 +0530217 //check for keep alive message
218 if (m.getType() != PcepType.KEEP_ALIVE) {
219 // When the message type is not keep alive message increment the wrong packet statistics
220 h.processUnknownMsg();
Avantika-Huawei56c11842016-04-28 00:56:56 +0530221 log.error("message is not KEEPALIVE message");
SureshBR25058b72015-08-13 13:05:06 +0530222 } else {
223 // Set the client connected status
224 h.pcepPacketStats.addInPacket();
SureshBR25058b72015-08-13 13:05:06 +0530225 log.debug("sending keep alive message in KEEPWAIT state");
SureshBR25058b72015-08-13 13:05:06 +0530226 h.pc = h.controller.getPcepClientInstance(h.thispccId, h.sessionId, h.pcepVersion,
227 h.pcepPacketStats);
Priyanka Bd2b28882016-04-04 16:57:04 +0530228 //Get pc instance and set capabilities
229 h.pc.setCapability(h.capability);
SureshBR25058b72015-08-13 13:05:06 +0530230 // set the status of pcc as connected
231 h.pc.setConnected(true);
232 h.pc.setChannel(h.channel);
233
234 // set any other specific parameters to the pcc
235 h.pc.setPcVersion(h.pcepVersion);
236 h.pc.setPcSessionId(h.sessionId);
237 h.pc.setPcKeepAliveTime(h.keepAliveTime);
238 h.pc.setPcDeadTime(h.deadTime);
239 int keepAliveTimer = h.keepAliveTime & BYTE_MASK;
240 int deadTimer = h.deadTime & BYTE_MASK;
241 if (0 == h.keepAliveTime) {
242 h.deadTime = 0;
243 }
244 // handle keep alive and dead time
245 if (keepAliveTimer != PcepPipelineFactory.DEFAULT_KEEP_ALIVE_TIME
246 || deadTimer != PcepPipelineFactory.DEFAULT_DEAD_TIME) {
247
248 h.channel.getPipeline().replace("idle", "idle",
249 new IdleStateHandler(PcepPipelineFactory.TIMER, deadTimer, keepAliveTimer, 0));
250 }
251 log.debug("Dead timer : " + deadTimer);
252 log.debug("Keep alive time : " + keepAliveTimer);
253
254 //set the state handshake completion.
255 h.sendKeepAliveMessage();
256 h.pcepPacketStats.addOutPacket();
257 h.setHandshakeComplete(true);
258
259 if (!h.pc.connectClient()) {
260 disconnectDuplicate(h);
261 } else {
262 h.setState(ESTABLISHED);
263 }
264 }
265 }
266 },
267 /**
268 * Once the keep alive messages are exchanged, the state is established.
269 */
270 ESTABLISHED(true) {
271 @Override
272 void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
273
274 //h.channel.getPipeline().remove("waittimeout");
275 log.debug("Message received in established state " + m.getType());
276 //dispatch the message
277 h.dispatchMessage(m);
278 }
279 };
280 private boolean handshakeComplete;
281
282 ChannelState(boolean handshakeComplete) {
283 this.handshakeComplete = handshakeComplete;
284 }
285
286 void processPcepMessage(PcepChannelHandler h, PcepMessage m) throws IOException, PcepParseException {
287 // do nothing
288 }
289
290 /**
291 * Is this a state in which the handshake has completed.
292 *
293 * @return true if the handshake is complete
294 */
295 public boolean isHandshakeComplete() {
296 return this.handshakeComplete;
297 }
298
299 protected void disconnectDuplicate(PcepChannelHandler h) {
300 log.error("Duplicated Pcc IP or incompleted cleanup - " + "disconnecting channel {}",
301 h.getClientInfoString());
302 h.duplicatePccIdFound = Boolean.TRUE;
303 h.channel.disconnect();
304 }
305
306 /**
307 * Sets handshake complete status.
308 *
309 * @param handshakeComplete status of handshake
310 */
311 public void setHandshakeComplete(boolean handshakeComplete) {
312 this.handshakeComplete = handshakeComplete;
313 }
314
315 }
316
317 @Override
318 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
319 channel = e.getChannel();
320 log.info("PCC connected from {}", channel.getRemoteAddress());
321
322 // Wait for open message from pcc client
323 setState(ChannelState.OPENWAIT);
324 }
325
326 @Override
327 public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
328 log.info("Pcc disconnected callback for pc:{}. Cleaning up ...", getClientInfoString());
329 if (thispccId != null) {
330 if (!duplicatePccIdFound) {
331 // if the disconnected client (on this ChannelHandler)
332 // was not one with a duplicate-dpid, it is safe to remove all
333 // state for it at the controller. Notice that if the disconnected
334 // client was a duplicate-ip, calling the method below would clear
335 // all state for the original client (with the same ip),
336 // which we obviously don't want.
337 log.debug("{}:removal called", getClientInfoString());
338 if (pc != null) {
339 pc.removeConnectedClient();
340 }
341 } else {
342 // A duplicate was disconnected on this ChannelHandler,
343 // this is the same client reconnecting, but the original state was
344 // not cleaned up - XXX check liveness of original ChannelHandler
345 log.debug("{}:duplicate found", getClientInfoString());
346 duplicatePccIdFound = Boolean.FALSE;
347 }
348 } else {
349 log.warn("no pccip in channelHandler registered for " + "disconnected client {}", getClientInfoString());
350 }
351 }
352
353 @Override
354 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
355 PcepErrorMsg errMsg;
356 log.info("exceptionCaught: " + e.toString());
357
358 if (e.getCause() instanceof ReadTimeoutException) {
359 if (ChannelState.OPENWAIT == state) {
360 // When ReadTimeout timer is expired in OPENWAIT state, it is considered
361 // OpenWait timer.
362 errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_2);
363 log.debug("Sending PCEP-ERROR message to PCC.");
364 channel.write(Collections.singletonList(errMsg));
365 channel.close();
366 state = ChannelState.INIT;
367 return;
368 } else if (ChannelState.KEEPWAIT == state) {
369 // When ReadTimeout timer is expired in KEEPWAIT state, is is considered
370 // KeepWait timer.
371 errMsg = getErrorMsg(PcepErrorDetailInfo.ERROR_TYPE_1, PcepErrorDetailInfo.ERROR_VALUE_7);
372 log.debug("Sending PCEP-ERROR message to PCC.");
373 channel.write(Collections.singletonList(errMsg));
374 channel.close();
375 state = ChannelState.INIT;
376 return;
377 }
378 } else if (e.getCause() instanceof ClosedChannelException) {
379 log.debug("Channel for pc {} already closed", getClientInfoString());
380 } else if (e.getCause() instanceof IOException) {
381 log.error("Disconnecting client {} due to IO Error: {}", getClientInfoString(), e.getCause().getMessage());
382 if (log.isDebugEnabled()) {
383 // still print stack trace if debug is enabled
384 log.debug("StackTrace for previous Exception: ", e.getCause());
385 }
386 channel.close();
387 } else if (e.getCause() instanceof PcepParseException) {
388 PcepParseException errMsgParse = (PcepParseException) e.getCause();
389 byte errorType = errMsgParse.getErrorType();
390 byte errorValue = errMsgParse.getErrorValue();
391
392 if ((errorType == (byte) 0x0) && (errorValue == (byte) 0x0)) {
393 processUnknownMsg();
394 } else {
395 errMsg = getErrorMsg(errorType, errorValue);
396 log.debug("Sending PCEP-ERROR message to PCC.");
397 channel.write(Collections.singletonList(errMsg));
398 }
399 } else if (e.getCause() instanceof RejectedExecutionException) {
400 log.warn("Could not process message: queue full");
401 } else {
402 log.error("Error while processing message from client " + getClientInfoString() + "state " + this.state);
403 channel.close();
404 }
405 }
406
407 @Override
408 public String toString() {
409 return getClientInfoString();
410 }
411
412 @Override
413 public void channelIdle(ChannelHandlerContext ctx, IdleStateEvent e) throws Exception {
414 if (!isHandshakeComplete()) {
415 return;
416 }
417
418 if (e.getState() == IdleState.READER_IDLE) {
419 // When no message is received on channel for read timeout, then close
420 // the channel
421 log.info("Disconnecting client {} due to read timeout", getClientInfoString());
422 ctx.getChannel().close();
423 } else if (e.getState() == IdleState.WRITER_IDLE) {
424 // Send keep alive message
425 log.debug("Sending keep alive message due to IdleState timeout " + pc.toString());
426 pc.sendMessage(Collections.singletonList(pc.factory().buildKeepaliveMsg().build()));
427 }
428 }
429
430 @Override
431 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
432 if (e.getMessage() instanceof List) {
433 @SuppressWarnings("unchecked")
434 List<PcepMessage> msglist = (List<PcepMessage>) e.getMessage();
435 for (PcepMessage pm : msglist) {
436 // Do the actual packet processing
437 state.processPcepMessage(this, pm);
438 }
439 } else {
440 state.processPcepMessage(this, (PcepMessage) e.getMessage());
441 }
442 }
443
444 /**
445 * To set the handshake status.
446 *
447 * @param handshakeComplete value is handshake status
448 */
449 public void setHandshakeComplete(boolean handshakeComplete) {
450 this.state.setHandshakeComplete(handshakeComplete);
451 }
452
453 /**
454 * Is this a state in which the handshake has completed.
455 *
456 * @return true if the handshake is complete
457 */
458 public boolean isHandshakeComplete() {
459 return this.state.isHandshakeComplete();
460 }
461
462 /**
463 * To handle the pcep message.
464 *
465 * @param m pcep message
466 */
467 private void dispatchMessage(PcepMessage m) {
468 pc.handleMessage(m);
469 }
470
471 /**
472 * Return a string describing this client based on the already available
473 * information (ip address and/or remote socket).
474 *
475 * @return display string
476 */
477 private String getClientInfoString() {
478 if (pc != null) {
479 return pc.toString();
480 }
481 String channelString;
482 if (channel == null || channel.getRemoteAddress() == null) {
483 channelString = "?";
484 } else {
485 channelString = channel.getRemoteAddress().toString();
486 }
487 String pccIpString;
488 // TODO : implement functionality to get pcc id string
489 pccIpString = "?";
490 return String.format("[%s PCCIP[%s]]", channelString, pccIpString);
491 }
492
493 /**
494 * Update the channels state. Only called from the state machine.
495 *
496 * @param state
497 */
498 private void setState(ChannelState state) {
499 this.state = state;
500 }
501
502 /**
503 * Send handshake open message.
504 *
505 * @throws IOException,PcepParseException
506 */
507 private void sendHandshakeOpenMessage() throws IOException, PcepParseException {
508 PcepOpenObject pcepOpenobj = factory1.buildOpenObject()
509 .setSessionId(sessionId)
510 .setKeepAliveTime(keepAliveTime)
511 .setDeadTime(deadTime)
512 .build();
513 PcepMessage msg = factory1.buildOpenMsg()
514 .setPcepOpenObj(pcepOpenobj)
515 .build();
516 log.debug("Sending OPEN message to {}", channel.getRemoteAddress());
517 channel.write(Collections.singletonList(msg));
518 }
519
Priyanka Bd2b28882016-04-04 16:57:04 +0530520 //Capability negotiation
521 private void capabilityNegotiation(PcepOpenMsg pOpenmsg) {
SureshBR25058b72015-08-13 13:05:06 +0530522 LinkedList<PcepValueType> tlvList = pOpenmsg.getPcepOpenObject().getOptionalTlv();
Priyanka Bd2b28882016-04-04 16:57:04 +0530523 boolean pceccCapability = false;
524 boolean statefulPceCapability = false;
525 boolean pcInstantiationCapability = false;
SureshBR25058b72015-08-13 13:05:06 +0530526
527 ListIterator<PcepValueType> listIterator = tlvList.listIterator();
528 while (listIterator.hasNext()) {
529 PcepValueType tlv = listIterator.next();
530
531 switch (tlv.getType()) {
532 case PceccCapabilityTlv.TYPE:
Priyanka Bd2b28882016-04-04 16:57:04 +0530533 pceccCapability = true;
SureshBR25058b72015-08-13 13:05:06 +0530534 break;
535 case StatefulPceCapabilityTlv.TYPE:
Priyanka Bd2b28882016-04-04 16:57:04 +0530536 statefulPceCapability = true;
SureshBR25058b72015-08-13 13:05:06 +0530537 StatefulPceCapabilityTlv stetefulPcCapTlv = (StatefulPceCapabilityTlv) tlv;
538 if (stetefulPcCapTlv.getIFlag()) {
Priyanka Bd2b28882016-04-04 16:57:04 +0530539 pcInstantiationCapability = true;
SureshBR25058b72015-08-13 13:05:06 +0530540 }
541 break;
542 default:
543 continue;
544 }
545 }
Priyanka Bd2b28882016-04-04 16:57:04 +0530546 this.capability = new ClientCapability(pceccCapability, statefulPceCapability, pcInstantiationCapability);
SureshBR25058b72015-08-13 13:05:06 +0530547 }
548
549 /**
550 * Send keep alive message.
551 *
552 * @throws IOException when channel is disconnected
553 * @throws PcepParseException while building keep alive message
554 */
555 private void sendKeepAliveMessage() throws IOException, PcepParseException {
556 PcepMessage msg = factory1.buildKeepaliveMsg().build();
557 log.debug("Sending KEEPALIVE message to {}", channel.getRemoteAddress());
558 channel.write(Collections.singletonList(msg));
559 }
560
561 /**
562 * Send error message and close channel with pcc.
563 */
564 private void sendErrMsgAndCloseChannel() {
565 // TODO send error message
566 channel.close();
567 }
568
569 /**
570 * Send error message when an invalid message is received.
571 *
572 * @throws PcepParseException while building error message
573 */
574 private void sendErrMsgForInvalidMsg() throws PcepParseException {
575 byte errorType = 0x02;
576 byte errorValue = 0x00;
577 PcepErrorMsg errMsg = getErrorMsg(errorType, errorValue);
578 channel.write(Collections.singletonList(errMsg));
579 }
580
581 /**
582 * Builds pcep error message based on error value and error type.
583 *
584 * @param errorType pcep error type
585 * @param errorValue pcep error value
586 * @return pcep error message
587 * @throws PcepParseException while bulding error message
588 */
589 public PcepErrorMsg getErrorMsg(byte errorType, byte errorValue) throws PcepParseException {
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700590 LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
SureshBR25058b72015-08-13 13:05:06 +0530591 PcepErrorMsg errMsg;
592
593 PcepErrorObject errObj = factory1.buildPcepErrorObject()
594 .setErrorValue(errorValue)
595 .setErrorType(errorType)
596 .build();
597
598 llerrObj.add(errObj);
599
SureshBR25058b72015-08-13 13:05:06 +0530600 //If Error caught in other than Openmessage
Sho SHIMIZU9b8274c2015-09-04 15:54:24 -0700601 LinkedList<PcepError> llPcepErr = new LinkedList<>();
SureshBR25058b72015-08-13 13:05:06 +0530602
603 PcepError pcepErr = factory1.buildPcepError()
604 .setErrorObjList(llerrObj)
605 .build();
606
607 llPcepErr.add(pcepErr);
608
609 PcepErrorInfo errInfo = factory1.buildPcepErrorInfo()
610 .setPcepErrorList(llPcepErr)
611 .build();
612
613 errMsg = factory1.buildPcepErrorMsg()
614 .setPcepErrorInfo(errInfo)
615 .build();
SureshBR25058b72015-08-13 13:05:06 +0530616 return errMsg;
617 }
618
619 /**
620 * Process unknown pcep message received.
621 *
622 * @throws PcepParseException while building pcep error message
623 */
624 public void processUnknownMsg() throws PcepParseException {
625 Date now = null;
626 if (pcepPacketStats.wrongPacketCount() == 0) {
627 now = new Date();
628 pcepPacketStats.setTime(now.getTime());
629 pcepPacketStats.addWrongPacket();
630 sendErrMsgForInvalidMsg();
631 }
632
633 if (pcepPacketStats.wrongPacketCount() > 1) {
634 Date lastest = new Date();
635 pcepPacketStats.addWrongPacket();
636 //converting to seconds
637 if (((lastest.getTime() - pcepPacketStats.getTime()) / 1000) > 60) {
638 now = lastest;
639 pcepPacketStats.setTime(now.getTime());
640 pcepPacketStats.resetWrongPacket();
641 pcepPacketStats.addWrongPacket();
642 } else if (((int) (lastest.getTime() - now.getTime()) / 1000) < 60) {
643 if (MAX_WRONG_COUNT_PACKET <= pcepPacketStats.wrongPacketCount()) {
644 //reset once wrong packet count reaches MAX_WRONG_COUNT_PACKET
645 pcepPacketStats.resetWrongPacket();
646 // max wrong packets received send error message and close the session
647 sendErrMsgAndCloseChannel();
648 }
649 }
650 }
651 }
652}