blob: f5d02b05e192347198e7b9e3d101656e99bf5c35 [file] [log] [blame]
sangho5afd02a2015-02-03 20:07:35 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
sangho5afd02a2015-02-03 20:07:35 -08003 *
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.provider.of.group.impl;
17
18import org.onlab.packet.Ip4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080019import org.onlab.packet.Ip6Address;
sangho5afd02a2015-02-03 20:07:35 -080020import org.onosproject.core.GroupId;
jiangruia6b46092015-11-11 16:28:51 +080021import org.onosproject.net.DeviceId;
sangho5afd02a2015-02-03 20:07:35 -080022import org.onosproject.net.PortNumber;
jiangruia6b46092015-11-11 16:28:51 +080023import org.onosproject.net.driver.DefaultDriverData;
24import org.onosproject.net.driver.DefaultDriverHandler;
25import org.onosproject.net.driver.Driver;
26import org.onosproject.net.driver.DriverService;
sangho5afd02a2015-02-03 20:07:35 -080027import org.onosproject.net.flow.TrafficTreatment;
alshabib880b6442015-11-23 22:13:04 -080028import org.onosproject.net.flow.instructions.ExtensionTreatment;
sangho5afd02a2015-02-03 20:07:35 -080029import org.onosproject.net.flow.instructions.Instruction;
30import org.onosproject.net.flow.instructions.Instructions;
31import org.onosproject.net.flow.instructions.L0ModificationInstruction;
32import org.onosproject.net.flow.instructions.L2ModificationInstruction;
33import org.onosproject.net.flow.instructions.L3ModificationInstruction;
Jian Li62cf8b32019-02-25 21:33:07 +090034import org.onosproject.net.flow.instructions.L4ModificationInstruction;
sangho5afd02a2015-02-03 20:07:35 -080035import org.onosproject.net.group.GroupBucket;
36import org.onosproject.net.group.GroupBuckets;
37import org.onosproject.net.group.GroupDescription;
alshabib880b6442015-11-23 22:13:04 -080038import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
sangho5afd02a2015-02-03 20:07:35 -080039import org.projectfloodlight.openflow.protocol.OFBucket;
40import org.projectfloodlight.openflow.protocol.OFFactory;
41import org.projectfloodlight.openflow.protocol.OFGroupAdd;
42import org.projectfloodlight.openflow.protocol.OFGroupDelete;
43import org.projectfloodlight.openflow.protocol.OFGroupMod;
44import org.projectfloodlight.openflow.protocol.OFGroupType;
45import org.projectfloodlight.openflow.protocol.action.OFAction;
Saurav Das100e3b82015-04-30 11:12:10 -070046import org.projectfloodlight.openflow.protocol.action.OFActionGroup;
sangho5afd02a2015-02-03 20:07:35 -080047import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
48import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
sangho5afd02a2015-02-03 20:07:35 -080049import org.projectfloodlight.openflow.types.EthType;
50import org.projectfloodlight.openflow.types.IPv4Address;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -080051import org.projectfloodlight.openflow.types.IPv6Address;
52import org.projectfloodlight.openflow.types.IPv6FlowLabel;
sangho5afd02a2015-02-03 20:07:35 -080053import org.projectfloodlight.openflow.types.MacAddress;
Saurav Das73a7dd42015-08-19 22:20:31 -070054import org.projectfloodlight.openflow.types.OFBooleanValue;
sangho5afd02a2015-02-03 20:07:35 -080055import org.projectfloodlight.openflow.types.OFGroup;
56import org.projectfloodlight.openflow.types.OFPort;
57import org.projectfloodlight.openflow.types.OFVlanVidMatch;
Jian Li62cf8b32019-02-25 21:33:07 +090058import org.projectfloodlight.openflow.types.TransportPort;
sangho5afd02a2015-02-03 20:07:35 -080059import org.projectfloodlight.openflow.types.U32;
Hyunsun Moon9ae22e92015-12-15 20:34:51 -080060import org.projectfloodlight.openflow.types.U64;
sangho5afd02a2015-02-03 20:07:35 -080061import org.projectfloodlight.openflow.types.VlanPcp;
62import org.slf4j.Logger;
63
Jian Li11260a02016-05-19 13:07:22 -070064import java.util.ArrayList;
65import java.util.Collections;
66import java.util.LinkedList;
67import java.util.List;
68import java.util.Optional;
69
70import static org.slf4j.LoggerFactory.getLogger;
71
sangho5afd02a2015-02-03 20:07:35 -080072/*
73 * Builder for GroupMod.
74 */
75public final class GroupModBuilder {
76
77 private GroupBuckets buckets;
78 private GroupId groupId;
79 private GroupDescription.Type type;
80 private OFFactory factory;
81 private Long xid;
jiangruia6b46092015-11-11 16:28:51 +080082 private Optional<DriverService> driverService;
sangho5afd02a2015-02-03 20:07:35 -080083
84 private final Logger log = getLogger(getClass());
85
86 private static final int OFPCML_NO_BUFFER = 0xffff;
87
88 private GroupModBuilder(GroupBuckets buckets, GroupId groupId,
89 GroupDescription.Type type, OFFactory factory,
90 Optional<Long> xid) {
91 this.buckets = buckets;
92 this.groupId = groupId;
93 this.type = type;
94 this.factory = factory;
95 this.xid = xid.orElse((long) 0);
96 }
97
jiangruia6b46092015-11-11 16:28:51 +080098 private GroupModBuilder(GroupBuckets buckets, GroupId groupId,
99 GroupDescription.Type type, OFFactory factory,
100 Optional<Long> xid, Optional<DriverService> driverService) {
101 this.buckets = buckets;
102 this.groupId = groupId;
103 this.type = type;
104 this.factory = factory;
105 this.xid = xid.orElse((long) 0);
106 this.driverService = driverService;
107 }
sangho5afd02a2015-02-03 20:07:35 -0800108 /**
109 * Creates a builder for GroupMod.
110 *
111 * @param buckets GroupBuckets object
112 * @param groupId Group Id to create
113 * @param type Group type
114 * @param factory OFFactory object
115 * @param xid transaction ID
116 * @return GroupModBuilder object
117 */
118 public static GroupModBuilder builder(GroupBuckets buckets, GroupId groupId,
119 GroupDescription.Type type, OFFactory factory,
120 Optional<Long> xid) {
121
122 return new GroupModBuilder(buckets, groupId, type, factory, xid);
123 }
124
125 /**
jiangruia6b46092015-11-11 16:28:51 +0800126 * Creates a builder for GroupMod.
127 *
128 * @param buckets GroupBuckets object
129 * @param groupId Group Id to create
130 * @param type Group type
131 * @param factory OFFactory object
132 * @param xid transaction ID
133 * @param driverService driver Service
134 * @return GroupModBuilder object
135 */
136 public static GroupModBuilder builder(GroupBuckets buckets, GroupId groupId,
137 GroupDescription.Type type, OFFactory factory,
138 Optional<Long> xid, Optional<DriverService> driverService) {
139
140 return new GroupModBuilder(buckets, groupId, type, factory, xid, driverService);
141 }
142
pier4d7efe22019-06-18 22:57:19 +0200143 private OFBucket.Builder ofBucketBuilder(GroupBucket bucket) {
144 OFBucket.Builder bucketBuilder = factory.buildBucket();
145 List<OFAction> actions = buildActions(bucket.treatment());
146 bucketBuilder.setActions(actions);
147 if (type == GroupDescription.Type.SELECT) {
148 bucketBuilder.setWeight(bucket.weight());
149 }
150 if (type == GroupDescription.Type.FAILOVER && bucket.watchPort() != null) {
151 bucketBuilder.setWatchPort(OFPort.of((int) bucket.watchPort().toLong()));
152 } else {
153 bucketBuilder.setWatchPort(OFPort.ANY);
154 }
155 if (type == GroupDescription.Type.FAILOVER && bucket.watchGroup() != null) {
156 bucketBuilder.setWatchGroup(OFGroup.of(bucket.watchGroup().id()));
157 } else {
158 bucketBuilder.setWatchGroup(OFGroup.ANY);
159 }
160 return bucketBuilder;
161 }
162
jiangruia6b46092015-11-11 16:28:51 +0800163 /**
sangho5afd02a2015-02-03 20:07:35 -0800164 * Builds the GroupAdd OF message.
165 *
166 * @return GroupAdd OF message
167 */
168 public OFGroupAdd buildGroupAdd() {
pier4d7efe22019-06-18 22:57:19 +0200169 // Build group add
sangho5afd02a2015-02-03 20:07:35 -0800170 List<OFBucket> ofBuckets = new ArrayList<OFBucket>();
171 for (GroupBucket bucket: buckets.buckets()) {
pier4d7efe22019-06-18 22:57:19 +0200172 OFBucket ofBucket = ofBucketBuilder(bucket).build();
sangho5afd02a2015-02-03 20:07:35 -0800173 ofBuckets.add(ofBucket);
174 }
pier4d7efe22019-06-18 22:57:19 +0200175 // Build the msg and return
176 return factory.buildGroupAdd()
sangho5afd02a2015-02-03 20:07:35 -0800177 .setGroup(OFGroup.of(groupId.id()))
178 .setBuckets(ofBuckets)
179 .setGroupType(getOFGroupType(type))
180 .setXid(xid)
181 .build();
pier4d7efe22019-06-18 22:57:19 +0200182 }
sangho5afd02a2015-02-03 20:07:35 -0800183
pier4d7efe22019-06-18 22:57:19 +0200184 /**
185 * Builds the GroupMod OF message.
186 *
187 * @return GroupMod OF message
188 */
189 public OFGroupMod buildGroupMod() {
190 // Build group mod
191 List<OFBucket> ofBuckets = new ArrayList<OFBucket>();
192 for (GroupBucket bucket: buckets.buckets()) {
193 OFBucket ofBucket = ofBucketBuilder(bucket).build();
194 ofBuckets.add(ofBucket);
195 }
196 // Build the msg and return
197 return factory.buildGroupModify()
198 .setGroup(OFGroup.of(groupId.id()))
199 .setBuckets(ofBuckets)
200 .setGroupType(getOFGroupType(type))
201 .setXid(xid)
202 .build();
sangho5afd02a2015-02-03 20:07:35 -0800203 }
204
205 /**
206 * Builds the GroupDel OF message.
207 *
208 * @return GroupDel OF message
209 */
210 public OFGroupDelete buildGroupDel() {
pier4d7efe22019-06-18 22:57:19 +0200211 // Build the msg and return
212 return factory.buildGroupDelete()
sangho5afd02a2015-02-03 20:07:35 -0800213 .setGroup(OFGroup.of(groupId.id()))
pier4d7efe22019-06-18 22:57:19 +0200214 .setGroupType(getOFGroupType(type))
sangho5afd02a2015-02-03 20:07:35 -0800215 .setXid(xid)
216 .build();
sangho5afd02a2015-02-03 20:07:35 -0800217 }
218
219 private List<OFAction> buildActions(TrafficTreatment treatment) {
sangho5afd02a2015-02-03 20:07:35 -0800220 if (treatment == null) {
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700221 return Collections.emptyList();
sangho5afd02a2015-02-03 20:07:35 -0800222 }
Jonathan Hart54b406b2015-03-06 16:24:14 -0800223
Sho SHIMIZUb35ed362015-04-28 11:05:19 -0700224 List<OFAction> actions = new LinkedList<>();
Ray Milkey42507352015-03-20 15:16:10 -0700225 for (Instruction i : treatment.allInstructions()) {
sangho5afd02a2015-02-03 20:07:35 -0800226 switch (i.type()) {
sangho5afd02a2015-02-03 20:07:35 -0800227 case L0MODIFICATION:
228 actions.add(buildL0Modification(i));
229 break;
230 case L2MODIFICATION:
231 actions.add(buildL2Modification(i));
232 break;
233 case L3MODIFICATION:
234 actions.add(buildL3Modification(i));
235 break;
Jian Li62cf8b32019-02-25 21:33:07 +0900236 case L4MODIFICATION:
237 actions.add(buildL4Modification(i));
238 break;
sangho5afd02a2015-02-03 20:07:35 -0800239 case OUTPUT:
240 Instructions.OutputInstruction out =
241 (Instructions.OutputInstruction) i;
242 OFActionOutput.Builder action = factory.actions().buildOutput()
243 .setPort(OFPort.of((int) out.port().toLong()));
244 if (out.port().equals(PortNumber.CONTROLLER)) {
245 action.setMaxLen(OFPCML_NO_BUFFER);
246 }
247 actions.add(action.build());
248 break;
249 case GROUP:
Saurav Das100e3b82015-04-30 11:12:10 -0700250 Instructions.GroupInstruction grp =
251 (Instructions.GroupInstruction) i;
252 OFActionGroup.Builder actgrp = factory.actions().buildGroup()
253 .setGroup(OFGroup.of(grp.groupId().id()));
254 actions.add(actgrp.build());
255 break;
jiangruia6b46092015-11-11 16:28:51 +0800256 case EXTENSION:
257 Instructions.ExtensionInstructionWrapper wrapper =
258 (Instructions.ExtensionInstructionWrapper) i;
259 actions.add(buildExtensionAction(
260 wrapper.extensionInstruction(), wrapper.deviceId()));
261 break;
sangho5afd02a2015-02-03 20:07:35 -0800262 default:
263 log.warn("Instruction type {} not yet implemented.", i.type());
264 }
265 }
266
267 return actions;
268 }
269
270 private OFAction buildL0Modification(Instruction i) {
271 L0ModificationInstruction l0m = (L0ModificationInstruction) i;
272 switch (l0m.subtype()) {
sangho5afd02a2015-02-03 20:07:35 -0800273 default:
274 log.warn("Unimplemented action type {}.", l0m.subtype());
275 break;
276 }
277 return null;
278 }
279
280 private OFAction buildL2Modification(Instruction i) {
281 L2ModificationInstruction l2m = (L2ModificationInstruction) i;
282 L2ModificationInstruction.ModEtherInstruction eth;
283 OFOxm<?> oxm = null;
284 switch (l2m.subtype()) {
285 case ETH_DST:
286 eth = (L2ModificationInstruction.ModEtherInstruction) l2m;
287 oxm = factory.oxms().ethDst(MacAddress.of(eth.mac().toLong()));
288 break;
289 case ETH_SRC:
290 eth = (L2ModificationInstruction.ModEtherInstruction) l2m;
291 oxm = factory.oxms().ethSrc(MacAddress.of(eth.mac().toLong()));
292 break;
293 case VLAN_ID:
294 L2ModificationInstruction.ModVlanIdInstruction vlanId =
295 (L2ModificationInstruction.ModVlanIdInstruction) l2m;
296 oxm = factory.oxms().vlanVid(OFVlanVidMatch.ofVlan(vlanId.vlanId().toShort()));
297 break;
298 case VLAN_PCP:
299 L2ModificationInstruction.ModVlanPcpInstruction vlanPcp =
300 (L2ModificationInstruction.ModVlanPcpInstruction) l2m;
301 oxm = factory.oxms().vlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
302 break;
Jonathan Hart54b406b2015-03-06 16:24:14 -0800303 case VLAN_POP:
304 return factory.actions().popVlan();
305 case VLAN_PUSH:
Jian Li11260a02016-05-19 13:07:22 -0700306 L2ModificationInstruction.ModVlanHeaderInstruction pushVlanInstruction
307 = (L2ModificationInstruction.ModVlanHeaderInstruction) l2m;
Jonathan Hart54b406b2015-03-06 16:24:14 -0800308 return factory.actions().pushVlan(
alshabib7b808c52015-06-26 14:22:24 -0700309 EthType.of(pushVlanInstruction.ethernetType().toShort()));
sangho5afd02a2015-02-03 20:07:35 -0800310 case MPLS_PUSH:
Jian Li11260a02016-05-19 13:07:22 -0700311 L2ModificationInstruction.ModMplsHeaderInstruction pushHeaderInstructions =
312 (L2ModificationInstruction.ModMplsHeaderInstruction) l2m;
sangho5afd02a2015-02-03 20:07:35 -0800313 return factory.actions().pushMpls(EthType.of(pushHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700314 .ethernetType().toShort()));
sangho5afd02a2015-02-03 20:07:35 -0800315 case MPLS_POP:
Jian Li11260a02016-05-19 13:07:22 -0700316 L2ModificationInstruction.ModMplsHeaderInstruction popHeaderInstructions =
317 (L2ModificationInstruction.ModMplsHeaderInstruction) l2m;
sangho5afd02a2015-02-03 20:07:35 -0800318 return factory.actions().popMpls(EthType.of(popHeaderInstructions
alshabib7b808c52015-06-26 14:22:24 -0700319 .ethernetType().toShort()));
sangho5afd02a2015-02-03 20:07:35 -0800320 case MPLS_LABEL:
321 L2ModificationInstruction.ModMplsLabelInstruction mplsLabel =
322 (L2ModificationInstruction.ModMplsLabelInstruction) l2m;
Ray Milkey125572b2016-02-22 16:48:17 -0800323 oxm = factory.oxms().mplsLabel(U32.of(mplsLabel.label().toInt()));
sangho5afd02a2015-02-03 20:07:35 -0800324 break;
Saurav Das73a7dd42015-08-19 22:20:31 -0700325 case MPLS_BOS:
326 L2ModificationInstruction.ModMplsBosInstruction mplsBos =
327 (L2ModificationInstruction.ModMplsBosInstruction) l2m;
328 oxm = factory.oxms()
329 .mplsBos(mplsBos.mplsBos() ? OFBooleanValue.TRUE
330 : OFBooleanValue.FALSE);
331 break;
sangho5afd02a2015-02-03 20:07:35 -0800332 case DEC_MPLS_TTL:
333 return factory.actions().decMplsTtl();
Hyunsun Moon9ae22e92015-12-15 20:34:51 -0800334 case TUNNEL_ID:
335 L2ModificationInstruction.ModTunnelIdInstruction tunnelId =
336 (L2ModificationInstruction.ModTunnelIdInstruction) l2m;
337 oxm = factory.oxms().tunnelId(U64.of(tunnelId.tunnelId()));
338 break;
sangho5afd02a2015-02-03 20:07:35 -0800339 default:
340 log.warn("Unimplemented action type {}.", l2m.subtype());
341 break;
342 }
343
344 if (oxm != null) {
345 return factory.actions().buildSetField().setField(oxm).build();
346 }
347 return null;
348 }
349
350 private OFAction buildL3Modification(Instruction i) {
351 L3ModificationInstruction l3m = (L3ModificationInstruction) i;
352 L3ModificationInstruction.ModIPInstruction ip;
353 Ip4Address ip4;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800354 Ip6Address ip6;
sangho5afd02a2015-02-03 20:07:35 -0800355 OFOxm<?> oxm = null;
356 switch (l3m.subtype()) {
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800357 case IPV4_SRC:
358 ip = (L3ModificationInstruction.ModIPInstruction) i;
359 ip4 = ip.ip().getIp4Address();
360 oxm = factory.oxms().ipv4Src(IPv4Address.of(ip4.toInt()));
361 break;
362 case IPV4_DST:
sangho5afd02a2015-02-03 20:07:35 -0800363 ip = (L3ModificationInstruction.ModIPInstruction) i;
364 ip4 = ip.ip().getIp4Address();
365 oxm = factory.oxms().ipv4Dst(IPv4Address.of(ip4.toInt()));
366 break;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800367 case IPV6_SRC:
sangho5afd02a2015-02-03 20:07:35 -0800368 ip = (L3ModificationInstruction.ModIPInstruction) i;
Pavlin Radoslavovfebe82c2015-02-11 19:08:15 -0800369 ip6 = ip.ip().getIp6Address();
370 oxm = factory.oxms().ipv6Src(IPv6Address.of(ip6.toOctets()));
371 break;
372 case IPV6_DST:
373 ip = (L3ModificationInstruction.ModIPInstruction) i;
374 ip6 = ip.ip().getIp6Address();
375 oxm = factory.oxms().ipv6Dst(IPv6Address.of(ip6.toOctets()));
376 break;
377 case IPV6_FLABEL:
378 L3ModificationInstruction.ModIPv6FlowLabelInstruction flowLabelInstruction =
379 (L3ModificationInstruction.ModIPv6FlowLabelInstruction) i;
380 int flowLabel = flowLabelInstruction.flowLabel();
381 oxm = factory.oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
sangho5afd02a2015-02-03 20:07:35 -0800382 break;
383 case DEC_TTL:
384 return factory.actions().decNwTtl();
385 case TTL_IN:
386 return factory.actions().copyTtlIn();
387 case TTL_OUT:
388 return factory.actions().copyTtlOut();
389 default:
390 log.warn("Unimplemented action type {}.", l3m.subtype());
391 break;
392 }
393
394 if (oxm != null) {
395 return factory.actions().buildSetField().setField(oxm).build();
396 }
397 return null;
398 }
399
Jian Li62cf8b32019-02-25 21:33:07 +0900400 protected OFAction buildL4Modification(Instruction i) {
401 L4ModificationInstruction l4m = (L4ModificationInstruction) i;
402 L4ModificationInstruction.ModTransportPortInstruction tp;
403 OFOxm<?> oxm = null;
404 switch (l4m.subtype()) {
405 case TCP_SRC:
406 tp = (L4ModificationInstruction.ModTransportPortInstruction) l4m;
407 oxm = factory.oxms().tcpSrc(TransportPort.of(tp.port().toInt()));
408 break;
409 case TCP_DST:
410 tp = (L4ModificationInstruction.ModTransportPortInstruction) l4m;
411 oxm = factory.oxms().tcpDst(TransportPort.of(tp.port().toInt()));
412 break;
413 case UDP_SRC:
414 tp = (L4ModificationInstruction.ModTransportPortInstruction) l4m;
415 oxm = factory.oxms().udpSrc(TransportPort.of(tp.port().toInt()));
416 break;
417 case UDP_DST:
418 tp = (L4ModificationInstruction.ModTransportPortInstruction) l4m;
419 oxm = factory.oxms().udpDst(TransportPort.of(tp.port().toInt()));
420 break;
421 default:
422 log.warn("Unimplemented action type {}.", l4m.subtype());
423 break;
424 }
425
426 if (oxm != null) {
427 return factory.actions().buildSetField().setField(oxm).build();
428 }
429 return null;
430 }
431
sangho5afd02a2015-02-03 20:07:35 -0800432 private OFGroupType getOFGroupType(GroupDescription.Type groupType) {
433 switch (groupType) {
434 case INDIRECT:
435 return OFGroupType.INDIRECT;
436 case SELECT:
437 return OFGroupType.SELECT;
438 case FAILOVER:
439 return OFGroupType.FF;
440 case ALL:
441 return OFGroupType.ALL;
442 default:
443 log.error("Unsupported group type : {}", groupType);
444 break;
445 }
446 return null;
447 }
jiangruia6b46092015-11-11 16:28:51 +0800448
alshabib880b6442015-11-23 22:13:04 -0800449 private OFAction buildExtensionAction(ExtensionTreatment i, DeviceId deviceId) {
jiangruia6b46092015-11-11 16:28:51 +0800450 if (!driverService.isPresent()) {
451 log.error("No driver service present");
452 return null;
453 }
454 Driver driver = driverService.get().getDriver(deviceId);
alshabib880b6442015-11-23 22:13:04 -0800455 if (driver.hasBehaviour(ExtensionTreatmentInterpreter.class)) {
jiangruia6b46092015-11-11 16:28:51 +0800456 DefaultDriverHandler handler =
457 new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
alshabib880b6442015-11-23 22:13:04 -0800458 ExtensionTreatmentInterpreter interpreter = handler.behaviour(ExtensionTreatmentInterpreter.class);
jiangruia6b46092015-11-11 16:28:51 +0800459 return interpreter.mapInstruction(factory, i);
460 }
461
462 return null;
463 }
sangho5afd02a2015-02-03 20:07:35 -0800464}
465