diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationConfig.java
deleted file mode 100644
index 0149566..0000000
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationConfig.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright 2019-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * This Work is contributed by Sterlite Technologies
- */
-
-package org.onosproject.drivers.odtn;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onosproject.drivers.odtn.util.NetconfSessionUtility;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Direction;
-import org.onosproject.net.ModulationScheme;
-import org.onosproject.net.OchSignal;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.ModulationConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.util.Optional;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/*
- * Driver Implementation of the ModulationConfig for OpenConfig terminal devices.
- */
-public class CassiniModulationConfig<T> extends AbstractHandlerBehaviour implements ModulationConfig<T> {
-
-
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-
-    private static final String RPC_CLOSE_TAG = "</rpc>";
-
-    private static final Logger log = LoggerFactory.getLogger(CassiniModulationConfig.class);
-
-    private ComponentType state = ComponentType.DIRECTION;
-
-    private static final double OSNR_THRESHOLD_VALUE = 13.0;
-
-
-    enum BitRate {
-        GBPS_200(200),      // 200 Gbps
-        GBPS_100(100),        // 100 Gbps
-        GBPS_40(40),          // 40 Gbps
-        GBPS_10(10);          // 10 Gbps
-
-        private final long value;
-
-        public long getValue() {
-            return value;
-        }
-
-        BitRate(long value) {
-            this.value = value;
-        }
-    }
-
-    private NetconfController getController() {
-        return handler().get(NetconfController.class);
-    }
-
-    /*
-     *
-     * Get the deviceId for which the methods apply.
-     *
-     * @return The deviceId as contained in the handler data
-     */
-
-
-    private DeviceId getDeviceId() {
-        return handler().data().deviceId();
-    }
-
-
-    /**
-     * Get the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @return ModulationScheme as per bitRate value
-     **/
-    @Override
-    public Optional<ModulationScheme> getModulationScheme(PortNumber port, T component) {
-        checkType(component);
-        return state.getModulationScheme(port, component);
-    }
-
-    /**
-     * Set the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @param bitRate   bit rate in bps
-     **/
-    @Override
-    public void setModulationScheme(PortNumber port, T component, long bitRate) {
-        checkType(component);
-        state.setModulationScheme(port, component, bitRate);
-    }
-
-    /*
-     *
-     * Set the ComponentType to invoke proper methods for different template T.
-     * @param component the component.
-     */
-    void checkType(Object component) {
-        String clsName = component.getClass().getName();
-
-        if (component instanceof Direction) {
-            state = CassiniModulationConfig.ComponentType.DIRECTION;
-        } else if (component instanceof OchSignal) {
-            state = CassiniModulationConfig.ComponentType.OCHSIGNAL;
-        } else {
-            log.error("Cannot parse the component type {}.", clsName);
-        }
-
-
-        state.cassini = this;
-    }
-
-    /*
-     *
-     * Component type.
-     */
-
-
-    enum ComponentType {
-
-        /*
-         *
-         * Direction.
-         */
-
-
-        DIRECTION() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                super.setModulationScheme(port, component, bitRate);
-            }
-        },
-
-        /**
-         * OchSignal.
-         */
-
-
-        OCHSIGNAL() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                super.setModulationScheme(port, component, bitRate);
-            }
-        };
-
-
-        CassiniModulationConfig cassini;
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @return target modulation
-         */
-        Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-            NetconfSession session = NetconfSessionUtility
-                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
-            checkNotNull(session);
-            String filter = createModulationFilter(cassini, port);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<get>")
-                    .append("<filter>")
-                    .append(filter)
-                    .append("</filter>")
-                    .append("</get>")
-                    .append(RPC_CLOSE_TAG);
-            log.debug("RPC Call for Getting Modulation : \n {}", rpcReq.toString());
-            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("components/component/optical-channel/config");
-
-                String modulationScheme = String.valueOf(config.getString("modulation"));
-
-                return Optional.of(ModulationScheme.valueOf(modulationScheme));
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
-        }
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @param power target value
-         */
-        void setModulationScheme(PortNumber port, Object component, long bitRate) {
-
-            ModulationScheme modulation = null;
-            String editConfig = null;
-            double osnr = 0.0;
-            boolean rpcResponse = false;
-            boolean receiver = false;
-
-            // TODO OSNR is valid only for receiver so need to modify
-            /*if(component.toString().equals(Direction.INGRESS.toString())){
-                receiver=true;
-            }*/
-
-            //check if bitrate is less than equal to 100 Gig
-            if (bitRate <= BitRate.GBPS_100.value) {
-                modulation = ModulationScheme.DP_QPSK;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                rpcResponse = setModulationRpc(port, component, editConfig);
-                if (rpcResponse) {
-                    // TODO OSNR is valid only for receiver so need to modify
-                    osnr = fetchDeviceSnr(cassini, port);
-                    if (osnr <= OSNR_THRESHOLD_VALUE) {
-                        log.error("Channel not possible for this OSNR Value : {}", osnr);
-                    }
-                }
-            } else { // check if bitrate is greater than 100 Gig
-                modulation = ModulationScheme.DP_16QAM;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                rpcResponse = setModulationRpc(port, component, editConfig);
-                if (rpcResponse) {
-                    //TODO OSNR is valid only for receiver so need to modify
-                    osnr = fetchDeviceSnr(cassini, port);
-                    if (osnr <= OSNR_THRESHOLD_VALUE) {
-                        modulation = ModulationScheme.DP_8QAM;
-                        editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                        //setting the modulation by calling rpc
-                        rpcResponse = setModulationRpc(port, component, editConfig);
-                        if (rpcResponse) {
-                            // TODO OSNR is valid only for receiver so need to modify
-                            osnr = fetchDeviceSnr(cassini, port);
-                            if (osnr <= OSNR_THRESHOLD_VALUE) {
-                                log.warn("Channel not possible for this OSNR Value : {}." +
-                                        " Please reduce the channel bitrate.", osnr);
-                            }
-                        }
-                    }
-                }
-            }
-
-
-        }
-
-
-        /*
-         * Get filtered content under <optical-channel><state>.
-         * @param pc power config instance
-         * @param port the port number
-         * @param underState the filter condition
-         * @return RPC reply
-         */
-
-        //RPC call for OSNR still not finalised, need to update Rpc once validated
-        private static XMLConfiguration getTerminalDeviceSnr(CassiniModulationConfig config, PortNumber port) {
-            NetconfSession session = NetconfSessionUtility
-                    .getNetconfSession(config.getDeviceId(), config.getController());
-            checkNotNull(session);
-            String name = ocName(config, port);
-            StringBuilder rpcReq = new StringBuilder(RPC_TAG_NETCONF_BASE);
-            rpcReq.append("<get><filter>")
-                    .append("<osnr xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                    .append("<instant/>")
-                    .append("</osnr></filter></get>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC Call for Fetching OSNR :\n\n {}", rpcReq.toString());
-            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
-            return xconf;
-        }
-
-        private static String createModulationFilter(CassiniModulationConfig modulationConfig, PortNumber portNumber) {
-            String name = ocName(modulationConfig, portNumber);
-            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-            sb.append("<component>").append("<name>").append(name).append("</name>");
-            sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">");
-            sb.append("<config><modulation/></config>");
-            sb.append("</optical-channel>");
-            sb.append("</component>").append("</components>");
-            return sb.toString();
-        }
-
-        /**
-         * Extract component name from portNumber's annotations.
-         *
-         * @param pc         modulation config instance
-         * @param portNumber the port number
-         * @return the component name
-         */
-
-
-        private static String ocName(CassiniModulationConfig pc, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = pc.handler().data().deviceId();
-            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
-        }
-
-        private static String channelSpacing(CassiniModulationConfig modulationConfig, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = modulationConfig.handler().data().deviceId();
-            String lambda = deviceService.getPort(deviceId, portNumber).annotations().value("lambda");
-
-            ObjectMapper mapper = new ObjectMapper();
-            String channelSpacing = "";
-            try {
-                JsonNode actualObj = mapper.readTree(lambda);
-                JsonNode csNode = actualObj.get("channelSpacing");
-                channelSpacing = csNode.asText();
-                log.info("Channel_Spacing : " + channelSpacing);
-
-            } catch (IOException e) {
-                log.error("Error while parsing Json");
-            }
-            return channelSpacing;
-
-        }
-
-        private double fetchDeviceSnr(CassiniModulationConfig modulationConfig, PortNumber portNumber) {
-            double osnr = 0.0;
-            XMLConfiguration xconf = getTerminalDeviceSnr(cassini, portNumber);
-            if (xconf == null) {
-                return osnr;
-            }
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/state/osnr");
-                osnr = Float.valueOf(config.getString("snr")).doubleValue();
-                return osnr;
-            } catch (IllegalArgumentException e) {
-                return osnr;
-            }
-        }
-        /*
-         *
-         * Parse filtering string from port and component.
-         * @param portNumber Port Number
-         * @param component port component (optical-channel)
-         * @param bitRate bitRate in bps
-         * @return filtering string in xml format
-
-         */
-
-        private String modulationEditConfig(CassiniModulationConfig modulationConfig, PortNumber portNumber,
-                                            Object component, long bitRate, String modulation) {
-            if (component != null) {
-                String portName = ocName(modulationConfig, portNumber);
-                //String channelSpacing = channelSpacing(modulationConfig,portNumber);
-                //ChannelSpacing cs= ChannelSpacing.valueOf(channelSpacing);
-                //double csValue= cs.frequency().asGHz();
-
-                StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-                sb.append("<component>").append("<name>").append(portName).append("</name>");
-                if (modulation != null) {
-                    // This is an edit-config operation.
-                    sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                            .append("<config>")
-                            .append("<modulation>")
-                            .append(modulation)
-                            .append("</modulation>")
-                            .append("</config>")
-                            .append("</optical-channel>");
-                }
-                sb.append("</component>").append("</components>");
-                return sb.toString();
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
-
-        private boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
-            NetconfSession session = NetconfSessionUtility
-                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
-            checkNotNull(session);
-            boolean response = true;
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<edit-config>")
-                    .append("<target><running/></target>")
-                    .append("<config>")
-                    .append(editConfig)
-                    .append("</config>")
-                    .append("</edit-config>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC call for Setting Modulation : {}", rpcReq.toString());
-            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
-            if (xconf == null) {
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            } else if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
-                    // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
-                response = false;
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            }
-            return response;
-        }
-    }
-
-
-}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
index 53b56db..fb9c090 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOcNos.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018-present Open Networking Foundation
+ * Copyright 2019-present Open Networking Foundation
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,143 +17,77 @@
  */
 package org.onosproject.drivers.odtn;
 
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onosproject.drivers.utilities.XmlConfigParser;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.ModulationScheme;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.ModulationConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfDevice;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
 /*
  * Driver Implementation of the ModulationConfig for OcNos based terminal devices.
  */
