94a268d50792f069c2e99d36ea20d173da8c6677
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / gates / impl / PCMMGateReq.java
1 /*
2  * Copyright (c) 2015 Cable Television Laboratories, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.pcmm.gates.impl;
10
11 import com.google.common.collect.Lists;
12 import com.google.common.primitives.Bytes;
13 import java.util.Collections;
14 import org.pcmm.base.impl.PCMMBaseObject.SNum;
15 import org.pcmm.gates.IAMID;
16 import org.pcmm.gates.IClassifier;
17 import org.pcmm.gates.ISubscriberID;
18 import org.pcmm.gates.ITransactionID;
19 import org.pcmm.gates.IGateSpec;
20 import org.pcmm.gates.IGateTimeInfo;
21 import org.pcmm.gates.ITrafficProfile;
22 import org.pcmm.gates.IPCMMError;
23 import org.pcmm.gates.IPCMMGate;
24 import org.pcmm.gates.IGateID;
25 import org.pcmm.gates.IExtendedClassifier;
26 import org.pcmm.gates.IIPv6Classifier;
27 import org.pcmm.gates.IGateState;
28 import org.pcmm.gates.IGateUsageInfo;
29 import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile;
30 import org.pcmm.gates.impl.DOCSISFlowSpecTrafficProfile;
31 import org.pcmm.gates.impl.BestEffortService;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.List;
38
39 /**
40  * {@code
41  * <Gate-set>=<Decision Header><TransactionID><AMID> <SubscriberID> [<GateI>]
42  * <GateSpec> <Traffic Profile> <classifier>[<classifier>...]
43  * }
44  *
45  */
46 public class PCMMGateReq implements IPCMMGate {
47
48     public static final Logger logger = LoggerFactory.getLogger(PCMMGateReq.class);
49
50     // Immutable references
51     private final boolean multicast;
52     private final IAMID iamid;
53     private final ISubscriberID subscriberID;
54     private transient ITransactionID transactionID;
55     private transient IGateSpec gateSpec;
56     private transient ITrafficProfile trafficProfile;
57     private transient List<IClassifier> classifiers;
58
59     // These values are transient as objects of these type will be updated asynchronously and will be used for
60     // synchronization purposes
61     private IGateID gateID;
62     private IPCMMError error;
63     private IGateState igateState;
64     private IGateTimeInfo gateTimeInfo;
65     private IGateUsageInfo gateUsageInfo;
66
67     /**
68      * Constructor
69      * @param iamid - the Application Manager ID
70      * @param subscriberID - the Subscriber ID
71      * @param transactionID - the transaction ID
72      * @param gateSpec - the Gate specification
73      * @param trafficProfile - the traffic profile
74      * @param classifiers - the classifier
75      * @param gateID - the gate ID
76      * @param error - the error
77      */
78     public PCMMGateReq(IAMID iamid, ISubscriberID subscriberID, ITransactionID transactionID,
79                        IGateSpec gateSpec, ITrafficProfile trafficProfile, List<IClassifier> classifiers,
80                        IGateID gateID,IPCMMError error,IGateState igateState,
81                        IGateTimeInfo gateTimeInfo,IGateUsageInfo gateUsageInfo ) {
82         // TODO - determine if and when this attribute should be used
83         this.multicast = false;
84
85         this.iamid = iamid;
86         this.subscriberID = subscriberID;
87         this.transactionID = transactionID;
88         this.gateSpec = gateSpec;
89         this.trafficProfile = trafficProfile;
90         this.classifiers = Lists.newArrayList(classifiers);
91         this.gateID = gateID;
92         this.error = error;
93         this.igateState = igateState;
94         this.gateTimeInfo = gateTimeInfo;
95         this.gateUsageInfo = gateUsageInfo;
96     }
97
98     /**
99      * Creates a PCMM Gate Request object from parsing a byte array
100      * @param data - the data to parse
101      * @return - the request
102      */
103     public static PCMMGateReq parse(byte[] data) {
104         GateID gateID = null;
105         AMID amid = null;
106         SubscriberID subscriberID = null;
107         TransactionID transactionID = null;
108         GateSpec gateSpec = null;
109         ITrafficProfile trafficProfile = null;
110         List<IClassifier> classifiers = Lists.newArrayListWithExpectedSize(4);
111         PCMMError error = null;
112         GateState gateState = null;
113         GateTimeInfo gateTimeInfo = null;
114         GateUsageInfo gateUsageInfo = null;
115
116
117         short offset = 0;
118         while (offset + 5 < data.length) {
119             short len = 0;
120             len |= ((short) data[offset]) << 8;
121             len |= ((short) data[offset + 1]) & 0xFF;
122             final SNum sNum = SNum.valueOf(data[offset + 2]);
123             final byte sType = data[offset + 3];
124             final int dataIndx = offset + 4;
125             byte[] dataBuffer = Arrays.copyOfRange(data, dataIndx, dataIndx + len - 4);
126             switch (sNum) {
127             case GATE_ID:
128                 gateID = GateID.parse(dataBuffer);
129                 break;
130             case AMID:
131                 amid = AMID.parse(dataBuffer);
132                 break;
133             case SUBSCRIBER_ID:
134                 subscriberID = SubscriberID.parse(dataBuffer);
135                 break;
136             case TRANSACTION_ID:
137                 transactionID = TransactionID.parse(dataBuffer);
138                 break;
139             case GATE_SPEC:
140                 gateSpec = GateSpec.parse(dataBuffer);
141                 break;
142             case TRAFFIC_PROFILE:
143                 switch (sType) {
144                 case DOCSISServiceClassNameTrafficProfile.STYPE:
145                     trafficProfile = DOCSISServiceClassNameTrafficProfile.parse(dataBuffer);
146                     break;
147                 case DOCSISFlowSpecTrafficProfile.STYPE:
148                     trafficProfile = DOCSISFlowSpecTrafficProfile.parse(dataBuffer);
149                     break;
150                 case BestEffortService.STYPE:
151                     trafficProfile = BestEffortService.parse(dataBuffer);
152                     break;
153                 }
154                 break;
155             case CLASSIFIERS:
156                 switch (sType) {
157                 case IClassifier.STYPE:
158                     classifiers.add(Classifier.parse(dataBuffer));
159                     break;
160                 case IExtendedClassifier.STYPE:
161                     classifiers.add(ExtendedClassifier.parse(dataBuffer));
162                     break;
163                 case IIPv6Classifier.STYPE:
164                     classifiers.add(IPv6Classifier.parse(dataBuffer));
165                     break;
166                 }
167                 break;
168             case PCMM_ERROR:
169                 error = PCMMError.parse(dataBuffer);
170                 break;
171                 //adding GATE_STATE
172             case GATE_STATE:
173                 gateState = GateState.parse(dataBuffer);
174                 break;
175                 //adding GATE_TIME_INFO
176             case GATE_TIME_INFO:
177                 gateTimeInfo = GateTimeInfo.parse(dataBuffer);
178                 logger.info("Gate Time Info: "+gateTimeInfo);
179                 break;
180                 //adding GATE_USAGE_INFO
181             case GATE_USAGE_INFO:
182                 gateUsageInfo = GateUsageInfo.parse(dataBuffer);
183                 logger.info("Gate Usage Info: "+gateUsageInfo);
184                 break;
185             default:
186                 logger.warn("Unhandled Object skept : S-NUM=" + sNum
187                             + "  S-TYPE=" + sType + "  LEN=" + len);
188             }
189             offset += len;
190         }
191
192         return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile,
193                         classifiers, gateID, error, gateState, gateTimeInfo,gateUsageInfo);
194     }
195
196     @Override
197     public boolean isMulticast() {
198         // TODO Auto-generated method stub
199         return multicast;
200     }
201
202     @Override
203     public void setGateID(IGateID gateid) {
204         this.gateID = gateid;
205
206     }
207
208     @Override
209     public void setGateState(IGateState gatestate) {
210         this.igateState = gatestate;
211     }
212
213     @Override
214     public void setTransactionID(ITransactionID transactionID) {
215         this.transactionID = transactionID;
216
217     }
218
219     @Override
220     public void setGateSpec(IGateSpec gateSpec) {
221         this.gateSpec = gateSpec;
222     }
223
224     @Override
225     public void setClassifiers(List<IClassifier> classifiers) {
226         if (classifiers == null) {
227             this.classifiers = null;
228         }
229         else {
230             this.classifiers = new ArrayList<>(classifiers);
231         }
232     }
233
234     @Override
235     public void setTrafficProfile(ITrafficProfile profile) {
236         this.trafficProfile = profile;
237     }
238
239     @Override
240     public void setGateTimeInfo(IGateTimeInfo gateTimeInfo) {
241         this.gateTimeInfo = gateTimeInfo;
242     }
243
244     @Override
245     public void setGateUsageInfo(IGateUsageInfo gateUsageInfo) {
246         this.gateUsageInfo = gateUsageInfo;
247     }
248
249
250     @Override
251     public IGateID getGateID() {
252         return gateID;
253     }
254
255    @Override
256    public IGateState getGateState() {
257         return igateState;
258    }
259
260
261     @Override
262     public IAMID getAMID() {
263         return iamid;
264     }
265
266     @Override
267     public ISubscriberID getSubscriberID() {
268         return subscriberID;
269     }
270
271     @Override
272     public IGateSpec getGateSpec() {
273         return gateSpec;
274     }
275
276     @Override
277     public List<IClassifier> getClassifiers() {
278         if (classifiers == null) {
279             return null;
280         }
281         return Collections.unmodifiableList(classifiers);
282     }
283
284     @Override
285     public ITrafficProfile getTrafficProfile() {
286         return trafficProfile;
287     }
288
289     @Override
290     public ITransactionID getTransactionID() {
291         return transactionID;
292     }
293
294     public IPCMMError getError() {
295         return error;
296     }
297
298     @Override
299     public IGateTimeInfo getGateTimeInfo() {
300          return gateTimeInfo;
301     }
302
303     @Override
304     public IGateUsageInfo getGateUsageInfo() {
305          return gateUsageInfo;
306     }
307
308     public void setError(IPCMMError error) {
309         this.error = error;
310     }
311
312     @Override
313     public byte[] getData() {
314         final List<Byte> byteList = new ArrayList<>();
315         if (getTransactionID() != null) {
316             byteList.addAll(Bytes.asList(getTransactionID().getAsBinaryArray()));
317         }
318         if (getGateID() != null) {
319             byteList.addAll(Bytes.asList(getGateID().getAsBinaryArray()));
320         }
321         if (getAMID() != null) {
322             byteList.addAll(Bytes.asList(getAMID().getAsBinaryArray()));
323         }
324         if (getSubscriberID() != null) {
325             byteList.addAll(Bytes.asList(getSubscriberID().getAsBinaryArray()));
326         }
327         if (getGateSpec() != null) {
328             byteList.addAll(Bytes.asList(getGateSpec().getAsBinaryArray()));
329         }
330         if (getTrafficProfile() != null) {
331             byteList.addAll(Bytes.asList(getTrafficProfile().getAsBinaryArray()));
332         }
333         if (getClassifiers() != null) {
334             for (IClassifier classifier : getClassifiers()) {
335                 byteList.addAll(Bytes.asList(classifier.getAsBinaryArray()));
336             }
337         }
338         if (getGateState() != null) {
339             byteList.addAll(Bytes.asList(getGateState().getAsBinaryArray()));
340         }
341         if (getGateTimeInfo() != null) {
342             byteList.addAll(Bytes.asList(getGateTimeInfo().getAsBinaryArray()));
343         }
344         if (getGateUsageInfo() != null) {
345             byteList.addAll(Bytes.asList(getGateUsageInfo().getAsBinaryArray()));
346         }
347         return Bytes.toArray(byteList);
348     }
349
350 /*
351     private byte[] fill(byte[] array, IPCMMBaseObject obj) {
352         byte[] a = obj.getAsBinaryArray();
353         int offset = array.length;
354         array = Arrays.copyOf(array, offset + a.length);
355         System.arraycopy(a, 0, array, offset, a.length);
356         return array;
357     }
358 */
359 }