blob: ff65e0c6d5673b38697ebcd16d812ccc48f21ddb [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
alshabibb452fd72015-04-22 20:46:20 -07002 * Copyright 2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
alshabibb452fd72015-04-22 20:46:20 -070016package org.onosproject.driver.handshaker;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070017
Marc De Leenheerb9311372015-07-09 11:36:49 -070018import org.onosproject.net.Device;
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070019import com.google.common.collect.ImmutableSet;
Ayaka Koshibe5460d622015-05-14 12:19:19 -070020import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
21import org.onosproject.openflow.controller.PortDescPropertyType;
Brian O'Connorabafb502014-12-02 22:26:20 -080022import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
23import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
24import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
25import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -070026import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070027import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
28import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070029import org.projectfloodlight.openflow.protocol.OFMessage;
Ayaka Koshibe5460d622015-05-14 12:19:19 -070030import org.projectfloodlight.openflow.protocol.OFObject;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070031import org.projectfloodlight.openflow.protocol.OFPortDesc;
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070032import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
33import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
34import org.projectfloodlight.openflow.protocol.OFPortOptical;
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -070035import org.projectfloodlight.openflow.protocol.OFStatsReply;
36import org.projectfloodlight.openflow.protocol.OFStatsType;
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070037import org.projectfloodlight.openflow.types.OFPort;
Ayaka Koshibe5460d622015-05-14 12:19:19 -070038
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070039import java.io.IOException;
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070040import java.util.ArrayList;
41import java.util.Collections;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070042import java.util.List;
Ayaka Koshibe5460d622015-05-14 12:19:19 -070043import java.util.Set;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070044import java.util.concurrent.atomic.AtomicBoolean;
45
46/**
47 * LINC-OE Optical Emulator switch class.
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070048 *
49 * The LINC ROADM emulator exposes two types of ports: OCh ports connect to ports in the packet layer,
50 * while OMS ports connect to an OMS port on a neighbouring ROADM.
51 *
52 * LINC sends the tap ports (OCh for our purposes) in the regular port desc stats reply,
53 * while it sends *all* ports (both tap and WDM ports, i.e., OCh and OMS) in the experimenter port desc stats reply.
54 *
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070055 */
Jonathan Hartd9df7bd2015-11-10 17:10:25 -080056public class OfOpticalSwitchImplLinc13
Ayaka Koshibe5460d622015-05-14 12:19:19 -070057 extends AbstractOpenFlowSwitch implements OpenFlowOpticalSwitch {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070058
alshabibb452fd72015-04-22 20:46:20 -070059 private final AtomicBoolean driverHandshakeComplete = new AtomicBoolean(false);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070060 private long barrierXidToWaitFor = -1;
61
Marc De Leenheerfc913dd2015-07-30 16:04:55 -070062 private List<OFPortOptical> opticalPorts;
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -070063
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070064 @Override
65 public void startDriverHandshake() {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -070066 log.warn("Starting driver handshake for sw {}", getStringId());
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070067 if (startDriverHandshakeCalled) {
68 throw new SwitchDriverSubHandshakeAlreadyStarted();
69 }
70 startDriverHandshakeCalled = true;
71 try {
72 sendHandshakeOFExperimenterPortDescRequest();
73 } catch (IOException e) {
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -070074 log.error("LINC-OE exception while sending experimenter port desc:",
75 e.getMessage());
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070076 e.printStackTrace();
77 }
78 }
79
80 @Override
81 public boolean isDriverHandshakeComplete() {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070082 return driverHandshakeComplete.get();
83 }
84
85 @Override
86 public void processDriverHandshakeMessage(OFMessage m) {
alshabib9af70072015-02-09 14:34:16 -080087 if (!startDriverHandshakeCalled) {
Praseed Balakrishnane48aa682014-10-08 17:31:37 -070088 throw new SwitchDriverSubHandshakeNotStarted();
89 }
90 if (driverHandshakeComplete.get()) {
91 throw new SwitchDriverSubHandshakeCompleted(m);
92 }
93
94 switch (m.getType()) {
95 case BARRIER_REPLY:
96 if (m.getXid() == barrierXidToWaitFor) {
97 log.debug("LINC-OE Received barrier response");
98 }
99 break;
100 case ERROR:
Yuta HIGUCHIf5416d82014-10-24 21:17:40 -0700101 log.error("Switch {} Error {}", getStringId(), m);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700102 break;
103 case FEATURES_REPLY:
104 break;
105 case FLOW_REMOVED:
106 break;
107 case GET_ASYNC_REPLY:
108 break;
109 case PACKET_IN:
110 break;
111 case PORT_STATUS:
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700112 log.warn("****LINC-OE Port Status {} {}", getStringId(), m);
113 processOFPortStatus((OFCircuitPortStatus) m);
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700114 break;
115 case QUEUE_GET_CONFIG_REPLY:
116 break;
117 case ROLE_REPLY:
118 break;
119 case STATS_REPLY:
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700120 OFStatsReply stats = (OFStatsReply) m;
121 if (stats.getStatsType() == OFStatsType.EXPERIMENTER) {
122 log.warn("LINC-OE : Received stats reply message {}", m);
Marc De Leenheerfc913dd2015-07-30 16:04:55 -0700123 createOpticalPortList((OFCircuitPortsReply) m);
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700124 driverHandshakeComplete.set(true);
125 }
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700126 break;
127 default:
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700128 log.warn("Received message {} during switch-driver " +
129 "subhandshake " + "from switch {} ... " +
130 "Ignoring message", m,
131 getStringId());
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700132
133 }
134 }
135
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700136 public void processOFPortStatus(OFCircuitPortStatus ps) {
137 log.debug("LINC-OE ..OF Port Status :", ps);
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700138 }
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700139
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700140 private void sendHandshakeOFExperimenterPortDescRequest() throws
141 IOException {
142 // send multi part message for port description for optical switches
143 OFCircuitPortsRequest circuitPortsRequest = factory()
144 .buildCircuitPortsRequest().setXid(getNextTransactionId())
145 .build();
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700146 log.warn("LINC-OE : Sending experimented circuit port stats " +
147 "message " +
148 "{}",
149 circuitPortsRequest.toString());
alshabiba2df7b2a2015-05-06 13:57:10 -0700150 this.sendHandshakeMessage(circuitPortsRequest);
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700151 }
152
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700153 @Override
Ayaka Koshibe5460d622015-05-14 12:19:19 -0700154 /**
155 * Returns a list of standard (Ethernet) ports.
156 *
157 * @return List of ports
158 */
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700159 public List<OFPortDesc> getPorts() {
Marc De Leenheerfc913dd2015-07-30 16:04:55 -0700160 return Collections.EMPTY_LIST;
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700161 }
162
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700163
164 @Override
165 public Boolean supportNxRole() {
166 return false;
167 }
168
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700169 @Override
Marc De Leenheerb9311372015-07-09 11:36:49 -0700170 public Device.Type deviceType() {
171 return Device.Type.ROADM;
Praseed Balakrishnana22eadf2014-10-20 14:21:45 -0700172 }
173
Marc De Leenheerfc913dd2015-07-30 16:04:55 -0700174 /**
175 * Checks if given port is also part of the regular port desc stats, i.e., is the port a tap port.
176 *
177 * @param port given OF port
178 * @return true if the port is a tap (OCh), false otherwise (OMS port)
179 */
180 private boolean hasPort(OFPort port) {
181 for (OFPortDescStatsReply reply : this.ports) {
182 for (OFPortDesc p : reply.getEntries()) {
183 if (p.getPortNo().equals(port)) {
184 return true;
185 }
186 }
187 }
188
189 return false;
190 }
191
192 /**
193 * Creates an OpenFlow optical port based on the given port and transport type.
194 *
195 * @param port OpenFlow optical port
196 * @param type transport type
197 * @return OpenFlow optical port
198 */
199 private OFPortOptical createOpticalPort(OFPortOptical port, short type) {
200 List<OFPortDescPropOpticalTransport> descList = new ArrayList<>(port.getDesc().size());
201
202 for (OFPortDescPropOpticalTransport desc : port.getDesc()) {
203 OFPortDescPropOpticalTransport newDesc = desc.createBuilder()
204 .setType(desc.getType())
205 .setPortSignalType(type)
206 .setPortType(desc.getPortType())
207 .setReserved(desc.getReserved())
208 .build();
209 descList.add(newDesc);
210 }
211
212 OFPortOptical newPort = port.createBuilder()
213 .setConfig(port.getConfig())
214 .setDesc(descList)
215 .setHwAddr(port.getHwAddr())
216 .setName(port.getName())
217 .setPortNo(port.getPortNo())
218 .setState(port.getState())
219 .build();
220
221 return newPort;
222 }
223
224 /**
225 * Builds list of OFPortOptical ports based on the multi-part circuit ports reply.
226 *
227 * Ensure the optical transport port's signal type is configured correctly.
228 *
229 * @param wPorts OF reply with circuit ports
230 */
231 private void createOpticalPortList(OFCircuitPortsReply wPorts) {
232 opticalPorts = new ArrayList<>(wPorts.getEntries().size());
233
234 for (OFPortOptical p : wPorts.getEntries()) {
235 short signalType;
236
237 // FIXME: use constants once loxi has full optical extensions
238 if (hasPort(p.getPortNo())) {
239 signalType = 5; // OCH port
240 } else {
241 signalType = 2; // OMS port
242 }
243
244 opticalPorts.add(createOpticalPort(p, signalType));
245 }
246 }
247
Ayaka Koshibe5460d622015-05-14 12:19:19 -0700248 @Override
249 public List<? extends OFObject> getPortsOf(PortDescPropertyType type) {
Marc De Leenheerfc913dd2015-07-30 16:04:55 -0700250 if (!type.equals(PortDescPropertyType.OPTICAL_TRANSPORT)) {
251 return Collections.EMPTY_LIST;
252 }
253
254 return opticalPorts;
Ayaka Koshibe5460d622015-05-14 12:19:19 -0700255 }
256
257 @Override
258 public Set<PortDescPropertyType> getPortTypes() {
259 return ImmutableSet.of(PortDescPropertyType.OPTICAL_TRANSPORT);
260 }
Praseed Balakrishnane48aa682014-10-08 17:31:37 -0700261}