-public class CassiniModulationOcNos<T> extends AbstractHandlerBehaviour implements ModulationConfig<T> {
+public class CassiniModulationOcNos<T> extends TerminalDeviceModulationConfig<T> {
 
 
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-
-    private static final String RPC_CLOSE_TAG = "</rpc>";
-
-    private static final Logger log = LoggerFactory.getLogger(CassiniModulationOcNos.class);
-
-    private ComponentType state = ComponentType.DIRECTION;
+    private static Logger log = LoggerFactory.getLogger(CassiniModulationOcNos.class);
 
 
-    enum BitRate {
-        GBPS_200(200),      // 200 Gbps
-        GBPS_100(100),        // 100 Gbps
-        GBPS_40(40),          // 40 Gbps
-        GBPS_10(10);          // 10 Gbps
-
-        private final long value;
-
-        public long getValue() {
-            return value;
-        }
-
-        BitRate(long value) {
-            this.value = value;
-        }
-    }
 
     /**
-     * Returns the NetconfSession with the device for which the method was called.
+     * Construct a rpc target power message.
      *
-     * @param deviceId device indetifier
-     * @return The netconf session or null
+     * @param name for optical channel name
+     * @return RPC payload
      */
+    @Override
+    public StringBuilder createModulationFilterRequestRpc(String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<name>").append(name).append("</name>");
+        return rpc;
+    }
 
+    @Override
+    public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
+        String modulation = null;
+        String editConfig = null;
+        if (bitRate <= TerminalDeviceModulationConfig.BitRate.GBPS_100.value) {
+            modulation = "dp_qpsk";
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        } else { // check if bitrate is greater than 100 Gig
+            modulation = "dp_16qam";
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        }
 
-    private NetconfSession getNetconfSession(DeviceId deviceId) {
-        log.info("Inside getNetconfSession () method for device : {}", deviceId);
-        NetconfController controller = handler().get(NetconfController.class);
-        NetconfDevice ncdev = controller.getDevicesMap().get(deviceId);
-        if (ncdev == null) {
-            log.trace("No netconf device, returning null session");
+    }
+
+    @Override
+    public String modulationEditConfigRequestRpc(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                                 Object component, long bitRate, String modulation) {
+        if (component != null) {
+            String portName = state.ocName(modulationConfig, portNumber); //oc1/1
+            String slotName = portName.split("/")[0]; //get oc1
+            String slotIndex = slotName.substring(slotName.length() - 1); //then just 1
+            String netIndex = portName.split("/")[1]; //get 1 after the /
+            StringBuilder sb = new StringBuilder("<cmmOpticalControllerTable " +
+                                                         "xmlns=\"http://www.ipinfusion.com/CMLSchema/zebos\">");
+            sb.append("<slotIndex>").append(slotIndex).append("</slotIndex>");
+            if (modulation != null) {
+                // This is an edit-config operation.
+                sb.append("<cmmOpticalChannelInterfaceTable>")
+                        .append("<netIndex>").append(netIndex).append("<netIndex>")
+                        .append("<modulationFormat>")
+                        .append(modulation)
+                        .append("</modulationFormat>")
+                        .append("</cmmOpticalNetworkInterfaceTable>");
+            }
+            sb.append("</cmmOpticalControllerTable>");
+            return sb.toString();
+        } else {
+            log.error("Cannot process the component {}.", component.getClass());
             return null;
         }
-        return ncdev.getSession();
-    }
-
-    /*
-     *
-     * Get the deviceId for which the methods apply.
-     *
-     * @return The deviceId as contained in the handler data
-     */
-
-
-    private DeviceId did() {
-        return handler().data().deviceId();
-    }
-
-    /**
-     * Execute RPC request.
-     *
-     * @param session Netconf session
-     * @param message Netconf message in XML format
-     * @return XMLConfiguration object
-     */
-
-    private XMLConfiguration executeRpc(NetconfSession session, String message) {
-        try {
-            CompletableFuture<String> fut = session.rpc(message);
-            String rpcReply = fut.get();
-            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
-            xconf.setExpressionEngine(new XPathExpressionEngine());
-            return xconf;
-        } catch (NetconfException ne) {
-            log.error("Exception on Netconf protocol: {}.", ne);
-        } catch (InterruptedException ie) {
-            log.error("Interrupted Exception: {}.", ie);
-        } catch (ExecutionException ee) {
-            log.error("Concurrent Exception while executing Netconf operation: {}.", ee);
-        }
-        return null;
-    }
-
-    /**
-     * Get the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @return ModulationScheme as per bitRate value
-     **/
-    @Override
-    public Optional<ModulationScheme> getModulationScheme(PortNumber port, T component) {
-        checkState(component);
-        return state.getModulationScheme(port, component);
-    }
-
-    /**
-     * Set the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @param bitRate   bit rate in bps
-     **/
-    @Override
-    public void setModulationScheme(PortNumber port, T component, long bitRate) {
-        checkState(component);
-        state.setModulationScheme(port, component, bitRate);
     }
 
     /*
@@ -165,10 +99,10 @@
         String clsName = component.getClass().getName();
         switch (clsName) {
             case "org.onosproject.net.Direction":
-                state = CassiniModulationOcNos.ComponentType.DIRECTION;
+                state = ComponentType.DIRECTION;
                 break;
             case "org.onosproject.net.OchSignal":
-                state = CassiniModulationOcNos.ComponentType.OCHSIGNAL;
+                state = ComponentType.OCHSIGNAL;
                 break;
             default:
                 log.error("Cannot parse the component type {}.", clsName);
@@ -179,216 +113,5 @@
         log.info("Setting the state with clsName :{} ", clsName);
     }
 
-    /*
-     *
-     * Component type.
-     */
-
-
-    enum ComponentType {
-
-        /*
-         *
-         * Direction.
-         */
-
-
-        DIRECTION() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                log.info("Inside the enum setModulationScheme()");
-                super.setModulationScheme(port, component, bitRate);
-            }
-        },
-
-        /**
-         * OchSignal.
-         */
-
-
-        OCHSIGNAL() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                super.setModulationScheme(port, component, bitRate);
-            }
-        };
-
-
-        CassiniModulationOcNos cassini;
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @return target modulation
-         */
-        Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-            NetconfSession session = cassini.getNetconfSession(cassini.did());
-            checkNotNull(session);
-            String filter = createModulationFilter(cassini, port);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<get>")
-                    .append("<filter type='subtree'>")
-                    .append(filter)
-                    .append("</filter>")
-                    .append("</get>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC Call for Getting Modulation : \n {}", rpcReq.toString());
-            XMLConfiguration xconf = cassini.executeRpc(session, rpcReq.toString());
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/config");
-
-                String modulationScheme = String.valueOf(config.getString("modulation"));
-                /*Used for Internal Testing */
-                //String modulationScheme="DP16QAM";
-                ModulationScheme modulation = ModulationScheme.valueOf(modulationScheme);
-                return Optional.of(modulation);
-            } catch (IllegalArgumentException e) {
-                return Optional.empty();
-            }
-        }
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @param power target value
-         */
-        void setModulationScheme(PortNumber port, Object component, long bitRate) {
-
-            ModulationScheme modulation = null;
-            String editConfig = null;
-
-            //check if bitrate is less than equal to 100 Gig
-            if (bitRate <= BitRate.GBPS_100.value) {
-                modulation = ModulationScheme.DP_QPSK;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                setModulationRpc(port, component, editConfig);
-            } else { // check if bitrate is greater than 100 Gig
-                modulation = ModulationScheme.DP_16QAM;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                setModulationRpc(port, component, editConfig);
-            }
-
-
-        }
-
-        private static String createModulationFilter(CassiniModulationOcNos modulationConfig, PortNumber portNumber) {
-            String name = ocName(modulationConfig, portNumber);
-            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-            sb.append("<component>").append("<name>").append(name).append("</name>");
-            sb.append("</component>").append("</components>");
-            return sb.toString();
-        }
-
-        /**
-         * Extract component name from portNumber's annotations.
-         *
-         * @param pc         modulation config instance
-         * @param portNumber the port number
-         * @return the component name
-         */
-
-
-        private static String ocName(CassiniModulationOcNos pc, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = pc.handler().data().deviceId();
-            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
-        }
-
-        /*
-         *
-         * Parse filtering string from port and component.
-         * @param portNumber Port Number
-         * @param component port component (optical-channel)
-         * @param bitRate bitRate in bps
-         * @return filtering string in xml format
-
-         */
-        private String modulationEditConfig(CassiniModulationOcNos modulationConfig, PortNumber portNumber,
-                                            Object component, long bitRate, String modulation) {
-            /*
-            <cmmOpticalControllerTable xmlns="http://www.ipinfusion.com/CMLSchema/zebos">
-                <slotIndex>1</slotIndex>   ==============>> optical-module-slot
-                <cmmOpticalChannelInterfaceTable>
-                    <netIndex>0</netIndex>    =============>> optical-channel-number (Reference to line-port)
-                    <modulationFormat>dp-qpsk</modulationFormat>
-                 </cmmOpticalNetworkInterfaceTable>
-            </cmmOpticalControllerTable>
-             */
-            String modulationOcNos = convertToOcNosModulation(modulation);
-            if (component != null) {
-                String portName = ocName(modulationConfig, portNumber); //oc1/1
-                String slotName = portName.split("/")[0]; //get oc1
-                String slotIndex = slotName.substring(slotName.length() - 1); //then just 1
-                String netIndex = portName.split("/")[1]; //get 1 after the /
-                StringBuilder sb = new StringBuilder("<cmmOpticalControllerTable " +
-                        "xmlns=\"http://www.ipinfusion.com/CMLSchema/zebos\">");
-                sb.append("<slotIndex>").append(slotIndex).append("</slotIndex>");
-                if (modulation != null) {
-                    // This is an edit-config operation.
-                    sb.append("<cmmOpticalChannelInterfaceTable>")
-                            .append("<netIndex>").append(netIndex).append("<netIndex>")
-                            .append("<modulationFormat>")
-                            .append(modulationOcNos)
-                            .append("</modulationFormat>")
-                            .append("</cmmOpticalNetworkInterfaceTable>");
-                }
-                sb.append("</cmmOpticalControllerTable>");
-                return sb.toString();
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
-
-        private String convertToOcNosModulation(String modulation) {
-            if (modulation.equals(ModulationScheme.DP_QPSK.name())) {
-                return "dp_qpsk";
-            } else {
-                return "dp_16qam";
-            }
-        }
-
-        private boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
-            NetconfSession session = cassini.getNetconfSession(cassini.did());
-            checkNotNull(session);
-            boolean response = true;
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<edit-config>")
-                    .append("<target><running/></target>")
-                    .append("<config>")
-                    .append(editConfig)
-                    .append("</config>")
-                    .append("</edit-config>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC call for Setting Modulation : {}", rpcReq.toString());
-            XMLConfiguration xconf = cassini.executeRpc(session, rpcReq.toString());
-
-            // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
-            if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
-                response = false;
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            }
-            return response;
-        }
-    }
-
 
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
index d848379..bb82685 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/CassiniModulationOpenConfig.java
@@ -17,168 +17,132 @@
  */
 package org.onosproject.drivers.odtn;
 
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.HierarchicalConfiguration;
-import org.apache.commons.configuration.XMLConfiguration;
-import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
-import org.onlab.osgi.DefaultServiceDirectory;
-import org.onosproject.drivers.utilities.XmlConfigParser;
-import org.onosproject.net.DeviceId;
+
 import org.onosproject.net.ModulationScheme;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.ModulationConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.netconf.DatastoreId;
