Add missing license headers to packetcable-driver gates
[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.*;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22
23 /**
24  * {@code
25  * <Gate-set>=<Decision Header><TransactionID><AMID> <SubscriberID> [<GateI>]
26  * <GateSpec> <Traffic Profile> <classifier>[<classifier>...]
27  * }
28  *
29  */
30 public class PCMMGateReq implements IPCMMGate {
31
32     public static final Logger logger = LoggerFactory.getLogger(PCMMGateReq.class);
33
34     // Immutable references
35     private final boolean multicast;
36     private final IAMID iamid;
37     private final ISubscriberID subscriberID;
38     private transient ITransactionID transactionID;
39     private transient IGateSpec gateSpec;
40     private transient ITrafficProfile trafficProfile;
41     private transient List<IClassifier> classifiers;
42
43     // These values are transient as objects of these type will be updated asynchronously and will be used for
44     // synchronization purposes
45     private IGateID gateID;
46     private IPCMMError error;
47
48     /**
49      * Constructor
50      * @param iamid - the Application Manager ID
51      * @param subscriberID - the Subscriber ID
52      * @param transactionID - the transaction ID
53      * @param gateSpec - the Gate specification
54      * @param trafficProfile - the traffic profile
55      * @param classifiers - the classifier
56      * @param gateID - the gate ID
57      * @param error - the error
58      */
59     public PCMMGateReq(IAMID iamid, ISubscriberID subscriberID, ITransactionID transactionID,
60                        IGateSpec gateSpec, ITrafficProfile trafficProfile, List<IClassifier> classifiers, IGateID gateID,
61                        IPCMMError error) {
62         // TODO - determine if and when this attribute should be used
63         this.multicast = false;
64
65         this.iamid = iamid;
66         this.subscriberID = subscriberID;
67         this.transactionID = transactionID;
68         this.gateSpec = gateSpec;
69         this.trafficProfile = trafficProfile;
70         this.classifiers = Lists.newArrayList(classifiers);
71         this.gateID = gateID;
72         this.error = error;
73     }
74
75     /**
76      * Creates a PCMM Gate Request object from parsing a byte array
77      * @param data - the data to parse
78      * @return - the request
79      */
80     public static PCMMGateReq parse(byte[] data) {
81         GateID gateID = null;
82         AMID amid = null;
83         SubscriberID subscriberID = null;
84         TransactionID transactionID = null;
85         GateSpec gateSpec = null;
86         ITrafficProfile trafficProfile = null;
87         List<IClassifier> classifiers = Lists.newArrayListWithExpectedSize(4);
88         PCMMError error = null;
89
90         short offset = 0;
91         while (offset + 5 < data.length) {
92             short len = 0;
93             len |= ((short) data[offset]) << 8;
94             len |= ((short) data[offset + 1]) & 0xFF;
95             final SNum sNum = SNum.valueOf(data[offset + 2]);
96             final byte sType = data[offset + 3];
97             final int dataIndx = offset + 4;
98             byte[] dataBuffer = Arrays.copyOfRange(data, dataIndx, dataIndx + len - 4);
99             switch (sNum) {
100                 case GATE_ID:
101                     gateID = GateID.parse(dataBuffer);
102                     break;
103                 case AMID:
104                     amid = AMID.parse(dataBuffer);
105                     break;
106                 case SUBSCRIBER_ID:
107                     subscriberID = SubscriberID.parse(dataBuffer);
108                     break;
109                 case TRANSACTION_ID:
110                     transactionID = TransactionID.parse(dataBuffer);
111                     break;
112                 case GATE_SPEC:
113                     gateSpec = GateSpec.parse(dataBuffer);
114                     break;
115                 case TRAFFIC_PROFILE:
116                     switch (sType) {
117                         case DOCSISServiceClassNameTrafficProfile.STYPE:
118                             trafficProfile = DOCSISServiceClassNameTrafficProfile.parse(dataBuffer);
119                             break;
120                         case BestEffortService.STYPE:
121                             trafficProfile = BestEffortService.parse(dataBuffer);
122                             break;
123                     }
124                     break;
125                 case CLASSIFIERS:
126                     switch (sType) {
127                         case IClassifier.STYPE:
128                             classifiers.add(Classifier.parse(dataBuffer));
129                             break;
130                         case IExtendedClassifier.STYPE:
131                             classifiers.add(ExtendedClassifier.parse(dataBuffer));
132                             break;
133                         case IIPv6Classifier.STYPE:
134                             classifiers.add(IPv6Classifier.parse(dataBuffer));
135                             break;
136                     }
137                     break;
138                 case PCMM_ERROR:
139                     error = PCMMError.parse(dataBuffer);
140                     break;
141             default:
142                 logger.warn("Unhandled Object skept : S-NUM=" + sNum
143                                    + "  S-TYPE=" + sType + "  LEN=" + len);
144             }
145             offset += len;
146         }
147
148         return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile, classifiers, gateID, error);
149     }
150
151     @Override
152     public boolean isMulticast() {
153         // TODO Auto-generated method stub
154         return multicast;
155     }
156
157     @Override
158     public void setGateID(IGateID gateid) {
159         this.gateID = gateid;
160
161     }
162
163     @Override
164     public void setTransactionID(ITransactionID transactionID) {
165         this.transactionID = transactionID;
166
167     }
168
169     @Override
170     public void setGateSpec(IGateSpec gateSpec) {
171         this.gateSpec = gateSpec;
172     }
173
174     @Override
175     public void setClassifiers(List<IClassifier> classifiers) {
176         if (classifiers == null) {
177             this.classifiers = null;
178         }
179         else {
180             this.classifiers = new ArrayList<>(classifiers);
181         }
182     }
183
184     @Override
185     public void setTrafficProfile(ITrafficProfile profile) {
186         this.trafficProfile = profile;
187     }
188
189     @Override
190     public IGateID getGateID() {
191         return gateID;
192     }
193
194     @Override
195     public IAMID getAMID() {
196         return iamid;
197     }
198
199     @Override
200     public ISubscriberID getSubscriberID() {
201         return subscriberID;
202     }
203
204     @Override
205     public IGateSpec getGateSpec() {
206         return gateSpec;
207     }
208
209     @Override
210     public List<IClassifier> getClassifiers() {
211         if (classifiers == null) {
212             return null;
213         }
214         return Collections.unmodifiableList(classifiers);
215     }
216
217     @Override
218     public ITrafficProfile getTrafficProfile() {
219         return trafficProfile;
220     }
221
222     @Override
223     public ITransactionID getTransactionID() {
224         return transactionID;
225     }
226
227     public IPCMMError getError() {
228         return error;
229     }
230
231     public void setError(IPCMMError error) {
232         this.error = error;
233     }
234
235     @Override
236     public byte[] getData() {
237         final List<Byte> byteList = new ArrayList<>();
238         if (getTransactionID() != null) {
239             byteList.addAll(Bytes.asList(getTransactionID().getAsBinaryArray()));
240         }
241         if (getGateID() != null) {
242             byteList.addAll(Bytes.asList(getGateID().getAsBinaryArray()));
243         }
244         if (getAMID() != null) {
245             byteList.addAll(Bytes.asList(getAMID().getAsBinaryArray()));
246         }
247         if (getSubscriberID() != null) {
248             byteList.addAll(Bytes.asList(getSubscriberID().getAsBinaryArray()));
249         }
250         if (getGateSpec() != null) {
251             byteList.addAll(Bytes.asList(getGateSpec().getAsBinaryArray()));
252         }
253         if (getTrafficProfile() != null) {
254             byteList.addAll(Bytes.asList(getTrafficProfile().getAsBinaryArray()));
255         }
256         if (getClassifiers() != null) {
257             for (IClassifier classifier : getClassifiers()) {
258                 byteList.addAll(Bytes.asList(classifier.getAsBinaryArray()));
259             }
260         }
261         return Bytes.toArray(byteList);
262     }
263
264 /*
265     private byte[] fill(byte[] array, IPCMMBaseObject obj) {
266         byte[] a = obj.getAsBinaryArray();
267         int offset = array.length;
268         array = Arrays.copyOf(array, offset + a.length);
269         System.arraycopy(a, 0, array, offset, a.length);
270         return array;
271     }
272 */
273 }