blob: bbfb9c289340dc46de27897d0167a425930ea128 [file] [log] [blame]
Jimmy Jinc0198032016-01-04 13:26:10 -08001/*
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 */
16package org.onosproject.driver.handshaker;
17
18import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableSet;
20
21import java.io.IOException;
22import java.util.ArrayList;
23import java.util.Collections;
24import java.util.List;
25import java.util.Set;
26import java.util.concurrent.atomic.AtomicBoolean;
27
28import org.onosproject.net.Device;
29import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
30import org.onosproject.openflow.controller.PortDescPropertyType;
31import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
32import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
33import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
34import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
35import org.projectfloodlight.openflow.protocol.OFCircuitPortStatus;
36import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
37import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
38import org.projectfloodlight.openflow.protocol.OFMessage;
39import org.projectfloodlight.openflow.protocol.OFObject;
40import org.projectfloodlight.openflow.protocol.OFPortDesc;
41import org.projectfloodlight.openflow.protocol.OFPortOptical;
42import org.projectfloodlight.openflow.protocol.OFStatsReply;
43import 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 */
51public 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}