-import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfDevice;
-import org.onosproject.netconf.NetconfException;
-import org.onosproject.netconf.NetconfSession;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-
-import java.io.StringWriter;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
 /*
  * Driver Implementation of the ModulationConfig for OcNos standard open config based terminal devices.
  */
-public class CassiniModulationOpenConfig<T> extends AbstractHandlerBehaviour implements ModulationConfig<T> {
+public class CassiniModulationOpenConfig<T> extends TerminalDeviceModulationConfig<T> {
 
+    public static Logger log = LoggerFactory.getLogger(CassiniModulationOpenConfig.class);
 
-    private static final String RPC_TAG_NETCONF_BASE =
-            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
-
-    private static final String RPC_CLOSE_TAG = "</rpc>";
-
-    private static final Logger log = LoggerFactory.getLogger(CassiniModulationOpenConfig.class);
-
-    private ComponentType state = ComponentType.DIRECTION;
-
-
-    enum BitRate {
-        GBPS_200(200),      // 200 Gbps
-        GBPS_100(100),        // 100 Gbps
-        GBPS_40(40),          // 40 Gbps
-        GBPS_10(10);          // 10 Gbps
-
-        private final long value;
-
-        public long getValue() {
-            return value;
-        }
-
-        BitRate(long value) {
-            this.value = value;
-        }
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param filter to build rpc
+     * @return RPC payload
+     */
+    @Override
+    public StringBuilder getModulationSchemeRequestRpc(String filter) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<get-config>")
+                .append("<source>")
+                .append("<" + DatastoreId.RUNNING + "/>")
+                .append("</source>")
+                .append("<filter type='subtree'>")
+                .append(filter)
+                .append("</filter>")
+                .append("</get-config>");
+        return rpc;
     }
 
     /**
-     * Returns the NetconfSession with the device for which the method was called.
+     * Construct a rpc target power message.
      *
-     * @param deviceId device indetifier
-     * @return The netconf session or null
+     * @return RPC payload
      */
+    @Override
+    public DatastoreId getDataStoreId() {
+        return DatastoreId.CANDIDATE;
+    }
 
-
-    private NetconfSession getNetconfSession(DeviceId deviceId) {
-        NetconfController controller = handler().get(NetconfController.class);
-        NetconfDevice ncdev = controller.getDevicesMap().get(deviceId);
-        if (ncdev == null) {
-            log.trace("No netconf device, returning null session");
-            return null;
-        }
-        return ncdev.getSession();
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param name for optical channel name
+     * @return RPC payload
+     */
+    @Override
+    public StringBuilder createModulationFilterRequestRpc(String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<name>").append(name).append("</name>");
+        return rpc;
     }
 
     /*
      *
-     * Get the deviceId for which the methods apply.
-     *
-     * @return The deviceId as contained in the handler data
+     * Parse filtering string from port and component.
+     * @param portNumber Port Number
+     * @param component port component (optical-channel)
+     * @param bitRate bitRate in bps
+     * @return filtering string in xml format
+
      */
-
-
-    private DeviceId did() {
-        return handler().data().deviceId();
-    }
-
-    /**
-     * Execute RPC request.
-     *
-     * @param session Netconf session
-     * @param message Netconf message in XML format
-     * @return XMLConfiguration object
-     */
-
-    private XMLConfiguration executeRpc(NetconfSession session, String message) {
-        try {
-            if (log.isDebugEnabled()) {
-                try {
-                    StringWriter stringWriter = new StringWriter();
-                    XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(message);
-                    xconf.setExpressionEngine(new XPathExpressionEngine());
-                    xconf.save(stringWriter);
-                    log.debug("Request {}", stringWriter.toString());
-                } catch (ConfigurationException e) {
-                    log.error("XML Config Exception ", e);
-                }
-            }
-            CompletableFuture<String> fut = session.rpc(message);
-            String rpcReply = fut.get();
-            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
-            xconf.setExpressionEngine(new XPathExpressionEngine());
-            if (log.isDebugEnabled()) {
-                try {
-                    StringWriter stringWriter = new StringWriter();
-                    xconf.save(stringWriter);
-                    log.debug("Response {}", stringWriter.toString());
-                } catch (ConfigurationException e) {
-                    log.error("XML Config Exception ", e);
-                }
-            }
-            return xconf;
-        } catch (NetconfException ne) {
-            log.error("Exception on Netconf protocol: {}.", ne);
-        } catch (InterruptedException ie) {
-            log.error("Interrupted Exception: {}.", ie);
-        } catch (ExecutionException ee) {
-            log.error("Concurrent Exception while executing Netconf operation: {}.", ee);
+    @Override
+    public String modulationEditConfigRequestRpc(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                                 Object component, long bitRate, String modulation) {
+        if (component != null) {
+            // This is an edit-config operation.
+            String portName = state.ocName(modulationConfig, portNumber); //oc1/0
+            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
+            sb.append("<component>");
+            sb.append("<name>").append(portName).append("</name>");
+            sb.append("<config>");
+            sb.append("<name>").append(portName).append("</name>");
+            sb.append("</config>");
+            sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
+                    .append("<config>")
+                    .append("<modulation-format>")
+                    .append(modulation)
+                    .append("</modulation-format>")
+                    .append("</config>")
+                    .append("</optical-channel>");
+            sb.append("</component>");
+            sb.append("</components>");
+            return sb.toString();
+        } else {
+            log.error("Cannot process the component {}.", component.getClass());
+            return null;
         }
-        return null;
     }
 
-    /**
-     * Get the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @return ModulationScheme as per bitRate value
-     **/
     @Override
-    public Optional<ModulationScheme> getModulationScheme(PortNumber port, T component) {
-        checkState(component);
-        return state.getModulationScheme(port, component);
+    public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
+        String modulation = null;
+        String editConfig = null;
+        if (bitRate <= BitRate.GBPS_100.value) {
+            modulation = "dp_qpsk";
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        } else { // check if bitrate is greater than 100 Gig
+            modulation = "dp_16qam";
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation);
+            //setting the modulation by calling rpc
+            state.setModulationRpc(port, component, editConfig);
+        }
+
     }
 
-    /**
-     * Set the target Modulation Scheme on the component.
-     *
-     * @param port      the port
-     * @param component the port component
-     * @param bitRate   bit rate in bps
-     **/
     @Override
-    public void setModulationScheme(PortNumber port, T component, long bitRate) {
-        checkState(component);
-        state.setModulationScheme(port, component, bitRate);
+    public ModulationScheme modulationSchemeType(String modulationScheme) {
+        /*Used for Internal Testing */
+        //String modulationScheme="DP16QAM";
+        ModulationScheme modulation;
+        if (modulationScheme.equalsIgnoreCase("dp-16-qam")) {
+            modulation = ModulationScheme.DP_16QAM;
+        } else if (modulationScheme.equalsIgnoreCase("dp-8-qam")) {
+            modulation = ModulationScheme.DP_8QAM;
+        } else {
+            modulation = ModulationScheme.DP_QPSK;
+        }
+        return modulation;
     }
 
-
     /*
      *
      * Set the ComponentType to invoke proper methods for different template T.
@@ -188,10 +152,10 @@
         String clsName = component.getClass().getName();
         switch (clsName) {
             case "org.onosproject.net.Direction":
-                state = CassiniModulationOpenConfig.ComponentType.DIRECTION;
+                state = ComponentType.DIRECTION;
                 break;
             case "org.onosproject.net.OchSignal":
-                state = CassiniModulationOpenConfig.ComponentType.OCHSIGNAL;
+                state = ComponentType.OCHSIGNAL;
                 break;
             default:
                 log.error("Cannot parse the component type {}.", clsName);
@@ -200,244 +164,4 @@
 
         state.cassini = this;
     }
-
-    /*
-     *
-     * Component type.
-     */
-
-
-    enum ComponentType {
-
-        /*
-         *
-         * Direction.
-         */
-
-
-        DIRECTION() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                log.info("Inside the enum setModulationScheme()");
-                super.setModulationScheme(port, component, bitRate);
-            }
-        },
-
-        /**
-         * OchSignal.
-         */
-
-
-        OCHSIGNAL() {
-            @Override
-            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-                return super.getModulationScheme(port, component);
-            }
-
-            @Override
-            void setModulationScheme(PortNumber port, Object component, long bitRate) {
-                super.setModulationScheme(port, component, bitRate);
-            }
-        };
-
-
-        CassiniModulationOpenConfig cassini;
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @return target modulation
-         */
-        Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
-            NetconfSession session = cassini.getNetconfSession(cassini.did());
-            checkNotNull(session);
-            String filter = createModulationFilter(cassini, port);
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<get-config>")
-                    .append("<source>")
-                    .append("<" + DatastoreId.RUNNING + "/>")
-                    .append("</source>")
-                    .append("<filter type='subtree'>")
-                    .append(filter)
-                    .append("</filter>")
-                    .append("</get-config>")
-                    .append(RPC_CLOSE_TAG);
-            XMLConfiguration xconf = cassini.executeRpc(session, rpcReq.toString());
-            if (xconf == null) {
-                log.error("Error in executingRpc");
-                return Optional.empty();
-            }
-            try {
-                HierarchicalConfiguration config =
-                        xconf.configurationAt("data/components/component/optical-channel/config");
-
-                String modulationScheme = String.valueOf(config.getString("modulation-format"));
-                /*Used for Internal Testing */
-                //String modulationScheme="DP16QAM";
-                ModulationScheme modulation;
-                if (modulationScheme.equalsIgnoreCase("dp-16-qam")) {
-                    modulation = ModulationScheme.DP_16QAM;
-                } else if (modulationScheme.equalsIgnoreCase("dp-8-qam")) {
-                    modulation = ModulationScheme.DP_8QAM;
-                } else {
-                    modulation = ModulationScheme.DP_QPSK;
-                }
-                return Optional.of(modulation);
-            } catch (IllegalArgumentException e) {
-                log.error("Error in parsing config", e);
-                return Optional.empty();
-            }
-        }
-
-        /*
-         * mirror method in the internal class.
-         * @param port port
-         * @param component component
-         * @param power target value
-         */
-        void setModulationScheme(PortNumber port, Object component, long bitRate) {
-
-            ModulationScheme modulation = null;
-            String editConfig = null;
-
-            //check if bitrate is less than equal to 100 Gig
-            if (bitRate <= BitRate.GBPS_100.value) {
-                modulation = ModulationScheme.DP_QPSK;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                setModulationRpc(port, component, editConfig);
-            } else { // check if bitrate is greater than 100 Gig
-                modulation = ModulationScheme.DP_16QAM;
-                editConfig = modulationEditConfig(cassini, port, component, bitRate, modulation.name());
-                //setting the modulation by calling rpc
-                setModulationRpc(port, component, editConfig);
-            }
-
-
-        }
-
-        private static String createModulationFilter(CassiniModulationOpenConfig modulationConfig,
-                                                     PortNumber portNumber) {
-            String name = ocName(modulationConfig, portNumber);
-            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-            sb.append("<component>").append("<name>").append(name).append("</name>");
-            sb.append("</component>").append("</components>");
-            return sb.toString();
-        }
-
-        /**
-         * Extract component name from portNumber's annotations.
-         *
-         * @param pc         modulation config instance
-         * @param portNumber the port number
-         * @return the component name
-         */
-
-
-        private static String ocName(CassiniModulationOpenConfig pc, PortNumber portNumber) {
-            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
-            DeviceId deviceId = pc.handler().data().deviceId();
-            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
-        }
-
-        /*
-         *
-         * Parse filtering string from port and component.
-         * @param portNumber Port Number
-         * @param component port component (optical-channel)
-         * @param bitRate bitRate in bps
-         * @return filtering string in xml format
-
-         */
-        private String modulationEditConfig(CassiniModulationOpenConfig modulationConfig, PortNumber portNumber,
-                                            Object component, long bitRate, String modulation) {
-            /*
-             <components xmlns="http://openconfig.net/yang/platform">
-               <component>
-                 <name>oc1/0</name>
-                 <config>
-                    <name>oc1/0</name>
-                 </config>
-                 <optical-channel xmlns="http://openconfig.net/yang/terminal-device">
-                   <config>
-                      <modulation-format>dp-16-qam</modulation-format>
-                   </config>
-                 </optical-channel>
-               </component>
-             </components>
-             */
-            String modulationOcNos = convertToOcNosModulation(modulation);
-            if (component != null) {
-                // This is an edit-config operation.
-                String portName = ocName(modulationConfig, portNumber); //oc1/0
-                StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
-                sb.append("<component>");
-                sb.append("<name>").append(portName).append("</name>");
-                sb.append("<config>");
-                sb.append("<name>").append(portName).append("</name>");
-                sb.append("</config>");
-                sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
-                        .append("<config>")
-                        .append("<modulation-format>")
-                        .append(modulationOcNos)
-                        .append("</modulation-format>")
-                        .append("</config>")
-                        .append("</optical-channel>");
-                sb.append("</component>");
-                sb.append("</components>");
-                return sb.toString();
-            } else {
-                log.error("Cannot process the component {}.", component.getClass());
-                return null;
-            }
-        }
-
-        private String convertToOcNosModulation(String modulation) {
-            if (modulation.equals(ModulationScheme.DP_QPSK.name())) {
-                return "dp-qpsk";
-            } else {
-                return "dp-16-qam";
-            }
-        }
-
-        private boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
-            NetconfSession session = cassini.getNetconfSession(cassini.did());
-            checkNotNull(session);
-            boolean response = true;
-            StringBuilder rpcReq = new StringBuilder();
-            rpcReq.append(RPC_TAG_NETCONF_BASE)
-                    .append("<edit-config>")
-                    .append("<target><" + DatastoreId.CANDIDATE + "/></target>")
-                    .append("<config>")
-                    .append(editConfig)
-                    .append("</config>")
-                    .append("</edit-config>")
-                    .append(RPC_CLOSE_TAG);
-            log.info("RPC call for Setting Modulation : {}", rpcReq.toString());
-            XMLConfiguration xconf = cassini.executeRpc(session, rpcReq.toString());
-            if (xconf == null) {
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            } else if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
-                // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
-                response = false;
-                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
-                        port.toString(), component.toString());
-            }
-            try {
-                session.commit();
-            } catch (NetconfException e) {
-                response = false;
-                log.error("error committing modulation changes");
-            }
-            return response;
-        }
-    }
 }
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
new file mode 100644
index 0000000..5b8992f
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/TerminalDeviceModulationConfig.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * This Work is contributed by Sterlite Technologies
+ */
+
+package org.onosproject.drivers.odtn;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onosproject.drivers.odtn.util.NetconfSessionUtility;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Direction;
+import org.onosproject.net.ModulationScheme;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.ModulationConfig;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/*
+ * Driver Implementation of the ModulationConfig for OpenConfig terminal devices.
+ */
+public class TerminalDeviceModulationConfig<T> extends AbstractHandlerBehaviour implements ModulationConfig<T> {
+
+
+    public static final String RPC_TAG_NETCONF_BASE =
+            "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
+
+    public static final String RPC_CLOSE_TAG = "</rpc>";
+
+    public static Logger log = LoggerFactory.getLogger(TerminalDeviceModulationConfig.class);
+
+    public TerminalDeviceModulationConfig.ComponentType state = ComponentType.DIRECTION;
+
+    private static final double OSNR_THRESHOLD_VALUE = 13.0;
+
+
+    public enum BitRate {
+        GBPS_200(200),      // 200 Gbps
+        GBPS_100(100),        // 100 Gbps
+        GBPS_40(40),          // 40 Gbps
+        GBPS_10(10);          // 10 Gbps
+
+        final long value;
+
+        public long getValue() {
+            return value;
+        }
+
+        BitRate(long value) {
+            this.value = value;
+        }
+    }
+
+    public NetconfController getController() {
+        return handler().get(NetconfController.class);
+    }
+
+    /*
+     *
+     * Get the deviceId for which the methods apply.
+     *
+     * @return The deviceId as contained in the handler data
+     */
+
+
+    public DeviceId getDeviceId() {
+        return handler().data().deviceId();
+    }
+
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param filter to build rpc
+     * @return RPC payload
+     */
+    public StringBuilder getModulationSchemeRequestRpc(String filter) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<get>")
+                .append("<filter>")
+                .append(filter)
+                .append("</filter>")
+                .append("</get>");
+        return rpc;
+    }
+
+    /**
+     * Construct a rpc target power message.
+     *
+     * @return RPC payload
+     */
+    public DatastoreId getDataStoreId() {
+        return DatastoreId.RUNNING;
+    }
+
+    /**
+     * Construct a rpc target power message.
+     *
+     * @param name for optical channel name
+     * @return RPC payload
+     */
+    public StringBuilder createModulationFilterRequestRpc(String name) {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<name>").append(name).append("</name>");
+        rpc.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">");
+        rpc.append("<config><modulation/></config>");
+        rpc.append("</optical-channel>");
+        return rpc;
+    }
+
+    /*
+     *
+     * Parse filtering string from port and component.
+     * @param portNumber Port Number
+     * @param component port component (optical-channel)
+     * @param bitRate bitRate in bps
+     * @return filtering string in xml format
+
+     */
+    public String modulationEditConfigRequestRpc(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                                 Object component, long bitRate, String modulation) {
+        if (component != null) {
+            String portName = state.ocName(modulationConfig, portNumber);
+            //String channelSpacing = channelSpacing(modulationConfig,portNumber);
+            //ChannelSpacing cs= ChannelSpacing.valueOf(channelSpacing);
+            //double csValue= cs.frequency().asGHz();
+
+            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
+            sb.append("<component>").append("<name>").append(portName).append("</name>");
+            if (modulation != null) {
+                // This is an edit-config operation.
+                sb.append("<optical-channel xmlns=\"http://openconfig.net/yang/terminal-device\">")
+                        .append("<config>")
+                        .append("<modulation>")
+                        .append(modulation)
+                        .append("</modulation>")
+                        .append("</config>")
+                        .append("</optical-channel>");
+            }
+            sb.append("</component>").append("</components>");
+            return sb.toString();
+        } else {
+            log.error("Cannot process the component {}.", component.getClass());
+            return null;
+        }
+    }
+
+    public void setModulationSchemeProcessor(PortNumber port, Object component, long bitRate) {
+        ModulationScheme modulation = null;
+        String editConfig = null;
+        double osnr = 0.0;
+        boolean rpcResponse = false;
+        boolean receiver = false;
+
+        // TODO OSNR is valid only for receiver so need to modify
+            /*if(component.toString().equals(Direction.INGRESS.toString())){
+                receiver=true;
+            }*/
+
+        //check if bitrate is less than equal to 100 Gig
+        if (bitRate <= BitRate.GBPS_100.value) {
+            modulation = ModulationScheme.DP_QPSK;
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation.name());
+            //setting the modulation by calling rpc
+            rpcResponse = state.setModulationRpc(port, component, editConfig);
+            if (rpcResponse) {
+                // TODO OSNR is valid only for receiver so need to modify
+                osnr = state.fetchDeviceSnr(state.cassini, port);
+                if (osnr <= OSNR_THRESHOLD_VALUE) {
+                    log.error("Channel not possible for this OSNR Value : {}", osnr);
+                }
+            }
+        } else { // check if bitrate is greater than 100 Gig
+            modulation = ModulationScheme.DP_16QAM;
+            editConfig = state.modulationEditConfig(state.cassini, port, component, bitRate, modulation.name());
+            //setting the modulation by calling rpc
+            rpcResponse = state.setModulationRpc(port, component, editConfig);
+            if (rpcResponse) {
+                //TODO OSNR is valid only for receiver so need to modify
+                osnr =  state.fetchDeviceSnr(state.cassini, port);
+                if (osnr <= OSNR_THRESHOLD_VALUE) {
+                    modulation = ModulationScheme.DP_8QAM;
+                    editConfig =  state.modulationEditConfig(state.cassini, port, component, bitRate,
+                                                             modulation.name());
+                    //setting the modulation by calling rpc
+                    rpcResponse = state.setModulationRpc(port, component, editConfig);
+                    if (rpcResponse) {
+                        // TODO OSNR is valid only for receiver so need to modify
+                        osnr = state.fetchDeviceSnr(state.cassini, port);
+                        if (osnr <= OSNR_THRESHOLD_VALUE) {
+                            log.warn("Channel not possible for this OSNR Value : {}." +
+                                             " Please reduce the channel bitrate.", osnr);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public ModulationScheme modulationSchemeType(String modulationScheme) {
+        return ModulationScheme.valueOf(modulationScheme);
+    }
+
+    /**
+     * Get the target Modulation Scheme on the component.
+     *
+     * @param port      the port
+     * @param component the port component
+     * @return ModulationScheme as per bitRate value
+     **/
+    @Override
+    public Optional<ModulationScheme> getModulationScheme(PortNumber port, T component) {
+        checkType(component);
+        return state.getModulationScheme(port, component);
+    }
+
+    /**
+     * Set the target Modulation Scheme on the component.
+     *
+     * @param port      the port
+     * @param component the port component
+     * @param bitRate   bit rate in bps
+     **/
+    @Override
+    public void setModulationScheme(PortNumber port, T component, long bitRate) {
+        checkType(component);
+        state.setModulationScheme(port, component, bitRate);
+    }
+
+    /*
+     *
+     * Set the ComponentType to invoke proper methods for different template T.
+     * @param component the component.
+     */
+    void checkType(Object component) {
+        String clsName = component.getClass().getName();
+
+        if (component instanceof Direction) {
+            state = TerminalDeviceModulationConfig.ComponentType.DIRECTION;
+        } else if (component instanceof OchSignal) {
+            state = TerminalDeviceModulationConfig.ComponentType.OCHSIGNAL;
+        } else {
+            log.error("Cannot parse the component type {}.", clsName);
+        }
+
+
+        state.cassini = this;
+    }
+
+    /*
+     *
+     * Component type.
+     */
+
+
+    public enum ComponentType {
+
+        /*
+         *
+         * Direction.
+         */
+
+
+        DIRECTION() {
+            @Override
+            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
+                return super.getModulationScheme(port, component);
+            }
+
+            @Override
+            void setModulationScheme(PortNumber port, Object component, long bitRate) {
+                super.setModulationScheme(port, component, bitRate);
+            }
+        },
+
+        /**
+         * OchSignal.
+         */
+
+
+        OCHSIGNAL() {
+            @Override
+            Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
+                return super.getModulationScheme(port, component);
+            }
+
+            @Override
+            void setModulationScheme(PortNumber port, Object component, long bitRate) {
+                super.setModulationScheme(port, component, bitRate);
+            }
+        };
+
+
+        TerminalDeviceModulationConfig cassini;
+
+        /*
+         * mirror method in the internal class.
+         * @param port port
+         * @param component component
+         * @return target modulation
+         */
+        Optional<ModulationScheme> getModulationScheme(PortNumber port, Object component) {
+            NetconfSession session = NetconfSessionUtility
+                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
+            checkNotNull(session);
+            String filter = createModulationFilter(cassini, port);
+            StringBuilder rpcReq = new StringBuilder();
+            rpcReq.append(RPC_TAG_NETCONF_BASE)
+                    .append(cassini.getModulationSchemeRequestRpc(filter))
+                    .append(RPC_CLOSE_TAG);
+            log.debug("RPC Call for Getting Modulation : \n {}", rpcReq.toString());
+            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
+            if (xconf == null) {
+                log.error("Error in executingRpc");
+                return Optional.empty();
+            }
+            try {
+                HierarchicalConfiguration config =
+                        xconf.configurationAt("components/component/optical-channel/config");
+
+                String modulationScheme = String.valueOf(config.getString("modulation"));
+
+                return Optional.of(cassini.modulationSchemeType(modulationScheme));
+            } catch (IllegalArgumentException e) {
+                return Optional.empty();
+            }
+        }
+
+        /*
+         * mirror method in the internal class.
+         * @param port port
+         * @param component component
+         * @param power target value
+         */
+        void setModulationScheme(PortNumber port, Object component, long bitRate) {
+            cassini.setModulationSchemeProcessor(port, component, bitRate);
+        }
+
+
+        /*
+         * Get filtered content under <optical-channel><state>.
+         * @param pc power config instance
+         * @param port the port number
+         * @param underState the filter condition
+         * @return RPC reply
+         */
+
+        //RPC call for OSNR still not finalised, need to update Rpc once validated
+        public static XMLConfiguration getTerminalDeviceSnr(TerminalDeviceModulationConfig config, PortNumber port) {
+            NetconfSession session = NetconfSessionUtility
+                    .getNetconfSession(config.getDeviceId(), config.getController());
+            checkNotNull(session);
+            String name = ocName(config, port);
+            StringBuilder rpcReq = new StringBuilder(RPC_TAG_NETCONF_BASE);
+            rpcReq.append("<get><filter>")
+                    .append("<osnr xmlns=\"http://openconfig.net/yang/terminal-device\">")
+                    .append("<instant/>")
+                    .append("</osnr></filter></get>")
+                    .append(RPC_CLOSE_TAG);
+            log.info("RPC Call for Fetching OSNR :\n\n {}", rpcReq.toString());
+            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
+            return xconf;
+        }
+
+        public static String createModulationFilter(TerminalDeviceModulationConfig modulationConfig,
+                                                        PortNumber portNumber) {
+            String name = ocName(modulationConfig, portNumber);
+            StringBuilder sb = new StringBuilder("<components xmlns=\"http://openconfig.net/yang/platform\">");
+            sb.append("<component>")
+                    .append(modulationConfig.createModulationFilterRequestRpc(name));
+            sb.append("</component>").append("</components>");
+            return sb.toString();
+        }
+
+        /**
+         * Extract component name from portNumber's annotations.
+         *
+         * @param pc         modulation config instance
+         * @param portNumber the port number
+         * @return the component name
+         */
+
+
+        public static String ocName(TerminalDeviceModulationConfig pc, PortNumber portNumber) {
+            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
+            DeviceId deviceId = pc.handler().data().deviceId();
+            return deviceService.getPort(deviceId, portNumber).annotations().value("oc-name");
+        }
+
+        private static String channelSpacing(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber) {
+            DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
+            DeviceId deviceId = modulationConfig.handler().data().deviceId();
+            String lambda = deviceService.getPort(deviceId, portNumber).annotations().value("lambda");
+
+            ObjectMapper mapper = new ObjectMapper();
+            String channelSpacing = "";
+            try {
+                JsonNode actualObj = mapper.readTree(lambda);
+                JsonNode csNode = actualObj.get("channelSpacing");
+                channelSpacing = csNode.asText();
+                log.info("Channel_Spacing : " + channelSpacing);
+
+            } catch (IOException e) {
+                log.error("Error while parsing Json");
+            }
+            return channelSpacing;
+
+        }
+
+        private double fetchDeviceSnr(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber) {
+            double osnr = 0.0;
+            XMLConfiguration xconf = getTerminalDeviceSnr(cassini, portNumber);
+            if (xconf == null) {
+                return osnr;
+            }
+            try {
+                HierarchicalConfiguration config =
+                        xconf.configurationAt("data/components/component/optical-channel/state/osnr");
+                osnr = Float.valueOf(config.getString("snr")).doubleValue();
+                return osnr;
+            } catch (IllegalArgumentException e) {
+                return osnr;
+            }
+        }
+        /*
+         *
+         * Parse filtering string from port and component.
+         * @param portNumber Port Number
+         * @param component port component (optical-channel)
+         * @param bitRate bitRate in bps
+         * @return filtering string in xml format
+
+         */
+
+        public String modulationEditConfig(TerminalDeviceModulationConfig modulationConfig, PortNumber portNumber,
+                                           Object component, long bitRate, String modulation) {
+            return cassini.modulationEditConfigRequestRpc(modulationConfig, portNumber, component, bitRate, modulation);
+        }
+
+        public boolean setModulationRpc(PortNumber port, Object component, String editConfig) {
+            NetconfSession session = NetconfSessionUtility
+                    .getNetconfSession(cassini.getDeviceId(), cassini.getController());
+            checkNotNull(session);
+            boolean response = true;
+            StringBuilder rpcReq = new StringBuilder();
+            rpcReq.append(RPC_TAG_NETCONF_BASE)
+                    .append("<edit-config>")
+                    .append("<target><" + cassini.getDataStoreId() + "/></target>")
+                    .append("<config>")
+                    .append(editConfig)
+                    .append("</config>")
+                    .append("</edit-config>")
+                    .append(RPC_CLOSE_TAG);
+            log.info("RPC call for Setting Modulation : {}", rpcReq.toString());
+            XMLConfiguration xconf = NetconfSessionUtility.executeRpc(session, rpcReq.toString());
+            if (xconf == null) {
+                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
+                        port.toString(), component.toString());
+            } else if (!xconf.getRoot().getChild(0).getName().equals("ok")) {
+                    // The successful reply should be "<rpc-reply ...><ok /></rpc-reply>"
+                response = false;
+                log.error("The <edit-config> operation to set target-modulation of Port({}:{}) is failed.",
+                        port.toString(), component.toString());
+            }
+            try {
+                session.commit();
+            } catch (NetconfException e) {
+                response = false;
+                log.error("error committing modulation changes");
+            }
+            return response;
+        }
+    }
+
+
+}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/util/NetconfSessionUtility.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/util/NetconfSessionUtility.java
index 6c9500c..363e90d 100644
--- a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/util/NetconfSessionUtility.java
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/util/NetconfSessionUtility.java
@@ -18,6 +18,7 @@
 
 package org.onosproject.drivers.odtn.util;
 
+import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.configuration.XMLConfiguration;
 import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
 import org.onosproject.drivers.utilities.XmlConfigParser;
@@ -29,6 +30,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.StringWriter;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
@@ -67,17 +69,37 @@
 
     public static XMLConfiguration executeRpc(NetconfSession session, String message) {
         try {
+            if (log.isDebugEnabled()) {
+                try {
+                    StringWriter stringWriter = new StringWriter();
+                    XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(message);
+                    xconf.setExpressionEngine(new XPathExpressionEngine());
+                    xconf.save(stringWriter);
+                    log.debug("Request {}", stringWriter.toString());
+                } catch (ConfigurationException e) {
+                    log.error("XML Config Exception ", e);
+                }
+            }
             CompletableFuture<String> fut = session.rpc(message);
             String rpcReply = fut.get();
             XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
             xconf.setExpressionEngine(new XPathExpressionEngine());
+            if (log.isDebugEnabled()) {
+                try {
+                    StringWriter stringWriter = new StringWriter();
+                    xconf.save(stringWriter);
+                    log.debug("Response {}", stringWriter.toString());
+                } catch (ConfigurationException e) {
+                    log.error("XML Config Exception ", e);
+                }
+            }
             return xconf;
         } catch (NetconfException ne) {
             log.error("Exception on Netconf protocol: {}.", ne);
         } catch (InterruptedException ie) {
             log.error("Interrupted Exception: {}.", ie);
         } catch (ExecutionException ee) {
-            log.error("Concurrent Exception while executing Netconf operation: {}.", ee.getCause());
+            log.error("Concurrent Exception while executing Netconf operation: {}.", ee);
         }
         return null;
     }
diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
index a32317a..7f1453f 100644
--- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
+++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
@@ -134,7 +134,7 @@
         <behaviour api="org.onosproject.net.behaviour.PowerConfig"
                    impl="org.onosproject.drivers.odtn.CassiniTerminalDevicePowerConfigExt"/>
         <behaviour api="org.onosproject.net.behaviour.ModulationConfig"
-                   impl="org.onosproject.drivers.odtn.CassiniModulationConfig"/>
+                   impl="org.onosproject.drivers.odtn.TerminalDeviceModulationConfig"/>
     </driver>
     <driver name="nokia-1830" manufacturer="nokia" hwVersion="1830" swVersion="R10.1.1">
         <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
