diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceDiscovery.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceDiscovery.java
new file mode 100644
index 0000000..4762bf1
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceDiscovery.java
@@ -0,0 +1,598 @@
+/*
+ * Copyright 2018-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 was partially supported by EC H2020 project METRO-HAUL (761727).
+ */
+
+package org.onosproject.drivers.odtn.openconfig;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.CltSignalType;
+import org.onosproject.net.OduSignalType;
+import org.onosproject.net.optical.device.OduCltPortHelper;
+import org.slf4j.Logger;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.concurrent.CompletableFuture;
+
+import org.onlab.packet.ChassisId;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
+
+import org.onosproject.drivers.utilities.XmlConfigParser;
+
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.PortDescription;
+
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import org.onosproject.net.optical.device.OchPortHelper;
+
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+
+import com.google.common.collect.ImmutableList;
+
+import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
+
+
+/**
+ * Driver Implementation of the DeviceDescription discovery for OpenConfig terminal devices.
+ *
+ * As defined in OpenConfig each PORT component includes a subcomponent:
+ * --- client ports have a subcomponent of type oc-platform-types:TRANSCEIVER
+ * --- line   ports have a subcomponent of type oc-opt-types:OPTICAL_CHANNEL
+ *
+ * Tested with a model in which each port includes the following two properties:
+ * --- odtn-port-type: can assume values "client" and "line"
+ * --- onos-index: integer value
+ *
+ * Other assumptions:
+ * --- The port name is in the format "port-xxx"
+ * --- The subcomponent of type TRANSCEIVER has a name in the format "transceiver-xxx"
+ * --- The subcomponent of type OPTICAL_CHANNEL has a name in the format "channel-xxx"
+ * --- In the section <terminal-device><logical-channels> the channel with index xxx is associated to transceiver-xxx
+ *
+ * Where xxx is the value of the onos-index property (e.g., port-11801, transceiver-11801, channel-11801)
+ *
+ * See simplified example of a port component:
+ *
+ * //CHECKSTYLE:OFF
+ * <component>
+ *     <name>port-11801</name>
+ *     <state>
+ *         <name>port-11801</name>
+ *         <type>oc-platform-types:PORT</type>
+ *     </state>
+ *     <properties>
+ *         <property>
+ *             <name>odtn-port-type</name>
+ *             <state>
+ *                 <name>odtn-port-type</name>
+ *                 <value>client</value>
+ *             </state>
+ *         </property>
+ *         <property>
+ *             <name>onos-index</name>
+ *             <state>
+ *                 <name>onos-index</name>
+ *                 <value>11801</value>
+ *             </state>
+ *             </property>
+ *     </properties>
+ *     <subcomponents>
+ *         <subcomponent>
+ *             <name>transceiver-11801</name>
+ *             <state>
+ *                 <name>transceiver-11801</name>
+ *             </state>
+ *         </subcomponent>
+ *     </subcomponents>
+ * </component>
+ * <terminal-device>
+ *     <logical-channels>
+ *         <channel>
+ *             <index>11801</index>
+ *             <state>
+ *                 <index>11801</index>
+ *                 <description>Logical channel 11801</description>
+ *                 <admin-state>DISABLED</admin-state>
+ *                 <rate-class>oc-opt-types:TRIB_RATE_10G</rate-class>
+ *                 <trib-protocol>oc-opt-types:PROT_10GE_LAN</trib-protocol>
+ *                 <logical-channel-type>oc-opt-types:PROT_ETHERNET</logical-channel-type>
+ *                 <loopback-mode>NONE</loopback-mode>
+ *                 <test-signal>false</test-signal>
+ *                 <link-state>UP</link-state>
+ *             </state>
+ *             <ingress>
+ *                 <state>
+ *                     <transceiver>transceiver-11801</transceiver>
+ *                 </state>
+ *             </ingress>
+ *         </channel>
+ *     <logical-channels>
+ * <terminal-device>
+ * //CHECKSTYLE:ON
+ */
+public class ClientLineTerminalDeviceDiscovery
+    extends AbstractHandlerBehaviour
+    implements OdtnDeviceDescriptionDiscovery, DeviceDescriptionDiscovery {
+
+    private static final String RPC_TAG_NETCONF_BASE =
+        "<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">";
+
+    private static final String OC_PLATFORM_TYPES_OPERATING_SYSTEM =
+            "oc-platform-types:OPERATING_SYSTEM";
+
+    private static final String RPC_CLOSE_TAG = "</rpc>";
+
+    private static final String OC_PLATFORM_TYPES_TRANSCEIVER =
+        "oc-platform-types:TRANSCEIVER";
+
+    private static final String OC_PLATFORM_TYPES_PORT =
+        "oc-platform-types:PORT";
+
+    private static final String OC_TRANSPORT_TYPES_OPTICAL_CHANNEL =
+        "oc-opt-types:OPTICAL_CHANNEL";
+
+    private static final Logger log = getLogger(ClientLineTerminalDeviceDiscovery.class);
+
+
+    /**
+     * Returns the NetconfSession with the device for which the method was called.
+     *
+     * @param deviceId device indetifier
+     *
+     * @return The netconf session or null
+     */
+    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();
+    }
+
+
+    /**
+     * Get the deviceId for which the methods apply.
+     *
+     * @return The deviceId as contained in the handler data
+     */
+    private DeviceId did() {
+        return handler().data().deviceId();
+    }
+
+
+    /**
+     * Get the device instance for which the methods apply.
+     *
+     * @return The device instance
+     */
+    private Device getDevice() {
+        DeviceService deviceService = checkNotNull(handler().get(DeviceService.class));
+        Device device = deviceService.getDevice(did());
+        return device;
+    }
+
+
+    /**
+     * Construct a String with a Netconf filtered get RPC Message.
+     *
+     * @param filter A valid XML tree with the filter to apply in the get
+     * @return a String containing the RPC XML Document
+     */
+    private String filteredGetBuilder(String filter) {
+        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
+        rpc.append("<get>");
+        rpc.append("<filter type='subtree'>");
+        rpc.append(filter);
+        rpc.append("</filter>");
+        rpc.append("</get>");
+        rpc.append(RPC_CLOSE_TAG);
+        return rpc.toString();
+    }
+
+
+    /**
+     * Construct a String with a Netconf filtered get RPC Message.
+     *
+     * @param filter A valid XPath Expression with the filter to apply in the get
+     * @return a String containing the RPC XML Document
+     *
+     * Note: server must support xpath capability.
+
+     * <select=" /components/component[name='PORT-A-In-1']/properties/...
+     * ...property[name='onos-index']/config/value" type="xpath"/>
+     */
+    private String xpathFilteredGetBuilder(String filter) {
+        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
+        rpc.append("<get>");
+        rpc.append("<filter type='xpath' select=\"");
+        rpc.append(filter);
+        rpc.append("\"/>");
+        rpc.append("</get>");
+        rpc.append(RPC_CLOSE_TAG);
+        return rpc.toString();
+    }
+
+
+    /**
+     * Builds a request to get Device details, operational data.
+     *
+     * @return A string with the Netconf RPC for a get with subtree rpcing based on
+     *    /components/component/state/type being oc-platform-types:OPERATING_SYSTEM
+     */
+    private String getDeviceDetailsBuilder() {
+        StringBuilder filter = new StringBuilder();
+        filter.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        filter.append(" <component>");
+        filter.append("  <state>");
+        filter.append("   <type xmlns:oc-platform-types='http://openconfig.net/yang/platform-types'>");
+        filter.append(OC_PLATFORM_TYPES_OPERATING_SYSTEM);
+        filter.append("   </type>");
+        filter.append("  </state>");
+        filter.append(" </component>");
+        filter.append("</components>");
+        return filteredGetBuilder(filter.toString());
+    }
+
+
+    /**
+     * Builds a request to get Device Components, config and operational data.
+     *
+     * @return A string with the Netconf RPC for a get with subtree rpcing based on
+     *    /components/
+     */
+    private String getDeviceComponentsBuilder() {
+        return filteredGetBuilder(
+            "<components xmlns='http://openconfig.net/yang/platform'/>");
+    }
+
+
+    /**
+     * Builds a request to get Device Ports, config and operational data.
+     *
+     * @return A string with the Netconf RPC for a get with subtree rpcing based on
+     *    /components/component/state/type being oc-platform-types:PORT
+     */
+    private String getDevicePortsBuilder() {
+        StringBuilder rpc = new StringBuilder();
+        rpc.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        rpc.append(" <component><state>");
+        rpc.append("   <type xmlns:oc-platform-types='http://openconfig.net/");
+        rpc.append("yang/platform-types'>oc-platform-types:PORT</type>");
+        rpc.append(" </state></component>");
+        rpc.append("</components>");
+        return filteredGetBuilder(rpc.toString());
+    }
+
+
+    /**
+     * Returns a DeviceDescription with Device info.
+     *
+     * @return DeviceDescription or null
+     *
+     * //CHECKSTYLE:OFF
+     * <pre>{@code
+     * <data>
+     * <components xmlns="http://openconfig.net/yang/platform">
+     *  <component>
+     *   <state>
+     *     <name>FIRMWARE</name>
+     *     <type>oc-platform-types:OPERATING_SYSTEM</type>
+     *     <description>CTTC METRO-HAUL Emulated OpenConfig TerminalDevice</description>
+     *     <version>0.0.1</version>
+     *   </state>
+     *  </component>
+     * </components>
+     * </data>
+     *}</pre>
+     * //CHECKSTYLE:ON
+     */
+    @Override
+    public DeviceDescription discoverDeviceDetails() {
+        boolean defaultAvailable = true;
+        SparseAnnotations annotations = DefaultAnnotations.builder().build();
+
+        log.debug("ClientLineTerminalDeviceDiscovery::discoverDeviceDetails device {}", did());
+
+        // Other option "OTN" or "OTHER", we use TERMINAL_DEVICE
+        org.onosproject.net.Device.Type type =
+            Device.Type.TERMINAL_DEVICE;
+
+        // Some defaults
+        String vendor       = "NOVENDOR";
+        String serialNumber = "0xCAFEBEEF";
+        String hwVersion    = "0.2.1";
+        String swVersion    = "0.2.1";
+        String chassisId    = "128";
+
+        // Get the session,
+        NetconfSession session = getNetconfSession(did());
+        try {
+            String reply = session.get(getDeviceDetailsBuilder());
+            log.debug("REPLY to DeviceDescription {}", reply);
+
+            // <rpc-reply> as root node, software hardare version requires openconfig >= 2018
+            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(reply);
+            vendor       = xconf.getString("data.components.component.state.mfg-name", vendor);
+            serialNumber = xconf.getString("data.components.component.state.serial-no", serialNumber);
+            swVersion    = xconf.getString("data.components.component.state.software-version", swVersion);
+            hwVersion    = xconf.getString("data.components.component.state.hardware-version", hwVersion);
+        } catch (Exception e) {
+                log.error("ClientLineTerminalDeviceDiscovery::discoverDeviceDetails - Failed to retrieve session {}",
+                        did());
+                throw new IllegalStateException(new NetconfException("Failed to retrieve version info.", e));
+        }
+
+        ChassisId cid = new ChassisId(Long.valueOf(chassisId, 10));
+
+        log.info("Device retrieved details");
+        log.info("VENDOR    {}", vendor);
+        log.info("HWVERSION {}", hwVersion);
+        log.info("SWVERSION {}", swVersion);
+        log.info("SERIAL    {}", serialNumber);
+        log.info("CHASSISID {}", chassisId);
+
+        return new DefaultDeviceDescription(did().uri(),
+                    type, vendor, hwVersion, swVersion, serialNumber,
+                    cid, defaultAvailable, annotations);
+    }
+
+
+
+    /**
+     * Returns a list of PortDescriptions for the device.
+     *
+     * @return a list of descriptions.
+     *
+     * The RPC reply follows the following pattern:
+     * //CHECKSTYLE:OFF
+     * <pre>{@code
+     * <?xml version="1.0" encoding="UTF-8"?>
+     * <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="7">
+     * <data>
+     *   <components xmlns="http://openconfig.net/yang/platform">
+     *     <component>....
+     *     </component>
+     *     <component>....
+     *     </component>
+     *   </components>
+     * </data>
+     * </rpc-reply>
+     * }</pre>
+     * //CHECKSTYLE:ON
+     */
+    @Override
+    public List<PortDescription> discoverPortDetails() {
+        try {
+            XPathExpressionEngine xpe = new XPathExpressionEngine();
+            NetconfSession session = getNetconfSession(did());
+            if (session == null) {
+                log.error("discoverPortDetails called with null session for {}", did());
+                return ImmutableList.of();
+            }
+
+            CompletableFuture<String> fut = session.rpc(getDeviceComponentsBuilder());
+            String rpcReply = fut.get();
+
+            XMLConfiguration xconf = (XMLConfiguration) XmlConfigParser.loadXmlString(rpcReply);
+            xconf.setExpressionEngine(xpe);
+
+            log.debug("REPLY {}", rpcReply);
+            HierarchicalConfiguration components = xconf.configurationAt("data/components");
+            return parsePorts(components);
+        } catch (Exception e) {
+            log.error("Exception discoverPortDetails() {}", did(), e);
+            return ImmutableList.of();
+        }
+    }
+
+    /**
+     * Parses port information from OpenConfig XML configuration.
+     *
+     * @param components the XML document with components root.
+     * @return List of ports
+     *
+     * //CHECKSTYLE:OFF
+     * <pre>{@code
+     *   <components xmlns="http://openconfig.net/yang/platform">
+     *     <component>....
+     *     </component>
+     *     <component>....
+     *     </component>
+     *   </components>
+     * }</pre>
+     * //CHECKSTYLE:ON
+     */
+    protected List<PortDescription> parsePorts(HierarchicalConfiguration components) {
+        return components.configurationsAt("component").stream()
+            .filter(component -> {
+                    return !component.getString("name", "unknown").equals("unknown") &&
+                    component.getString("state/type", "unknown").equals(OC_PLATFORM_TYPES_PORT);
+                    })
+            .map(component -> {
+                try {
+                    // Pass the root document for cross-reference
+                    return parsePortComponent(component, components);
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+            )
+            .filter(Objects::nonNull)
+            .collect(Collectors.toList());
+    }
+
+
+    /**
+     * Checks if a given component has a subcomponent of a given type.
+     *
+     * @param component subtree to parse looking for subcomponents.
+     * @param components the full components tree, to cross-ref in
+     *  case we need to check (sub)components' types.
+     *
+     * @return true or false
+     */
+    private boolean hasSubComponentOfType(
+            HierarchicalConfiguration component,
+            HierarchicalConfiguration components,
+            String type) {
+        long count = component.configurationsAt("subcomponents/subcomponent")
+            .stream()
+            .filter(subcomponent -> {
+                        String scName = subcomponent.getString("name");
+                        StringBuilder sb = new StringBuilder("component[name='");
+                        sb.append(scName);
+                        sb.append("']/state/type");
+                        String scType = components.getString(sb.toString(), "unknown");
+                        return scType.equals(type);
+                    })
+            .count();
+        return (count > 0);
+    }
+
+
+    /**
+     * Checks if a given component has a subcomponent of type OPTICAL_CHANNEL.
+     *
+     * @param component subtree to parse
+     * @param components the full components tree, to cross-ref in
+     *  case we need to check transceivers or optical channels.
+     *
+     * @return true or false
+     */
+    private boolean hasOpticalChannelSubComponent(
+            HierarchicalConfiguration component,
+            HierarchicalConfiguration components) {
+        return hasSubComponentOfType(component, components, OC_TRANSPORT_TYPES_OPTICAL_CHANNEL);
+    }
+
+
+    /**
+     *  Checks if a given component has a subcomponent of type TRANSCEIVER.
+     *
+     * @param component subtree to parse
+     * @param components the full components tree, to cross-ref in
+     *  case we need to check transceivers or optical channels.
+     *
+     * @return true or false
+     */
+    private boolean hasTransceiverSubComponent(
+            HierarchicalConfiguration component,
+            HierarchicalConfiguration components) {
+        return hasSubComponentOfType(component, components, OC_PLATFORM_TYPES_TRANSCEIVER);
+    }
+
+
+    /**
+     * Parses a component XML doc into a PortDescription.
+     *
+     * @param component subtree to parse. It must be a component ot type PORT.
+     * @param components the full components tree, to cross-ref in
+     *  case we need to check transceivers or optical channels.
+     *
+     * @return PortDescription or null if component does not have onos-index
+     */
+    private PortDescription parsePortComponent(
+            HierarchicalConfiguration component,
+            HierarchicalConfiguration components) {
+        Map<String, String> annotations = new HashMap<>();
+        String name = component.getString("name");
+        String type = component.getString("state/type");
+
+        log.info("Parsing Component {} type {}", name, type);
+
+        annotations.put(OdtnDeviceDescriptionDiscovery.OC_NAME, name);
+        annotations.put(OdtnDeviceDescriptionDiscovery.OC_TYPE, type);
+
+        // Store all properties as port properties
+        component.configurationsAt("properties/property")
+            .forEach(property -> {
+                    String pn = property.getString("name");
+                    String pv = property.getString("state/value");
+                    annotations.put(pn, pv);
+                    });
+
+        // Assing an ONOS port number
+        PortNumber portNum;
+        if (annotations.containsKey(ONOS_PORT_INDEX)) {
+            portNum = PortNumber.portNumber(Long.parseLong(annotations.get(ONOS_PORT_INDEX)));
+        } else {
+            log.warn("PORT {} does not include onos-index, hashing...", name);
+            portNum = PortNumber.portNumber(name.hashCode());
+        }
+        log.debug("PORT {} number {}", name, portNum);
+
+        // The heuristic to know if it is client or line side
+        if (!annotations.containsKey(PORT_TYPE)) {
+            if (hasTransceiverSubComponent(component, components)) {
+                annotations.put(PORT_TYPE, OdtnPortType.CLIENT.value());
+            } else if (hasOpticalChannelSubComponent(component, components)) {
+                annotations.put(PORT_TYPE, OdtnPortType.LINE.value());
+            }
+        }
+
+        // Build the port
+        // NOTE: using portNumber(id, name) breaks things. Intent parsing, port resorce management, etc. There seems
+        // to be an issue with resource mapping
+        if (annotations.get(PORT_TYPE).equals(OdtnPortType.CLIENT.value())) {
+            log.debug("PORT {} number {} added as CLIENT port", name, portNum);
+
+            return OduCltPortHelper.oduCltPortDescription(portNum,
+                    true,
+                    CltSignalType.CLT_10GBE,
+                    DefaultAnnotations.builder().putAll(annotations).build());
+        }
+        if (annotations.get(PORT_TYPE).equals(OdtnPortType.LINE.value())) {
+            log.debug("PORT {} number {} added as LINE port", name, portNum);
+
+            // TODO: To be configured
+            OchSignal signalId = OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1);
+
+            return OchPortHelper.ochPortDescription(
+                    portNum, true,
+                    OduSignalType.ODU4, // TODO Client signal to be discovered
+                    true,
+                    signalId,
+                    DefaultAnnotations.builder().putAll(annotations).build());
+        }
+        log.error("PORT {} number {} is of UNKNOWN type", name, portNum);
+        return null;
+    }
+}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceFlowRuleProgrammable.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceFlowRuleProgrammable.java
new file mode 100644
index 0000000..f316fc0
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/ClientLineTerminalDeviceFlowRuleProgrammable.java
@@ -0,0 +1,942 @@
+/*
+ * Copyright 2018-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 was partially supported by EC H2020 project METRO-HAUL (761727).
+ */
+
+package org.onosproject.drivers.odtn.openconfig;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.onlab.util.Frequency;
+import org.onlab.util.Spectrum;
+import org.onosproject.drivers.odtn.impl.DeviceConnectionCache;
+import org.onosproject.drivers.odtn.impl.FlowRuleParser;
+import org.onosproject.drivers.utilities.XmlConfigParser;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.OchSignalType;
+import org.onosproject.net.ChannelSpacing;
+import org.onosproject.net.GridType;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.odtn.behaviour.OdtnDeviceDescriptionDiscovery;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathFactory;
+import java.io.ByteArrayInputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Implementation of FlowRuleProgrammable interface for
+ * OpenConfig terminal devices.
+ */
+public class ClientLineTerminalDeviceFlowRuleProgrammable
+        extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(ClientLineTerminalDeviceFlowRuleProgrammable.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 String PREFIX_PORT = "port-";
+    private static final String PREFIX_CHANNEL = "channel-";
+    private static final String DEFAULT_OPERATIONAL_MODE = "0";
+    private static final String DEFAULT_TARGET_POWER = "0";
+    private static final String DEFAULT_ASSIGNMENT_INDEX = "1";
+    private static final String DEFAULT_ALLOCATION_INDEX = "10";
+    private static final int DEFAULT_RULE_PRIORITY = 10;
+    private static final long DEFAULT_RULE_COOKIE = 1234L;
+    private static final String OPERATION_DISABLE = "DISABLED";
+    private static final String OPERATION_ENABLE = "ENABLED";
+    private static final String OC_TYPE_PROT_OTN = "oc-opt-types:PROT_OTN";
+    private static final String OC_TYPE_PROT_ETH = "oc-opt-types:PROT_ETHERNET";
+
+
+    /**
+     * Apply the flow entries specified in the collection rules.
+     *
+     * @param rules A collection of Flow Rules to be applied
+     * @return The collection of added Flow Entries
+     */
+    @Override
+    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            openConfigError("null session");
+            return ImmutableList.of();
+        }
+
+        // Apply the  rules on the device
+        Collection<FlowRule> added = rules.stream()
+                .map(r -> new TerminalDeviceFlowRule(r, getLinePorts()))
+                .filter(xc -> applyFlowRule(session, xc))
+                .collect(Collectors.toList());
+
+        for (FlowRule flowRule : added) {
+            log.info("OpenConfig added flowrule {}", flowRule);
+            getConnectionCache().add(did(), ((TerminalDeviceFlowRule) flowRule).connectionName(), flowRule);
+        }
+
+        //Print out number of rules sent to the device (without receiving errors)
+        openConfigLog("applyFlowRules added {}", added.size());
+
+        return added;
+    }
+
+    /**
+     * Get the flow entries that are present on the device.
+     *
+     * @return A collection of Flow Entries
+     */
+    @Override
+    public Collection<FlowEntry> getFlowEntries() {
+        Collection<FlowEntry> fetched = fetchConnectionsFromDevice().stream()
+                .map(fr -> new DefaultFlowEntry(fr, FlowEntry.FlowEntryState.ADDED, 0, 0, 0))
+                .collect(Collectors.toList());
+
+        //Print out number of rules actually found on the device that are also included in the cache
+        openConfigLog("getFlowEntries fetched connections {}", fetched.size());
+
+        return fetched;
+    }
+
+    /**
+     * Remove the specified flow rules.
+     *
+     * @param rules A collection of Flow Rules to be removed
+     * @return The collection of removed Flow Entries
+     */
+    @Override
+    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
+        NetconfSession session = getNetconfSession();
+        if (session == null) {
+            openConfigError("null session");
+            return ImmutableList.of();
+        }
+        List<FlowRule> removed = new ArrayList<>();
+        for (FlowRule r : rules) {
+            try {
+                TerminalDeviceFlowRule termFlowRule = new TerminalDeviceFlowRule(r, getLinePorts());
+                removeFlowRule(session, termFlowRule);
+                getConnectionCache().remove(did(), r);
+                removed.add(r);
+            } catch (Exception e) {
+                openConfigError("Error {}", e);
+                continue;
+            }
+        }
+
+        //Print out number of removed rules from the device (without receiving errors)
+        openConfigLog("removeFlowRules removed {}", removed.size());
+
+        return removed;
+    }
+
+    private DeviceConnectionCache getConnectionCache() {
+        return DeviceConnectionCache.init();
+    }
+
+    // Context so XPath expressions are aware of XML namespaces
+    private static final NamespaceContext NS_CONTEXT = new NamespaceContext() {
+        @Override
+        public String getNamespaceURI(String prefix) {
+            if (prefix.equals("oc-platform-types")) {
+                return "http://openconfig.net/yang/platform-types";
+            }
+            if (prefix.equals("oc-opt-term")) {
+                return "http://openconfig.net/yang/terminal-device";
+            }
+            return null;
+        }
+
+        @Override
+        public Iterator getPrefixes(String val) {
+            return null;
+        }
+
+        @Override
+        public String getPrefix(String uri) {
+            return null;
+        }
+    };
+
+
+    /**
+     * Helper method to get the device id.
+     */
+    private DeviceId did() {
+        return data().deviceId();
+    }
+
+    /**
+     * Helper method to log from this class adding DeviceId.
+     */
+    private void openConfigLog(String format, Object... arguments) {
+        log.info("OPENCONFIG {}: " + format, did(), arguments);
+    }
+
+    /**
+     * Helper method to log an error from this class adding DeviceId.
+     */
+    private void openConfigError(String format, Object... arguments) {
+        log.error("OPENCONFIG {}: " + format, did(), arguments);
+    }
+
+
+    /**
+     * Helper method to get the Netconf Session.
+     */
+    private NetconfSession getNetconfSession() {
+        NetconfController controller =
+                checkNotNull(handler().get(NetconfController.class));
+        return controller.getNetconfDevice(did()).getSession();
+    }
+
+
+    /**
+     * Construct a String with a Netconf filtered get RPC Message.
+     *
+     * @param filter A valid XML tree with the filter to apply in the get
+     * @return a String containing the RPC XML Document
+     */
+    private String filteredGetBuilder(String filter) {
+        StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
+        rpc.append("<get>");
+        rpc.append("<filter type='subtree'>");
+        rpc.append(filter);
+        rpc.append("</filter>");
+        rpc.append("</get>");
+        rpc.append(RPC_CLOSE_TAG);
+        return rpc.toString();
+    }
+
+    /**
+     * Construct a get request to retrieve Components and their
+     * properties (for the ONOS port, index).
+     *
+     * @return The filt content to send to the device.
+     */
+    private String getComponents() {
+        StringBuilder filt = new StringBuilder();
+        filt.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        filt.append(" <component>");
+        filt.append("  <name/>");
+        filt.append("  <properties/>");
+        filt.append(" </component>");
+        filt.append("</components>");
+        return filteredGetBuilder(filt.toString());
+    }
+
+    /**
+     * Construct a get request to retrieve Optical Channels and
+     * the line port they are using.
+     * <p>
+     * This method is used to query the device so we can find the
+     * OpticalChannel component name that used a given line port.
+     *
+     * @return The filt content to send to the device.
+     */
+    private String getOpticalChannels() {
+        StringBuilder filt = new StringBuilder();
+        filt.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        filt.append(" <component>");
+        filt.append("  <name/>");
+        filt.append("  <state/>");
+        filt.append("  <oc-opt-term:optical-channel xmlns:oc-opt-term"
+                + " = 'http://openconfig.net/yang/terminal-device'>");
+        filt.append("    <oc-opt-term:config>");
+        filt.append("     <oc-opt-term:line-port/>");
+        filt.append("    </oc-opt-term:config>");
+        filt.append("  </oc-opt-term:optical-channel>");
+        filt.append(" </component>");
+        filt.append("</components>");
+        return filteredGetBuilder(filt.toString());
+    }
+
+    /**
+     * Get the OpenConfig component name for the OpticalChannel component
+     * associated to the passed port number (typically a line side port, already
+     * mapped to ONOS port).
+     *
+     * @param session    The netconf session to the device.
+     * @param portNumber ONOS port number of the Line port ().
+     * @return the channel component name or null
+     */
+    private String getOpticalChannel(NetconfSession session,
+                                     PortNumber portNumber) {
+        try {
+            checkNotNull(session);
+            checkNotNull(portNumber);
+            XPath xp = XPathFactory.newInstance().newXPath();
+            xp.setNamespaceContext(NS_CONTEXT);
+
+            // Get the port name for a given port number
+            // We could iterate the port annotations too, no need to
+            // interact with device.
+            String xpGetPortName =
+                    "/rpc-reply/data/components/"
+                            +
+                            "component[./properties/property[name='onos-index']/config/value ='" +
+                            portNumber.toLong() + "']/"
+                            + "name/text()";
+
+            // Get all the components and their properties
+            String compReply = session.rpc(getComponents()).get();
+            DocumentBuilderFactory builderFactory =
+                    DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder = builderFactory.newDocumentBuilder();
+            Document document =
+                    builder.parse(new InputSource(new StringReader(compReply)));
+            String portName = xp.evaluate(xpGetPortName, document);
+            String xpGetOptChannelName =
+                    "/rpc-reply/data/components/"
+                            + "component[./optical-channel/config/line-port='" + portName +
+                            "']/name/text()";
+
+            String optChannelReply = session.rpc(getOpticalChannels()).get();
+            document =
+                    builder.parse(new InputSource(new StringReader(optChannelReply)));
+            return xp.evaluate(xpGetOptChannelName, document);
+        } catch (Exception e) {
+            openConfigError("Exception {}", e);
+            return null;
+        }
+    }
+
+    private void setLogicalChannel(NetconfSession session, String operation, String logChannel)
+            throws NetconfException {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<terminal-device xmlns='http://openconfig.net/yang/terminal-device'>");
+        sb.append("<logical-channels>");
+        sb.append("<channel>");
+        sb.append("<index>" + logChannel + "</index>");
+        sb.append("<config>");
+        sb.append("<admin-state>" + operation + "</admin-state>");
+        sb.append("</config>");
+        sb.append("</channel>");
+        sb.append("</logical-channels>");
+        sb.append("</terminal-device>");
+
+        boolean ok =
+                session.editConfig(DatastoreId.RUNNING, null, sb.toString());
+        if (!ok) {
+            throw new NetconfException("error writing the logical channel");
+        }
+    }
+
+    private void setOpticalChannelFrequency(NetconfSession session, String optChannel, Frequency freq)
+            throws NetconfException {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        sb.append("<component>");
+        sb.append("<name>" + PREFIX_CHANNEL + optChannel + "</name>");
+        sb.append("<oc-opt-term:optical-channel xmlns:oc-opt-term='http://openconfig.net/yang/terminal-device'>");
+        sb.append("<oc-opt-term:config>");
+        sb.append("<oc-opt-term:frequency>" + (long) freq.asMHz() + "</oc-opt-term:frequency>");
+        sb.append("<oc-opt-term:target-output-power>" + DEFAULT_TARGET_POWER + "</oc-opt-term:target-output-power>");
+        sb.append("<oc-opt-term:operational-mode>" + DEFAULT_OPERATIONAL_MODE + "</oc-opt-term:operational-mode>");
+        sb.append("<oc-opt-term:line-port>" + PREFIX_PORT + optChannel + "</oc-opt-term:line-port>");
+        sb.append("</oc-opt-term:config>");
+        sb.append("</oc-opt-term:optical-channel>");
+        sb.append("</component>");
+        sb.append("</components>");
+
+        boolean ok =
+                session.editConfig(DatastoreId.RUNNING, null, sb.toString());
+        if (!ok) {
+            throw new NetconfException("error writing channel frequency");
+        }
+    }
+
+    private void setLogicalChannelAssignment(NetconfSession session, String operation, String client, String line,
+                                             String assignmentIndex, String allocationIndex)
+            throws NetconfException {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("<terminal-device xmlns='http://openconfig.net/yang/terminal-device'>");
+        sb.append("<logical-channels>");
+        sb.append("<channel>");
+        sb.append("<index>" + client + "</index>");
+        sb.append("<config>");
+        sb.append("<admin-state>" + operation + "</admin-state>");
+        sb.append("</config>");
+        sb.append("<logical-channel-assignments>");
+        sb.append("<assignment>");
+        sb.append("<index>" + assignmentIndex + "</index>");
+        sb.append("<config>");
+        sb.append("<logical-channel>" + line + "</logical-channel>");
+        sb.append("<allocation>" + allocationIndex + "</allocation>");
+        sb.append("</config>");
+        sb.append("</assignment>");
+        sb.append("</logical-channel-assignments>");
+        sb.append("</channel>");
+        sb.append("</logical-channels>");
+        sb.append("</terminal-device>");
+
+        boolean ok =
+                session.editConfig(DatastoreId.RUNNING, null, sb.toString());
+        if (!ok) {
+            throw new NetconfException("error writing logical channel assignment");
+        }
+    }
+
+    /**
+     * Apply a single flowrule to the device.
+     *
+     * --- Directionality details:
+     * Driver supports ADD (INGRESS) and DROP (EGRESS) rules generated by OpticalCircuit/OpticalConnectivity intents
+     * the format of the rules are checked in class TerminalDeviceFlowRule
+     *
+     * However, the physical transponder is always bidirectional as specified in OpenConfig YANG models
+     * therefore ADD and DROP rules are mapped in the same xml that ENABLE (and tune) a transponder port.
+     *
+     * If the intent is generated as bidirectional both ADD and DROP flowrules are generated for each device, thus
+     * the same xml is sent twice to the device.
+     *
+     * @param session   The Netconf session.
+     * @param rule      Flow Rules to be applied.
+     * @return true if no Netconf errors are received from the device when xml is sent
+     * @throws NetconfException if exchange goes wrong
+     */
+    protected boolean applyFlowRule(NetconfSession session, TerminalDeviceFlowRule rule) {
+
+        //Configuration of LINE side, used for OpticalConnectivity intents
+        //--- configure central frequency
+        //--- enable the line port
+        if (rule.type == TerminalDeviceFlowRule.Type.LINE_INGRESS ||
+                rule.type == TerminalDeviceFlowRule.Type.LINE_EGRESS) {
+
+            FlowRuleParser frp = new FlowRuleParser(rule);
+            String componentName = frp.getPortNumber().toString();
+            Frequency centralFrequency = frp.getCentralFrequency();
+
+            StringBuilder componentConf = new StringBuilder();
+
+            log.info("Sending LINE FlowRule to device {} LINE port {}, frequency {}",
+                    did(), componentName, centralFrequency);
+
+            try {
+                setOpticalChannelFrequency(session, componentName, centralFrequency);
+            } catch (NetconfException e) {
+                log.error("Error writing central frequency in the component");
+                return false;
+            }
+
+            try {
+                setLogicalChannel(session, OPERATION_ENABLE, componentName);
+            } catch (NetconfException e) {
+                log.error("Error enabling the logical channel");
+                return false;
+            }
+        }
+
+        //Configuration of CLIENT side, used for OpticalCircuit intents
+        //--- associate the client port to the line port
+        //--- enable the client port
+        //
+        //Assumes only one "assignment" per logical-channel with index 1
+        //TODO check the OTN mapping of client ports into the line port frame specified by parameter "<allocation>"
+        if (rule.type == TerminalDeviceFlowRule.Type.CLIENT_INGRESS ||
+                rule.type == TerminalDeviceFlowRule.Type.CLIENT_EGRESS) {
+
+            String clientPortName;
+            String linePortName;
+            if (rule.type == TerminalDeviceFlowRule.Type.CLIENT_INGRESS) {
+                clientPortName = rule.inPort().toString();
+                linePortName = rule.outPort().toString();
+            } else {
+                clientPortName = rule.outPort().toString();
+                linePortName = rule.inPort().toString();
+            }
+
+            log.info("Sending CLIENT FlowRule to device {} CLIENT port: {}, LINE port {}",
+                    did(), clientPortName, linePortName);
+
+            try {
+                setLogicalChannelAssignment(session, OPERATION_ENABLE, clientPortName, linePortName,
+                        DEFAULT_ASSIGNMENT_INDEX, DEFAULT_ALLOCATION_INDEX);
+            } catch (NetconfException e) {
+                log.error("Error setting the logical channel assignment");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected boolean removeFlowRule(NetconfSession session, TerminalDeviceFlowRule rule)
+            throws NetconfException {
+
+        //Configuration of LINE side, used for OpticalConnectivity intents
+        //--- configure central frequency to ZERO
+        //--- disable the line port
+        if (rule.type == TerminalDeviceFlowRule.Type.LINE_INGRESS ||
+                rule.type == TerminalDeviceFlowRule.Type.LINE_EGRESS) {
+
+            FlowRuleParser frp = new FlowRuleParser(rule);
+            String componentName = frp.getPortNumber().toString();
+
+            log.info("Removing LINE FlowRule device {} line port {}",
+                    did(), componentName);
+
+            try {
+                setLogicalChannel(session, OPERATION_DISABLE, componentName);
+            } catch (NetconfException e) {
+                log.error("Error disabling the logical channel line side");
+                return false;
+            }
+        }
+
+        //Configuration of CLIENT side, used for OpticalCircuit intents
+        //--- configure central frequency to ZERO
+        //--- disable the line port
+        if (rule.type == TerminalDeviceFlowRule.Type.CLIENT_INGRESS ||
+                rule.type == TerminalDeviceFlowRule.Type.CLIENT_EGRESS) {
+
+            String clientPortName;
+            String linePortName;
+            if (rule.type == TerminalDeviceFlowRule.Type.CLIENT_INGRESS) {
+                clientPortName = rule.inPort().toString();
+                linePortName = rule.outPort().toString();
+            } else {
+                clientPortName = rule.outPort().toString();
+                linePortName = rule.inPort().toString();
+            }
+
+            log.debug("Removing CLIENT FlowRule device {} client port: {}, line port {}",
+                    did(), clientPortName, linePortName);
+
+            try {
+                setLogicalChannelAssignment(session, OPERATION_DISABLE, clientPortName, linePortName,
+                        DEFAULT_ASSIGNMENT_INDEX, DEFAULT_ALLOCATION_INDEX);
+            } catch (NetconfException e) {
+                log.error("Error disabling the logical channel assignment");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private List<FlowRule> fetchLineConnectionFromDevice(String channel, Frequency centralFreq) {
+        List<FlowRule> confirmedRules = new ArrayList<>();
+        FlowRule cacheAddRule;
+        FlowRule cacheDropRule;
+        NetconfSession session = getNetconfSession();
+
+        log.debug("fetchOpticalConnectionsFromDevice {} frequency {}", did(), centralFreq);
+
+        //Build the corresponding flow rule as expected
+        //Selector including port and ochSignal
+        //Treatment including port
+        PortNumber inputPortNumber = PortNumber.portNumber(channel);
+        PortNumber outputPortNumber = PortNumber.portNumber(channel);
+
+        log.debug("fetchOpticalConnectionsFromDevice {} port {}-{}", did(), inputPortNumber, outputPortNumber);
+
+        TrafficSelector selectorDrop = DefaultTrafficSelector.builder()
+                .matchInPort(inputPortNumber)
+                .add(Criteria.matchOchSignalType(OchSignalType.FIXED_GRID))
+                .add(Criteria.matchLambda(toOchSignal(centralFreq, 50.0)))
+                .build();
+
+        TrafficTreatment treatmentDrop = DefaultTrafficTreatment.builder()
+                .setOutput(outputPortNumber)
+                .build();
+
+        TrafficSelector selectorAdd = DefaultTrafficSelector.builder()
+                .matchInPort(inputPortNumber)
+                .build();
+
+        TrafficTreatment treatmentAdd = DefaultTrafficTreatment.builder()
+                .add(Instructions.modL0Lambda(toOchSignal(centralFreq, 50.0)))
+                .setOutput(outputPortNumber)
+                .build();
+
+        //Retrieved rules and cached rules are considered equal if both selector and treatment are equal
+        cacheAddRule = null;
+        cacheDropRule = null;
+        if (getConnectionCache().size(did()) != 0) {
+            cacheDropRule = getConnectionCache().get(did()).stream()
+                    .filter(r -> (r.selector().equals(selectorDrop) && r.treatment().equals(treatmentDrop)))
+                    .findFirst()
+                    .orElse(null);
+
+            cacheAddRule = getConnectionCache().get(did()).stream()
+                    .filter(r -> (r.selector().equals(selectorAdd) && r.treatment().equals(treatmentAdd)))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        //Include the DROP rule to the retrieved rules if found in cache
+        if ((cacheDropRule != null)) {
+            confirmedRules.add(cacheDropRule);
+            log.debug("fetchOpticalConnectionsFromDevice {} DROP LINE rule included in the cache {}",
+                    did(), cacheDropRule);
+        } else {
+            log.warn("fetchOpticalConnectionsFromDevice {} DROP LINE rule not included in cache", did());
+        }
+
+        //Include the ADD rule to the retrieved rules if found in cache
+        if ((cacheAddRule != null)) {
+            confirmedRules.add(cacheAddRule);
+            log.debug("fetchOpticalConnectionsFromDevice {} ADD LINE rule included in the cache {}",
+                    did(), cacheAddRule.selector());
+        } else {
+            log.warn("fetchOpticalConnectionsFromDevice {} ADD LINE rule not included in cache", did());
+        }
+
+        //If neither Add or Drop rules are present in the cache, remove configuration from the device
+        if ((cacheDropRule == null) && (cacheAddRule == null)) {
+            log.warn("fetchOpticalConnectionsFromDevice {} ADD and DROP rule not included in the cache", did());
+
+            FlowRule deviceDropRule = DefaultFlowRule.builder()
+                    .forDevice(data().deviceId())
+                    .makePermanent()
+                    .withSelector(selectorDrop)
+                    .withTreatment(treatmentDrop)
+                    .withCookie(DEFAULT_RULE_COOKIE)
+                    .withPriority(DEFAULT_RULE_PRIORITY)
+                    .build();
+
+            FlowRule deviceAddRule = DefaultFlowRule.builder()
+                    .forDevice(data().deviceId())
+                    .makePermanent()
+                    .withSelector(selectorAdd)
+                    .withTreatment(treatmentAdd)
+                    .withCookie(DEFAULT_RULE_COOKIE)
+                    .withPriority(DEFAULT_RULE_PRIORITY)
+                    .build();
+
+            try {
+                //TODO this is not required if allowExternalFlowRules
+                TerminalDeviceFlowRule addRule = new TerminalDeviceFlowRule(deviceAddRule, getLinePorts());
+                removeFlowRule(session, addRule);
+
+                TerminalDeviceFlowRule dropRule = new TerminalDeviceFlowRule(deviceDropRule, getLinePorts());
+                removeFlowRule(session, dropRule);
+            } catch (NetconfException e) {
+                openConfigError("Error removing LINE rule from device", e);
+            }
+        }
+        return confirmedRules;
+    }
+
+    private List<FlowRule> fetchClientConnectionFromDevice(PortNumber clientPortNumber, PortNumber linePortNumber) {
+        List<FlowRule> confirmedRules = new ArrayList<>();
+        FlowRule cacheAddRule;
+        FlowRule cacheDropRule;
+        NetconfSession session = getNetconfSession();
+
+        //Build the corresponding flow rule as expected
+        //Selector including port
+        //Treatment including port
+
+        log.debug("fetchClientConnectionsFromDevice {} client {} line {}", did(), clientPortNumber, linePortNumber);
+
+        TrafficSelector selectorDrop = DefaultTrafficSelector.builder()
+                .matchInPort(linePortNumber)
+                .build();
+
+        TrafficTreatment treatmentDrop = DefaultTrafficTreatment.builder()
+                .setOutput(clientPortNumber)
+                .build();
+
+        TrafficSelector selectorAdd = DefaultTrafficSelector.builder()
+                .matchInPort(clientPortNumber)
+                .build();
+
+        TrafficTreatment treatmentAdd = DefaultTrafficTreatment.builder()
+                .setOutput(linePortNumber)
+                .build();
+
+        //Retrieved rules and cached rules are considered equal if both selector and treatment are equal
+        cacheAddRule = null;
+        cacheDropRule = null;
+        if (getConnectionCache().size(did()) != 0) {
+            cacheDropRule = getConnectionCache().get(did()).stream()
+                    .filter(r -> (r.selector().equals(selectorDrop) && r.treatment().equals(treatmentDrop)))
+                    .findFirst()
+                    .orElse(null);
+
+            cacheAddRule = getConnectionCache().get(did()).stream()
+                    .filter(r -> (r.selector().equals(selectorAdd) && r.treatment().equals(treatmentAdd)))
+                    .findFirst()
+                    .orElse(null);
+        }
+
+        //Include the DROP rule to the retrieved rules if found in cache
+        if ((cacheDropRule != null)) {
+            confirmedRules.add(cacheDropRule);
+            log.debug("fetchClientConnectionsFromDevice {} DROP CLIENT rule in the cache {}",
+                    did(), cacheDropRule);
+        } else {
+            log.warn("fetchClientConnectionsFromDevice {} DROP CLIENT rule not found in cache", did());
+        }
+
+        //Include the ADD rule to the retrieved rules if found in cache
+        if ((cacheAddRule != null)) {
+            confirmedRules.add(cacheAddRule);
+            log.debug("fetchClientConnectionsFromDevice {} ADD CLIENT rule in the cache {}",
+                    did(), cacheAddRule);
+        } else {
+            log.warn("fetchClientConnectionsFromDevice {} ADD CLIENT rule not found in cache", did());
+        }
+
+        if ((cacheDropRule == null) && (cacheAddRule == null)) {
+            log.warn("fetchClientConnectionsFromDevice {} ADD and DROP rule not included in the cache", did());
+
+            FlowRule deviceDropRule = DefaultFlowRule.builder()
+                    .forDevice(data().deviceId())
+                    .makePermanent()
+                    .withSelector(selectorDrop)
+                    .withTreatment(treatmentDrop)
+                    .withCookie(DEFAULT_RULE_COOKIE)
+                    .withPriority(DEFAULT_RULE_PRIORITY)
+                    .build();
+
+            FlowRule deviceAddRule = DefaultFlowRule.builder()
+                    .forDevice(data().deviceId())
+                    .makePermanent()
+                    .withSelector(selectorAdd)
+                    .withTreatment(treatmentAdd)
+                    .withCookie(DEFAULT_RULE_COOKIE)
+                    .withPriority(DEFAULT_RULE_PRIORITY)
+                    .build();
+
+            try {
+                //TODO this is not required if allowExternalFlowRules
+                TerminalDeviceFlowRule addRule = new TerminalDeviceFlowRule(deviceAddRule, getLinePorts());
+                removeFlowRule(session, addRule);
+
+                TerminalDeviceFlowRule dropRule = new TerminalDeviceFlowRule(deviceDropRule, getLinePorts());
+                removeFlowRule(session, dropRule);
+            } catch (NetconfException e) {
+                openConfigError("Error removing CLIENT rule from device", e);
+            }
+        }
+        return confirmedRules;
+    }
+
+    /**
+     * Fetches list of connections from device.
+     *
+     * TODO manage allow external flow rules (allowExternalFlowRules)
+     * Currently removes from the device all connections that are not currently present in the DeviceConnectionCache.
+     *
+     * @return connections that are present on the device and in the DeviceConnectionCache.
+     */
+    private List<FlowRule> fetchConnectionsFromDevice() {
+        List<FlowRule> confirmedRules = new ArrayList<>();
+        String reply;
+        FlowRule cacheAddRule;
+        FlowRule cacheDropRule;
+        NetconfSession session = getNetconfSession();
+
+        //Get relevant information from the device
+        StringBuilder requestFilter = new StringBuilder();
+        requestFilter.append("<components xmlns='http://openconfig.net/yang/platform'>");
+        requestFilter.append("  <component>");
+        requestFilter.append("    <name/>");
+        requestFilter.append("    <oc-opt-term:optical-channel " +
+                "xmlns:oc-opt-term='http://openconfig.net/yang/terminal-device'>");
+        requestFilter.append("      <oc-opt-term:config/>");
+        requestFilter.append("    </oc-opt-term:optical-channel>");
+        requestFilter.append("  </component>");
+        requestFilter.append("</components>");
+        requestFilter.append("<terminal-device xmlns='http://openconfig.net/yang/terminal-device'>");
+        requestFilter.append("  <logical-channels>");
+        requestFilter.append("    <channel>");
+        requestFilter.append("      <index/>");
+        requestFilter.append("      <config>");
+        requestFilter.append("        <admin-state/>");
+        requestFilter.append("        <logical-channel-type/>");
+        requestFilter.append("      </config>");
+        requestFilter.append("      <logical-channel-assignments>");
+        requestFilter.append("        <assignment>");
+        requestFilter.append("          <config>");
+        requestFilter.append("            <logical-channel/>");
+        requestFilter.append("          </config>");
+        requestFilter.append("        </assignment>");
+        requestFilter.append("      </logical-channel-assignments>");
+        requestFilter.append("    </channel>");
+        requestFilter.append("  </logical-channels>");
+        requestFilter.append("</terminal-device>");
+
+        try {
+            reply = session.get(requestFilter.toString(), null);
+            //log.debug("TRANSPONDER CONNECTIONS - fetchConnectionsFromDevice {} reply {}", did(), reply);
+        } catch (NetconfException e) {
+            log.error("Failed to retrieve configuration details for device {}", handler().data().deviceId(), e);
+            return ImmutableList.of();
+        }
+
+        HierarchicalConfiguration cfg = XmlConfigParser.loadXml(new ByteArrayInputStream(reply.getBytes()));
+
+        List<HierarchicalConfiguration> logicalChannels =
+                cfg.configurationsAt("data.terminal-device.logical-channels.channel");
+
+        List<HierarchicalConfiguration> components =
+                cfg.configurationsAt("data.components.component");
+
+        //Retrieve the ENABLED line ports
+        List<String> enabledOpticalChannels = logicalChannels.stream()
+                .filter(r -> r.getString("config.logical-channel-type").equals(OC_TYPE_PROT_OTN))
+                .filter(r -> r.getString("config.admin-state").equals(OPERATION_ENABLE))
+                .map(r -> r.getString("index"))
+                .collect(Collectors.toList());
+
+        log.debug("fetchConnectionsFromDevice {} enabledOpticalChannelsIndex {}", did(), enabledOpticalChannels);
+
+        if (enabledOpticalChannels.size() != 0) {
+            for (String channel : enabledOpticalChannels) {
+                log.debug("fetchOpticalConnectionsFromDevice {} channel {}", did(), channel);
+
+                //Retrieve the corresponding central frequency from the associated component
+                //TODO correlate the components instead of relying on naming
+                Frequency centralFreq = components.stream()
+                        .filter(c -> c.getString("name").equals(PREFIX_CHANNEL + channel))
+                        .map(c -> c.getDouble("optical-channel.config.frequency"))
+                        .map(c -> Frequency.ofMHz(c))
+                        .findFirst()
+                        .orElse(null);
+
+                confirmedRules.addAll(fetchLineConnectionFromDevice(channel, centralFreq));
+            }
+        }
+
+        //Retrieve the ENABLED client ports
+        List<String> enabledClientChannels = logicalChannels.stream()
+                .filter(r -> r.getString("config.logical-channel-type").equals(OC_TYPE_PROT_ETH))
+                .filter(r -> r.getString("config.admin-state").equals(OPERATION_ENABLE))
+                .map(r -> r.getString("index"))
+                .collect(Collectors.toList());
+
+        log.debug("fetchClientConnectionsFromDevice {} enabledClientChannelsIndex {}", did(), enabledClientChannels);
+
+        if (enabledClientChannels.size() != 0) {
+            for (String clientPort : enabledClientChannels) {
+
+                log.debug("fetchClientConnectionsFromDevice {} channel {}", did(), clientPort);
+
+                String linePort = logicalChannels.stream()
+                    .filter(r -> r.getString("config.logical-channel-type").equals(OC_TYPE_PROT_ETH))
+                    .filter(r -> r.getString("config.admin-state").equals(OPERATION_ENABLE))
+                    .filter(r -> r.getString("index").equals(clientPort))
+                    .map(r -> r.getString("logical-channel-assignments.assignment.config.logical-channel"))
+                    .findFirst()
+                    .orElse(null);
+
+                //Build the corresponding flow rule as expected
+                //Selector including port
+                //Treatment including port
+                PortNumber clientPortNumber = PortNumber.portNumber(clientPort);
+                PortNumber linePortNumber = PortNumber.portNumber(linePort);
+
+                confirmedRules.addAll(fetchClientConnectionFromDevice(clientPortNumber, linePortNumber));
+            }
+        }
+
+        //Returns rules that are both on the device and on the cache
+        if (confirmedRules.size() != 0) {
+            log.info("fetchConnectionsFromDevice {} number of confirmed rules {}", did(), confirmedRules.size());
+            return confirmedRules;
+        } else {
+            return ImmutableList.of();
+        }
+    }
+
+    /**
+     * Convert start and end frequencies to OCh signal.
+     *
+     * FIXME: supports channel spacing 50 and 100
+     *
+     * @param central central frequency as double in THz
+     * @param width width of the channel arounf the central frequency as double in GHz
+     * @return OCh signal
+     */
+    public static OchSignal toOchSignal(Frequency central, double width) {
+        int slots = (int) (width / ChannelSpacing.CHL_12P5GHZ.frequency().asGHz());
+        int multiplier = 0;
+
+        double centralAsGHz = central.asGHz();
+
+        if (width == 50) {
+            multiplier = (int) ((centralAsGHz - Spectrum.CENTER_FREQUENCY.asGHz())
+                    / ChannelSpacing.CHL_50GHZ.frequency().asGHz());
+
+            return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, multiplier, slots);
+        }
+
+        if (width == 100) {
+            multiplier = (int) ((centralAsGHz - Spectrum.CENTER_FREQUENCY.asGHz())
+                    / ChannelSpacing.CHL_100GHZ.frequency().asGHz());
+
+            return new OchSignal(GridType.DWDM, ChannelSpacing.CHL_100GHZ, multiplier, slots);
+        }
+
+        return null;
+    }
+
+    private List<PortNumber> getLinePorts() {
+        List<PortNumber> linePorts;
+
+        DeviceService deviceService = this.handler().get(DeviceService.class);
+        linePorts = deviceService.getPorts(data().deviceId()).stream()
+                .filter(p -> p.annotations().value(OdtnDeviceDescriptionDiscovery.PORT_TYPE)
+                        .equals(OdtnDeviceDescriptionDiscovery.OdtnPortType.LINE.value()))
+                .map(p -> p.number())
+                .collect(Collectors.toList());
+
+        return linePorts;
+
+    }
+}
diff --git a/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/TerminalDeviceFlowRule.java b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/TerminalDeviceFlowRule.java
new file mode 100644
index 0000000..fb6eead
--- /dev/null
+++ b/drivers/odtn-driver/src/main/java/org/onosproject/drivers/odtn/openconfig/TerminalDeviceFlowRule.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2018-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 was partially supported by EC H2020 project METRO-HAUL (761727).
+ */
+
+package org.onosproject.drivers.odtn.openconfig;
+
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.L0ModificationInstruction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class TerminalDeviceFlowRule extends DefaultFlowRule {
+    private static final Logger log = LoggerFactory.getLogger(TerminalDeviceFlowRule.class);
+
+    public enum Type {
+        CLIENT_INGRESS,
+        CLIENT_EGRESS,
+        LINE_INGRESS,
+        LINE_EGRESS
+    }
+
+    //As generated by the OpticalConnectivityIntentCompiler
+    private static final int NUM_CRITERIA_LINE_EGRESS_RULE = 3;
+    private static final int NUM_INSTRUCTIONS_LINE_EGRESS_RULE = 1;
+    private static final int NUM_CRITERIA_LINE_INGRESS_RULE = 1;
+    private static final int NUM_INSTRUCTIONS_LINE_INGRESS_RULE = 2;
+
+    //As generated by the OpticalCoircuitIntentCompiler
+    private static final int NUM_CRITERIA_CLIENT_RULES = 1;
+    private static final int NUM_INSTRUCTIONS_CLIENT_RULES = 1;
+
+    public Type type;
+
+    private PortNumber inPortNumber;
+    private PortNumber outPortNumber;
+    private OchSignal ochSignal;
+    private String connectionName;
+
+
+    public TerminalDeviceFlowRule(FlowRule rule, List<PortNumber> linePorts) {
+        super(rule);
+
+        Set<Criterion> criteria = rule.selector().criteria();
+        List<Instruction> instructions = rule.treatment().immediate();
+
+        /*Rules for TerminalDevice are generated in OpticalPathIntentCompiler with two types of intents
+        --- OpticalConnectivity intent compilation generates following flow rules
+        OPTICAL LINE level at INGRESS node -- criteria: input port; output port, OChSignal;
+        OPTICAL LINE level at EGRESS node -- criteria: input port, OChSignal and OCh type; instruction: output port
+        --- OpticalCircuit intent compilation generates following flow rules
+        CLIENT PORT at INGRESS node -- criteria: input port (OduClt); instruction output port (Och)
+        CLIENT PORT at EGRESS node -- criteria: input port (Och); instruction output port (OduClt)*/
+
+        checkArgument((criteria.size() == NUM_CRITERIA_LINE_EGRESS_RULE) ||
+                (criteria.size() == NUM_CRITERIA_LINE_INGRESS_RULE) ||
+                (criteria.size() == NUM_CRITERIA_CLIENT_RULES),
+                "Wrong size of flow rule criteria for TerminalDevice size" + criteria.size());
+
+        checkArgument((instructions.size() == NUM_INSTRUCTIONS_LINE_EGRESS_RULE) ||
+                        (instructions.size() == NUM_INSTRUCTIONS_LINE_INGRESS_RULE) ||
+                        (instructions.size() == NUM_INSTRUCTIONS_CLIENT_RULES),
+                "Wrong size of flow rule instructions for TerminalDevice size " + instructions.size());
+
+        //This is EGRESS rule on the LINE side
+        if ((criteria.size() == NUM_CRITERIA_LINE_EGRESS_RULE) &&
+                (instructions.size() == NUM_INSTRUCTIONS_LINE_EGRESS_RULE)) {
+            log.debug("Building the TerminalDeviceFlowRule for LINE_EGRESS");
+            type = Type.LINE_EGRESS;
+
+            criteria.forEach(
+                    c -> checkArgument(c instanceof OchSignalCriterion ||
+                                    c instanceof OchSignalTypeCriterion ||
+                                    c instanceof PortCriterion,
+                            "Incompatible flow rule criteria for ADD TerminalDevice: " + criteria
+                    )
+            );
+            instructions.forEach(
+                    c -> checkArgument(c instanceof Instructions.OutputInstruction,
+                            "Incompatible flow rule instruction for ADD TerminalDevice: " + instructions
+                    )
+            );
+
+            ochSignal = criteria.stream()
+                    .filter(c -> c instanceof OchSignalCriterion)
+                    .map(c -> ((OchSignalCriterion) c).lambda())
+                    .findAny()
+                    .orElse(null);
+
+            inPortNumber = criteria.stream()
+                    .filter(c -> c instanceof PortCriterion)
+                    .map(c -> ((PortCriterion) c).port())
+                    .findAny()
+                    .orElse(null);
+
+            outPortNumber = ((Instructions.OutputInstruction) instructions.get(0)).port();
+
+            checkArgument(linePorts.contains(outPortNumber),
+                    "Incompatible output port for DROP TerminalDevice");
+
+        }
+
+        //This is INGRESS rule on the LINE side
+        if ((criteria.size() == NUM_CRITERIA_LINE_INGRESS_RULE) &&
+                (instructions.size() == NUM_INSTRUCTIONS_LINE_INGRESS_RULE)) {
+            log.debug("Building the TerminalDeviceFlowRule LINE_INGRESS");
+            type = Type.LINE_INGRESS;
+
+            criteria.forEach(
+                    c -> checkArgument(
+                            c instanceof PortCriterion,
+                            "Incompatible flow rule criteria for ADD TerminalDevice: " + criteria
+                    )
+            );
+            instructions.forEach(
+                    c -> checkArgument(c.type() == Instruction.Type.L0MODIFICATION ||
+                                    c.type() == Instruction.Type.OUTPUT,
+                            "Incompatible flow rule instruction for ADD TerminalDevice: " + instructions
+                    )
+            );
+
+            inPortNumber = criteria.stream()
+                    .filter(c -> c instanceof PortCriterion)
+                    .map(c -> ((PortCriterion) c).port())
+                    .findAny()
+                    .orElse(null);
+
+            checkArgument(linePorts.contains(inPortNumber),
+                    "Incompatible input port for DROP TerminalDevice");
+
+            ochSignal = instructions.stream()
+                    .filter(c -> c.type() == Instruction.Type.L0MODIFICATION)
+                    .map(c -> ((L0ModificationInstruction.ModOchSignalInstruction) c).lambda())
+                    .findAny()
+                    .orElse(null);
+
+            outPortNumber = instructions.stream()
+                    .filter(c -> c.type() == Instruction.Type.OUTPUT)
+                    .map(c -> ((Instructions.OutputInstruction) c).port())
+                    .findAny()
+                    .orElse(null);
+        }
+
+        //This is INGRESS or EGRESS rule on the CLIENT side
+        if ((criteria.size() == NUM_CRITERIA_CLIENT_RULES) &&
+                (instructions.size() == NUM_INSTRUCTIONS_CLIENT_RULES)) {
+
+            criteria.forEach(
+                    c -> checkArgument(
+                            c instanceof PortCriterion,
+                            "Incompatible flow rule criteria for ADD TerminalDevice: " + criteria
+                    )
+            );
+            instructions.forEach(
+                    c -> checkArgument(c.type() == Instruction.Type.OUTPUT,
+                            "Incompatible flow rule instruction for ADD TerminalDevice: " + instructions
+                    )
+            );
+
+            inPortNumber = criteria.stream()
+                    .filter(c -> c instanceof PortCriterion)
+                    .map(c -> ((PortCriterion) c).port())
+                    .findAny()
+                    .orElse(null);
+
+            outPortNumber = instructions.stream()
+                    .filter(c -> c.type() == Instruction.Type.OUTPUT)
+                    .map(c -> ((Instructions.OutputInstruction) c).port())
+                    .findAny()
+                    .orElse(null);
+
+            ochSignal = null;
+
+            if (linePorts.contains(outPortNumber)) {
+                type = Type.CLIENT_INGRESS;
+            } else {
+                type = Type.CLIENT_EGRESS;
+            }
+        }
+
+        if (type == Type.LINE_EGRESS) {
+            connectionName = "LineEgress-LinePort-" + inPortNumber.toString()
+                    + "-ochSig-" + ochSignal.centralFrequency().toString();
+        }
+        if (type == Type.LINE_INGRESS) {
+            connectionName = "LineIngress-LinePort-" + outPortNumber.toString()
+                    + "-ochSig-" + ochSignal.centralFrequency().toString();
+        }
+        if (type == Type.CLIENT_EGRESS) {
+            connectionName = "ClientEgress-LinePort-" + inPortNumber.toString()
+                    + "-ClientPort-" + outPortNumber.toString();
+        }
+        if (type == Type.CLIENT_INGRESS) {
+            connectionName = "ClientIngress-ClientPort-" + inPortNumber.toString()
+                    + "-LinePort-" + outPortNumber.toString();
+        }
+
+        log.info("TerminalFlowRule built with name {}", connectionName);
+    }
+
+    public PortNumber inPort() {
+        return inPortNumber;
+    }
+
+    public PortNumber outPort() {
+        return outPortNumber;
+    }
+
+    public OchSignal ochSignal() {
+        return ochSignal;
+    }
+
+    public String connectionName() {
+        return connectionName;
+    }
+}
+
diff --git a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
index 2028af7..dfc418a 100644
--- a/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
+++ b/drivers/odtn-driver/src/main/resources/odtn-drivers.xml
@@ -45,6 +45,17 @@
                    impl="org.onosproject.drivers.odtn.openconfig.TerminalDeviceFlowRuleProgrammable"/>
     </driver>
 
+    <driver name="client-line-terminal-device"  manufacturer="CTTC" hwVersion="" swVersion="">
+        <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery"
+                   impl="org.onosproject.drivers.odtn.openconfig.ClientLineTerminalDeviceDiscovery"/>
+        <behaviour api ="org.onosproject.net.optical.OpticalDevice"
+                   impl="org.onosproject.net.optical.DefaultOpticalDevice"/>
+        <behaviour api ="org.onosproject.net.behaviour.LambdaQuery"
+                   impl="org.onosproject.drivers.odtn.openconfig.TerminalDeviceLambdaQuery"/>
+        <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable"
+                   impl="org.onosproject.drivers.odtn.openconfig.ClientLineTerminalDeviceFlowRuleProgrammable"/>
+    </driver>
+
     <driver name="openroadm" extends="" manufacturer="CTTC/CNIT" hwVersion="0.0.1" swVersion="0.0.1">
         <behaviour api ="org.onosproject.net.device.DeviceDescriptionDiscovery"
                    impl="org.onosproject.drivers.odtn.openroadm.OpenRoadmDeviceDescription"/>
