Showing
3 changed files
with
472 additions
and
2 deletions
... | @@ -5,8 +5,9 @@ import org.projectfloodlight.openflow.types.OFPort; | ... | @@ -5,8 +5,9 @@ import org.projectfloodlight.openflow.types.OFPort; |
5 | 5 | ||
6 | /** | 6 | /** |
7 | * A representation of a packet context which allows any provider | 7 | * A representation of a packet context which allows any provider |
8 | - * to view the packet in event but may block the response to the | 8 | + * to view a packet in event, but may block the response to the |
9 | - * event if blocked has been called. | 9 | + * event if blocked has been called. This packet context can be used |
10 | + * to react to the packet in event with a packet out. | ||
10 | */ | 11 | */ |
11 | public interface OpenFlowPacketContext { | 12 | public interface OpenFlowPacketContext { |
12 | 13 | ... | ... |
... | @@ -3,6 +3,7 @@ package org.onlab.onos.provider.of.packet.impl; | ... | @@ -3,6 +3,7 @@ package org.onlab.onos.provider.of.packet.impl; |
3 | import static org.slf4j.LoggerFactory.getLogger; | 3 | import static org.slf4j.LoggerFactory.getLogger; |
4 | 4 | ||
5 | import java.nio.ByteBuffer; | 5 | import java.nio.ByteBuffer; |
6 | +import java.util.Collections; | ||
6 | 7 | ||
7 | import org.apache.felix.scr.annotations.Activate; | 8 | import org.apache.felix.scr.annotations.Activate; |
8 | import org.apache.felix.scr.annotations.Component; | 9 | import org.apache.felix.scr.annotations.Component; |
... | @@ -12,6 +13,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -12,6 +13,8 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
12 | import org.onlab.onos.net.ConnectPoint; | 13 | import org.onlab.onos.net.ConnectPoint; |
13 | import org.onlab.onos.net.DeviceId; | 14 | import org.onlab.onos.net.DeviceId; |
14 | import org.onlab.onos.net.PortNumber; | 15 | import org.onlab.onos.net.PortNumber; |
16 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
17 | +import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction; | ||
15 | import org.onlab.onos.net.packet.DefaultInboundPacket; | 18 | import org.onlab.onos.net.packet.DefaultInboundPacket; |
16 | import org.onlab.onos.net.packet.OutboundPacket; | 19 | import org.onlab.onos.net.packet.OutboundPacket; |
17 | import org.onlab.onos.net.packet.PacketProvider; | 20 | import org.onlab.onos.net.packet.PacketProvider; |
... | @@ -22,9 +25,20 @@ import org.onlab.onos.net.provider.ProviderId; | ... | @@ -22,9 +25,20 @@ import org.onlab.onos.net.provider.ProviderId; |
22 | import org.onlab.onos.openflow.controller.Dpid; | 25 | import org.onlab.onos.openflow.controller.Dpid; |
23 | import org.onlab.onos.openflow.controller.OpenFlowController; | 26 | import org.onlab.onos.openflow.controller.OpenFlowController; |
24 | import org.onlab.onos.openflow.controller.OpenFlowPacketContext; | 27 | import org.onlab.onos.openflow.controller.OpenFlowPacketContext; |
28 | +import org.onlab.onos.openflow.controller.OpenFlowSwitch; | ||
25 | import org.onlab.onos.openflow.controller.PacketListener; | 29 | import org.onlab.onos.openflow.controller.PacketListener; |
30 | +import org.onlab.packet.Ethernet; | ||
31 | +import org.projectfloodlight.openflow.protocol.OFPacketOut; | ||
32 | +import org.projectfloodlight.openflow.protocol.OFPortDesc; | ||
33 | +import org.projectfloodlight.openflow.protocol.action.OFAction; | ||
34 | +import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10; | ||
35 | +import org.projectfloodlight.openflow.types.OFBufferId; | ||
36 | +import org.projectfloodlight.openflow.types.OFPort; | ||
26 | import org.slf4j.Logger; | 37 | import org.slf4j.Logger; |
27 | 38 | ||
39 | +import static org.onlab.onos.openflow.controller.RoleState.*; | ||
40 | + | ||
41 | + | ||
28 | /** | 42 | /** |
29 | * Provider which uses an OpenFlow controller to detect network | 43 | * Provider which uses an OpenFlow controller to detect network |
30 | * infrastructure links. | 44 | * infrastructure links. |
... | @@ -68,9 +82,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr | ... | @@ -68,9 +82,61 @@ public class OpenFlowPacketProvider extends AbstractProvider implements PacketPr |
68 | 82 | ||
69 | @Override | 83 | @Override |
70 | public void emit(OutboundPacket packet) { | 84 | public void emit(OutboundPacket packet) { |
85 | + DeviceId devId = packet.sendThrough(); | ||
86 | + String scheme = devId.toString().split(":")[0]; | ||
87 | + | ||
88 | + if (!scheme.equals(this.id().scheme())) { | ||
89 | + throw new IllegalArgumentException( | ||
90 | + "Don't know how to handle Device with scheme " + scheme); | ||
91 | + } | ||
92 | + | ||
93 | + Dpid dpid = Dpid.dpid(devId.uri()); | ||
94 | + OpenFlowSwitch sw = controller.getSwitch(dpid); | ||
95 | + if (sw == null) { | ||
96 | + log.warn("Device {} isn't available?", devId); | ||
97 | + return; | ||
98 | + } else if (sw.getRole().equals(SLAVE)) { | ||
99 | + log.warn("Can't write to Device {} as slave", devId); | ||
100 | + return; | ||
101 | + } | ||
102 | + | ||
103 | + Ethernet eth = new Ethernet(); | ||
104 | + eth.deserialize(packet.data().array(), 0, packet.data().array().length); | ||
105 | + OFPortDesc p = null; | ||
106 | + for (Instruction inst : packet.treatment().instructions()) { | ||
107 | + if (inst.type().equals(Instruction.Type.OUTPUT)) { | ||
108 | + p = portDesc(((OutputInstruction) inst).port()); | ||
109 | + if (!sw.getPorts().contains(p)) { | ||
110 | + log.warn("Tried to write out non-existint port {}", p.getPortNo()); | ||
111 | + continue; | ||
112 | + } | ||
113 | + OFPacketOut po = packetOut(sw, eth, p.getPortNo()); | ||
114 | + sw.sendMsg(po); | ||
115 | + } | ||
116 | + } | ||
71 | 117 | ||
72 | } | 118 | } |
73 | 119 | ||
120 | + private OFPortDesc portDesc(PortNumber port) { | ||
121 | + OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc(); | ||
122 | + builder.setPortNo(OFPort.of((int) port.toLong())); | ||
123 | + | ||
124 | + return builder.build(); | ||
125 | + } | ||
126 | + | ||
127 | + private OFPacketOut packetOut(OpenFlowSwitch sw, Ethernet eth, OFPort out) { | ||
128 | + OFPacketOut.Builder builder = sw.factory().buildPacketOut(); | ||
129 | + OFAction act = sw.factory().actions() | ||
130 | + .buildOutput() | ||
131 | + .setPort(out) | ||
132 | + .build(); | ||
133 | + return builder | ||
134 | + .setBufferId(OFBufferId.NO_BUFFER) | ||
135 | + .setInPort(OFPort.NO_MASK) | ||
136 | + .setActions(Collections.singletonList(act)) | ||
137 | + .setData(eth.serialize()) | ||
138 | + .build(); | ||
139 | + } | ||
74 | 140 | ||
75 | /** | 141 | /** |
76 | * Internal Packet Provider implementation. | 142 | * Internal Packet Provider implementation. | ... | ... |
1 | +package org.onlab.onos.provider.of.packet.impl; | ||
2 | + | ||
3 | +import static org.junit.Assert.assertEquals; | ||
4 | +import static org.junit.Assert.assertNotNull; | ||
5 | +import static org.junit.Assert.assertNull; | ||
6 | + | ||
7 | +import java.nio.ByteBuffer; | ||
8 | +import java.util.ArrayList; | ||
9 | +import java.util.List; | ||
10 | +import java.util.Set; | ||
11 | + | ||
12 | +import org.junit.After; | ||
13 | +import org.junit.Before; | ||
14 | +import org.junit.Test; | ||
15 | +import org.onlab.onos.net.DeviceId; | ||
16 | +import org.onlab.onos.net.PortNumber; | ||
17 | +import org.onlab.onos.net.flow.DefaultTrafficTreatment; | ||
18 | +import org.onlab.onos.net.flow.TrafficTreatment; | ||
19 | +import org.onlab.onos.net.flow.instructions.Instruction; | ||
20 | +import org.onlab.onos.net.flow.instructions.Instructions; | ||
21 | +import org.onlab.onos.net.packet.DefaultOutboundPacket; | ||
22 | +import org.onlab.onos.net.packet.OutboundPacket; | ||
23 | +import org.onlab.onos.net.packet.PacketContext; | ||
24 | +import org.onlab.onos.net.packet.PacketProvider; | ||
25 | +import org.onlab.onos.net.packet.PacketProviderRegistry; | ||
26 | +import org.onlab.onos.net.packet.PacketProviderService; | ||
27 | +import org.onlab.onos.net.provider.ProviderId; | ||
28 | +import org.onlab.onos.openflow.controller.DefaultOpenFlowPacketContext; | ||
29 | +import org.onlab.onos.openflow.controller.Dpid; | ||
30 | +import org.onlab.onos.openflow.controller.OpenFlowController; | ||
31 | +import org.onlab.onos.openflow.controller.OpenFlowEventListener; | ||
32 | +import org.onlab.onos.openflow.controller.OpenFlowPacketContext; | ||
33 | +import org.onlab.onos.openflow.controller.OpenFlowSwitch; | ||
34 | +import org.onlab.onos.openflow.controller.OpenFlowSwitchListener; | ||
35 | +import org.onlab.onos.openflow.controller.PacketListener; | ||
36 | +import org.onlab.onos.openflow.controller.RoleState; | ||
37 | +import org.onlab.packet.ARP; | ||
38 | +import org.onlab.packet.Ethernet; | ||
39 | +import org.onlab.packet.IpAddress; | ||
40 | +import org.projectfloodlight.openflow.protocol.OFFactory; | ||
41 | +import org.projectfloodlight.openflow.protocol.OFMessage; | ||
42 | +import org.projectfloodlight.openflow.protocol.OFPacketIn; | ||
43 | +import org.projectfloodlight.openflow.protocol.OFPacketInReason; | ||
44 | +import org.projectfloodlight.openflow.protocol.OFPortDesc; | ||
45 | +import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10; | ||
46 | +import org.projectfloodlight.openflow.types.MacAddress; | ||
47 | +import org.projectfloodlight.openflow.types.OFBufferId; | ||
48 | +import org.projectfloodlight.openflow.types.OFPort; | ||
49 | + | ||
50 | +import com.google.common.collect.Lists; | ||
51 | +import com.google.common.collect.Sets; | ||
52 | + | ||
53 | + | ||
54 | +public class OpenFlowPacketProviderTest { | ||
55 | + | ||
56 | + private static final int PN1 = 100; | ||
57 | + private static final int PN2 = 200; | ||
58 | + private static final int PN3 = 300; | ||
59 | + private static final short VLANID = (short) 100; | ||
60 | + | ||
61 | + private static final DeviceId DID = DeviceId.deviceId("of:1"); | ||
62 | + private static final DeviceId DID_MISSING = DeviceId.deviceId("of:2"); | ||
63 | + private static final DeviceId DID_WRONG = DeviceId.deviceId("test:1"); | ||
64 | + private static final PortNumber P1 = PortNumber.portNumber(PN1); | ||
65 | + private static final PortNumber P2 = PortNumber.portNumber(PN2); | ||
66 | + private static final PortNumber P3 = PortNumber.portNumber(PN3); | ||
67 | + | ||
68 | + private static final Instruction INST1 = Instructions.createOutput(P1); | ||
69 | + private static final Instruction INST2 = Instructions.createOutput(P2); | ||
70 | + private static final Instruction INST3 = Instructions.createOutput(P3); | ||
71 | + | ||
72 | + private static final OFPortDesc PD1 = portDesc(PN1); | ||
73 | + private static final OFPortDesc PD2 = portDesc(PN2); | ||
74 | + | ||
75 | + private static final List<OFPortDesc> PLIST = Lists.newArrayList(PD1, PD2); | ||
76 | + private static final TrafficTreatment TR = treatment(INST1, INST2); | ||
77 | + private static final TrafficTreatment TR_MISSING = treatment(INST1, INST3); | ||
78 | + | ||
79 | + private final OpenFlowPacketProvider provider = new OpenFlowPacketProvider(); | ||
80 | + private final TestPacketRegistry registry = new TestPacketRegistry(); | ||
81 | + private final TestController controller = new TestController(); | ||
82 | + | ||
83 | + private final TestOpenFlowSwitch sw = new TestOpenFlowSwitch(PLIST); | ||
84 | + | ||
85 | + @Before | ||
86 | + public void startUp() { | ||
87 | + provider.providerRegistry = registry; | ||
88 | + provider.controller = controller; | ||
89 | + provider.activate(); | ||
90 | + assertNotNull("listener should be registered", registry.listener); | ||
91 | + } | ||
92 | + | ||
93 | + @After | ||
94 | + public void teardown() { | ||
95 | + provider.deactivate(); | ||
96 | + assertNull("listeners shouldn't be registered", registry.listener); | ||
97 | + provider.controller = null; | ||
98 | + provider.providerRegistry = null; | ||
99 | + } | ||
100 | + | ||
101 | + @Test(expected = IllegalArgumentException.class) | ||
102 | + public void wrongScheme() { | ||
103 | + sw.setRole(RoleState.MASTER); | ||
104 | + OutboundPacket schemeFailPkt = outPacket(DID_WRONG, TR, null); | ||
105 | + provider.emit(schemeFailPkt); | ||
106 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
107 | + } | ||
108 | + | ||
109 | + @Test | ||
110 | + public void emit() { | ||
111 | + | ||
112 | + MacAddress mac1 = MacAddress.of("00:00:00:11:00:01"); | ||
113 | + MacAddress mac2 = MacAddress.of("00:00:00:22:00:02"); | ||
114 | + | ||
115 | + ARP arp = new ARP(); | ||
116 | + arp.setSenderProtocolAddress(IpAddress.ANY) | ||
117 | + .setSenderHardwareAddress(mac1.getBytes()) | ||
118 | + .setTargetHardwareAddress(mac2.getBytes()) | ||
119 | + .setTargetProtocolAddress(IpAddress.ANY) | ||
120 | + .setHardwareType((short) 0) | ||
121 | + .setProtocolType((short) 0) | ||
122 | + .setHardwareAddressLength((byte) 6) | ||
123 | + .setProtocolAddressLength((byte) 4) | ||
124 | + .setOpCode((byte) 0); | ||
125 | + | ||
126 | + Ethernet eth = new Ethernet(); | ||
127 | + eth.setVlanID(VLANID) | ||
128 | + .setEtherType(Ethernet.TYPE_ARP) | ||
129 | + .setSourceMACAddress("00:00:00:11:00:01") | ||
130 | + .setDestinationMACAddress("00:00:00:22:00:02") | ||
131 | + .setPayload(arp); | ||
132 | + | ||
133 | + //the should-be working setup. | ||
134 | + OutboundPacket passPkt = outPacket(DID, TR, eth); | ||
135 | + sw.setRole(RoleState.MASTER); | ||
136 | + provider.emit(passPkt); | ||
137 | + assertEquals("invalid switch", sw, controller.current); | ||
138 | + assertEquals("message not sent", PLIST.size(), sw.sent.size()); | ||
139 | + sw.sent.clear(); | ||
140 | + | ||
141 | + //wrong Role | ||
142 | + sw.setRole(RoleState.SLAVE); | ||
143 | + provider.emit(passPkt); | ||
144 | + assertEquals("invalid switch", sw, controller.current); | ||
145 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
146 | + | ||
147 | + sw.setRole(RoleState.MASTER); | ||
148 | + | ||
149 | + //missing switch | ||
150 | + OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth); | ||
151 | + provider.emit(swFailPkt); | ||
152 | + assertNull("invalid switch", controller.current); | ||
153 | + assertEquals("message sent incorrectly", 0, sw.sent.size()); | ||
154 | + | ||
155 | + //to missing port | ||
156 | + OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth); | ||
157 | + provider.emit(portFailPkt); | ||
158 | + assertEquals("extra message sent", 1, sw.sent.size()); | ||
159 | + | ||
160 | + } | ||
161 | + | ||
162 | + @Test | ||
163 | + public void handlePacket() { | ||
164 | + OFPacketIn pkt = sw.factory().buildPacketIn() | ||
165 | + .setBufferId(OFBufferId.NO_BUFFER) | ||
166 | + .setInPort(OFPort.NO_MASK) | ||
167 | + .setReason(OFPacketInReason.INVALID_TTL) | ||
168 | + .build(); | ||
169 | + | ||
170 | + controller.processPacket(null, pkt); | ||
171 | + assertNotNull("message unprocessed", registry.ctx); | ||
172 | + | ||
173 | + } | ||
174 | + | ||
175 | + private static OFPortDesc portDesc(int port) { | ||
176 | + OFPortDesc.Builder builder = OFFactoryVer10.INSTANCE.buildPortDesc(); | ||
177 | + builder.setPortNo(OFPort.of(port)); | ||
178 | + | ||
179 | + return builder.build(); | ||
180 | + } | ||
181 | + | ||
182 | + private static TrafficTreatment treatment(Instruction ... insts) { | ||
183 | + TrafficTreatment.Builder builder = new DefaultTrafficTreatment.Builder(); | ||
184 | + for (Instruction i : insts) { | ||
185 | + builder.add(i); | ||
186 | + } | ||
187 | + return builder.build(); | ||
188 | + } | ||
189 | + | ||
190 | + private static OutboundPacket outPacket( | ||
191 | + DeviceId d, TrafficTreatment t, Ethernet e) { | ||
192 | + ByteBuffer buf = null; | ||
193 | + if (e != null) { | ||
194 | + buf = ByteBuffer.wrap(e.serialize()); | ||
195 | + } | ||
196 | + return new DefaultOutboundPacket(d, t, buf); | ||
197 | + } | ||
198 | + | ||
199 | + private class TestPacketRegistry implements PacketProviderRegistry { | ||
200 | + | ||
201 | + PacketProvider listener = null; | ||
202 | + PacketContext ctx = null; | ||
203 | + | ||
204 | + @Override | ||
205 | + public PacketProviderService register(PacketProvider provider) { | ||
206 | + listener = provider; | ||
207 | + return new TestPacketProviderService(); | ||
208 | + } | ||
209 | + | ||
210 | + @Override | ||
211 | + public void unregister(PacketProvider provider) { | ||
212 | + listener = null; | ||
213 | + } | ||
214 | + | ||
215 | + @Override | ||
216 | + public Set<ProviderId> getProviders() { | ||
217 | + return Sets.newHashSet(listener.id()); | ||
218 | + } | ||
219 | + | ||
220 | + private class TestPacketProviderService implements PacketProviderService { | ||
221 | + | ||
222 | + @Override | ||
223 | + public PacketProvider provider() { | ||
224 | + return null; | ||
225 | + } | ||
226 | + | ||
227 | + @Override | ||
228 | + public void processPacket(PacketContext context) { | ||
229 | + ctx = context; | ||
230 | + } | ||
231 | + | ||
232 | + } | ||
233 | + } | ||
234 | + | ||
235 | + private class TestController implements OpenFlowController { | ||
236 | + | ||
237 | + PacketListener pktListener; | ||
238 | + OpenFlowSwitch current; | ||
239 | + | ||
240 | + @Override | ||
241 | + public Iterable<OpenFlowSwitch> getSwitches() { | ||
242 | + return null; | ||
243 | + } | ||
244 | + | ||
245 | + @Override | ||
246 | + public Iterable<OpenFlowSwitch> getMasterSwitches() { | ||
247 | + return null; | ||
248 | + } | ||
249 | + | ||
250 | + @Override | ||
251 | + public Iterable<OpenFlowSwitch> getEqualSwitches() { | ||
252 | + return null; | ||
253 | + } | ||
254 | + | ||
255 | + @Override | ||
256 | + public OpenFlowSwitch getSwitch(Dpid dpid) { | ||
257 | + if (dpid.equals(Dpid.dpid(DID.uri()))) { | ||
258 | + current = sw; | ||
259 | + } else { | ||
260 | + current = null; | ||
261 | + } | ||
262 | + return current; | ||
263 | + } | ||
264 | + | ||
265 | + @Override | ||
266 | + public OpenFlowSwitch getMasterSwitch(Dpid dpid) { | ||
267 | + return null; | ||
268 | + } | ||
269 | + | ||
270 | + @Override | ||
271 | + public OpenFlowSwitch getEqualSwitch(Dpid dpid) { | ||
272 | + return null; | ||
273 | + } | ||
274 | + | ||
275 | + @Override | ||
276 | + public void addListener(OpenFlowSwitchListener listener) { | ||
277 | + } | ||
278 | + | ||
279 | + @Override | ||
280 | + public void removeListener(OpenFlowSwitchListener listener) { | ||
281 | + } | ||
282 | + | ||
283 | + @Override | ||
284 | + public void addPacketListener(int priority, PacketListener listener) { | ||
285 | + pktListener = listener; | ||
286 | + } | ||
287 | + | ||
288 | + @Override | ||
289 | + public void removePacketListener(PacketListener listener) { | ||
290 | + } | ||
291 | + | ||
292 | + @Override | ||
293 | + public void addEventListener(OpenFlowEventListener listener) { | ||
294 | + } | ||
295 | + | ||
296 | + @Override | ||
297 | + public void removeEventListener(OpenFlowEventListener listener) { | ||
298 | + } | ||
299 | + | ||
300 | + @Override | ||
301 | + public void write(Dpid dpid, OFMessage msg) { | ||
302 | + } | ||
303 | + | ||
304 | + @Override | ||
305 | + public void processPacket(Dpid dpid, OFMessage msg) { | ||
306 | + OpenFlowPacketContext pktCtx = | ||
307 | + DefaultOpenFlowPacketContext. | ||
308 | + packetContextFromPacketIn(sw, (OFPacketIn) msg); | ||
309 | + pktListener.handlePacket(pktCtx); | ||
310 | + } | ||
311 | + | ||
312 | + @Override | ||
313 | + public void setRole(Dpid dpid, RoleState role) { | ||
314 | + } | ||
315 | + | ||
316 | + } | ||
317 | + | ||
318 | + private class TestOpenFlowSwitch implements OpenFlowSwitch { | ||
319 | + | ||
320 | + List<OFPortDesc> ports; | ||
321 | + RoleState state; | ||
322 | + List<OFMessage> sent = new ArrayList<OFMessage>(); | ||
323 | + OFFactory factory = OFFactoryVer10.INSTANCE; | ||
324 | + | ||
325 | + TestOpenFlowSwitch(List<OFPortDesc> p) { | ||
326 | + ports = p; | ||
327 | + } | ||
328 | + | ||
329 | + @Override | ||
330 | + public void sendMsg(OFMessage msg) { | ||
331 | + sent.add(msg); | ||
332 | + } | ||
333 | + | ||
334 | + @Override | ||
335 | + public void sendMsg(List<OFMessage> msgs) { | ||
336 | + } | ||
337 | + | ||
338 | + @Override | ||
339 | + public void handleMessage(OFMessage fromSwitch) { | ||
340 | + } | ||
341 | + | ||
342 | + @Override | ||
343 | + public void setRole(RoleState role) { | ||
344 | + state = role; | ||
345 | + } | ||
346 | + | ||
347 | + @Override | ||
348 | + public RoleState getRole() { | ||
349 | + return state; | ||
350 | + } | ||
351 | + | ||
352 | + @Override | ||
353 | + public List<OFPortDesc> getPorts() { | ||
354 | + return ports; | ||
355 | + } | ||
356 | + | ||
357 | + @Override | ||
358 | + public OFFactory factory() { | ||
359 | + return factory; | ||
360 | + } | ||
361 | + | ||
362 | + @Override | ||
363 | + public String getStringId() { | ||
364 | + return null; | ||
365 | + } | ||
366 | + | ||
367 | + @Override | ||
368 | + public long getId() { | ||
369 | + return 0; | ||
370 | + } | ||
371 | + | ||
372 | + @Override | ||
373 | + public String manfacturerDescription() { | ||
374 | + return null; | ||
375 | + } | ||
376 | + | ||
377 | + @Override | ||
378 | + public String datapathDescription() { | ||
379 | + return null; | ||
380 | + } | ||
381 | + | ||
382 | + @Override | ||
383 | + public String hardwareDescription() { | ||
384 | + return null; | ||
385 | + } | ||
386 | + | ||
387 | + @Override | ||
388 | + public String softwareDescription() { | ||
389 | + return null; | ||
390 | + } | ||
391 | + | ||
392 | + @Override | ||
393 | + public String serialNumber() { | ||
394 | + return null; | ||
395 | + } | ||
396 | + | ||
397 | + @Override | ||
398 | + public void disconnectSwitch() { | ||
399 | + } | ||
400 | + | ||
401 | + } | ||
402 | + | ||
403 | +} |
-
Please register or login to post a comment