2 * Copyright (c) 2015 CableLabs and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.packetcable.provider;
11 import java.net.Inet4Address;
12 import java.net.Inet6Address;
13 import java.net.InetAddress;
14 import java.net.UnknownHostException;
15 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.ServiceFlowDirection;
16 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.TosByte;
17 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.ccap.attributes.AmId;
18 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.pcmm.qos.classifier.Classifier;
19 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.pcmm.qos.ext.classifier.ExtClassifier;
20 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.pcmm.qos.gate.spec.GateSpec;
21 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.pcmm.qos.ipv6.classifier.Ipv6Classifier;
22 import org.opendaylight.yang.gen.v1.urn.packetcable.rev151026.pcmm.qos.traffic.profile.TrafficProfile;
23 import org.pcmm.gates.IClassifier;
24 import org.pcmm.gates.IClassifier.Protocol;
25 import org.pcmm.gates.IExtendedClassifier.ActivationState;
26 import org.pcmm.gates.IGateSpec.Direction;
27 import org.pcmm.gates.IIPv6Classifier.FlowLabel;
28 import org.pcmm.gates.ITrafficProfile;
29 import org.pcmm.gates.impl.AMID;
30 import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile;
31 import org.pcmm.gates.impl.GateID;
32 import org.pcmm.gates.impl.PCMMError;
33 import org.pcmm.gates.impl.PCMMGateReq;
34 import org.pcmm.gates.impl.SubscriberID;
35 import org.pcmm.gates.impl.TransactionID;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Build PCMM gate requests from API QoS Gate objects
42 public class PCMMGateReqBuilder {
44 private final Logger logger = LoggerFactory.getLogger(PCMMGateReqBuilder.class);
46 private GateID gateID = null;
47 private AMID amid = null;
48 private SubscriberID subscriberID = null;
49 private TransactionID transactionID = null;
50 private org.pcmm.gates.impl.GateSpec gateSpec = null;
51 private ITrafficProfile trafficProfile = null;
52 private IClassifier classifier = null;
53 private PCMMError error = null;
55 public PCMMGateReq build() {
56 return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile, classifier, gateID, error);
59 public void setAmId(final AmId qosAmId) {
60 amid = new AMID(qosAmId.getAmType().shortValue(), qosAmId.getAmTag().shortValue());
63 public void setSubscriberId(final InetAddress qosSubId) {
64 subscriberID = new SubscriberID(qosSubId);
67 public void setGateSpec(final GateSpec qosGateSpec, final ServiceFlowDirection scnDirection) {
69 final ServiceFlowDirection qosDir;
70 if (scnDirection != null) {
71 qosDir = scnDirection;
73 if (qosGateSpec.getDirection() != null) {
74 qosDir = qosGateSpec.getDirection();
76 // TODO - determine if this is a valid default value
77 qosDir = ServiceFlowDirection.Ds;
81 final Direction gateDir;
82 if (qosDir == ServiceFlowDirection.Ds) {
83 gateDir = Direction.DOWNSTREAM;
85 gateDir = Direction.UPSTREAM;
90 final byte gateTosMask;
92 final TosByte tosOverwrite = qosGateSpec.getDscpTosOverwrite();
93 if (tosOverwrite != null) {
95 TosByte tosMask = qosGateSpec.getDscpTosMask();
96 if (tosMask != null) {
97 gateTosMask = tosMask.getValue().byteValue();
99 gateTosMask = (byte) 0xff;
102 // TODO - These values appear to be required
106 gateSpec = new org.pcmm.gates.impl.GateSpec(gateDir, dscptos, gateTosMask);
109 public void setTrafficProfile(final TrafficProfile qosTrafficProfile) {
110 if (qosTrafficProfile.getServiceClassName() != null) {
112 new DOCSISServiceClassNameTrafficProfile(qosTrafficProfile.getServiceClassName().getValue());
116 private InetAddress getByName(final String ipAddressStr) {
118 return InetAddress.getByName(ipAddressStr);
119 } catch (UnknownHostException e) {
120 logger.error(e.getMessage());
125 public void setClassifier(final Classifier qosClassifier) {
126 // TODO - try and make these variables immutable
127 Protocol protocol = null;
128 byte tosOverwrite = 0;
129 byte tosMask = (byte)0x0;
130 Inet4Address srcAddress = null;
131 Inet4Address dstAddress = null;
132 short srcPort = (short) 0;
133 short dstPort = (short) 0;
134 byte priority = (byte) 64;
137 if (qosClassifier.getProtocol() != null) {
138 protocol = Protocol.valueOf(qosClassifier.getProtocol().getValue().shortValue());
140 if (qosClassifier.getSrcIp() != null) {
141 final InetAddress sip = getByName(qosClassifier.getSrcIp().getValue());
142 if (sip != null && sip instanceof Inet4Address) {
143 srcAddress = (Inet4Address) sip;
146 if (qosClassifier.getDstIp() != null) {
147 final InetAddress dip = getByName(qosClassifier.getDstIp().getValue());
148 if (dip != null && dip instanceof Inet4Address) {
149 dstAddress = (Inet4Address) dip;
152 if (qosClassifier.getSrcPort() != null) {
153 srcPort = qosClassifier.getSrcPort().getValue().shortValue();
155 if (qosClassifier.getDstPort() != null) {
156 dstPort = qosClassifier.getDstPort().getValue().shortValue();
158 if (qosClassifier.getTosByte() != null) {
159 tosOverwrite = qosClassifier.getTosByte().getValue().byteValue();
160 if (qosClassifier.getTosMask() != null) {
161 tosMask = qosClassifier.getTosMask().getValue().byteValue();
163 // set default TOS mask
164 tosMask = (byte) 0xff;
167 // push the classifier to the gate request
169 new org.pcmm.gates.impl.Classifier(protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPort,
173 public void setExtClassifier(final ExtClassifier qosExtClassifier) {
174 // Extended classifier
175 final byte priority = (byte) 64;
176 final ActivationState activationState = ActivationState.ACTIVE;
177 // Protocol -- zero is match any
178 final Protocol protocol;
179 if (qosExtClassifier.getProtocol() != null) {
180 protocol = Protocol.valueOf(qosExtClassifier.getProtocol().getValue().shortValue());
182 protocol = Protocol.NONE;
185 // default source port range must be set to match any even if qosExtClassifier has no range
186 // match any port range is 0-65535, NOT 0-0
187 // TODO - try to make these two variables immutable
188 short srcStartPort = (short) 0;
189 short srcEndPort = (short) 65535;
190 if (qosExtClassifier.getSrcPortStart() != null) {
191 srcStartPort = qosExtClassifier.getSrcPortStart().getValue().shortValue();
192 srcEndPort = srcStartPort;
193 if (qosExtClassifier.getSrcPortEnd() != null) {
194 srcEndPort = qosExtClassifier.getSrcPortEnd().getValue().shortValue();
196 if (srcStartPort > srcEndPort) {
197 logger.warn("Start port %d > End port %d in ext-classifier source port range -- forcing to same",
198 srcStartPort, srcEndPort);
199 srcEndPort = srcStartPort;
202 // default destination port range must be set to match any even if qosExtClassifier has no range
203 // match any port range is 0-65535, NOT 0-0
204 // TODO - try to make these two variables immutable
205 short dstStartPort = (short) 0;
206 short dstEndPort = (short) 65535;
207 if (qosExtClassifier.getDstPortStart() != null) {
208 dstStartPort = qosExtClassifier.getDstPortStart().getValue().shortValue();
209 dstEndPort = dstStartPort;
210 if (qosExtClassifier.getDstPortEnd() != null) {
211 dstEndPort = qosExtClassifier.getDstPortEnd().getValue().shortValue();
213 if (dstStartPort > dstEndPort) {
214 logger.warn("Start port %d > End port %d in ext-classifier destination port range -- forcing to same",
215 dstStartPort, dstEndPort);
216 dstEndPort = dstStartPort;
221 // TODO - try to make these two variables immutable
222 byte tosOverwrite = 0;
223 byte tosMask = (byte)0x00;
224 if (qosExtClassifier.getTosByte() != null) {
225 // OR in the DSCP/TOS enable bit 0x01
226 tosOverwrite = (byte) (qosExtClassifier.getTosByte().getValue().byteValue() | 0x01);
227 if (qosExtClassifier.getTosMask() != null) {
228 tosMask = qosExtClassifier.getTosMask().getValue().byteValue();
230 // set default TOS mask
231 tosMask = (byte) 0xff;
235 // TODO - find out what the classifier ID should really be. It was never getting set previously
236 final short classifierId = (short)0;
238 // TODO - find out what the action value should really be. It was never getting set previously
239 final byte action = (byte)0;
241 // push the extended classifier to the gate request
242 classifier = new org.pcmm.gates.impl.ExtendedClassifier(protocol, tosOverwrite, tosMask,
243 getInet4Address(qosExtClassifier.getSrcIp()), getInet4Address(qosExtClassifier.getDstIp()),
244 srcStartPort, dstStartPort, priority, getInet4Address(qosExtClassifier.getSrcIpMask()),
245 getInet4Address(qosExtClassifier.getDstIpMask()), srcEndPort, dstEndPort, classifierId, activationState,
249 private Inet4Address getInet4Address(
250 final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address address) {
251 if (address != null) {
252 final InetAddress out = getByName(address.getValue());
253 if (out != null && out instanceof Inet4Address) {
254 return (Inet4Address) out;
260 public void setIpv6Classifier(final Ipv6Classifier qosIpv6Classifier) {
263 if (qosIpv6Classifier.getNextHdr() != null) {
264 nextHdr = qosIpv6Classifier.getNextHdr().getValue().shortValue();
266 // default: match any nextHdr is 256 because nextHdr 0 is Hop-by-Hop option
268 nextHdr = (short) 256;
271 // Source IPv6 address & prefix len
272 // TODO - try to make these two variables immutable
273 byte srcPrefixLen = (byte) 128;
274 Inet6Address srcAddress = null;
275 if (qosIpv6Classifier.getSrcIp6() != null) {
276 String[] parts = qosIpv6Classifier.getSrcIp6().getValue().split("/");
277 String Ipv6AddressStr = parts[0];
278 srcAddress = (Inet6Address) getByName(Ipv6AddressStr);
279 if (parts.length > 1) {
280 srcPrefixLen = (byte) Integer.parseInt(parts[1]);
282 srcPrefixLen = (byte) 128;
287 // TODO - try to make these two variables immutable
288 Inet6Address dstAddress = null;
289 byte dstPrefLen = (byte) 128;
290 // Destination IPv6 address & prefix len
291 if (qosIpv6Classifier.getDstIp6() != null) {
292 final String[] parts = qosIpv6Classifier.getDstIp6().getValue().split("/");
293 final String Ipv6AddressStr = parts[0];
294 dstAddress = (Inet6Address)getByName(Ipv6AddressStr);
295 if (parts.length > 1) dstPrefLen = (byte) Integer.parseInt(parts[1]);
296 else dstPrefLen = (byte) 128;
299 // default source port range must be set to match any -- even if qosExtClassifier has no range value
300 // match any port range is 0-65535, NOT 0-0
301 short srcPortBegin = (short) 0;
302 short srcPortEnd = (short) 65535;
303 if (qosIpv6Classifier.getSrcPortStart() != null) {
304 srcPortBegin = qosIpv6Classifier.getSrcPortStart().getValue().shortValue();
305 srcPortEnd = srcPortBegin;
306 if (qosIpv6Classifier.getSrcPortEnd() != null) {
307 srcPortEnd = qosIpv6Classifier.getSrcPortEnd().getValue().shortValue();
309 if (srcPortBegin > srcPortEnd) {
310 logger.warn("Start port %d > End port %d in ipv6-classifier source port range -- forcing to same",
311 srcPortBegin, srcPortEnd);
312 srcPortEnd = srcPortBegin;
316 // default destination port range must be set to match any -- even if qosExtClassifier has no range value
317 // match any port range is 0-65535, NOT 0-0
318 short dstPortBegin = (short) 0;
319 short dstPortEnd = (short) 65535;
320 if (qosIpv6Classifier.getDstPortStart() != null) {
321 dstPortBegin = qosIpv6Classifier.getDstPortStart().getValue().shortValue();
322 dstPortEnd = dstPortBegin;
323 if (qosIpv6Classifier.getDstPortEnd() != null) {
324 dstPortEnd = qosIpv6Classifier.getDstPortEnd().getValue().shortValue();
326 if (dstPortBegin > dstPortEnd) {
327 logger.warn("Start port %d > End port %d in ipv6-classifier destination port range -- forcing to same",
328 dstPortBegin, dstPortEnd);
329 dstPortEnd = dstPortBegin;
334 if (qosIpv6Classifier.getTcLow() != null)
335 tcLow = qosIpv6Classifier.getTcLow().getValue().byteValue();
336 else tcLow = (byte) 0x00;
339 if (qosIpv6Classifier.getTcHigh() != null)
340 tcHigh = qosIpv6Classifier.getTcHigh().getValue().byteValue();
341 else tcHigh = (byte) 0x00;
344 if (qosIpv6Classifier.getTcHigh() != null)
345 tcMask = qosIpv6Classifier.getTcHigh().getValue().byteValue();
346 else if (qosIpv6Classifier.getTcLow() != null) tcMask = (byte) 0xff;
347 else tcMask = (byte) 0x00;
349 // TODO - find out what the classifier ID should really be. It was never getting set previously
350 final short classifierId = (short)0;
352 // TODO - find out what the action value should really be. It was never getting set previously
353 final byte action = (byte)0;
355 // push the IPv6 classifier to the gate request
356 classifier = new org.pcmm.gates.impl.IPv6Classifier(srcAddress, dstAddress, srcPortBegin, dstPortBegin,
357 (byte) 64, srcPortEnd, dstPortEnd, classifierId, ActivationState.ACTIVE, action, FlowLabel.VALID, tcLow,
358 tcHigh, tcMask, qosIpv6Classifier.getFlowLabel().intValue(), nextHdr, srcPrefixLen, dstPrefLen);