LINC-OE Optical Switch Driveri changes
diff --git a/openflow/api/pom.xml b/openflow/api/pom.xml
index afc2faf..4e91328 100644
--- a/openflow/api/pom.xml
+++ b/openflow/api/pom.xml
@@ -30,7 +30,7 @@
<groupId>org.projectfloodlight</groupId>
<artifactId>openflowj</artifactId>
<!-- FIXME once experimenter gets merged to upstream -->
- <version>0.3.8-optical_experimenter</version>
+ <version>0.3.8-optical_experimenter2</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java
index 868eb86..fafe546 100644
--- a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java
+++ b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/DriverManager.java
@@ -57,6 +57,12 @@
}
}
+ String sw = desc.getSwDesc();
+ if (sw.startsWith("LINC-OE")) {
+ log.debug("Optical Emulator LINC-OE with DPID:{} found..",dpid);
+ return new OFOpticalSwitchImplLINC13(dpid,desc);
+ }
+
log.warn("DriverManager could not identify switch desc: {}. "
+ "Assigning AbstractOpenFlowSwich", desc);
return new AbstractOpenFlowSwitch(dpid, desc) {
diff --git a/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
new file mode 100644
index 0000000..99d77a6
--- /dev/null
+++ b/openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFOpticalSwitchImplLINC13.java
@@ -0,0 +1,383 @@
+package org.onlab.onos.openflow.drivers.impl;
+
+import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
+import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
+import org.onlab.onos.openflow.controller.driver.SwitchDriverSubHandshakeNotStarted;
+import org.onlab.onos.openflow.controller.Dpid;
+import org.onlab.onos.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.projectfloodlight.openflow.protocol.OFCircuitPortsReply;
+import org.projectfloodlight.openflow.protocol.OFCircuitPortsRequest;
+import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
+import org.projectfloodlight.openflow.protocol.OFErrorMsg;
+import org.projectfloodlight.openflow.protocol.OFMatchV3;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFOxmList;
+import org.projectfloodlight.openflow.protocol.OFPortDesc;
+import org.projectfloodlight.openflow.protocol.OFPortOptical;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionCircuit;
+import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmInPort;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigid;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigidBasic;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtype;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOchSigtypeBasic;
+import org.projectfloodlight.openflow.types.CircuitSignalID;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.U8;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * LINC-OE Optical Emulator switch class.
+ */
+public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
+
+ private final AtomicBoolean driverHandshakeComplete;
+ private long barrierXidToWaitFor = -1;
+
+ private final Logger log =
+ LoggerFactory.getLogger(OFOpticalSwitchImplLINC13.class);
+
+ OFOpticalSwitchImplLINC13(Dpid dpid,OFDescStatsReply desc) {
+ super(dpid);
+ //setAttribute("optical", "true");
+ driverHandshakeComplete = new AtomicBoolean(false);
+ setSwitchDescription(desc);
+ }
+
+ @Override
+ public String toString() {
+ return "OFOpticalSwitchImplLINC13 [" + ((channel != null)
+ ? channel.getRemoteAddress() : "?")
+ + " DPID[" + ((getStringId() != null) ? getStringId() : "?") + "]]";
+ }
+
+ @Override
+ public void startDriverHandshake() {
+ log.debug("Starting driver handshake for sw {}", getStringId());
+ if (startDriverHandshakeCalled) {
+ throw new SwitchDriverSubHandshakeAlreadyStarted();
+ }
+ startDriverHandshakeCalled = true;
+ try {
+ sendHandshakeOFExperimenterPortDescRequest();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean isDriverHandshakeComplete() {
+ if (!startDriverHandshakeCalled) {
+ throw new SwitchDriverSubHandshakeNotStarted();
+ }
+ 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:
+ if (m.getXid() == barrierXidToWaitFor) {
+ log.debug("LINC-OE Received barrier response");
+ }
+ break;
+ case ERROR:
+ log.error("Switch {} Error {}", getStringId(), (OFErrorMsg) m);
+ break;
+ case FEATURES_REPLY:
+ break;
+ case FLOW_REMOVED:
+ break;
+ case GET_ASYNC_REPLY:
+ break;
+ case PACKET_IN:
+ break;
+ case PORT_STATUS:
+ break;
+ case QUEUE_GET_CONFIG_REPLY:
+ break;
+ case ROLE_REPLY:
+ break;
+ case STATS_REPLY:
+ log.debug("LINC-OE : Received stats reply message {}", m);
+ processHandshakeOFExperimenterPortDescRequest(
+ (OFCircuitPortsReply) m);
+ driverHandshakeComplete.set(true);
+ /* try {
+ testMA();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }*/
+ break;
+ default:
+ log.debug("Received message {} during switch-driver " +
+ "subhandshake " + "from switch {} ... " +
+ "Ignoring message", m,
+ getStringId());
+
+ }
+ }
+
+
+ private void processHandshakeOFExperimenterPortDescRequest(
+ OFCircuitPortsReply sr) {
+ Collection<OFPortOptical> entries = sr.getEntries();
+ List<OFPortDesc> ofPortDescList = new ArrayList<>(entries.size());
+ for (OFPortOptical entry : entries) {
+ ofPortDescList.add(factory().buildPortDesc().
+ setPortNo(entry.getPortNo())
+ .setConfig(entry.getConfig())
+ .setState(entry.getState())
+ .setHwAddr(entry.getHwAddr())
+ .setName(entry.getName())
+ .build());
+ }
+ setPortDescReply(factory().buildPortDescStatsReply().
+ setEntries(ofPortDescList).build());
+ }
+
+
+ private void sendHandshakeOFExperimenterPortDescRequest() throws
+ IOException {
+ // send multi part message for port description for optical switches
+ OFCircuitPortsRequest circuitPortsRequest = factory()
+ .buildCircuitPortsRequest().setXid(getNextTransactionId())
+ .build();
+ log.debug("LINC-OE : Sending experimented circuit port stats " +
+ "message " +
+ "{}",
+ circuitPortsRequest.toString());
+ channel.write(Collections.singletonList(circuitPortsRequest));
+ }
+
+
+
+ //todo for testing
+ public static final U8 SIGNAL_TYPE = U8.of((short) 1);
+ private void testMA() throws IOException {
+ log.debug("LINC OE *** Testing MA ");
+ short lambda = 100;
+ if (getId() == 0x0000ffffffffff02L) {
+ final int inport = 10;
+ final int outport = 20;
+ //Circuit signal id
+ CircuitSignalID sigID = getSignalID(lambda);
+
+ OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
+ OFOxmOchSigtype fieldSigType = factory()
+ .oxms()
+ .ochSigtype(SIGNAL_TYPE);
+
+ OFOxmOchSigidBasic ofOxmOchSigidBasic =
+ factory().oxms().ochSigidBasic(sigID);
+
+ OFOxmOchSigtypeBasic ofOxmOchSigtypeBasic =
+ factory().oxms().ochSigtypeBasic(SIGNAL_TYPE);
+
+ //Match Port
+ OFOxmInPort fieldPort = factory().oxms()
+ .inPort(OFPort.of(inport));
+ OFMatchV3 matchPort =
+ factory()
+ .buildMatchV3().
+ setOxmList(OFOxmList.of(fieldPort,
+ fieldSigType,
+ fieldSigIDMatch)).build();
+
+
+ // Set Action outport ,sigType and sigID
+ List<OFAction> actionList = new ArrayList<>();
+ OFAction actionOutPort =
+ factory().actions().output(OFPort.of(outport),
+ Short.MAX_VALUE);
+
+ OFActionCircuit actionCircuit = factory()
+ .actions()
+ .circuit(ofOxmOchSigidBasic);
+ OFActionCircuit setActionSigType = factory()
+ .actions()
+ .circuit(ofOxmOchSigtypeBasic);
+
+ actionList.add(actionOutPort);
+ actionList.add(setActionSigType);
+ actionList.add(actionCircuit);
+
+ OFInstruction instructionAction =
+ factory().instructions().buildApplyActions()
+ .setActions(actionList)
+ .build();
+ List<OFInstruction> instructions =
+ Collections.singletonList(instructionAction);
+
+ OFMessage opticalFlowEntry =
+ factory().buildFlowAdd()
+ .setMatch(matchPort)
+ .setInstructions(instructions)
+ .setXid(getNextTransactionId())
+ .build();
+ log.debug("Adding optical flow in sw {}", getStringId());
+ List<OFMessage> msglist = new ArrayList<>(1);
+ msglist.add(opticalFlowEntry);
+ write(msglist);
+ } else if (getId() == 0x0000ffffffffff03L) {
+ final int inport = 21;
+ final int outport = 22;
+ //Circuit signal id
+ CircuitSignalID sigID = getSignalID(lambda);
+
+ OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
+ OFOxmOchSigtype fieldSigType = factory()
+ .oxms()
+ .ochSigtype(SIGNAL_TYPE);
+
+ OFOxmOchSigidBasic ofOxmOchSigidBasic =
+ factory().oxms().ochSigidBasic(sigID);
+
+ OFOxmOchSigtypeBasic ofOxmOchSigtypeBasic =
+ factory().oxms().ochSigtypeBasic(SIGNAL_TYPE);
+
+ //Match Port,SigType,SigID
+ OFOxmInPort fieldPort = factory()
+ .oxms()
+ .inPort(OFPort.of(inport));
+ OFMatchV3 matchPort = factory()
+ .buildMatchV3()
+ .setOxmList(OFOxmList.of(fieldPort,
+ fieldSigType,
+ fieldSigIDMatch))
+ .build();
+
+ // Set Action outport ,SigType, sigID
+ List<OFAction> actionList = new ArrayList<>();
+ OFAction actionOutPort =
+ factory().actions().output(OFPort.of(outport),
+ Short.MAX_VALUE);
+
+ OFActionCircuit setActionSigType = factory()
+ .actions()
+ .circuit(ofOxmOchSigtypeBasic);
+ OFActionCircuit actionCircuit = factory()
+ .actions()
+ .circuit(ofOxmOchSigidBasic);
+
+
+ actionList.add(actionOutPort);
+ actionList.add(setActionSigType);
+ actionList.add(actionCircuit);
+
+ OFInstruction instructionAction =
+ factory().instructions().buildApplyActions()
+ .setActions(actionList)
+ .build();
+ List<OFInstruction> instructions =
+ Collections.singletonList(instructionAction);
+
+ OFMessage opticalFlowEntry =
+ factory().buildFlowAdd()
+ .setMatch(matchPort)
+ .setInstructions(instructions)
+ .setXid(getNextTransactionId())
+ .build();
+ log.debug("Adding optical flow in sw {}", getStringId());
+ List<OFMessage> msglist = new ArrayList<>(1);
+ msglist.add(opticalFlowEntry);
+ write(msglist);
+
+ } else if (getId() == 0x0000ffffffffff04L) {
+ final int inport = 23;
+ final int outport = 11;
+ //Circuit signal id
+ CircuitSignalID sigID = getSignalID(lambda);
+
+ OFOxmOchSigid fieldSigIDMatch = factory().oxms().ochSigid(sigID);
+ OFOxmOchSigtype fieldSigType = factory()
+ .oxms()
+ .ochSigtype(SIGNAL_TYPE);
+
+
+ //Match Port, sig type and sig id
+ OFOxmInPort fieldPort = factory()
+ .oxms()
+ .inPort(OFPort.of(inport));
+ OFMatchV3 matchPort =
+ factory().buildMatchV3()
+ .setOxmList(OFOxmList.of(fieldPort,
+ fieldSigType,
+ fieldSigIDMatch))
+ .build();
+
+ // Set Action outport
+ List<OFAction> actionList = new ArrayList<>();
+ OFAction actionOutPort =
+ factory().actions().output(OFPort.of(outport),
+ Short.MAX_VALUE);
+
+ actionList.add(actionOutPort);
+
+ OFInstruction instructionAction =
+ factory().instructions().buildApplyActions()
+ .setActions(actionList)
+ .build();
+ List<OFInstruction> instructions =
+ Collections.singletonList(instructionAction);
+
+ OFMessage opticalFlowEntry =
+ factory().buildFlowAdd()
+ .setMatch(matchPort)
+ .setInstructions(instructions)
+ .setXid(getNextTransactionId())
+ .build();
+ log.debug("Adding optical flow in sw {}", getStringId());
+ List<OFMessage> msglist = new ArrayList<>(1);
+ msglist.add(opticalFlowEntry);
+ write(msglist);
+ }
+
+ }
+
+ // Todo remove - for testing purpose only
+ private static CircuitSignalID getSignalID(short lambda) {
+ byte myGrid = 1;
+ byte myCs = 2;
+ short myCn = lambda;
+ short mySw = 1;
+
+ CircuitSignalID signalID = new CircuitSignalID(myGrid,
+ myCs,
+ myCn,
+ mySw);
+ return signalID;
+ }
+
+ @Override
+ public void write(OFMessage msg) {
+ this.channel.write(msg);
+ }
+
+ @Override
+ public void write(List<OFMessage> msgs) {
+ this.channel.write(msgs);
+ }
+
+ @Override
+ public Boolean supportNxRole() {
+ return false;
+ }
+
+}