diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadm.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadm.java
deleted file mode 100644
index 273469b..0000000
--- a/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadm.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * 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.
- */
-package org.onosproject.driver.optical.handshaker;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.onosproject.drivers.optical.OpticalAdjacencyLinkService;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DefaultPortDescription;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.link.DefaultLinkDescription;
-import org.onosproject.net.link.LinkService;
-import org.onosproject.net.optical.OpticalAnnotations;
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
-import org.onosproject.openflow.controller.PortDescPropertyType;
-import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
-import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
-import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
-import org.projectfloodlight.openflow.protocol.OFExpExtAdId;
-import org.projectfloodlight.openflow.protocol.OFExpPortAdidOtn;
-import org.projectfloodlight.openflow.protocol.OFExpPortAdjacency;
-import org.projectfloodlight.openflow.protocol.OFExpPortAdjacencyId;
-import org.projectfloodlight.openflow.protocol.OFExpPortAdjacencyReply;
-import org.projectfloodlight.openflow.protocol.OFExpPortAdjacencyRequest;
-import org.projectfloodlight.openflow.protocol.OFMessage;
-import org.projectfloodlight.openflow.protocol.OFObject;
-import org.projectfloodlight.openflow.protocol.OFOplinkPortPower;
-import org.projectfloodlight.openflow.protocol.OFPortDesc;
-import org.projectfloodlight.openflow.protocol.OFPortOptical;
-import org.projectfloodlight.openflow.protocol.OFStatsReply;
-import org.projectfloodlight.openflow.protocol.OFStatsRequest;
-import org.projectfloodlight.openflow.protocol.OFStatsType;
-import org.projectfloodlight.openflow.protocol.OFType;
-import org.projectfloodlight.openflow.protocol.OFOplinkPortPowerRequest;
-import org.projectfloodlight.openflow.protocol.OFOplinkPortPowerReply;
-
-
-/**
- * Driver for Oplink single WSS 8D ROADM.
- *
- * Driver implements custom handshaker and supports for Optical channel Port based on OpenFlow OTN extension.
- * The device consists of Och ports, and performances wavelength cross-connect among the ports.
- */
-public class OplinkRoadm extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
-
-    private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
-    private List<OFPortOptical> opticalPorts;
-
-    @Override
-    public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
-        return ImmutableList.copyOf(opticalPorts);
-    }
-
-    @Override
-    /**
-     * Returns a list of standard (Ethernet) ports.
-     *
-     * @return List of ports
-     */
-    public List<OFPortDesc> getPorts() {
-        return Collections.EMPTY_LIST;
-    }
-
-    @Override
-    public Set<PortDescPropertyType> getPortTypes() {
-        return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
-    }
-
-    @Override
-    public Boolean supportNxRole() {
-        return false;
-    }
-
-    @Override
-    public void startDriverHandshake() {
-        log.warn("Starting driver handshake for sw {}", getStringId());
-        if (startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeAlreadyStarted();
-        }
-        startDriverHandshakeCalled = true;
-        try {
-            sendHandshakeOFExperimenterPortDescRequest();
-        } catch (IOException e) {
-            log.error("OPLK ROADM exception while sending experimenter port desc:", e);
-        }
-    }
-
-    @Override
-    public boolean isDriverHandshakeComplete() {
-        return driverHandshakeComplete.get();
-    }
-
-    @Override
-    public void processDriverHandshakeMessage(OFMessage m) {
-
-        if (!startDriverHandshakeCalled) {
-            throw new SwitchDriverSubHandshakeNotStarted();
-        }
-
-        if (driverHandshakeComplete.get()) {
-            throw new SwitchDriverSubHandshakeCompleted(m);
-        }
-
-        switch (m.getType()) {
-            case BARRIER_REPLY:
-                log.debug("OPLK ROADM Received barrier response");
-                break;
-            case ERROR:
-                log.error("Switch {} Error {}", getStringId(), m);
-                break;
-            case FEATURES_REPLY:
-                break;
-            case FLOW_REMOVED:
-                break;
-            case GET_ASYNC_REPLY:
-                break;
-            case PACKET_IN:
-                break;
-            case PORT_STATUS:
-                processOFPortStatus((OFCircuitPortStatus) m);
-                break;
-            case QUEUE_GET_CONFIG_REPLY:
-                break;
-            case ROLE_REPLY:
-                break;
-            case STATS_REPLY:
-                OFStatsReply stats = (OFStatsReply) m;
-                if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
-                    log.warn("OPLK ROADM : Received multipart (port desc) reply message {}", m);
-                    //OTN Optical extension 1.0 port-desc
-                    createOpticalPortList((OFCircuitPortsReply) m);
-                    driverHandshakeComplete.set(true);
-                }
-                break;
-            default:
-                log.warn("Received message {} during switch-driver " +
-                                 "subhandshake " + "from switch {} ... " +
-                                 "Ignoring message", m,
-                         getStringId());
-
-        }
-    }
-
-    private void processOFPortStatus(OFCircuitPortStatus ps) {
-        log.debug("OPLK ROADM ..OF Port Status :", ps);
-    }
-
-    @Override
-    public Device.Type deviceType() {
-        return Device.Type.ROADM;
-    }
-
-    @Override
-    public final void sendMsg(OFMessage m) {
-        List<OFMessage> messages = new ArrayList<>();
-        messages.add(m);
-
-        if (m.getType() == OFType.STATS_REQUEST) {
-            OFStatsRequest sr = (OFStatsRequest) m;
-            log.debug("OPLK ROADM rebuilding stats request type {}", sr.getStatsType());
-            switch (sr.getStatsType()) {
-                case PORT:
-                    //add Oplink experiment stats message to get the port's current power
-                    OFOplinkPortPowerRequest powerRequest = this.factory().buildOplinkPortPowerRequest()
-                            .setXid(sr.getXid())
-                            .setFlags(sr.getFlags())
-                            .build();
-                    messages.add(powerRequest);
-                    // add experiment message to get adjacent ports
-                    OFExpPortAdjacencyRequest adjacencyRequest = this.factory().buildExpPortAdjacencyRequest()
-                            .setXid(sr.getXid())
-                            .setFlags(sr.getFlags())
-                            .build();
-                    messages.add(adjacencyRequest);
-                    break;
-                default:
-                    break;
-            }
-        } else {
-            log.debug("OPLK ROADM sends msg:{}, as is", m.getType());
-        }
-
-        for (OFMessage message : messages) {
-            super.sendMsg(message);
-        }
-    }
-
-    private void sendHandshakeOFExperimenterPortDescRequest() throws IOException {
-        // send multi part message for port description for optical switches
-        OFCircuitPortsRequest circuitPortsRequest = factory()
-                .buildCircuitPortsRequest().setXid(getNextTransactionId())
-                .build();
-        log.info("OPLK ROADM : Sending experimented circuit port stats " +
-                 "message " +
-                 "{}",
-                 circuitPortsRequest);
-        this.sendHandshakeMessage(circuitPortsRequest);
-    }
-
-    /**
-     * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
-     * Ensure the optical transport port's signal type is configured correctly.
-     *
-     * @param wPorts OF reply with circuit ports
-     */
-    private void createOpticalPortList(OFCircuitPortsReply wPorts) {
-        opticalPorts = new ArrayList<>();
-        opticalPorts.addAll(wPorts.getEntries());
-    }
-
-    @Override
-    public List<PortDescription> processExpPortStats(OFMessage msg) {
-        if (msg instanceof OFOplinkPortPowerReply) {
-            return buildPortPowerDescriptions(((OFOplinkPortPowerReply) msg).getEntries());
-        } else if (msg instanceof OFExpPortAdjacencyReply) {
-            return buildPortAdjacencyDescriptions(((OFExpPortAdjacencyReply) msg).getEntries());
-        }
-        return Collections.emptyList();
-    }
-
-    private List<PortDescription> buildPortPowerDescriptions(List<OFOplinkPortPower> portPowers) {
-        DeviceService deviceService = this.handler().get(DeviceService.class);
-        List<Port> ports = deviceService.getPorts(this.data().deviceId());
-        HashMap<Long, OFOplinkPortPower> powerMap = new HashMap<>(portPowers.size());
-        portPowers.forEach(power -> powerMap.put((long) power.getPort(), power));
-        final List<PortDescription> portDescs = new ArrayList<>();
-        for (Port port : ports) {
-            DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
-            builder.putAll(port.annotations());
-            OFOplinkPortPower power = powerMap.get(port.number().toLong());
-            if (power != null) {
-                builder.set(OpticalAnnotations.CURRENT_POWER, Long.toString(power.getPowerValue()));
-            }
-            portDescs.add(new DefaultPortDescription(port.number(), port.isEnabled(),
-                    port.type(), port.portSpeed(), builder.build()));
-        }
-        return portDescs;
-    }
-
-    private OplinkPortAdjacency getNeighbor(OFExpPortAdjacency ad) {
-        for (OFExpPortAdjacencyId adid : ad.getProperties()) {
-            List<OFExpExtAdId> otns = adid.getAdId();
-            if (otns != null && !otns.isEmpty()) {
-                OFExpPortAdidOtn otn = (OFExpPortAdidOtn) otns.get(0);
-                // ITU-T G.7714 ETH MAC Format (in second 16 bytes of the following)
-                // |---------------------------------------------------------------------------|
-                // | Other format (16 bytes)                                                   |
-                // |---------------------------------------------------------------------------|
-                // | Header (2 bytes) | ID (4 bits) | MAC (6 bytes) | Port (4 bytes) | Unused  |
-                // |---------------------------------------------------------------------------|
-                ChannelBuffer buffer = ChannelBuffers.buffer(32);
-                otn.getOpspec().write32Bytes(buffer);
-                long mac = buffer.getLong(18) << 4 >>> 16;
-                int port = (int) (buffer.getLong(24) << 4 >>> 32);
-                // Oplink does not use the 4 most significant bytes of Dpid so Dpid can be
-                // constructed from MAC address
-                return new OplinkPortAdjacency(DeviceId.deviceId(Dpid.uri(new Dpid(mac))),
-                        PortNumber.portNumber(port));
-            }
-        }
-        return null;
-    }
-
-    private List<PortDescription> buildPortAdjacencyDescriptions(List<OFExpPortAdjacency> portAds) {
-        DeviceService deviceService = this.handler().get(DeviceService.class);
-        List<Port> ports = deviceService.getPorts(this.data().deviceId());
-
-        // Map port's number with port's adjacency
-        HashMap<Long, OFExpPortAdjacency> adMap = new HashMap<>(portAds.size());
-        portAds.forEach(ad -> adMap.put((long) ad.getPortNo().getPortNumber(), ad));
-
-        List<PortDescription> portDescs = new ArrayList<>();
-        for (Port port : ports) {
-            DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
-            Annotations oldAnnotations = port.annotations();
-            builder.putAll(oldAnnotations);
-            OFExpPortAdjacency ad = adMap.get(port.number().toLong());
-            if (ad != null) {
-                // neighbor discovered, add to port descriptions
-                OplinkPortAdjacency neighbor = getNeighbor(ad);
-                String newId = neighbor.getDeviceId().toString();
-                String newPort = neighbor.getPort().toString();
-                // Check if annotation already exists
-                if (!newId.equals(oldAnnotations.value(OpticalAnnotations.NEIGHBOR_ID)) ||
-                    !newPort.equals(oldAnnotations.value(OpticalAnnotations.NEIGHBOR_PORT))) {
-                    builder.set(OpticalAnnotations.NEIGHBOR_ID, newId);
-                    builder.set(OpticalAnnotations.NEIGHBOR_PORT, newPort);
-                }
-                addLink(port.number(), neighbor);
-            } else {
-                // no neighbors found
-                builder.remove(OpticalAnnotations.NEIGHBOR_ID);
-                builder.remove(OpticalAnnotations.NEIGHBOR_PORT);
-                removeLink(port.number());
-            }
-            portDescs.add(new DefaultPortDescription(port.number(), port.isEnabled(),
-                    port.type(), port.portSpeed(), builder.build()));
-        }
-        return portDescs;
-    }
-
-    private void addLink(PortNumber portNumber, OplinkPortAdjacency neighbor) {
-        ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber);
-        ConnectPoint src = new ConnectPoint(neighbor.getDeviceId(), neighbor.getPort());
-        OpticalAdjacencyLinkService adService =
-                this.handler().get(OpticalAdjacencyLinkService.class);
-        adService.linkDetected(new DefaultLinkDescription(src, dst, Link.Type.OPTICAL));
-    }
-
-    // Remove incoming link with port if there are any.
-    private void removeLink(PortNumber portNumber) {
-        ConnectPoint dst = new ConnectPoint(handler().data().deviceId(), portNumber);
-        // Check so only incoming links are removed
-        Set<Link> links = this.handler().get(LinkService.class).getIngressLinks(dst);
-        if (!links.isEmpty()) {
-            OpticalAdjacencyLinkService adService =
-                    this.handler().get(OpticalAdjacencyLinkService.class);
-            adService.linksVanished(dst);
-        }
-    }
-
-    private class OplinkPortAdjacency {
-        private DeviceId deviceId;
-        private PortNumber portNumber;
-
-        public OplinkPortAdjacency(DeviceId deviceId, PortNumber portNumber) {
-            this.deviceId = deviceId;
-            this.portNumber = portNumber;
-        }
-
-        public DeviceId getDeviceId() {
-            return deviceId;
-        }
-
-        public PortNumber getPort() {
-            return portNumber;
-        }
-    }
-}
diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadmHandshaker.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadmHandshaker.java
new file mode 100644
index 0000000..d805f97
--- /dev/null
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/handshaker/OplinkRoadmHandshaker.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.
+ */
+package org.onosproject.driver.optical.handshaker;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.onosproject.net.Device;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
+import org.onosproject.openflow.controller.PortDescPropertyType;
+import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
+import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
+import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
+import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
+import org.projectfloodlight.openflow.protocol.OFExpPortAdjacencyReply;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFObject;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortOptical;
+import org.projectfloodlight.openflow.protocol.OFStatsReply;
+import org.projectfloodlight.openflow.protocol.OFStatsRequest;
+import org.projectfloodlight.openflow.protocol.OFStatsType;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.OFOplinkPortPowerReply;
+
+import static org.onosproject.net.Device.Type;
+
+/**
+ * Driver for Oplink single WSS 8D ROADM.
+ *
+ * Driver implements custom handshaker and supports optical channel Port based on OpenFlow OTN extension.
+ * The device consists of Och ports, and performances wavelength cross-connect among the ports.
+ */
+public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
+
+    private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
+    private List<OFPortOptical> opticalPorts = new ArrayList<>();
+    private OplinkHandshakerUtil oplinkUtil = new OplinkHandshakerUtil(this);
+
+    @Override
+    public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
+        // Expected type is OPTICAL_TRANSPORT
+        if (type == PortDescPropertyType.OPTICAL_TRANSPORT) {
+            return ImmutableList.copyOf(opticalPorts);
+        }
+        // Any other type, return empty
+        log.warn("Unexpected port description property type: {}", type);
+        return ImmutableList.of();
+    }
+
+    /**
+     * Returns a list of standard (Ethernet) ports.
+     *
+     * @return List of ports
+     */
+    @Override
+    public List<OFPortDesc> getPorts() {
+        return ImmutableList.of();
+    }
+
+    @Override
+    public Set<PortDescPropertyType> getPortTypes() {
+        return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
+    }
+
+    @Override
+    public Boolean supportNxRole() {
+        return false;
+    }
+
+    @Override
+    public void startDriverHandshake() {
+        log.info("Starting driver handshake for sw {}", getStringId());
+        if (startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeAlreadyStarted();
+        }
+        startDriverHandshakeCalled = true;
+        try {
+            sendHandshakeOFExperimenterPortDescRequest();
+        } catch (IOException e) {
+            log.error("OPLK ROADM exception while sending experimenter port desc:", e);
+        }
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        return driverHandshakeComplete.get();
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+
+        if (!startDriverHandshakeCalled) {
+            throw new SwitchDriverSubHandshakeNotStarted();
+        }
+
+        if (driverHandshakeComplete.get()) {
+            throw new SwitchDriverSubHandshakeCompleted(m);
+        }
+
+        switch (m.getType()) {
+            case BARRIER_REPLY:
+                log.debug("OPLK ROADM Received barrier response");
+                break;
+            case ERROR:
+                log.error("Switch {} Error {}", getStringId(), m);
+                break;
+            case FEATURES_REPLY:
+                break;
+            case FLOW_REMOVED:
+                break;
+            case GET_ASYNC_REPLY:
+                break;
+            case PACKET_IN:
+                break;
+            case PORT_STATUS:
+                processOFPortStatus((OFCircuitPortStatus) m);
+                break;
+            case QUEUE_GET_CONFIG_REPLY:
+                break;
+            case ROLE_REPLY:
+                break;
+            case STATS_REPLY:
+                OFStatsReply stats = (OFStatsReply) m;
+                if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
+                    log.debug("OPLK ROADM : Received multipart (port desc) reply message {}", m);
+                    //OTN Optical extension 1.0 port-desc
+                    createOpticalPortList((OFCircuitPortsReply) m);
+                    driverHandshakeComplete.set(true);
+                }
+                break;
+            default:
+                log.warn("Received message {} during switch-driver " +
+                        "subhandshake from switch {} ... " +
+                        "Ignoring message", m, getStringId());
+
+        }
+    }
+
+    @Override
+    public Device.Type deviceType() {
+        return Type.ROADM;
+    }
+
+    @Override
+    public final void sendMsg(OFMessage m) {
+        List<OFMessage> messages = new ArrayList<>();
+        messages.add(m);
+
+        if (m.getType() == OFType.STATS_REQUEST) {
+            OFStatsRequest sr = (OFStatsRequest) m;
+            log.debug("OPLK ROADM rebuilding stats request type {}", sr.getStatsType());
+            switch (sr.getStatsType()) {
+                case PORT:
+                    // add Oplink experiment message to get the port's current power
+                    messages.add(oplinkUtil.buildPortPowerRequest());
+                    // add experiment message to get adjacent ports
+                    messages.add(oplinkUtil.buildPortAdjacencyRequest());
+                    break;
+                default:
+                    break;
+            }
+        } else {
+            log.debug("OPLK ROADM sends msg:{}, as is", m.getType());
+        }
+
+        super.sendMsg(messages);
+    }
+
+    @Override
+    public List<PortDescription> processExpPortStats(OFMessage msg) {
+        if (msg instanceof OFOplinkPortPowerReply) {
+            return oplinkUtil.buildPortPowerDescriptions(((OFOplinkPortPowerReply) msg).getEntries());
+        } else if (msg instanceof OFExpPortAdjacencyReply) {
+            return oplinkUtil.buildPortAdjacencyDescriptions(((OFExpPortAdjacencyReply) msg).getEntries());
+        }
+        return Collections.emptyList();
+    }
+
+    private void processOFPortStatus(OFCircuitPortStatus ps) {
+        log.debug("OPLK ROADM ..OF Port Status :", ps);
+    }
+
+    private void sendHandshakeOFExperimenterPortDescRequest() throws IOException {
+        // Send multipart message for port description for optical switches
+        OFCircuitPortsRequest circuitPortsRequest = oplinkUtil.buildCircuitPortsRequest();
+        log.debug("OPLK ROADM : Sending experimented port description message {}", circuitPortsRequest);
+        sendHandshakeMessage(circuitPortsRequest);
+    }
+
+    /**
+     * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
+     * Ensure the optical transport port's signal type is configured correctly.
+     *
+     * @param wPorts OF reply with circuit ports
+     */
+    private void createOpticalPortList(OFCircuitPortsReply wPorts) {
+        opticalPorts.addAll(wPorts.getEntries());
+    }
+
+}
diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkEdfaPowerConfig.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkEdfaPowerConfig.java
index 554df14..4538258 100644
--- a/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkEdfaPowerConfig.java
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkEdfaPowerConfig.java
@@ -16,21 +16,12 @@
 
 package org.onosproject.driver.optical.power;
 
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.Optional;
 
 import com.google.common.collect.Range;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.PowerConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.optical.OpticalAnnotations;
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.OpenFlowController;
-import org.onosproject.openflow.controller.OpenFlowSwitch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Port Power (Gain and attenuation) implementation for Oplink EDFA device.
@@ -43,148 +34,31 @@
 public class OplinkEdfaPowerConfig extends AbstractHandlerBehaviour
                                     implements PowerConfig<Object> {
 
-    /**
-     * Input and ouput port number
-     * Note:
-     * These port number configurations are just in use for a short time.
-     * In the future, the port number and direction type would be obtained from physical device.
-     */
-    private static final int LINE_IN_WEST = 1;
-    private static final int LINE_OUT_WEST = 2;
-    private static final int LINE_IN_EAST = 3;
-    private static final int LINE_OUT_EAST = 4;
-
-    /**
-     * Power threshold of each port, magnified 100 times
-     * Note:
-     * These threshold configurations are just in use for a short time.
-     * In the future, the power threshold would be obtained from physical device.
-     */
-    private static final long POWER_IN_WEST_LOW_THRES = -1900L;
-    private static final long POWER_IN_WEST_HIGH_THRES = 0L;
-    private static final long POWER_IN_EAST_LOW_THRES = -3100L;
-    private static final long POWER_IN_EAST_HIGH_THRES = 700L;
-    private static final long POWER_OUT_LOW_THRES = 0L;
-    private static final long POWER_OUT_HIGH_THRES = 1900L;
-
-    // Transaction id to use.
-    private final AtomicInteger xidCounter = new AtomicInteger(0);
-    // Log
-    protected final Logger log = LoggerFactory.getLogger(getClass());
+    // oplink power config utility
+    private OplinkPowerConfigUtil oplinkUtil = new OplinkPowerConfigUtil(this);
 
     @Override
-    public Optional<Long> getTargetPower(PortNumber portNum, Object component) {
-        Long returnVal = getTargetPortPower(portNum);
-        return Optional.ofNullable(returnVal);
+    public Optional<Long> getTargetPower(PortNumber port, Object component) {
+        return Optional.ofNullable(oplinkUtil.getTargetPower(port, component));
     }
 
     @Override
-    public Optional<Long> currentPower(PortNumber portNum, Object component) {
-        Long returnVal = getCurrentPortPower(portNum);
-        return Optional.ofNullable(returnVal);
+    public Optional<Long> currentPower(PortNumber port, Object component) {
+        return Optional.ofNullable(oplinkUtil.getCurrentPower(port, component));
     }
 
     @Override
-    public void setTargetPower(PortNumber portNum, Object component, long power) {
-        setTargetPortPower(portNum, power);
+    public void setTargetPower(PortNumber port, Object component, long power) {
+        oplinkUtil.setTargetPower(port, component, power);
     }
 
     @Override
     public Optional<Range<Long>> getTargetPowerRange(PortNumber port, Object component) {
-        Range<Long> range = getTargetPortPowerRange(port);
-        return Optional.ofNullable(range);
+        return Optional.ofNullable(oplinkUtil.getTargetPowerRange(port, component));
     }
 
     @Override
     public Optional<Range<Long>> getInputPowerRange(PortNumber port, Object component) {
-        Range<Long> range = getInputPortPowerRange(port);
-        return Optional.ofNullable(range);
-    }
-
-    private OpenFlowSwitch getOpenFlowDevice() {
-        final OpenFlowController controller = handler().get(OpenFlowController.class);
-        final Dpid dpid = Dpid.dpid(data().deviceId().uri());
-        OpenFlowSwitch sw = controller.getSwitch(dpid);
-        if (sw == null || !sw.isConnected()) {
-            log.warn("OpenFlow handshaker driver not found or device is not connected");
-            return null;
-        }
-        return sw;
-    }
-
-    private Long getPowerFromPort(PortNumber portNum, String annotation) {
-        // Check if switch is connected, otherwise do not return value in store, which is obsolete.
-        if (getOpenFlowDevice() == null) {
-            // Warning already exists in method getOpenFlowDevice()
-            return null;
-        }
-        DeviceService deviceService = handler().get(DeviceService.class);
-        Port port = deviceService.getPort(data().deviceId(), portNum);
-        if (port == null) {
-            log.warn("Unexpected port: {}", portNum);
-            return null;
-        }
-        String power = port.annotations().value(annotation);
-        if (power == null) {
-            log.warn("Cannot get {} from port {}.", annotation, portNum);
-            return null;
-        }
-        return Long.valueOf(power);
-    }
-
-    private Long getTargetPortPower(PortNumber portNum) {
-        return getPowerFromPort(portNum, OpticalAnnotations.TARGET_POWER);
-    }
-
-    private Long getCurrentPortPower(PortNumber portNum) {
-        return getPowerFromPort(portNum, OpticalAnnotations.CURRENT_POWER);
-    }
-
-    private void setTargetPortPower(PortNumber portNum, long power) {
-        OpenFlowSwitch device = getOpenFlowDevice();
-        // Check if switch is connected, otherwise do not return value in store, which is obsolete.
-        if (device == null) {
-            // Warning already exists in method getOpenFlowDevice()
-            return;
-        }
-        device.sendMsg(device.factory().buildOplinkPortPowerSet()
-                .setXid(xidCounter.getAndIncrement())
-                .setPort((int) portNum.toLong())
-                .setPowerValue((int) power)
-                .build());
-    }
-
-    // Returns the acceptable target range for an output Port, null otherwise
-    private Range<Long> getTargetPortPowerRange(PortNumber port) {
-        long portNum = port.toLong();
-        // FIXME
-        // Short time hard code, we will use port direction type instead in the future.
-        // And more, the power range will be also obtained from device configuration.
-        switch ((int) portNum) {
-            case LINE_OUT_EAST:
-            case LINE_OUT_WEST:
-                return Range.closed(POWER_OUT_LOW_THRES, POWER_OUT_HIGH_THRES);
-            default:
-                // Unexpected port. Do not need warning here for port polling.
-                return null;
-        }
-    }
-
-    // Returns the working input power range for an input port, null if the port
-    // is not an input port.
-    private Range<Long> getInputPortPowerRange(PortNumber port) {
-        long portNum = port.toLong();
-        // FIXME
-        // Short time hard code, we will use port direction type instead in the future.
-        // And more, the power range will be also obtained from device configuration.
-        switch ((int) portNum) {
-            case LINE_IN_EAST:
-                return Range.closed(POWER_IN_EAST_LOW_THRES, POWER_IN_EAST_HIGH_THRES);
-            case LINE_IN_WEST:
-                return Range.closed(POWER_IN_WEST_LOW_THRES, POWER_IN_WEST_HIGH_THRES);
-            default:
-                // Unexpected port. Do not need warning here for port polling.
-                return null;
-        }
+        return Optional.ofNullable(oplinkUtil.getInputPowerRange(port, component));
     }
 }
diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkPowerConfigUtil.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkPowerConfigUtil.java
new file mode 100644
index 0000000..a24df09
--- /dev/null
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkPowerConfigUtil.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.
+ */
+
+package org.onosproject.driver.optical.power;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.List;
+
+import com.google.common.collect.Range;
+
+import org.onosproject.driver.extensions.OplinkAttenuation;
+import org.onosproject.net.OchSignal;
+import org.onosproject.net.Direction;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.optical.OpticalAnnotations;
+import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.OpenFlowController;
+import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
+import org.onosproject.openflow.controller.OpenFlowSwitch;
+import org.onosproject.openflow.controller.PortDescPropertyType;
+import org.projectfloodlight.openflow.protocol.OFObject;
+import org.projectfloodlight.openflow.protocol.OFPortOptical;
+
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.net.Device.Type;
+
+/**
+ * Oplink power config utility.
+ */
+public class OplinkPowerConfigUtil {
+
+    // Parent driver handler behaviour
+    private HandlerBehaviour behaviour;
+    // Transaction id to use.
+    private final AtomicInteger xidCounter = new AtomicInteger(0);
+    // Log
+    private final Logger log = getLogger(getClass());
+
+    // Component type
+    private enum ComponentType {
+        NONE,
+        PORT,
+        CHANNEL
+    }
+
+    // Port properties for oplink devices, currently supports EDFA and ROADM.
+    // This type is mapped to OFPortDescPropOpticalTransport#getPortType() value.
+    private enum PortDescType {
+        NONE,
+        PA_LINE_IN,
+        PA_LINE_OUT,
+        BA_LINE_IN,
+        BA_LINE_OUT,
+        EXP_IN,
+        EXP_OUT,
+        AUX_IN,
+        AUX_OUT,
+    }
+
+    /**
+     * Power threshold of each port, in 0.01 dB
+     * Note:
+     * These threshold configurations are just in use for a short time.
+     * In the future, the power threshold would be obtained from physical device.
+     */
+    // EDFA
+    private static final long EDFA_POWER_IN_WEST_LOW_THRES = -1900L;
+    private static final long EDFA_POWER_IN_WEST_HIGH_THRES = 0L;
+    private static final long EDFA_POWER_IN_EAST_LOW_THRES = -3100L;
+    private static final long EDFA_POWER_IN_EAST_HIGH_THRES = 700L;
+    private static final long EDFA_POWER_OUT_LOW_THRES = 0L;
+    private static final long EDFA_POWER_OUT_HIGH_THRES = 1900L;
+    // ROADM
+    private static final long ROADM_POWER_LINE_IN_LOW_THRES = -3000L;
+    private static final long ROADM_POWER_LINE_IN_HIGH_THRES = 2350L;
+    private static final long ROADM_POWER_LINE_OUT_LOW_THRES = 0L;
+    private static final long ROADM_POWER_LINE_OUT_HIGH_THRES = 2350L;
+    private static final long ROADM_POWER_OTHER_IN_LOW_THRES = -1500L;
+    private static final long ROADM_POWER_OTHER_IN_HIGH_THRES = 2000L;
+    private static final long ROADM_POWER_OTHER_OUT_LOW_THRES = -600L;
+    private static final long ROADM_POWER_OTHER_OUT_HIGH_THRES = 1500L;
+    private static final long ROADM_MIN_ATTENUATION = 0L;
+    private static final long ROADM_MAX_ATTENUATION = 2500L;
+
+    /**
+     * Create a new OplinkPowerConfigUtil.
+     * @param behaviour driver handler behaviour
+     */
+    public OplinkPowerConfigUtil(HandlerBehaviour behaviour) {
+        this.behaviour = behaviour;
+    }
+
+    /**
+     * Obtains specified port/channel target power.
+     *
+     * @param port the port number
+     * @param component the port component
+     * @return target power value in .01 dBm
+     */
+    public Long getTargetPower(PortNumber port, Object component) {
+        switch (getComponentType(component)) {
+            case PORT:
+                return getPortPower(port, OpticalAnnotations.TARGET_POWER);
+            case CHANNEL:
+                return getChannelAttenuation(port, (OchSignal) component);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Obtains specified port/channel current power.
+     *
+     * @param port the port number
+     * @param component the port component
+     * @return current power value in .01 dBm
+     */
+    public Long getCurrentPower(PortNumber port, Object component) {
+        switch (getComponentType(component)) {
+            case PORT:
+                return getPortPower(port, OpticalAnnotations.CURRENT_POWER);
+            case CHANNEL:
+                return getCurrentChannelPower(port, (OchSignal) component);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Sets specified port target power or channel attenuation.
+     *
+     * @param port the port number
+     * @param component the port component
+     * @param power target power in .01 dBm
+     */
+    public void setTargetPower(PortNumber port, Object component, long power) {
+        switch (getComponentType(component)) {
+            case PORT:
+                setPortPower(port, power);
+                break;
+            case CHANNEL:
+                setChannelAttenuation(port, (OchSignal) component, power);
+               break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Returns the acceptable target range for an output port/channel, null otherwise.
+     *
+     * @param port the port number
+     * @param component the port component
+     * @return power range
+     */
+    public Range<Long> getTargetPowerRange(PortNumber port, Object component) {
+        switch (getComponentType(component)) {
+            case PORT:
+                return getTargetPortPowerRange(port);
+            case CHANNEL:
+                return getChannelAttenuationRange(port);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Returns the working input power range for an input port, null otherwise.
+     *
+     * @param port the port number
+     * @param component the port component
+     * @return power range
+     */
+    public Range<Long> getInputPowerRange(PortNumber port, Object component) {
+        switch (getComponentType(component)) {
+            case PORT:
+                return getInputPortPowerRange(port);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Returns specified component type.
+     *
+     * @param component the port component
+     * @return component type
+     */
+    private ComponentType getComponentType(Object component) {
+        if (component == null || component instanceof Direction) {
+            return ComponentType.PORT;
+        } else if (component instanceof OchSignal) {
+            return ComponentType.CHANNEL;
+        }
+        return ComponentType.NONE;
+    }
+
+    /**
+     * Returns current switch known to this OF controller.
+     *
+     * @return current switch
+     */
+    private OpenFlowSwitch getOpenFlowDevice() {
+        final DriverHandler handler = behaviour.handler();
+        final OpenFlowController controller = handler.get(OpenFlowController.class);
+        final Dpid dpid = Dpid.dpid(handler.data().deviceId().uri());
+        OpenFlowSwitch sw = controller.getSwitch(dpid);
+        if (sw == null || !sw.isConnected()) {
+            log.warn("OpenFlow handshaker driver not found or device is not connected, dpid = {}", dpid);
+            return null;
+        }
+        return sw;
+    }
+
+    /**
+     * Find oplink port description type from optical ports.
+     *
+     * @param opsw switch
+     * @param portNum the port number
+     * @return port oplink port description type
+     */
+    private PortDescType getPortDescType(OpenFlowOpticalSwitch opsw, PortNumber portNum) {
+        for (PortDescPropertyType type : opsw.getPortTypes()) {
+            List<? extends OFObject> portsOf = opsw.getPortsOf(type);
+            for (OFObject op : portsOf) {
+                if (op instanceof OFPortOptical) {
+                    OFPortOptical opticalPort = (OFPortOptical) op;
+                    if ((long) opticalPort.getPortNo().getPortNumber() == portNum.toLong()) {
+                        return PortDescType.values()[opticalPort.getDesc().get(0).getPortType()];
+                    }
+                }
+            }
+        }
+        return PortDescType.NONE;
+    }
+
+    /**
+     * Returns the target port power range.
+     *
+     * @param portNum the port number
+     * @return power range
+     */
+    private Range<Long> getTargetPortPowerRange(PortNumber portNum) {
+        OpenFlowSwitch ofs = getOpenFlowDevice();
+        if (ofs == null) {
+            return null;
+        }
+        PortDescType portType = getPortDescType((OpenFlowOpticalSwitch) ofs, portNum);
+        Type devType = ofs.deviceType();
+        // FIXME
+        // Short time hard code.
+        // The power range will be obtained from physical device in the future.
+        switch (devType) {
+            case OPTICAL_AMPLIFIER:
+                if (portType == PortDescType.PA_LINE_OUT || portType == PortDescType.BA_LINE_OUT) {
+                    return Range.closed(EDFA_POWER_OUT_LOW_THRES, EDFA_POWER_OUT_HIGH_THRES);
+                }
+                break;
+            case ROADM:
+                if (portType == PortDescType.PA_LINE_OUT) {
+                    return Range.closed(ROADM_POWER_LINE_OUT_LOW_THRES, ROADM_POWER_LINE_OUT_HIGH_THRES);
+                } else if (portType == PortDescType.EXP_OUT || portType == PortDescType.AUX_OUT) {
+                    return Range.closed(ROADM_POWER_OTHER_OUT_LOW_THRES, ROADM_POWER_OTHER_OUT_HIGH_THRES);
+                }
+                break;
+            default:
+                log.warn("Unexpected device type: {}", devType);
+                break;
+        }
+        // Unexpected port or device type. Do not need warning here for port polling.
+        return null;
+    }
+
+    /**
+     * Returns the input port power range.
+     *
+     * @param portNum the port number
+     * @return power range
+     */
+    private Range<Long> getInputPortPowerRange(PortNumber portNum) {
+        OpenFlowSwitch ofs = getOpenFlowDevice();
+        if (ofs == null) {
+            return null;
+        }
+        PortDescType portType = getPortDescType((OpenFlowOpticalSwitch) ofs, portNum);
+        Type devType = ofs.deviceType();
+        // FIXME
+        // Short time hard code.
+        // The port type and power range will be obtained from physical device in the future.
+        switch (devType) {
+            case OPTICAL_AMPLIFIER:
+                if (portType == PortDescType.PA_LINE_IN) {
+                    return Range.closed(EDFA_POWER_IN_WEST_LOW_THRES, EDFA_POWER_IN_WEST_HIGH_THRES);
+                } else if (portType == PortDescType.BA_LINE_IN) {
+                    return Range.closed(EDFA_POWER_IN_EAST_LOW_THRES, EDFA_POWER_IN_EAST_HIGH_THRES);
+                }
+                break;
+            case ROADM:
+                if (portType == PortDescType.PA_LINE_IN) {
+                    return Range.closed(ROADM_POWER_LINE_IN_LOW_THRES, ROADM_POWER_LINE_IN_HIGH_THRES);
+                } else if (portType == PortDescType.EXP_IN || portType == PortDescType.AUX_IN) {
+                    return Range.closed(ROADM_POWER_OTHER_IN_LOW_THRES, ROADM_POWER_OTHER_IN_HIGH_THRES);
+                }
+                break;
+            default:
+                log.warn("Unexpected device type: {}", devType);
+                break;
+        }
+        // Unexpected port or device type. Do not need warning here for port polling.
+        return null;
+    }
+
+    /**
+     * Returns the acceptable attenuation range for a connection (represented as
+     * a flow with attenuation instruction). Port can be either the input or
+     * output port of the connection. Returns null if the connection does not
+     * support attenuation.
+     *
+     * @param portNum the port number
+     * @return attenuation range
+     */
+    private Range<Long> getChannelAttenuationRange(PortNumber portNum) {
+        OpenFlowSwitch ofs = getOpenFlowDevice();
+        if (ofs == null) {
+            return null;
+        }
+        if (ofs.deviceType() != Type.ROADM) {
+            return null;
+        }
+        PortDescType portType = getPortDescType((OpenFlowOpticalSwitch) ofs, portNum);
+        // Short time hard code.
+        // The port type and attenuation range will be obtained from physical device in the future.
+        if (portType == PortDescType.PA_LINE_OUT || portType == PortDescType.EXP_IN ||
+                portType == PortDescType.AUX_IN) {
+            return Range.closed(ROADM_MIN_ATTENUATION, ROADM_MAX_ATTENUATION);
+        }
+        // Unexpected port. Do not need warning here for port polling.
+        return null;
+    }
+
+    /**
+     * Find specified port power from port description.
+     *
+     * @param portNum the port number
+     * @param annotation annotation in port description
+     * @return power value in 0.01 dBm
+     */
+    private Long getPortPower(PortNumber portNum, String annotation) {
+        // Check if switch is connected, otherwise do not return value in store, which is obsolete.
+        if (getOpenFlowDevice() == null) {
+            // Warning already exists in method getOpenFlowDevice()
+            return null;
+        }
+        final DriverHandler handler = behaviour.handler();
+        DeviceService deviceService = handler.get(DeviceService.class);
+        Port port = deviceService.getPort(handler.data().deviceId(), portNum);
+        if (port == null) {
+            log.warn("Unexpected port: {}", portNum);
+            return null;
+        }
+        String power = port.annotations().value(annotation);
+        if (power == null) {
+            log.warn("Cannot get {} from port {}.", annotation, portNum);
+            return null;
+        }
+        return Long.valueOf(power);
+    }
+
+    /**
+     * Sets specified port power value.
+     *
+     * @param portNum the port number
+     * @param power power value
+     */
+    private void setPortPower(PortNumber portNum, long power) {
+        OpenFlowSwitch device = getOpenFlowDevice();
+        // Check if switch is connected
+        if (device == null) {
+            return;
+        }
+        device.sendMsg(device.factory().buildOplinkPortPowerSet()
+                .setXid(xidCounter.getAndIncrement())
+                .setPort((int) portNum.toLong())
+                .setPowerValue((int) power)
+                .build());
+    }
+
+    /**
+     * Gets specified channel attenuation.
+     *
+     * @param portNum the port number
+     * @param och channel signal
+     * @return atteuation in 0.01 dB
+     */
+    private Long getChannelAttenuation(PortNumber portNum, OchSignal och) {
+        FlowEntry flowEntry = findFlow(portNum, och);
+        if (flowEntry == null) {
+            return null;
+        }
+        List<Instruction> instructions = flowEntry.treatment().allInstructions();
+        for (Instruction ins : instructions) {
+            if (ins.type() != Instruction.Type.EXTENSION) {
+                continue;
+            }
+            ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction();
+            if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) {
+                return (long) ((OplinkAttenuation) ext).getAttenuation();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Sets specified channle attenuation.
+     *
+     * @param portNum the port number
+     * @param och channel signal
+     * @param power attenuation in 0.01 dB
+     */
+    private void setChannelAttenuation(PortNumber portNum, OchSignal och, long power) {
+        FlowEntry flowEntry = findFlow(portNum, och);
+        if (flowEntry == null) {
+            log.warn("Target channel power not set");
+            return;
+        }
+        final DriverHandler handler = behaviour.handler();
+        for (Instruction ins : flowEntry.treatment().allInstructions()) {
+            if (ins.type() != Instruction.Type.EXTENSION) {
+                continue;
+            }
+            ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction();
+            if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) {
+                ((OplinkAttenuation) ext).setAttenuation((int) power);
+                FlowRuleService service = handler.get(FlowRuleService.class);
+                service.applyFlowRules(flowEntry);
+                return;
+            }
+        }
+        addAttenuation(flowEntry, power);
+    }
+
+    /**
+     * Gets specified channle current power.
+     *
+     * @param portNum the port number
+     * @param och channel signal
+     * @return power value in 0.01 dBm
+     */
+    private Long getCurrentChannelPower(PortNumber portNum, OchSignal och) {
+        FlowEntry flowEntry = findFlow(portNum, och);
+        if (flowEntry != null) {
+            // TODO put somewhere else if possible
+            // We put channel power in packets
+            return flowEntry.packets();
+        }
+        return null;
+    }
+
+    /**
+     * Find matching flow on device.
+     *
+     * @param portNum the port number
+     * @param och channel signal
+     * @return flow entry
+     */
+    private FlowEntry findFlow(PortNumber portNum, OchSignal och) {
+        final DriverHandler handler = behaviour.handler();
+        FlowRuleService service = handler.get(FlowRuleService.class);
+        Iterable<FlowEntry> flowEntries = service.getFlowEntries(handler.data().deviceId());
+
+        // Return first matching flow
+        for (FlowEntry entry : flowEntries) {
+            TrafficSelector selector = entry.selector();
+            OchSignalCriterion entrySigid =
+                    (OchSignalCriterion) selector.getCriterion(Criterion.Type.OCH_SIGID);
+            // Check channel
+            if (entrySigid != null && och.equals(entrySigid.lambda())) {
+                // Check input port
+                PortCriterion entryPort =
+                        (PortCriterion) selector.getCriterion(Criterion.Type.IN_PORT);
+                if (entryPort != null && portNum.equals(entryPort.port())) {
+                    return entry;
+                }
+
+                // Check output port
+                TrafficTreatment treatment = entry.treatment();
+                for (Instruction instruction : treatment.allInstructions()) {
+                    if (instruction.type() == Instruction.Type.OUTPUT &&
+                        ((Instructions.OutputInstruction) instruction).port().equals(portNum)) {
+                        return entry;
+                    }
+                }
+            }
+        }
+        log.warn("No matching flow found");
+        return null;
+    }
+
+    /**
+     * Replace flow with new flow containing Oplink attenuation extension instruction. Also resets metrics.
+     *
+     * @param flowEntry flow entry
+     * @param power power value
+     */
+    private void addAttenuation(FlowEntry flowEntry, long power) {
+        FlowRule.Builder flowBuilder = new DefaultFlowRule.Builder()
+                .withCookie(flowEntry.id().value())
+                .withPriority(flowEntry.priority())
+                .forDevice(flowEntry.deviceId())
+                .forTable(flowEntry.tableId());
+        if (flowEntry.isPermanent()) {
+            flowBuilder.makePermanent();
+        } else {
+            flowBuilder.makeTemporary(flowEntry.timeout());
+        }
+        flowBuilder.withSelector(flowEntry.selector());
+        // Copy original instructions and add attenuation instruction
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+        flowEntry.treatment().allInstructions().forEach(ins -> treatmentBuilder.add(ins));
+        final DriverHandler handler = behaviour.handler();
+        treatmentBuilder.add(Instructions.extension(new OplinkAttenuation((int) power), handler.data().deviceId()));
+        flowBuilder.withTreatment(treatmentBuilder.build());
+
+        FlowRuleService service = handler.get(FlowRuleService.class);
+        service.applyFlowRules(flowBuilder.build());
+    }
+}
diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkRoadmPowerConfig.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkRoadmPowerConfig.java
index 3a7dc0c..4904168 100644
--- a/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkRoadmPowerConfig.java
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/power/OplinkRoadmPowerConfig.java
@@ -16,38 +16,12 @@
 
 package org.onosproject.driver.optical.power;
 
-import java.util.List;
 import java.util.Optional;
 
 import com.google.common.collect.Range;
-import org.onosproject.driver.extensions.OplinkAttenuation;
-import org.onosproject.net.OchSignal;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.Direction;
-import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.PowerConfig;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.OchSignalCriterion;
-import org.onosproject.net.flow.criteria.PortCriterion;
-import org.onosproject.net.flow.instructions.ExtensionTreatment;
-import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.optical.OpticalAnnotations;
-import org.onosproject.openflow.controller.Dpid;
-import org.onosproject.openflow.controller.OpenFlowController;
-import org.onosproject.openflow.controller.OpenFlowSwitch;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Port Power (Gain and attenuation) implementation for Oplink 1-SLOT-8D ROADM.
@@ -60,314 +34,31 @@
 public class OplinkRoadmPowerConfig extends AbstractHandlerBehaviour
                                     implements PowerConfig<Object> {
 
-    private static final int LINE_IN = 1;
-    private static final int LINE_OUT = 2;
-    private static final int AUX_OUT_1 = 3;
-    private static final int AUX_OUT_2 = 4;
-    private static final int EXPRESS_OUT_1 = 5;
-    private static final int EXPRESS_OUT_2 = 6;
-    private static final int EXPRESS_OUT_3 = 7;
-    private static final int EXPRESS_OUT_4 = 8;
-    private static final int EXPRESS_OUT_5 = 9;
-    private static final int EXPRESS_OUT_6 = 10;
-    private static final int EXPRESS_OUT_7 = 11;
-    private static final int AUX_IN_1 = 12;
-    private static final int AUX_IN_2 = 13;
-    private static final int EXPRESS_IN_1 = 14;
-    private static final int EXPRESS_IN_2 = 15;
-    private static final int EXPRESS_IN_3 = 16;
-    private static final int EXPRESS_IN_4 = 17;
-    private static final int EXPRESS_IN_5 = 18;
-    private static final int EXPRESS_IN_6 = 19;
-    private static final int EXPRESS_IN_7 = 20;
+    // oplink power config utility
+    private OplinkPowerConfigUtil oplinkUtil = new OplinkPowerConfigUtil(this);
 
-    protected final Logger log = LoggerFactory.getLogger(getClass());
-
-    // Component type
-    private enum Type {
-        NONE,
-        PORT,
-        CHANNEL
-    }
-
-    // Get the type if component is valid
-    private Type getType(Object component) {
-        if (component == null || component instanceof Direction) {
-            return Type.PORT;
-        } else if (component instanceof OchSignal) {
-            return Type.CHANNEL;
-        } else {
-            return Type.NONE;
-        }
-    }
-
-    private OpenFlowSwitch getOpenFlowDevice() {
-        final OpenFlowController controller = this.handler().get(OpenFlowController.class);
-        final Dpid dpid = Dpid.dpid(this.data().deviceId().uri());
-        OpenFlowSwitch sw = controller.getSwitch(dpid);
-        if (sw == null || !sw.isConnected()) {
-            return null;
-        } else {
-            return sw;
-        }
-    }
-
-    // Find matching flow on device
-    private FlowEntry findFlow(PortNumber portNum, OchSignal och) {
-        FlowRuleService service = this.handler().get(FlowRuleService.class);
-        Iterable<FlowEntry> flowEntries = service.getFlowEntries(this.data().deviceId());
-
-        // Return first matching flow
-        for (FlowEntry entry : flowEntries) {
-            TrafficSelector selector = entry.selector();
-            OchSignalCriterion entrySigid =
-                    (OchSignalCriterion) selector.getCriterion(Criterion.Type.OCH_SIGID);
-            // Check channel
-            if (entrySigid != null && och.equals(entrySigid.lambda())) {
-                // Check input port
-                PortCriterion entryPort =
-                        (PortCriterion) selector.getCriterion(Criterion.Type.IN_PORT);
-                if (entryPort != null && portNum.equals(entryPort.port())) {
-                    return entry;
-                }
-
-                // Check output port
-                TrafficTreatment treatment = entry.treatment();
-                for (Instruction instruction : treatment.allInstructions()) {
-                    if (instruction.type() == Instruction.Type.OUTPUT &&
-                        ((Instructions.OutputInstruction) instruction).port().equals(portNum)) {
-                        return entry;
-                    }
-                }
-            }
-        }
-        log.warn("No matching flow found");
-        return null;
+    @Override
+    public Optional<Long> getTargetPower(PortNumber port, Object component) {
+        return Optional.ofNullable(oplinkUtil.getTargetPower(port, component));
     }
 
     @Override
-    public Optional<Long> getTargetPower(PortNumber portNum, Object component) {
-        Long returnVal = null;
-        // Check if switch is connected, otherwise do not return value in store,
-        // which is obsolete.
-        if (getOpenFlowDevice() != null) {
-            switch (getType(component)) {
-                case PORT:
-                    // Will be implemented in the future.
-                    break;
-                case CHANNEL:
-                    returnVal = getChannelAttenuation(portNum, (OchSignal) component);
-                    break;
-                default:
-                    break;
-            }
-        }
-        return Optional.ofNullable(returnVal);
+    public Optional<Long> currentPower(PortNumber port, Object component) {
+        return Optional.ofNullable(oplinkUtil.getCurrentPower(port, component));
     }
 
     @Override
-    public Optional<Long> currentPower(PortNumber portNum, Object component) {
-        Long returnVal = null;
-        // Check if switch is connected, otherwise do not return value in store,
-        // which is obsolete.
-        if (getOpenFlowDevice() != null) {
-            switch (getType(component)) {
-                case PORT:
-                    returnVal = getCurrentPortPower(portNum);
-                    break;
-                case CHANNEL:
-                    returnVal = getCurrentChannelPower(portNum, (OchSignal) component);
-                    break;
-                default:
-                    break;
-            }
-        }
-        return Optional.ofNullable(returnVal);
-    }
-
-    @Override
-    public void setTargetPower(PortNumber portNum, Object component, long power) {
-        if (getOpenFlowDevice() != null) {
-            switch (getType(component)) {
-                case PORT:
-                    setTargetPortPower(portNum, power);
-                    break;
-                case CHANNEL:
-                    setChannelAttenuation(portNum, (OchSignal) component, power);
-                    break;
-                default:
-                    break;
-            }
-        } else {
-            log.warn("OpenFlow handshaker driver not found or device is not connected");
-        }
+    public void setTargetPower(PortNumber port, Object component, long power) {
+        oplinkUtil.setTargetPower(port, component, power);
     }
 
     @Override
     public Optional<Range<Long>> getTargetPowerRange(PortNumber port, Object component) {
-        Range<Long> range = null;
-        switch (getType(component)) {
-            case PORT:
-                range = getTargetPortPowerRange(port);
-                break;
-            case CHANNEL:
-                range = getChannelAttenuationRange(port);
-                break;
-            default:
-                break;
-        }
-        return Optional.ofNullable(range);
+        return Optional.ofNullable(oplinkUtil.getTargetPowerRange(port, component));
     }
 
     @Override
     public Optional<Range<Long>> getInputPowerRange(PortNumber port, Object component) {
-        Range<Long> range = null;
-        switch (getType(component)) {
-            case PORT:
-                range = getInputPortPowerRange(port);
-                break;
-            default:
-                break;
-        }
-        return Optional.ofNullable(range);
-    }
-
-    private Long getChannelAttenuation(PortNumber portNum, OchSignal och) {
-        FlowEntry flowEntry = findFlow(portNum, och);
-        if (flowEntry != null) {
-            List<Instruction> instructions = flowEntry.treatment().allInstructions();
-            for (Instruction ins : instructions) {
-                if (ins.type() == Instruction.Type.EXTENSION) {
-                    ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction();
-                    if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) {
-                        return (long) ((OplinkAttenuation) ext).getAttenuation();
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
-    private Long getCurrentPortPower(PortNumber portNum) {
-        DeviceService deviceService = this.handler().get(DeviceService.class);
-        Port port = deviceService.getPort(this.data().deviceId(), portNum);
-        if (port != null) {
-            String currentPower = port.annotations().value(OpticalAnnotations.CURRENT_POWER);
-            if (currentPower != null) {
-                return Long.valueOf(currentPower);
-            }
-        }
-        return null;
-    }
-
-    private Long getCurrentChannelPower(PortNumber portNum, OchSignal och) {
-        FlowEntry flowEntry = findFlow(portNum, och);
-        if (flowEntry != null) {
-            // TODO put somewhere else if possible
-            // We put channel power in packets
-            return flowEntry.packets();
-        }
-        return null;
-    }
-
-    private void setTargetPortPower(PortNumber portNum, long power) {
-        OpenFlowSwitch device = getOpenFlowDevice();
-        device.sendMsg(device.factory().buildOplinkPortPowerSet()
-                .setXid(0)
-                .setPort((int) portNum.toLong())
-                .setPowerValue((int) power)
-                .build());
-    }
-
-    private void setChannelAttenuation(PortNumber portNum, OchSignal och, long power) {
-        FlowEntry flowEntry = findFlow(portNum, och);
-        if (flowEntry != null) {
-            List<Instruction> instructions = flowEntry.treatment().allInstructions();
-            for (Instruction ins : instructions) {
-                if (ins.type() == Instruction.Type.EXTENSION) {
-                    ExtensionTreatment ext = ((Instructions.ExtensionInstructionWrapper) ins).extensionInstruction();
-                    if (ext.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.OPLINK_ATTENUATION.type()) {
-                        ((OplinkAttenuation) ext).setAttenuation((int) power);
-                        FlowRuleService service = this.handler().get(FlowRuleService.class);
-                        service.applyFlowRules(flowEntry);
-                        return;
-                    }
-                }
-            }
-            addAttenuation(flowEntry, power);
-        } else {
-            log.warn("Target channel power not set");
-        }
-    }
-
-    // Replace flow with new flow containing Oplink attenuation extension instruction. Also resets
-    // metrics.
-    private void addAttenuation(FlowEntry flowEntry, long power) {
-        FlowRule.Builder flowBuilder = new DefaultFlowRule.Builder();
-        flowBuilder.withCookie(flowEntry.id().value());
-        flowBuilder.withPriority(flowEntry.priority());
-        flowBuilder.forDevice(flowEntry.deviceId());
-        flowBuilder.forTable(flowEntry.tableId());
-        if (flowEntry.isPermanent()) {
-            flowBuilder.makePermanent();
-        } else {
-            flowBuilder.makeTemporary(flowEntry.timeout());
-        }
-
-        flowBuilder.withSelector(flowEntry.selector());
-
-        // Copy original instructions and add attenuation instruction
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-        flowEntry.treatment().allInstructions().forEach(ins -> treatmentBuilder.add(ins));
-        treatmentBuilder.add(Instructions.extension(new OplinkAttenuation((int) power), this.data().deviceId()));
-        flowBuilder.withTreatment(treatmentBuilder.build());
-
-        FlowRuleService service = this.handler().get(FlowRuleService.class);
-        service.applyFlowRules(flowBuilder.build());
-    }
-
-    // Returns the acceptable target range for an output Port, null otherwise
-    private Range<Long> getTargetPortPowerRange(PortNumber port) {
-        Range<Long> range = null;
-        long num = port.toLong();
-        if (num == LINE_OUT) {
-            range = Range.closed(100L, 2040L);
-        } else if (num >= AUX_OUT_1 && num <= EXPRESS_OUT_7) {
-            range = Range.closed(-680L, 1530L);
-        }
-        return range;
-    }
-
-    // Returns the acceptable attenuation range for a connection (represented as
-    // a flow with attenuation instruction). Port can be either the input or
-    // output port of the connection. Returns null if the connection does not
-    // support attenuation.
-    private Range<Long> getChannelAttenuationRange(PortNumber port) {
-        Range<Long> range = null;
-        long num = port.toLong();
-        // Only connections from AuxIn to LineOut or ExpressIn to LineOut support
-        // attenuation.
-        if (num == LINE_OUT ||
-            num >= AUX_IN_1 && num <= EXPRESS_IN_7) {
-            range = Range.closed(0L, 2550L);
-        }
-        return range;
-    }
-
-    // Returns the working input power range for an input port, null if the port
-    // is not an input port.
-    private Range<Long> getInputPortPowerRange(PortNumber port) {
-        Range<Long> range = null;
-        long portNum = port.toLong();
-        if (portNum == LINE_IN) {
-            // TODO implement support for IR and ER range
-            // only supports LR right now
-            range = Range.closed(-2600L, 540L);
-        } else if (portNum == AUX_IN_1 || portNum == AUX_IN_2) {
-            range = Range.closed(-1250L, 1590L);
-        } else if (portNum >= EXPRESS_IN_1 && portNum <= EXPRESS_IN_7) {
-            range = Range.closed(-1420L, 1420L);
-        }
-        return range;
+        return Optional.ofNullable(oplinkUtil.getInputPowerRange(port, component));
     }
 }
diff --git a/drivers/optical/src/main/java/org/onosproject/driver/optical/query/OplinkRoadmLambdaQuery.java b/drivers/optical/src/main/java/org/onosproject/driver/optical/query/OplinkRoadmLambdaQuery.java
index d797979..1532a80 100644
--- a/drivers/optical/src/main/java/org/onosproject/driver/optical/query/OplinkRoadmLambdaQuery.java
+++ b/drivers/optical/src/main/java/org/onosproject/driver/optical/query/OplinkRoadmLambdaQuery.java
@@ -36,13 +36,13 @@
 
 public class OplinkRoadmLambdaQuery extends AbstractHandlerBehaviour implements LambdaQuery {
 
-    private static final int LAMBDA_COUNT = 88;
-    private static final int CENTER_OFFSET = 29;
+    private static final int MIN_CHANNEL = -28;
+    private static final int MAX_CHANNEL = 59;
 
     @Override
     public Set<OchSignal> queryLambdas(PortNumber port) {
-        return IntStream.rangeClosed(1, LAMBDA_COUNT)
-                .mapToObj(x -> OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, x - CENTER_OFFSET))
+        return IntStream.rangeClosed(MIN_CHANNEL, MAX_CHANNEL)
+                .mapToObj(x -> OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, x))
                 .collect(Collectors.toSet());
     }
 }
\ No newline at end of file
diff --git a/drivers/optical/src/main/resources/optical-drivers.xml b/drivers/optical/src/main/resources/optical-drivers.xml
index 65ed00f..ca4016f 100644
--- a/drivers/optical/src/main/resources/optical-drivers.xml
+++ b/drivers/optical/src/main/resources/optical-drivers.xml
@@ -51,7 +51,7 @@
             manufacturer="Oplink a Molex company" hwVersion="ROADM"
             swVersion="of-agent">
         <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
-                   impl="org.onosproject.driver.optical.handshaker.OplinkRoadm"/>
+                   impl="org.onosproject.driver.optical.handshaker.OplinkRoadmHandshaker"/>
         <behaviour api="org.onosproject.net.behaviour.LambdaQuery"
                    impl="org.onosproject.driver.optical.query.OplinkRoadmLambdaQuery"/>
         <behaviour api="org.onosproject.net.optical.OpticalDevice"
