2 * Copyright (c) 2015 Cable Television Laboratories, Inc. 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.pcmm.gates.impl;
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;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
25 * <Gate-set>=<Decision Header><TransactionID><AMID> <SubscriberID> [<GateI>]
26 * <GateSpec> <Traffic Profile> <classifier>[<classifier>...]
30 public class PCMMGateReq implements IPCMMGate {
32 public static final Logger logger = LoggerFactory.getLogger(PCMMGateReq.class);
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;
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;
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
59 public PCMMGateReq(IAMID iamid, ISubscriberID subscriberID, ITransactionID transactionID,
60 IGateSpec gateSpec, ITrafficProfile trafficProfile, List<IClassifier> classifiers, IGateID gateID,
62 // TODO - determine if and when this attribute should be used
63 this.multicast = false;
66 this.subscriberID = subscriberID;
67 this.transactionID = transactionID;
68 this.gateSpec = gateSpec;
69 this.trafficProfile = trafficProfile;
70 this.classifiers = Lists.newArrayList(classifiers);
76 * Creates a PCMM Gate Request object from parsing a byte array
77 * @param data - the data to parse
78 * @return - the request
80 public static PCMMGateReq parse(byte[] data) {
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;
91 while (offset + 5 < data.length) {
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);
101 gateID = GateID.parse(dataBuffer);
104 amid = AMID.parse(dataBuffer);
107 subscriberID = SubscriberID.parse(dataBuffer);
110 transactionID = TransactionID.parse(dataBuffer);
113 gateSpec = GateSpec.parse(dataBuffer);
115 case TRAFFIC_PROFILE:
117 case DOCSISServiceClassNameTrafficProfile.STYPE:
118 trafficProfile = DOCSISServiceClassNameTrafficProfile.parse(dataBuffer);
120 case BestEffortService.STYPE:
121 trafficProfile = BestEffortService.parse(dataBuffer);
127 case IClassifier.STYPE:
128 classifiers.add(Classifier.parse(dataBuffer));
130 case IExtendedClassifier.STYPE:
131 classifiers.add(ExtendedClassifier.parse(dataBuffer));
133 case IIPv6Classifier.STYPE:
134 classifiers.add(IPv6Classifier.parse(dataBuffer));
139 error = PCMMError.parse(dataBuffer);
142 logger.warn("Unhandled Object skept : S-NUM=" + sNum
143 + " S-TYPE=" + sType + " LEN=" + len);
148 return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile, classifiers, gateID, error);
152 public boolean isMulticast() {
153 // TODO Auto-generated method stub
158 public void setGateID(IGateID gateid) {
159 this.gateID = gateid;
164 public void setTransactionID(ITransactionID transactionID) {
165 this.transactionID = transactionID;
170 public void setGateSpec(IGateSpec gateSpec) {
171 this.gateSpec = gateSpec;
175 public void setClassifiers(List<IClassifier> classifiers) {
176 if (classifiers == null) {
177 this.classifiers = null;
180 this.classifiers = new ArrayList<>(classifiers);
185 public void setTrafficProfile(ITrafficProfile profile) {
186 this.trafficProfile = profile;
190 public IGateID getGateID() {
195 public IAMID getAMID() {
200 public ISubscriberID getSubscriberID() {
205 public IGateSpec getGateSpec() {
210 public List<IClassifier> getClassifiers() {
211 if (classifiers == null) {
214 return Collections.unmodifiableList(classifiers);
218 public ITrafficProfile getTrafficProfile() {
219 return trafficProfile;
223 public ITransactionID getTransactionID() {
224 return transactionID;
227 public IPCMMError getError() {
231 public void setError(IPCMMError error) {
236 public byte[] getData() {
237 final List<Byte> byteList = new ArrayList<>();
238 if (getTransactionID() != null) {
239 byteList.addAll(Bytes.asList(getTransactionID().getAsBinaryArray()));
241 if (getGateID() != null) {
242 byteList.addAll(Bytes.asList(getGateID().getAsBinaryArray()));
244 if (getAMID() != null) {
245 byteList.addAll(Bytes.asList(getAMID().getAsBinaryArray()));
247 if (getSubscriberID() != null) {
248 byteList.addAll(Bytes.asList(getSubscriberID().getAsBinaryArray()));
250 if (getGateSpec() != null) {
251 byteList.addAll(Bytes.asList(getGateSpec().getAsBinaryArray()));
253 if (getTrafficProfile() != null) {
254 byteList.addAll(Bytes.asList(getTrafficProfile().getAsBinaryArray()));
256 if (getClassifiers() != null) {
257 for (IClassifier classifier : getClassifiers()) {
258 byteList.addAll(Bytes.asList(classifier.getAsBinaryArray()));
261 return Bytes.toArray(byteList);
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);