Jimmy Jin
Committed by Gerrit Code Review

Oplink ROADM Support - 6

Change-Id: I20028989e3547753ed20c370f2bf3c18340c4576
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.driver.handshaker;
17 +
18 +import com.google.common.collect.ImmutableList;
19 +import com.google.common.collect.ImmutableSet;
20 +
21 +import java.io.IOException;
22 +import java.util.ArrayList;
23 +import java.util.Collections;
24 +import java.util.List;
25 +import java.util.Set;
26 +import java.util.concurrent.atomic.AtomicBoolean;
27 +
28 +import org.onosproject.net.Device;
29 +import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
30 +import org.onosproject.openflow.controller.PortDescPropertyType;
31 +import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
32 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
33 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
34 +import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
35 +import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
36 +import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
37 +import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
38 +import org.projectfloodlight.openflow.protocol.OFMessage;
39 +import org.projectfloodlight.openflow.protocol.OFObject;
40 +import org.projectfloodlight.openflow.protocol.OFPortDesc;
41 +import org.projectfloodlight.openflow.protocol.OFPortOptical;
42 +import org.projectfloodlight.openflow.protocol.OFStatsReply;
43 +import org.projectfloodlight.openflow.protocol.OFStatsType;
44 +
45 +/**
46 + * Driver for Oplink single WSS 8D ROADM.
47 + *
48 + * Driver implements custom handshaker and supports for Optical channel Port based on OpenFlow OTN extension.
49 + * The device consists of Och ports, and performances wavelength cross-connect among the ports.
50 + */
51 +public class OplinkRoadmHandshaker extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
52 + private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
53 + private List<OFPortOptical> opticalPorts;
54 +
55 + @Override
56 + public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
57 + return ImmutableList.copyOf(opticalPorts);
58 + }
59 +
60 + @Override
61 + /**
62 + * Returns a list of standard (Ethernet) ports.
63 + *
64 + * @return List of ports
65 + */
66 + public List<OFPortDesc> getPorts() {
67 + return Collections.EMPTY_LIST;
68 + }
69 +
70 + @Override
71 + public Set<PortDescPropertyType> getPortTypes() {
72 + return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
73 + }
74 +
75 + @Override
76 + public Boolean supportNxRole() {
77 + return false;
78 + }
79 +
80 + @Override
81 + public void startDriverHandshake() {
82 + log.warn("Starting driver handshake for sw {}", getStringId());
83 + if (startDriverHandshakeCalled) {
84 + throw new SwitchDriverSubHandshakeAlreadyStarted();
85 + }
86 + startDriverHandshakeCalled = true;
87 + try {
88 + sendHandshakeOFExperimenterPortDescRequest();
89 + } catch (IOException e) {
90 + log.error("OPLK ROADM exception while sending experimenter port desc:", e);
91 + }
92 + }
93 +
94 + @Override
95 + public boolean isDriverHandshakeComplete() {
96 + return driverHandshakeComplete.get();
97 + }
98 +
99 + @Override
100 + public void processDriverHandshakeMessage(OFMessage m) {
101 +
102 + if (!startDriverHandshakeCalled) {
103 + throw new SwitchDriverSubHandshakeNotStarted();
104 + }
105 +
106 + if (driverHandshakeComplete.get()) {
107 + throw new SwitchDriverSubHandshakeCompleted(m);
108 + }
109 +
110 + switch (m.getType()) {
111 + case BARRIER_REPLY:
112 + log.debug("OPLK ROADM Received barrier response");
113 + break;
114 + case ERROR:
115 + log.error("Switch {} Error {}", getStringId(), m);
116 + break;
117 + case FEATURES_REPLY:
118 + break;
119 + case FLOW_REMOVED:
120 + break;
121 + case GET_ASYNC_REPLY:
122 + break;
123 + case PACKET_IN:
124 + break;
125 + case PORT_STATUS:
126 + processOFPortStatus((OFCircuitPortStatus) m);
127 + break;
128 + case QUEUE_GET_CONFIG_REPLY:
129 + break;
130 + case ROLE_REPLY:
131 + break;
132 + case STATS_REPLY:
133 + OFStatsReply stats = (OFStatsReply) m;
134 + if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
135 + log.warn("OPLK ROADM : Received multipart (port desc) reply message {}", m);
136 + //OTN Optical extension 1.0 port-desc
137 + createOpticalPortList((OFCircuitPortsReply) m);
138 + driverHandshakeComplete.set(true);
139 + }
140 + break;
141 + default:
142 + log.warn("Received message {} during switch-driver " +
143 + "subhandshake " + "from switch {} ... " +
144 + "Ignoring message", m,
145 + getStringId());
146 +
147 + }
148 + }
149 +
150 + private void processOFPortStatus(OFCircuitPortStatus ps) {
151 + log.debug("OPLK ROADM ..OF Port Status :", ps);
152 + }
153 +
154 + @Override
155 + public Device.Type deviceType() {
156 + return Device.Type.ROADM;
157 + }
158 +
159 + @Override
160 + public final void sendMsg(OFMessage m) {
161 + OFMessage newMsg = m;
162 + //Stub for later enhancement.
163 + super.sendMsg(newMsg);
164 + }
165 +
166 + private void sendHandshakeOFExperimenterPortDescRequest() throws IOException {
167 + // send multi part message for port description for optical switches
168 + OFCircuitPortsRequest circuitPortsRequest = factory()
169 + .buildCircuitPortsRequest().setXid(getNextTransactionId())
170 + .build();
171 + log.info("OPLK ROADM : Sending experimented circuit port stats " +
172 + "message " +
173 + "{}",
174 + circuitPortsRequest);
175 + this.sendHandshakeMessage(circuitPortsRequest);
176 + }
177 +
178 + /**
179 + * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
180 + * Ensure the optical transport port's signal type is configured correctly.
181 + *
182 + * @param wPorts OF reply with circuit ports
183 + */
184 + private void createOpticalPortList(OFCircuitPortsReply wPorts) {
185 + opticalPorts = new ArrayList<>();
186 + opticalPorts.addAll(wPorts.getEntries());
187 + }
188 +}
...@@ -186,5 +186,11 @@ ...@@ -186,5 +186,11 @@
186 <behaviour api="org.onosproject.net.behaviour.Pipeliner" 186 <behaviour api="org.onosproject.net.behaviour.Pipeliner"
187 impl="org.onosproject.driver.pipeline.OpenstackPipeline"/> 187 impl="org.onosproject.driver.pipeline.OpenstackPipeline"/>
188 </driver> 188 </driver>
189 + <driver name="oplk-roadm" extends="default"
190 + manufacturer="Oplink a Molex company" hwVersion="ROADM"
191 + swVersion="of-agent">
192 + <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
193 + impl="org.onosproject.driver.handshaker.OplinkRoadmHandshaker"/>
194 + </driver>
189 </drivers> 195 </drivers>
190 196
......