Merge "Removed original Hydrogen demo from repo."
[packetcable.git] / packetcable-policy-server / src / main / java / org / opendaylight / controller / packetcable / provider / PCMMGateReqBuilder.java
1 /**
2  * Build PCMM gate requests from API QoS Gate objects
3  */
4 package org.opendaylight.controller.packetcable.provider;
5
6 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.ServiceFlowDirection;
7 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.TosByte;
8 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.ccap.attributes.AmId;
9 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.classifier.Classifier;
10 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.ext.classifier.ExtClassifier;
11 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.gate.spec.GateSpec;
12 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.ipv6.classifier.Ipv6Classifier;
13 import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.traffic.profile.TrafficProfile;
14 import org.pcmm.gates.IClassifier;
15 import org.pcmm.gates.IClassifier.Protocol;
16 import org.pcmm.gates.IExtendedClassifier.ActivationState;
17 import org.pcmm.gates.IGateSpec.Direction;
18 import org.pcmm.gates.IIPv6Classifier.FlowLabel;
19 import org.pcmm.gates.ITrafficProfile;
20 import org.pcmm.gates.impl.*;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 import java.net.Inet4Address;
25 import java.net.Inet6Address;
26 import java.net.InetAddress;
27 import java.net.UnknownHostException;
28
29 /**
30  * PacketCable data processor
31  */
32 public class PCMMGateReqBuilder {
33
34     private Logger logger = LoggerFactory.getLogger(PCMMGateReqBuilder.class);
35
36     private GateID gateID = null;
37     private AMID amid = null;
38     private SubscriberID subscriberID = null;
39     private TransactionID transactionID = null;
40     private org.pcmm.gates.impl.GateSpec gateSpec = null;
41     private ITrafficProfile trafficProfile = null;
42     private IClassifier classifier = null;
43     private PCMMError error = null;
44
45     public PCMMGateReq getGateReq() {
46         return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile, classifier, gateID, error);
47     }
48
49     public void build(final AmId qosAmId) {
50         amid = new AMID(qosAmId.getAmType().shortValue(), qosAmId.getAmTag().shortValue());
51     }
52
53     public void build(final InetAddress qosSubId) {
54         subscriberID = new SubscriberID(qosSubId);
55     }
56
57     public void build(final GateSpec qosGateSpec, final ServiceFlowDirection scnDirection) {
58
59         final ServiceFlowDirection qosDir;
60         if (scnDirection != null) {
61             qosDir = scnDirection;
62         } else {
63             if (qosGateSpec.getDirection() != null) {
64                 qosDir = qosGateSpec.getDirection();
65             } else {
66                 // TODO - determine if this is a valid default value
67                 qosDir = ServiceFlowDirection.Ds;
68             }
69         }
70
71         final Direction gateDir;
72         if (qosDir == ServiceFlowDirection.Ds) {
73             gateDir = Direction.DOWNSTREAM;
74         } else {
75             gateDir = Direction.UPSTREAM;
76         }
77
78         // DSCP/TOS Overwrite
79         final byte dscptos;
80         final byte gateTosMask;
81
82         final TosByte tosOverwrite = qosGateSpec.getDscpTosOverwrite();
83         if (tosOverwrite != null) {
84             dscptos = 1;
85             TosByte tosMask = qosGateSpec.getDscpTosMask();
86             if (tosMask != null) {
87                 gateTosMask = tosMask.getValue().byteValue();
88             } else {
89                 gateTosMask = (byte) 0xff;
90             }
91         } else {
92             // TODO - These values appear to be required
93             dscptos = 0;
94             gateTosMask = 0;
95         }
96         gateSpec = new org.pcmm.gates.impl.GateSpec(gateDir, dscptos, gateTosMask);
97     }
98
99     public void build(final TrafficProfile qosTrafficProfile) {
100         if (qosTrafficProfile.getServiceClassName() != null) {
101             trafficProfile =
102                     new DOCSISServiceClassNameTrafficProfile(qosTrafficProfile.getServiceClassName().getValue());
103         }
104     }
105
106     private InetAddress getByName(final String ipAddressStr) {
107         try {
108             return InetAddress.getByName(ipAddressStr);
109         } catch (UnknownHostException e) {
110             logger.error(e.getMessage());
111         }
112         return null;
113     }
114
115     public void build(final Classifier qosClassifier) {
116         // TODO - try and make these variables immutable
117         Protocol protocol = null;
118         byte tosOverwrite = 0;
119         byte tosMask = (byte)0x0;
120         Inet4Address srcAddress = null;
121         Inet4Address dstAddress = null;
122         short srcPort = (short) 0;
123         short dstPort = (short) 0;
124         byte priority = (byte) 64;
125
126         // Legacy classifier
127         if (qosClassifier.getProtocol() != null) {
128             protocol = Protocol.valueOf(qosClassifier.getProtocol().getValue().shortValue());
129         }
130         if (qosClassifier.getSrcIp() != null) {
131             final InetAddress sip = getByName(qosClassifier.getSrcIp().getValue());
132             if (sip != null && sip instanceof Inet4Address) {
133                 srcAddress = (Inet4Address) sip;
134             }
135         }
136         if (qosClassifier.getDstIp() != null) {
137             final InetAddress dip = getByName(qosClassifier.getDstIp().getValue());
138             if (dip != null && dip instanceof Inet4Address) {
139                 dstAddress = (Inet4Address) dip;
140             }
141         }
142         if (qosClassifier.getSrcPort() != null) {
143             srcPort = qosClassifier.getSrcPort().getValue().shortValue();
144         }
145         if (qosClassifier.getDstPort() != null) {
146             dstPort = qosClassifier.getDstPort().getValue().shortValue();
147         }
148         if (qosClassifier.getTosByte() != null) {
149             tosOverwrite = qosClassifier.getTosByte().getValue().byteValue();
150             if (qosClassifier.getTosMask() != null) {
151                 tosMask = qosClassifier.getTosMask().getValue().byteValue();
152             } else {
153                 // set default TOS mask
154                 tosMask = (byte) 0xff;
155             }
156         }
157         // push the classifier to the gate request
158         classifier =
159                 new org.pcmm.gates.impl.Classifier(protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPort,
160                         dstPort, priority);
161     }
162
163     public void build(final ExtClassifier qosExtClassifier) {
164         // Extended classifier
165         final byte priority = (byte) 64;
166         final ActivationState activationState = ActivationState.ACTIVE;
167         // Protocol -- zero is match any
168         final Protocol protocol;
169         if (qosExtClassifier.getProtocol() != null) {
170             protocol = Protocol.valueOf(qosExtClassifier.getProtocol().getValue().shortValue());
171         } else {
172             protocol = Protocol.NONE;
173         }
174
175         // default source port range must be set to match any even if qosExtClassifier has no range
176         // match any port range is 0-65535, NOT 0-0
177         // TODO - try to make these two variables immutable
178         short srcStartPort = (short) 0;
179         short srcEndPort = (short) 65535;
180         if (qosExtClassifier.getSrcPortStart() != null) {
181             srcStartPort = qosExtClassifier.getSrcPortStart().getValue().shortValue();
182             srcEndPort = srcStartPort;
183             if (qosExtClassifier.getSrcPortEnd() != null) {
184                 srcEndPort = qosExtClassifier.getSrcPortEnd().getValue().shortValue();
185             }
186             if (srcStartPort > srcEndPort) {
187                 logger.warn("Start port %d > End port %d in ext-classifier source port range -- forcing to same",
188                         srcStartPort, srcEndPort);
189                 srcEndPort = srcStartPort;
190             }
191         }
192         // default destination port range must be set to match any even if qosExtClassifier has no range
193         // match any port range is 0-65535, NOT 0-0
194         // TODO - try to make these two variables immutable
195         short dstStartPort = (short) 0;
196         short dstEndPort = (short) 65535;
197         if (qosExtClassifier.getDstPortStart() != null) {
198             dstStartPort = qosExtClassifier.getDstPortStart().getValue().shortValue();
199             dstEndPort = dstStartPort;
200             if (qosExtClassifier.getDstPortEnd() != null) {
201                 dstEndPort = qosExtClassifier.getDstPortEnd().getValue().shortValue();
202             }
203             if (dstStartPort > dstEndPort) {
204                 logger.warn("Start port %d > End port %d in ext-classifier destination port range -- forcing to same",
205                         dstStartPort, dstEndPort);
206                 dstEndPort = dstStartPort;
207             }
208         }
209
210         // DSCP/TOP byte
211         // TODO - try to make these two variables immutable
212         byte tosOverwrite = 0;
213         byte tosMask = (byte)0x00;
214         if (qosExtClassifier.getTosByte() != null) {
215             // OR in the DSCP/TOS enable bit 0x01
216             tosOverwrite = (byte) (qosExtClassifier.getTosByte().getValue().byteValue() | 0x01);
217             if (qosExtClassifier.getTosMask() != null) {
218                 tosMask = qosExtClassifier.getTosMask().getValue().byteValue();
219             } else {
220                 // set default TOS mask
221                 tosMask = (byte) 0xff;
222             }
223         }
224
225         // TODO - find out what the classifier ID should really be. It was never getting set previously
226         final short classifierId = (short)0;
227
228         // TODO - find out what the action value should really be. It was never getting set previously
229         final byte action = (byte)0;
230
231         // push the extended classifier to the gate request
232         classifier = new org.pcmm.gates.impl.ExtendedClassifier(protocol, tosOverwrite, tosMask,
233                 getInet4Address(qosExtClassifier.getSrcIp()), getInet4Address(qosExtClassifier.getDstIp()),
234                 srcStartPort, dstStartPort, priority, getInet4Address(qosExtClassifier.getSrcIpMask()),
235                 getInet4Address(qosExtClassifier.getDstIpMask()), srcEndPort, dstEndPort, classifierId, activationState,
236                 action);
237     }
238
239     private Inet4Address getInet4Address(
240             final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address address) {
241         if (address != null) {
242             final InetAddress out = getByName(address.getValue());
243             if (out != null && out instanceof Inet4Address) {
244                 return (Inet4Address) out;
245             }
246         }
247         return null;
248     }
249
250     public void build(final Ipv6Classifier qosIpv6Classifier) {
251         // Next Header
252         final short nextHdr;
253         if (qosIpv6Classifier.getNextHdr() != null) {
254             nextHdr = qosIpv6Classifier.getNextHdr().getValue().shortValue();
255         }
256         // default: match any nextHdr is 256 because nextHdr 0 is Hop-by-Hop option
257         else {
258             nextHdr = (short) 256;
259         }
260
261         // Source IPv6 address & prefix len
262         // TODO - try to make these two variables immutable
263         byte srcPrefixLen = (byte) 128;
264         Inet6Address srcAddress = null;
265         if (qosIpv6Classifier.getSrcIp6() != null) {
266             String[] parts = qosIpv6Classifier.getSrcIp6().getValue().split("/");
267             String Ipv6AddressStr = parts[0];
268             srcAddress = (Inet6Address) getByName(Ipv6AddressStr);
269             if (parts.length > 1) {
270                 srcPrefixLen = (byte) Integer.parseInt(parts[1]);
271             } else {
272                 srcPrefixLen = (byte) 128;
273             }
274
275         }
276
277         // TODO - try to make these two variables immutable
278         Inet6Address dstAddress = null;
279         byte dstPrefLen = (byte) 128;
280         // Destination IPv6 address & prefix len
281         if (qosIpv6Classifier.getDstIp6() != null) {
282             final String[] parts = qosIpv6Classifier.getDstIp6().getValue().split("/");
283             final String Ipv6AddressStr = parts[0];
284             dstAddress = (Inet6Address)getByName(Ipv6AddressStr);
285             if (parts.length > 1) dstPrefLen = (byte) Integer.parseInt(parts[1]);
286             else dstPrefLen = (byte) 128;
287         }
288
289         // default source port range must be set to match any -- even if qosExtClassifier has no range value
290         // match any port range is 0-65535, NOT 0-0
291         short srcPortBegin = (short) 0;
292         short srcPortEnd = (short) 65535;
293         if (qosIpv6Classifier.getSrcPortStart() != null) {
294             srcPortBegin = qosIpv6Classifier.getSrcPortStart().getValue().shortValue();
295             srcPortEnd = srcPortBegin;
296             if (qosIpv6Classifier.getSrcPortEnd() != null) {
297                 srcPortEnd = qosIpv6Classifier.getSrcPortEnd().getValue().shortValue();
298             }
299             if (srcPortBegin > srcPortEnd) {
300                 logger.warn("Start port %d > End port %d in ipv6-classifier source port range -- forcing to same",
301                         srcPortBegin, srcPortEnd);
302                 srcPortEnd = srcPortBegin;
303             }
304         }
305
306         // default destination port range must be set to match any -- even if qosExtClassifier has no range value
307         // match any port range is 0-65535, NOT 0-0
308         short dstPortBegin = (short) 0;
309         short dstPortEnd = (short) 65535;
310         if (qosIpv6Classifier.getDstPortStart() != null) {
311             dstPortBegin = qosIpv6Classifier.getDstPortStart().getValue().shortValue();
312             dstPortEnd = dstPortBegin;
313             if (qosIpv6Classifier.getDstPortEnd() != null) {
314                 dstPortEnd = qosIpv6Classifier.getDstPortEnd().getValue().shortValue();
315             }
316             if (dstPortBegin > dstPortEnd) {
317                 logger.warn("Start port %d > End port %d in ipv6-classifier destination port range -- forcing to same",
318                         dstPortBegin, dstPortEnd);
319                 dstPortEnd = dstPortBegin;
320             }
321         }
322
323         final byte tcLow;
324         if (qosIpv6Classifier.getTcLow() != null)
325             tcLow = qosIpv6Classifier.getTcLow().getValue().byteValue();
326         else tcLow = (byte) 0x00;
327
328         final byte tcHigh;
329         if (qosIpv6Classifier.getTcHigh() != null)
330             tcHigh = qosIpv6Classifier.getTcHigh().getValue().byteValue();
331         else tcHigh = (byte) 0x00;
332
333         final byte tcMask;
334         if (qosIpv6Classifier.getTcHigh() != null)
335             tcMask = qosIpv6Classifier.getTcHigh().getValue().byteValue();
336         else if (qosIpv6Classifier.getTcLow() != null) tcMask = (byte) 0xff;
337         else tcMask = (byte) 0x00;
338
339         // TODO - find out what the classifier ID should really be. It was never getting set previously
340         final short classifierId = (short)0;
341
342         // TODO - find out what the action value should really be. It was never getting set previously
343         final byte action = (byte)0;
344
345         // push the IPv6 classifier to the gate request
346         classifier = new org.pcmm.gates.impl.IPv6Classifier(srcAddress, dstAddress, srcPortBegin, dstPortBegin,
347                 (byte) 64, srcPortEnd, dstPortEnd, classifierId, ActivationState.ACTIVE, action, FlowLabel.VALID, tcLow,
348                 tcHigh, tcMask, qosIpv6Classifier.getFlowLabel().intValue(), nextHdr, srcPrefixLen, dstPrefLen);
349     }
350 }