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