-/**
- @header@
+/*
+ * Copyright (c) 2015 Cable Television Laboratories, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+
package org.pcmm.gates.impl;
-import org.pcmm.base.IPCMMBaseObject;
+import com.google.common.collect.Lists;
+import com.google.common.primitives.Bytes;
+import java.util.Collections;
+import org.pcmm.base.impl.PCMMBaseObject.SNum;
import org.pcmm.gates.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
/**
- * <p>
+ * {@code
* <Gate-set>=<Decision Header><TransactionID><AMID> <SubscriberID> [<GateI>]
- * <GateSpec> <Traffic Profile> <classifier>
- * </p>
+ * <GateSpec> <Traffic Profile> <classifier>[<classifier>...]
+ * }
+ *
*/
public class PCMMGateReq implements IPCMMGate {
- public final static Logger logger = LoggerFactory.getLogger(PCMMGateReq.class);
+ public static final Logger logger = LoggerFactory.getLogger(PCMMGateReq.class);
- private boolean multicast;
+ // Immutable references
+ private final boolean multicast;
+ private final IAMID iamid;
+ private final ISubscriberID subscriberID;
+ private transient ITransactionID transactionID;
+ private transient IGateSpec gateSpec;
+ private transient ITrafficProfile trafficProfile;
+ private transient List<IClassifier> classifiers;
+
+ // These values are transient as objects of these type will be updated asynchronously and will be used for
+ // synchronization purposes
private IGateID gateID;
- private IAMID iamid;
private IPCMMError error;
- private ISubscriberID subscriberID;
- private ITransactionID transactionID;
- private IGateSpec gateSpec;
- private ITrafficProfile trafficProfile;
- private IClassifier classifier;
+ private IGateState igateState;
+ private IGateTimeInfo gateTimeInfo;
+ private IGateUsageInfo gateUsageInfo;
+
+ /**
+ * Constructor
+ * @param iamid - the Application Manager ID
+ * @param subscriberID - the Subscriber ID
+ * @param transactionID - the transaction ID
+ * @param gateSpec - the Gate specification
+ * @param trafficProfile - the traffic profile
+ * @param classifiers - the classifier
+ * @param gateID - the gate ID
+ * @param error - the error
+ */
+ public PCMMGateReq(IAMID iamid, ISubscriberID subscriberID, ITransactionID transactionID,
+ IGateSpec gateSpec, ITrafficProfile trafficProfile, List<IClassifier> classifiers,
+ IGateID gateID,IPCMMError error,IGateState igateState,
+ IGateTimeInfo gateTimeInfo,IGateUsageInfo gateUsageInfo ) {
+ // TODO - determine if and when this attribute should be used
+ this.multicast = false;
- public PCMMGateReq() {
+ this.iamid = iamid;
+ this.subscriberID = subscriberID;
+ this.transactionID = transactionID;
+ this.gateSpec = gateSpec;
+ this.trafficProfile = trafficProfile;
+ this.classifiers = Lists.newArrayList(classifiers);
+ this.gateID = gateID;
+ this.error = error;
+ this.igateState = igateState;
+ this.gateTimeInfo = gateTimeInfo;
+ this.gateUsageInfo = gateUsageInfo;
}
- public PCMMGateReq(byte[] data) {
- short len, offset;
- byte sNum, sType;
- len = offset = 0;
- sNum = sType = (byte) 0;
+ /**
+ * Creates a PCMM Gate Request object from parsing a byte array
+ * @param data - the data to parse
+ * @return - the request
+ */
+ public static PCMMGateReq parse(byte[] data) {
+ GateID gateID = null;
+ AMID amid = null;
+ SubscriberID subscriberID = null;
+ TransactionID transactionID = null;
+ GateSpec gateSpec = null;
+ ITrafficProfile trafficProfile = null;
+ List<IClassifier> classifiers = Lists.newArrayListWithExpectedSize(4);
+ PCMMError error = null;
+ GateState gateState = null;
+ GateTimeInfo gateTimeInfo = null;
+ GateUsageInfo gateUsageInfo = null;
+
+
+ short offset = 0;
while (offset + 5 < data.length) {
- len = 0;
+ short len = 0;
len |= ((short) data[offset]) << 8;
len |= ((short) data[offset + 1]) & 0xFF;
- sNum = data[offset + 2];
- sType = data[offset + 3];
- byte[] dataBuffer = Arrays.copyOfRange(data, offset, offset + len);
+ final SNum sNum = SNum.valueOf(data[offset + 2]);
+ final byte sType = data[offset + 3];
+ final int dataIndx = offset + 4;
+ byte[] dataBuffer = Arrays.copyOfRange(data, dataIndx, dataIndx + len - 4);
switch (sNum) {
- case IGateID.SNUM:
- setGateID(new GateID(dataBuffer));
- break;
- case IAMID.SNUM:
- setAMID(new AMID(dataBuffer));
- break;
- case ISubscriberID.SNUM:
- setSubscriberID(new SubscriberID(dataBuffer));
- break;
- case ITransactionID.SNUM:
- setTransactionID(new TransactionID(dataBuffer));
- break;
- case IGateSpec.SNUM:
- setGateSpec(new GateSpec(dataBuffer));
- break;
- case ITrafficProfile.SNUM:
- setTrafficProfile(new DOCSISServiceClassNameTrafficProfile(dataBuffer));
-// setTrafficProfile(new BestEffortService(dataBuffer));
- break;
- case IClassifier.SNUM:
- setClassifier(new Classifier(dataBuffer));
- break;
- case IPCMMError.SNUM:
- error = new PCMMError(dataBuffer);
- break;
+ case GATE_ID:
+ gateID = GateID.parse(dataBuffer);
+ break;
+ case AMID:
+ amid = AMID.parse(dataBuffer);
+ break;
+ case SUBSCRIBER_ID:
+ subscriberID = SubscriberID.parse(dataBuffer);
+ break;
+ case TRANSACTION_ID:
+ transactionID = TransactionID.parse(dataBuffer);
+ break;
+ case GATE_SPEC:
+ gateSpec = GateSpec.parse(dataBuffer);
+ break;
+ case TRAFFIC_PROFILE:
+ switch (sType) {
+ case DOCSISServiceClassNameTrafficProfile.STYPE:
+ trafficProfile = DOCSISServiceClassNameTrafficProfile.parse(dataBuffer);
+ break;
+ case BestEffortService.STYPE:
+ trafficProfile = BestEffortService.parse(dataBuffer);
+ break;
+ }
+ break;
+ case CLASSIFIERS:
+ switch (sType) {
+ case IClassifier.STYPE:
+ classifiers.add(Classifier.parse(dataBuffer));
+ break;
+ case IExtendedClassifier.STYPE:
+ classifiers.add(ExtendedClassifier.parse(dataBuffer));
+ break;
+ case IIPv6Classifier.STYPE:
+ classifiers.add(IPv6Classifier.parse(dataBuffer));
+ break;
+ }
+ break;
+ case PCMM_ERROR:
+ error = PCMMError.parse(dataBuffer);
+ break;
+ //adding GATE_STATE
+ case GATE_STATE:
+ gateState = GateState.parse(dataBuffer);
+ break;
+ //adding GATE_TIME_INFO
+ case GATE_TIME_INFO:
+ gateTimeInfo = GateTimeInfo.parse(dataBuffer);
+ logger.info("Gate Time Info: "+gateTimeInfo);
+ break;
+ //adding GATE_USAGE_INFO
+ case GATE_USAGE_INFO:
+ gateUsageInfo = GateUsageInfo.parse(dataBuffer);
+ logger.info("Gate Usage Info: "+gateUsageInfo);
+ break;
default:
logger.warn("Unhandled Object skept : S-NUM=" + sNum
+ " S-TYPE=" + sType + " LEN=" + len);
}
offset += len;
}
+
+ return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile,
+ classifiers, gateID, error, gateState, gateTimeInfo,gateUsageInfo);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#isMulticast()
- */
@Override
public boolean isMulticast() {
// TODO Auto-generated method stub
return multicast;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#setGateID(short)
- */
@Override
public void setGateID(IGateID gateid) {
this.gateID = gateid;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#setAMID(org.pcmm.gates.IAMID)
- */
@Override
- public void setAMID(IAMID iamid) {
- this.iamid = iamid;
+ public void setGateState(IGateState gatestate) {
+ this.igateState = gatestate;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IPCMMGate#getSubscriberID(org.pcmm.gates.ISubscriberID)
- */
@Override
- public void setSubscriberID(ISubscriberID subscriberID) {
- this.subscriberID = subscriberID;
+ public void setTransactionID(ITransactionID transactionID) {
+ this.transactionID = transactionID;
+
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getGateSpec(org.pcmm.gates.IGateSpec)
- */
@Override
public void setGateSpec(IGateSpec gateSpec) {
this.gateSpec = gateSpec;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getClassifier(org.pcmm.gates.IClassifier)
- */
@Override
- public void setClassifier(IClassifier classifier) {
- this.classifier = classifier;
+ public void setClassifiers(List<IClassifier> classifiers) {
+ if (classifiers == null) {
+ this.classifiers = null;
+ }
+ else {
+ this.classifiers = new ArrayList<>(classifiers);
+ }
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IPCMMGate#getTrafficProfile(org.pcmm.gates.ITrafficProfile
- * )
- */
@Override
public void setTrafficProfile(ITrafficProfile profile) {
this.trafficProfile = profile;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getGateID()
- */
+ @Override
+ public void setGateTimeInfo(IGateTimeInfo gateTimeInfo) {
+ this.gateTimeInfo = gateTimeInfo;
+ }
+
+ @Override
+ public void setGateUsageInfo(IGateUsageInfo gateUsageInfo) {
+ this.gateUsageInfo = gateUsageInfo;
+ }
+
+
@Override
public IGateID getGateID() {
return gateID;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getAMID()
- */
+ @Override
+ public IGateState getGateState() {
+ return igateState;
+ }
+
+
@Override
public IAMID getAMID() {
return iamid;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getSubscriberID()
- */
@Override
public ISubscriberID getSubscriberID() {
return subscriberID;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getGateSpec()
- */
@Override
public IGateSpec getGateSpec() {
return gateSpec;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getClassifier()
- */
@Override
- public IClassifier getClassifier() {
- return classifier;
+ public List<IClassifier> getClassifiers() {
+ if (classifiers == null) {
+ return null;
+ }
+ return Collections.unmodifiableList(classifiers);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getTrafficProfile()
- */
@Override
public ITrafficProfile getTrafficProfile() {
return trafficProfile;
}
- @Override
- public void setTransactionID(ITransactionID transactionID) {
- this.transactionID = transactionID;
- }
-
@Override
public ITransactionID getTransactionID() {
return transactionID;
return error;
}
+ @Override
+ public IGateTimeInfo getGateTimeInfo() {
+ return gateTimeInfo;
+ }
+
+ @Override
+ public IGateUsageInfo getGateUsageInfo() {
+ return gateUsageInfo;
+ }
+
public void setError(IPCMMError error) {
this.error = error;
}
@Override
public byte[] getData() {
- byte[] array = new byte[0];
+ final List<Byte> byteList = new ArrayList<>();
if (getTransactionID() != null) {
- array = fill(array, getTransactionID());
+ byteList.addAll(Bytes.asList(getTransactionID().getAsBinaryArray()));
}
if (getGateID() != null) {
- array = fill(array, getGateID());
+ byteList.addAll(Bytes.asList(getGateID().getAsBinaryArray()));
}
if (getAMID() != null) {
- array = fill(array, getAMID());
-
+ byteList.addAll(Bytes.asList(getAMID().getAsBinaryArray()));
}
if (getSubscriberID() != null) {
- array = fill(array, getSubscriberID());
+ byteList.addAll(Bytes.asList(getSubscriberID().getAsBinaryArray()));
}
if (getGateSpec() != null) {
- array = fill(array, getGateSpec());
+ byteList.addAll(Bytes.asList(getGateSpec().getAsBinaryArray()));
}
if (getTrafficProfile() != null) {
- array = fill(array, getTrafficProfile());
+ byteList.addAll(Bytes.asList(getTrafficProfile().getAsBinaryArray()));
}
- if (getClassifier() != null) {
- array = fill(array, getClassifier());
+ if (getClassifiers() != null) {
+ for (IClassifier classifier : getClassifiers()) {
+ byteList.addAll(Bytes.asList(classifier.getAsBinaryArray()));
+ }
}
- return array;
+ if (getGateState() != null) {
+ byteList.addAll(Bytes.asList(getGateState().getAsBinaryArray()));
+ }
+ if (getGateTimeInfo() != null) {
+ byteList.addAll(Bytes.asList(getGateTimeInfo().getAsBinaryArray()));
+ }
+ if (getGateUsageInfo() != null) {
+ byteList.addAll(Bytes.asList(getGateUsageInfo().getAsBinaryArray()));
+ }
+ return Bytes.toArray(byteList);
}
+/*
private byte[] fill(byte[] array, IPCMMBaseObject obj) {
byte[] a = obj.getAsBinaryArray();
int offset = array.length;
System.arraycopy(a, 0, array, offset, a.length);
return array;
}
+*/
}