1 package org.openflow.protocol.factory;
3 import java.nio.ByteBuffer;
4 import java.util.ArrayList;
7 import org.openflow.protocol.OFMessage;
8 import org.openflow.protocol.OFType;
9 import org.openflow.protocol.action.OFAction;
10 import org.openflow.protocol.action.OFActionType;
11 import org.openflow.protocol.queue.OFQueueProperty;
12 import org.openflow.protocol.queue.OFQueuePropertyType;
13 import org.openflow.protocol.statistics.OFStatistics;
14 import org.openflow.protocol.statistics.OFStatisticsType;
15 import org.openflow.protocol.statistics.OFVendorStatistics;
19 * A basic OpenFlow factory that supports naive creation of both Messages and
22 * @author David Erickson (daviderickson@cs.stanford.edu)
23 * @author Rob Sherwood (rob.sherwood@stanford.edu)
26 public class BasicFactory implements OFMessageFactory, OFActionFactory,
27 OFQueuePropertyFactory, OFStatisticsFactory {
29 public OFMessage getMessage(OFType t) {
30 return t.newInstance();
34 public List<OFMessage> parseMessages(ByteBuffer data) {
35 return parseMessages(data, 0);
39 public List<OFMessage> parseMessages(ByteBuffer data, int limit) {
40 List<OFMessage> results = new ArrayList<OFMessage>();
41 OFMessage demux = new OFMessage();
44 while (limit == 0 || results.size() <= limit) {
45 if (data.remaining() < OFMessage.MINIMUM_LENGTH)
52 if (demux.getLengthU() > data.remaining())
55 ofm = getMessage(demux.getType());
56 if (ofm instanceof OFActionFactoryAware) {
57 ((OFActionFactoryAware)ofm).setActionFactory(this);
59 if (ofm instanceof OFMessageFactoryAware) {
60 ((OFMessageFactoryAware)ofm).setMessageFactory(this);
62 if (ofm instanceof OFQueuePropertyFactoryAware) {
63 ((OFQueuePropertyFactoryAware)ofm).setQueuePropertyFactory(this);
65 if (ofm instanceof OFStatisticsFactoryAware) {
66 ((OFStatisticsFactoryAware)ofm).setStatisticsFactory(this);
69 if (OFMessage.class.equals(ofm.getClass())) {
70 // advance the position for un-implemented messages
71 data.position(data.position()+(ofm.getLengthU() -
72 OFMessage.MINIMUM_LENGTH));
81 public OFAction getAction(OFActionType t) {
82 return t.newInstance();
86 public List<OFAction> parseActions(ByteBuffer data, int length) {
87 return parseActions(data, length, 0);
91 public List<OFAction> parseActions(ByteBuffer data, int length, int limit) {
92 List<OFAction> results = new ArrayList<OFAction>();
93 OFAction demux = new OFAction();
95 int end = data.position() + length;
97 while (limit == 0 || results.size() <= limit) {
98 if (data.remaining() < OFAction.MINIMUM_LENGTH ||
99 (data.position() + OFAction.MINIMUM_LENGTH) > end)
103 demux.readFrom(data);
106 if (demux.getLengthU() > data.remaining() ||
107 (data.position() + demux.getLengthU()) > end)
110 ofa = getAction(demux.getType());
112 if (OFAction.class.equals(ofa.getClass())) {
113 // advance the position for un-implemented messages
114 data.position(data.position()+(ofa.getLengthU() -
115 OFAction.MINIMUM_LENGTH));
124 public OFActionFactory getActionFactory() {
129 public OFStatistics getStatistics(OFType t, OFStatisticsType st) {
130 return st.newInstance(t);
134 public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
135 ByteBuffer data, int length) {
136 return parseStatistics(t, st, data, length, 0);
141 * OFMessage type: should be one of stats_request or stats_reply
143 * statistics type of this message, e.g., DESC, TABLE
145 * buffer to read from
147 * length of statistics
149 * number of statistics to grab; 0 == all
151 * @return list of statistics
155 public List<OFStatistics> parseStatistics(OFType t, OFStatisticsType st,
156 ByteBuffer data, int length, int limit) {
157 List<OFStatistics> results = new ArrayList<OFStatistics>();
158 OFStatistics statistics = getStatistics(t, st);
160 int start = data.position();
163 while (limit == 0 || results.size() <= limit) {
164 // TODO Create a separate MUX/DEMUX path for vendor stats
165 if (statistics instanceof OFVendorStatistics)
166 ((OFVendorStatistics)statistics).setLength(length);
169 * can't use data.remaining() here, b/c there could be other data
170 * buffered past this message
172 if ((length - count) >= statistics.getLength()) {
173 if (statistics instanceof OFActionFactoryAware)
174 ((OFActionFactoryAware)statistics).setActionFactory(this);
175 statistics.readFrom(data);
176 results.add(statistics);
177 count += statistics.getLength();
178 statistics = getStatistics(t, st);
180 if (count < length) {
182 * Nasty case: partial/incomplete statistic found even
183 * though we have a full message. Found when NOX sent
184 * agg_stats request with wrong agg statistics length (52
187 * just throw the rest away, or we will break framing
189 data.position(start + length);
194 return results; // empty; no statistics at all
198 public OFQueueProperty getQueueProperty(OFQueuePropertyType t) {
199 return t.newInstance();
203 public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
205 return parseQueueProperties(data, length, 0);
209 public List<OFQueueProperty> parseQueueProperties(ByteBuffer data,
210 int length, int limit) {
211 List<OFQueueProperty> results = new ArrayList<OFQueueProperty>();
212 OFQueueProperty demux = new OFQueueProperty();
213 OFQueueProperty ofqp;
214 int end = data.position() + length;
216 while (limit == 0 || results.size() <= limit) {
217 if (data.remaining() < OFQueueProperty.MINIMUM_LENGTH ||
218 (data.position() + OFQueueProperty.MINIMUM_LENGTH) > end)
222 demux.readFrom(data);
225 if (demux.getLengthU() > data.remaining() ||
226 (data.position() + demux.getLengthU()) > end)
229 ofqp = getQueueProperty(demux.getType());
231 if (OFQueueProperty.class.equals(ofqp.getClass())) {
232 // advance the position for un-implemented messages
233 data.position(data.position()+(ofqp.getLengthU() -
234 OFQueueProperty.MINIMUM_LENGTH));