[ONOS-4209] Unsuccessful PCEP session formation between ONOS and IOS XR

Change-Id: Ic509c50c5cef39e5f1a5319570f8c9406177b788
diff --git a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
index 8b78d23..91a68fc 100644
--- a/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
+++ b/providers/pcep/tunnel/src/test/java/org/onosproject/provider/pcep/tunnel/impl/PcepClientControllerAdapter.java
@@ -18,23 +18,36 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.onlab.packet.IpAddress;
+import org.onosproject.pcep.controller.ClientCapability;
 import org.onosproject.pcep.controller.PccId;
 import org.onosproject.pcep.controller.PcepClient;
 import org.onosproject.pcep.controller.PcepClientController;
 import org.onosproject.pcep.controller.PcepClientListener;
 import org.onosproject.pcep.controller.PcepEventListener;
 import org.onosproject.pcep.controller.driver.PcepAgent;
+import org.onosproject.pcepio.protocol.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepFactory;
 import org.onosproject.pcepio.protocol.PcepMessage;
 import org.onosproject.pcepio.protocol.PcepVersion;
 
 import com.google.common.collect.Sets;
 
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_TYPE_19;
+import static org.onosproject.pcepio.types.PcepErrorDetailInfo.ERROR_VALUE_5;
+
+/**
+ * Representation of PCEP client controller adapter.
+ */
 public class PcepClientControllerAdapter implements PcepClientController {
 
     protected ConcurrentHashMap<PccId, PcepClient> connectedClients =
@@ -60,9 +73,14 @@
 
     @Override
     public PcepClient getClient(PccId pccId) {
-        //return connectedClients.get(pccIpAddress);
         PcepClientAdapter pc = new PcepClientAdapter();
-        pc.init(PccId.pccId(IpAddress.valueOf(0xac000001)), PcepVersion.PCEP_1);
+        if (pccId.ipAddress().equals(IpAddress.valueOf(0xC010103))
+            || pccId.ipAddress().equals(IpAddress.valueOf(0xB6024E22))) {
+            pc.setCapability(new ClientCapability(true, false, false));
+        } else {
+            pc.setCapability(new ClientCapability(true, true, true));
+        }
+        pc.init(PccId.pccId(pccId.ipAddress()), PcepVersion.PCEP_1);
         return pc;
     }
 
@@ -119,22 +137,35 @@
             //log.debug("Sending Close Message  to { }", pccIpAddress.toString());
             pc.sendMessage(Collections.singletonList(pc.factory().buildCloseMsg().build()));
             break;
+        case INITIATE:
+            if (!pc.capability().pcInstantiationCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
+            break;
         case REPORT:
-            for (PcepEventListener l : pcepEventListener) {
-                l.handleMessage(pccId, msg);
+            //Only update the listener if respective capability is supported else send PCEP-ERR msg
+            if (pc.capability().statefulPceCapability()) {
+                for (PcepEventListener l : pcepEventListener) {
+                    l.handleMessage(pccId, msg);
+                }
+            } else {
+                // Send PCEP-ERROR message.
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
             }
             break;
         case UPDATE:
-            for (PcepEventListener l : pcepEventListener) {
-                l.handleMessage(pccId, msg);
-            }
-            break;
-        case INITIATE:
-            for (PcepEventListener l : pcepEventListener) {
-                l.handleMessage(pccId, msg);
+            if (!pc.capability().statefulPceCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                       ERROR_TYPE_19, ERROR_VALUE_5)));
             }
             break;
         case LABEL_UPDATE:
+            if (!pc.capability().pceccCapability()) {
+                pc.sendMessage(Collections.singletonList(getErrMsg(pc.factory(),
+                        ERROR_TYPE_19, ERROR_VALUE_5)));
+            }
             break;
         case MAX:
             break;
@@ -154,6 +185,26 @@
         }
     }
 
+    private PcepErrorMsg getErrMsg(PcepFactory factory, byte errorType, byte errorValue) {
+        LinkedList<PcepError> llPcepErr = new LinkedList<>();
+
+        LinkedList<PcepErrorObject> llerrObj = new LinkedList<>();
+        PcepErrorMsg errMsg;
+
+        PcepErrorObject errObj = factory.buildPcepErrorObject().setErrorValue(errorValue).setErrorType(errorType)
+                .build();
+
+        llerrObj.add(errObj);
+        PcepError pcepErr = factory.buildPcepError().setErrorObjList(llerrObj).build();
+
+        llPcepErr.add(pcepErr);
+
+        PcepErrorInfo errInfo = factory.buildPcepErrorInfo().setPcepErrorList(llPcepErr).build();
+
+        errMsg = factory.buildPcepErrorMsg().setPcepErrorInfo(errInfo).build();
+        return errMsg;
+    }
+
     /**
      * Implementation of an Pcep Agent which is responsible for
      * keeping track of connected clients and the state in which
@@ -200,5 +251,4 @@
             processClientMessage(pccId, m);
         }
     }
-
 }