Made immutable, added enumerations & unit tests.
Change-Id: I47f44fe2a863d9d933902bc33bb11046613728ef
Signed-off-by: Steven Pisarski <s.pisarski@cablelabs.com>
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm;
-import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.ITransactionID.GateCommandType;
import org.pcmm.gates.impl.PCMMGateReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public void successReport(final COPSPdpReqStateMan man, final PCMMGateReq gateMsg) {
logger.info("Success Report notified.");
- if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {
+ if ( gateMsg.getTransactionID().getGateCommandType().equals(GateCommandType.GATE_DELETE_ACK)) {
logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID());
if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())
PCMMGlobalConfig.setGateID1(0);
PCMMGlobalConfig.setGateID2(0);
}
- if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) {
+ if ( gateMsg.getTransactionID().getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
logger.info("GateSetAck : GateID = " + gateMsg.getGateID().getGateID());
if (0 == PCMMGlobalConfig.getGateID1())
PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm;
-import org.pcmm.gates.*;
-import org.pcmm.gates.IGateSpec.DSCPTOS;
-import org.pcmm.gates.IGateSpec.Direction;
-import org.pcmm.gates.impl.*;
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IPCMMGate;
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.ITransactionID.GateCommandType;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.pcmm.gates.impl.TransactionID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.COPSMsgSender;
import org.umu.cops.prpdp.COPSPdpException;
import org.umu.cops.stack.*;
-import org.umu.cops.stack.COPSClientSI.CSIType;
import org.umu.cops.stack.COPSContext.RType;
import org.umu.cops.stack.COPSDecision.Command;
import org.umu.cops.stack.COPSDecision.DecisionFlag;
import org.umu.cops.stack.COPSObjHeader.CType;
import java.io.IOException;
-import java.net.InetAddress;
import java.net.Socket;
-import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public final static Logger logger = LoggerFactory.getLogger(PCMMPdpMsgSender.class);
- protected short _transactionID;
+ protected final short _transactionID;
protected final short _classifierID;
// XXX - this does not need to be here
public PCMMPdpMsgSender(final short clientType, final short tID, final COPSHandle clientHandle,
final Socket sock) {
super(clientType, clientHandle, sock);
- _transactionID = tID;
+ _transactionID = tID == 0 ? (short) (Math.random() * hashCode()) : tID;
_classifierID = 0;
}
- /**
- * Gets the transaction-id
- *
- * @return transaction-id value
- */
- public short getTransactionID() {
- return _transactionID;
- }
-
/**
* Gets the gate-id
*
* @throws COPSPdpException
*/
public void sendGateSet(final IPCMMGate gate) throws COPSPdpException {
- final ITransactionID trID = new TransactionID();
-
// set transaction ID to gate set
- trID.setGateCommandType(ITransactionID.GateSet);
- _transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
- trID.setTransactionIdentifier(_transactionID);
+ final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_SET);
gate.setTransactionID(trID);
// retain the transactionId to gate request mapping for gateID recovery after response
}
- /**
- * Sends a PCMM GateSet COPS Decision message
- *
- * @param num - the number
- * @throws COPSPdpException
- */
- public void sendGateSetDemo(int num) throws COPSPdpException {
- final IPCMMGate gate = new PCMMGateReq();
- final ITransactionID trID = new TransactionID();
- final IAMID amid = new AMID();
- final ISubscriberID subscriberID = new SubscriberID();
- final IGateSpec gateSpec = new GateSpec();
- final IClassifier classifier = new Classifier();
- final IExtendedClassifier eclassifier = new ExtendedClassifier();
- final int trafficRate;
- if (num == 1)
- trafficRate = PCMMGlobalConfig.DefaultBestEffortTrafficRate;
- else
- trafficRate = PCMMGlobalConfig.DefaultLowBestEffortTrafficRate;
-
- final ITrafficProfile trafficProfile = new BestEffortService(
- (byte) 7); //BestEffortService.DEFAULT_ENVELOP);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setMaximumSustainedTrafficRate(
- trafficRate);
- // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setMaximumSustainedTrafficRate(
- trafficRate);
- // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
-
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setMaximumSustainedTrafficRate(
- trafficRate);
- // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
-
-
- // set transaction ID to gate set
- trID.setGateCommandType(ITransactionID.GateSet);
- _transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
- trID.setTransactionIdentifier(_transactionID);
-
- amid.setApplicationType((short) 1);
- amid.setApplicationMgrTag((short) 1);
- gateSpec.setDirection(Direction.UPSTREAM);
- gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
- gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
- gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
- gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
- gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
-
- // XXX - if the version major is less than 4 we need to use Classifier
- // TODO - Use some variable here or remove...
- if (true) {
- //eclassifier.setProtocol(IClassifier.Protocol.NONE);
-// eclassifier.setProtocol(IClassifier.Protocol.TCP);
- try {
- InetAddress subIP = InetAddress
- .getByName(PCMMGlobalConfig.SubscriberID);
- InetAddress srcIP = InetAddress
- .getByName(PCMMGlobalConfig.srcIP);
- InetAddress dstIP = InetAddress
- .getByName(PCMMGlobalConfig.dstIP);
- InetAddress mask = InetAddress.getByName("0.0.0.0");
- subscriberID.setSourceIPAddress(subIP);
- eclassifier.setSourceIPAddress(srcIP);
- eclassifier.setDestinationIPAddress(dstIP);
- eclassifier.setIPDestinationMask(mask);
- eclassifier.setIPSourceMask(mask);
- } catch (UnknownHostException unae) {
- logger.error("Error getByName", unae);
- }
- eclassifier.setSourcePortStart(PCMMGlobalConfig.srcPort);
- eclassifier.setSourcePortEnd(PCMMGlobalConfig.srcPort);
- eclassifier.setDestinationPortStart(PCMMGlobalConfig.dstPort);
- eclassifier.setDestinationPortEnd(PCMMGlobalConfig.dstPort);
- eclassifier.setActivationState((byte) 0x01);
- // check if we have a stored value of classifierID else we just
- // create
- // one
- // eclassifier.setClassifierID((short) 0x01);
- eclassifier.setClassifierID((short) (_classifierID == 0 ? Math
- .random() * hashCode() : _classifierID));
- // XXX - testie
- // eclassifier.setClassifierID((short) 1);
-
- eclassifier.setAction((byte) 0x00);
- // XXX - temp default until Gate Modify is hacked in
- // eclassifier.setPriority(PCMMGlobalConfig.EClassifierPriority);
- eclassifier.setPriority((byte) 65);
-
- } else {
-// classifier.setProtocol(IClassifier.Protocol.TCP);
- try {
- InetAddress subIP = InetAddress
- .getByName(PCMMGlobalConfig.SubscriberID);
- InetAddress srcIP = InetAddress
- .getByName(PCMMGlobalConfig.srcIP);
- InetAddress dstIP = InetAddress
- .getByName(PCMMGlobalConfig.dstIP);
- subscriberID.setSourceIPAddress(subIP);
- classifier.setSourceIPAddress(srcIP);
- classifier.setDestinationIPAddress(dstIP);
- } catch (UnknownHostException unae) {
- logger.error("Error getByName", unae);
- }
- classifier.setSourcePort(PCMMGlobalConfig.srcPort);
- classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
- }
-
- gate.setTransactionID(trID);
- gate.setAMID(amid);
- gate.setSubscriberID(subscriberID);
- gate.setGateSpec(gateSpec);
- gate.setTrafficProfile(trafficProfile);
- gate.setClassifier(eclassifier);
-
- final byte[] data = gate.getData();
-
- final Set<COPSDecision> decisionSet = new HashSet<>();
- decisionSet.add(new COPSDecision(CType.NA, Command.INSTALL, DecisionFlag.REQERROR));
- final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
- decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
- final COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length));
-
- // Common Header with the same ClientType as the request
- // Client Handle with the same clientHandle as the request
- final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
-
- // ** Send the GateSet Decision
- // **
- try {
- decisionMsg.writeData(_sock);
- } catch (IOException e) {
- logger.error("Failed to send the decision", e);
- }
-
- }
- /**
- * Sends a PCMM GateSet COPS Decision message
- * @throws COPSPdpException
- */
- public void sendGateSetBestEffortWithExtendedClassifier() throws COPSPdpException {
- final IPCMMGate gate = new PCMMGateReq();
- final ITransactionID trID = new TransactionID();
- final IAMID amid = new AMID();
- final ISubscriberID subscriberID = new SubscriberID();
- final IGateSpec gateSpec = new GateSpec();
- final IClassifier classifier = new Classifier();
- final IExtendedClassifier eclassifier = new ExtendedClassifier();
-
- // XXX check if other values should be provided
- //
- final ITrafficProfile trafficProfile = new BestEffortService(
- (byte) 7); //BestEffortService.DEFAULT_ENVELOP);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setMaximumSustainedTrafficRate(
- PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getReservedEnvelop()
- .setMaximumSustainedTrafficRate(
- PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
-
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
- ((BestEffortService) trafficProfile).getCommittedEnvelop()
- .setMaximumSustainedTrafficRate(
- PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
- // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
-
-
-
- // set transaction ID to gate set
- trID.setGateCommandType(ITransactionID.GateSet);
- _transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
- trID.setTransactionIdentifier(_transactionID);
-
- amid.setApplicationType((short) 1);
- amid.setApplicationMgrTag((short) 1);
- gateSpec.setDirection(Direction.UPSTREAM);
- gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
- gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
- gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
- gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
- gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
-
- // XXX - if the version major is less than 4 we need to use Classifier
- if (true) {
- //eclassifier.setProtocol(IClassifier.Protocol.NONE);
-// eclassifier.setProtocol(IClassifier.Protocol.TCP);
- try {
- InetAddress subIP = InetAddress
- .getByName(PCMMGlobalConfig.SubscriberID);
- InetAddress srcIP = InetAddress
- .getByName(PCMMGlobalConfig.srcIP);
- InetAddress dstIP = InetAddress
- .getByName(PCMMGlobalConfig.dstIP);
- InetAddress mask = InetAddress.getByName("0.0.0.0");
- subscriberID.setSourceIPAddress(subIP);
- eclassifier.setSourceIPAddress(srcIP);
- eclassifier.setDestinationIPAddress(dstIP);
- eclassifier.setIPDestinationMask(mask);
- eclassifier.setIPSourceMask(mask);
- } catch (UnknownHostException unae) {
- logger.error("Error getByName", unae);
- }
- eclassifier.setSourcePortStart(PCMMGlobalConfig.srcPort);
- eclassifier.setSourcePortEnd(PCMMGlobalConfig.srcPort);
- eclassifier.setDestinationPortStart(PCMMGlobalConfig.dstPort);
- eclassifier.setDestinationPortEnd(PCMMGlobalConfig.dstPort);
- eclassifier.setActivationState((byte) 0x01);
- // check if we have a stored value of classifierID else we just
- // create
- // one
- // eclassifier.setClassifierID((short) 0x01);
- eclassifier.setClassifierID((short) (_classifierID == 0 ? Math
- .random() * hashCode() : _classifierID));
- // XXX - testie
- // eclassifier.setClassifierID((short) 1);
-
- eclassifier.setAction((byte) 0x00);
- // XXX - temp default until Gate Modify is hacked in
- // eclassifier.setPriority(PCMMGlobalConfig.EClassifierPriority);
- eclassifier.setPriority((byte) 65);
-
- } else {
-// classifier.setProtocol(IClassifier.Protocol.TCP);
- try {
- InetAddress subIP = InetAddress
- .getByName(PCMMGlobalConfig.SubscriberID);
- InetAddress srcIP = InetAddress
- .getByName(PCMMGlobalConfig.srcIP);
- InetAddress dstIP = InetAddress
- .getByName(PCMMGlobalConfig.dstIP);
- subscriberID.setSourceIPAddress(subIP);
- classifier.setSourceIPAddress(srcIP);
- classifier.setDestinationIPAddress(dstIP);
- } catch (UnknownHostException unae) {
- logger.error("Error getByName", unae);
- }
- classifier.setSourcePort(PCMMGlobalConfig.srcPort);
- classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
- }
-
- gate.setTransactionID(trID);
- gate.setAMID(amid);
- gate.setSubscriberID(subscriberID);
- gate.setGateSpec(gateSpec);
- gate.setTrafficProfile(trafficProfile);
- gate.setClassifier(eclassifier);
-
- byte[] data = gate.getData();
-
- final Set<COPSDecision> decisionSet = new HashSet<>();
- decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR));
- final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
- decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
- final COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length));
-
- // Common Header with the same ClientType as the request
- // Client Handle with the same clientHandle as the request
- final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, _handle, decisionMap, null, clientSD);
-
- // ** Send the GateSet Decision
- // **
- try {
- decisionMsg.writeData(_sock);
- } catch (IOException e) {
- logger.error("Failed to send the decision", e);
- }
-
- }
-
-
public boolean handleGateReport(final Socket socket) throws COPSPdpException {
try {
// waits for the gate-set-ack or error
if (reportMsg.getClientSI() == null) {
return false;
}
- final IPCMMGate responseGate = new PCMMGateReq(reportMsg.getClientSI().getData().getData());
+ final IPCMMGate responseGate = PCMMGateReq.parse(reportMsg.getClientSI().getData().getData());
if (responseGate.getTransactionID() != null
- && responseGate.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
+ && responseGate.getTransactionID().getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
logger.info("the CMTS has sent a Gate-Set-Ack response");
// here CMTS responded that he acknowledged the Gate-Set
// TODO do further check of Gate-Set-Ack GateID etc...
}
- /**
- * Sends a PCMM GateSet COPS Decision message
- *
- * @throws COPSPdpException
- */
- public void sendGateSet() throws COPSPdpException {
- // Common Header with the same ClientType as the request
-
- final IPCMMGate gate = new PCMMGateReq();
- final ITransactionID trID = new TransactionID();
-
- final IAMID amid = new AMID();
- final ISubscriberID subscriberID = new SubscriberID();
- final IGateSpec gateSpec = new GateSpec();
- final IClassifier classifier = new Classifier();
- // XXX check if other values should be provided
- final ITrafficProfile trafficProfile = new BestEffortService(
- BestEffortService.DEFAULT_ENVELOP);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setMaximumTrafficBurst(
- BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
- ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
- .setRequestTransmissionPolicy(
- PCMMGlobalConfig.BETransmissionPolicy);
-
- // set transaction ID to gate set
- trID.setGateCommandType(ITransactionID.GateSet);
- _transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
- trID.setTransactionIdentifier(_transactionID);
-
- amid.setApplicationType((short) 1);
- amid.setApplicationMgrTag((short) 1);
- gateSpec.setDirection(Direction.UPSTREAM);
- gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
- gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
- gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
- gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
- gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
-
- /*
- * ((DOCSISServiceClassNameTrafficProfile) trafficProfile)
- * .setServiceClassName("S_up");
- */
-
-// classifier.setProtocol(IClassifier.Protocol.TCP);
- try {
- InetAddress subIP = InetAddress.getByName(PCMMGlobalConfig.SubscriberID);
- InetAddress srcIP = InetAddress.getByName(PCMMGlobalConfig.srcIP);
- InetAddress dstIP = InetAddress.getByName(PCMMGlobalConfig.dstIP);
- subscriberID.setSourceIPAddress(subIP);
- classifier.setSourceIPAddress(srcIP);
- classifier.setDestinationIPAddress(dstIP);
- } catch (UnknownHostException unae) {
- logger.error("Error getByName", unae);
- }
- classifier.setSourcePort(PCMMGlobalConfig.srcPort);
- classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
-
- gate.setTransactionID(trID);
- gate.setAMID(amid);
- gate.setSubscriberID(subscriberID);
- gate.setGateSpec(gateSpec);
- gate.setTrafficProfile(trafficProfile);
- gate.setClassifier(classifier);
-
- final byte[] data = gate.getData();
-
- final Set<COPSDecision> decisionSet = new HashSet<>();
- decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR));
- final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
- decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
-
- final COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length));
-
- // Client Handle with the same clientHandle as the request
- final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
-
- // ** Send the GateSet Decision
- // **
- try {
- decisionMsg.writeData(_sock);
- } catch (IOException e) {
- logger.error("Failed to send the decision", e);
- }
- }
-
/**
* Sends a message asking that the request state be deleted
*
*/
public void sendGateDelete(final IPCMMGate gate) throws COPSPdpException {
// set transaction ID to gate set
- final ITransactionID trID = new TransactionID();
- trID.setGateCommandType(ITransactionID.GateDelete);
- _transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
- trID.setTransactionIdentifier(_transactionID);
+ final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_DELETE);
gate.setTransactionID(trID);
Short trIDnum = trID.getTransactionIdentifier();
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm;
import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IPCMMError.ErrorCode;
import org.pcmm.gates.IPCMMGate;
import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.ITransactionID.GateCommandType;
import org.pcmm.gates.impl.PCMMError;
import org.pcmm.gates.impl.PCMMGateReq;
import org.slf4j.Logger;
// PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);
logger.info("PCMMGateReq Parse Gate Message");
- final PCMMGateReq gateMsg = new PCMMGateReq(data);
+ final PCMMGateReq gateMsg = PCMMGateReq.parse(data);
// TODO FIXME - Why is this Map being filled but never used???
final Map<String, String> repSIs = new HashMap<>();
_thisProcess.successReport(this, gateMsg);
} else {
final String cmdType;
- if ( trID.getGateCommandType() == ITransactionID.GateDeleteAck ) {
+ if (trID.getGateCommandType().equals(GateCommandType.GATE_DELETE_ACK)) {
cmdType = "GateDeleteAck";
- } else if ( trID.getGateCommandType() == ITransactionID.GateSetAck ) {
+ } else if (trID.getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
cmdType = "GateSetAck";
} else cmdType = null;
// capture the gateId from the response message
if (gateMsg.getError() != null)
logger.info("Gate message error - " + gateMsg.getError().toString());
else {
- final PCMMError error = new PCMMError();
- // TODO - figure out correct error code
- error.setErrorCode((short)19);
+ // TODO - Determine if this is the correct error code
+ final PCMMError error = new PCMMError(ErrorCode.UNK_GATE_CMD);
gate.setError(error);
logger.warn("Gate request failed without an error, setting one - " + error);
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm.base;
import java.io.IOException;
import java.net.Socket;
-import org.umu.cops.stack.COPSData;
-
/**
* Base interface for all PCMM objects, it define the {@code S-Type},
* {@code S-Num} and the data length
*/
public interface IPCMMBaseObject {
- /**
- * sets the S-Type
- *
- * @param stype
- */
- void setSType(byte stype);
-
- /**
- *
- * @return S-Type
- */
- byte getSType();
-
- /**
- * sets the S-Num
- *
- * @param snum
- * S-Num
- */
- void setSNum(byte snum);
-
- /**
- * gets the S-Num
- *
- * @return S-Num
- */
- byte getSNum();
-
- /**
- * sets the length;
- *
- * @param len
- */
- void setLength(short len);
-
- /**
- * gets the length;
- *
- * @return length
- */
- short getLength();
-
- /**
- * sets the COPS data
- *
- * @param data
- * COPS data
- */
- void setData(COPSData data);
-
- /**
- * gets the COPS data
- *
- * @return COPS data
- */
- COPSData getData();
-
void writeData(Socket id) throws IOException;
+// short getDataLen();
+
byte[] getAsBinaryArray();
}
-/**
- *
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-package org.pcmm.base.impl;
-import java.io.IOException;
-import java.net.Socket;
-import java.util.Arrays;
+package org.pcmm.base.impl;
+import com.google.common.primitives.Bytes;
import org.pcmm.base.IPCMMBaseObject;
import org.umu.cops.stack.COPSData;
+import org.umu.cops.stack.COPSMsgParser;
+import org.umu.cops.stack.COPSObjectParser;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
/**
*
- * Implementation of the base class {@link IPCMMBaseObject}
- *
+ * Abstract implementation of the base class {@link IPCMMBaseObject}
+ * Implementations of this class are used for sending/receiving PCMM data to/from a COPS client
*/
-public class PCMMBaseObject /* extends COPSPrObjBase */implements
- IPCMMBaseObject {
-
- private byte sType;
- private byte sNum;
- private short len;
- private COPSData copsData;
- private COPSData pad;
- protected final short offset = (short) 4;
-
- public PCMMBaseObject(byte[] data) {
- parse(data);
- }
+public abstract class PCMMBaseObject implements IPCMMBaseObject {
- public PCMMBaseObject(short len, byte sType, byte sNum) {
- this.len = (len);
- this.sType = (sType);
- this.sNum = (sNum);
- byte[] array = new byte[len - offset];
- Arrays.fill(array, (byte) 0);
- setData(new COPSData(array, 0, array.length));
- }
+ protected static final short HEADER_OFFSET = (short) 4;
+ protected static final short PADDING_OFFSET = (short) 4;
- protected COPSData getPadding(int len) {
- byte[] padBuf = new byte[len];
- Arrays.fill(padBuf, (byte) 0);
- COPSData d = new COPSData(padBuf, 0, len);
- return d;
- }
+ // The following two attributes denote the type of PCMMBaseObject
+ private final SNum sNum;
+ private final byte sType;
/**
- * Add head padding to the specified byte array filled with zeros
- *
- * @param off
- * offset
- * @param array
- * input array
- * @return byte array
+ * Constructor
+ * @param sNum - the S-Num
+ * @param sType - the S-Type
*/
- protected byte[] headPadding(int off, byte[] array) {
- byte[] returnArray = new byte[array.length + off];
- Arrays.fill(returnArray, (byte) 0);
- System.arraycopy(array, 0, returnArray, off, array.length);
- return returnArray;
- }
-
- protected void parse(byte[] data) {
- if (data == null || data.length == 0)
- throw new IllegalArgumentException("data could not be null");
- len = 0;
- len |= ((short) data[0]) << 8;
- len |= ((short) data[1]) & 0xFF;
- sNum = data[2];
- sType = data[3];
- copsData = new COPSData(data, offset, data.length - offset);
+ protected PCMMBaseObject(final SNum sNum, final byte sType) {
+ if (sNum == null) throw new IllegalArgumentException("Invalid or null SNum");
+ this.sNum = sNum;
+ this.sType = sType;
}
- protected void setShort(short value, short startPos) {
- byte[] data = getData().getData();
- data[startPos] = (byte) (value >> 8);
- data[startPos + 1] = (byte) value;
- setData(new COPSData(data, 0, data.length));
- }
-
- protected short getShort(short startPos) {
- byte[] data = getData().getData();
- short retVal = 0;
- retVal |= ((short) data[startPos]) << 8;
- retVal |= ((short) data[startPos + 1]) & 0xFF;
- return retVal;
- }
-
- protected void setInt(int value, short startPos) {
- byte[] data = getData().getData();
- data[startPos] = (byte) (value >> 24);
- data[startPos + 1] = (byte) (value >> 16);
- data[startPos + 2] = (byte) (value >> 8);
- data[startPos + 3] = (byte) value;
- setData(new COPSData(data, 0, data.length));
- }
-
- protected int getInt(short startPos) {
- byte[] data = getData().getData();
- int retVal = 0;
- retVal |= ((short) data[startPos]) << 24;
- retVal |= ((short) data[startPos + 1]) << 16;
- retVal |= ((short) data[startPos + 2]) << 8;
- retVal |= ((short) data[startPos + 3]) & 0xFF;
- return retVal;
- }
-
- protected void setBytes(byte[] value, short startPos) {
- byte[] data = getData().getData();
- for (byte b : value)
- data[startPos++] = b;
- setData(new COPSData(data, 0, data.length));
- }
-
- protected byte[] getBytes(short startPos, short size) {
- return Arrays.copyOfRange(getData().getData(), startPos, startPos
- + size);
- }
-
- protected void setByte(byte value, short startPos) {
- setBytes(new byte[] { value }, startPos);
- }
-
- protected byte getByte(short startPos) {
- return getBytes(startPos, (short) 1)[0];
+ @Override
+ public final void writeData(final Socket socket) throws IOException {
+ final byte[] data = getAsBinaryArray();
+ socket.getOutputStream().write(data, 0, data.length);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#setSType(byte)
- */
@Override
- public void setSType(byte stype) {
- this.sType = stype;
+ public final byte[] getAsBinaryArray() {
+ final byte[] data = getBytes();
+ final COPSData padding;
+ if ((data.length % PADDING_OFFSET) != 0) {
+ final int padLen = PADDING_OFFSET - (data.length % PADDING_OFFSET);
+ padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ padding = new COPSData();
+ }
+ final int payloadSize = data.length + padding.length() + HEADER_OFFSET;
+ final List<Byte> outBytes = new ArrayList<>();
+ outBytes.addAll(Bytes.asList(COPSMsgParser.shortToBytes((short) payloadSize)));
+ outBytes.add(sNum.getValue());
+ outBytes.add(sType);
+ outBytes.addAll(Bytes.asList(data));
+ outBytes.addAll(Bytes.asList(padding.getData()));
+ return Bytes.toArray(outBytes);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#getSType()
- */
@Override
- public byte getSType() {
- return sType;
- }
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof PCMMBaseObject)) {
+ return false;
+ }
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#setSNum(byte)
- */
- @Override
- public void setSNum(byte snum) {
- this.sNum = snum;
+ final PCMMBaseObject that = (PCMMBaseObject) o;
+ return sType == that.sType && sNum == that.sNum;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#getSNum()
- */
@Override
- public byte getSNum() {
- return sNum;
+ public int hashCode() {
+ int result = sNum.hashCode();
+ result = 31 * result + (int) sType;
+ return result;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#setLength(short)
+ /**
+ * Returns the byte array consisting of the data contained within the implementation class
+ * @return - the byte array
*/
- @Override
- public void setLength(short len) {
- this.len = len;
- }
+ protected abstract byte[] getBytes();
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#getLength()
+ /**
+ * Enumeration of SNum values that is used by the client to determine which Object type is being sent
*/
- @Override
- public short getLength() {
- return (short) (len + (pad != null ? pad.length() : 0));
- }
+ public enum SNum {
+ TRANSACTION_ID((byte) 1),
+ AMID((byte) 2),
+ SUBSCRIBER_ID((byte) 3),
+ GATE_ID((byte) 4),
+ GATE_SPEC((byte) 5),
+ CLASSIFIERS((byte) 6),
+ TRAFFIC_PROFILE((byte) 7),
+ EVENT_GEN_INFO((byte) 8),
+ VOL_BASED_USAGE_LIMIT((byte) 9),
+ TIME_BASED_USAGE_LIMIT((byte) 10),
+ OPAQUE_DATA((byte) 11),
+ GATE_TIME_INFO((byte) 12),
+ GATE_USAGE_INFO((byte) 13),
+ PCMM_ERROR((byte) 14),
+ GATE_STATE((byte) 15),
+ VERSION_INFO((byte) 16),
+ PSID((byte) 17),
+ SYNC_OPTS((byte) 18),
+ MSG_RECEIPT_KEY((byte) 19),
+ USER_ID((byte) 20),
+ SHARED_RES_ID((byte) 21);
+
+ private byte value;
+
+ SNum(byte value) {
+ this.value = value;
+ }
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#setData(org.umu.cops.stack.COPSData)
- */
- @Override
- public void setData(COPSData data) {
- this.copsData = data;
- if (data.length() % offset != 0) {
- int padLen = offset - (data.length() % offset);
- pad = getPadding(padLen);
+ public byte getValue() {
+ return value;
}
- len = (short) (data.length() + offset);
- }
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#getData()
- */
- @Override
- public COPSData getData() {
- return copsData;
- }
+ public static SNum valueOf(byte v) {
+ switch (v) {
+ case 1:
+ return SNum.TRANSACTION_ID;
+ case 2:
+ return SNum.AMID;
+ case 3:
+ return SNum.SUBSCRIBER_ID;
+ case 4:
+ return SNum.GATE_ID;
+ case 5:
+ return SNum.GATE_SPEC;
+ case 6:
+ return SNum.CLASSIFIERS;
+ case 7:
+ return SNum.TRAFFIC_PROFILE;
+ case 8:
+ return SNum.EVENT_GEN_INFO;
+ case 9:
+ return SNum.VOL_BASED_USAGE_LIMIT;
+ case 10:
+ return SNum.TIME_BASED_USAGE_LIMIT;
+ case 11:
+ return SNum.OPAQUE_DATA;
+ case 12:
+ return SNum.GATE_TIME_INFO;
+ case 13:
+ return SNum.GATE_USAGE_INFO;
+ case 14:
+ return SNum.PCMM_ERROR;
+ case 15:
+ return SNum.GATE_STATE;
+ case 16:
+ return SNum.VERSION_INFO;
+ case 17:
+ return SNum.PSID;
+ case 18:
+ return SNum.SYNC_OPTS;
+ case 19:
+ return SNum.MSG_RECEIPT_KEY;
+ case 20:
+ return SNum.USER_ID;
+ case 21:
+ return SNum.SHARED_RES_ID;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#writeData(java.net.Socket)
- */
- public void writeData(Socket id) throws IOException {
- byte[] data = getAsBinaryArray();
- id.getOutputStream().write(data, 0, data.length);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.base.IPCMMBaseObject#getAsBinaryArray()
- */
- @Override
- public byte[] getAsBinaryArray() {
- byte[] array = new byte[getLength()];
- array[0] = (byte) (len >> 8);
- array[1] = (byte) len;
- array[2] = sNum;
- array[3] = sType;
- System.arraycopy(getData().getData(), 0, array, offset, getData()
- .length());
- if (pad != null)
- System.arraycopy(pad.getData(), 0, array, offset
- + getData().length(), pad.length());
- return array;
- }
+
+
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
/**
+ * Class to hold the Application Manager Identification which is the handle that identifies the Application Manager
+ * and Application Type.
+ *
+ * From the Packetcable Multimedia specification section 6.1.2
+ *
* <p>
* The AMID consists of two fields: the Application Manager Tag and Application
* Type. Each Application Manager is pre-provisioned with an Application Manager
*/
public interface IAMID extends IPCMMBaseObject {
- static final short LENGTH = 8;
- static final byte SNUM = 2;
- static final byte STYPE = 1;
-
- void setApplicationType(short type);
+ byte STYPE = 1;
+ /**
+ * Returns the application type value
+ * @return - a short
+ */
short getApplicationType();
- void setApplicationMgrTag(short type);
-
+ /**
+ * Returns the application manager tag value
+ * @return - a short
+ */
short getApplicationMgrTag();
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
import java.net.InetAddress;
/**
- *
- *
- *
+ * The Classifier object specifies the packet matching rules associated with a Gate. As defined in Sections 6.4.3.1 and
+ * 6.4.3.2, for Unicast Gates multiple Classifier objects may be included in the Gate-Set to allow for complex
+ * classifier rules. When an AM is using Classifier objects, at least one Classifier MUST be provided by the PDP in all
+ * Gate-Set messages. More than one Classifier is allowed for Unicast Gates. Only one classifier is required to be
+ * supported for Multicast Gates. Unlike DOCSIS DSx signaling, Classifiers have no identifier and have no explicit add,
+ * change, or remove operations. The entire set of Classifiers present in a Gate-Set message replaces the entire set of
+ * classifiers for the existing Gate. Equivalence of Classifiers is determined by comparing all fields within the
+ * Classifier. Classifiers may be provided in any order.
*/
public interface IClassifier extends IPCMMBaseObject {
- short LENGTH = 24;
- byte SNUM = 6;
byte STYPE = 1;
- enum Protocol {
- /*ICMP((short) 1), IGMP((short) 2), */
- NONE((short)0), TCP((short) 6), UDP((short) 17);
-
- Protocol(short v) {
- this.value = v;
- }
-
- public static Protocol valueOf(short v) {
- switch (v) {
- case 0:
- return NONE;
- /*
- case 1:
- return ICMP;
- case 2:
- return IGMP;
- */
- case 6:
- return TCP;
- default:
- return UDP;
- }
- }
- private short value;
-
- public short getValue() {
- return value;
- }
- }
-
/**
* IP Destination Address or IPv6 Destination Address is the termination
* point for the IP flow
*/
InetAddress getDestinationIPAddress();
- void setDestinationIPAddress(InetAddress address);
-
+ /**
+ * Returns the destination port value
+ * @return - the port number
+ */
short getDestinationPort();
- void setDestinationPort(short p);
-
/**
* Source IP, IP Source Address, or IPv6 Source Address (in the case of
* Extended Classifier or IPv6 Classifier) is the IP address (as seen at the
*/
InetAddress getSourceIPAddress();
- void setSourceIPAddress(InetAddress a);
-
+ /**
+ * Returns the source port value
+ * @return - the port number
+ */
short getSourcePort();
- void setSourcePort(short p);
-
/**
* Protocol field, in a legacy Classifier or Extended Classifier, identifies
* the type of protocol (e.g., IP, ICMP, etc.). The Next Header Type field
*
* @return the protocol.
*/
- short getProtocol();
-
- /**
- * @see <a
- * href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.txt">protocols</a>
- * @param p - the protocol value
- */
- void setProtocol(short p);
+ Protocol getProtocol();
/**
* Priority may be used to distinguish between multiple classifiers that
byte getPriority();
/**
- * sets the priority;
- *
- * @param p
- * priority
+ * Returns the DSCPTOS enumeration value (ENABLE|DISABLE)
+ * @return the enumeration
*/
- void setPriority(byte p);
-
byte getDSCPTOS();
- void setDSCPTOS(byte v);
-
+ /**
+ * Returns the DSCPTOS mask value
+ * @return the mask
+ */
byte getDSCPTOSMask();
- void setDSCPTOSMask(byte v);
+ /**
+ * Enumeration of supported protocols
+ */
+ enum Protocol {
+ /*ICMP((short) 1), IGMP((short) 2), */
+ NONE((short)0), TCP((short) 6), UDP((short) 17);
- // DSCP/TOS Field
- // ï‚·
- // DSCP/TOS Mask
+ Protocol(short v) {
+ this.value = v;
+ }
+
+ public static Protocol valueOf(short v) {
+ switch (v) {
+ case 0:
+ return NONE;
+ /* TODO - Determine why these two values are not being supported???
+ case 1:
+ return ICMP;
+ case 2:
+ return IGMP;
+ */
+ case 6:
+ return TCP;
+ default:
+ return UDP;
+ }
+ }
+ private short value;
+
+ public short getValue() {
+ return value;
+ }
+ }
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
import java.net.InetAddress;
+/**
+ * The Extended Classifier object specifies the packet matching rules associated with a Gate, but includes more
+ * detailed information for matching traffic, as well adding, modifying, deleting, activating and inactivating Classifiers.
+ * As defined in sections 6.4.3.1 and 6.4.3.2, for Unicast Gates multiple Extended Classifier objects may be included
+ * in the Gate-Set to allow for complex classifier rules. However, since the ordering of objects in a message and the
+ * order of processing those objects is not mandated, and AM SHOULD NOT send a GateSet with multiple Extended
+ * Classifiers with the same ClassifierID, yet different Actions. When an AM is using Extended Classifier objects, at
+ * least one Extended Classifier is allowed. For Multicast Gates, only one Extended Classifier is required to be supported.
+ * Since the Extended Classifier is based on the DOCSIS IP Classifier, all DOCSIS classifier semantics apply, with the
+ * exception that at least one Extended Classifier be present in a Gate-Set message.
+ *
+ * Message length including header == 40
+ */
public interface IExtendedClassifier extends IClassifier {
- static final short LENGTH = 40;
- static final byte SNUM = 6;
- static final byte STYPE = 2;
-
- void setIPSourceMask(InetAddress a);
+ byte STYPE = 2;
- void setIPDestinationMask(InetAddress m);
+ /**
+ * Returns the IP Source Mask value
+ * @return - the InetAddress object
+ */
+ InetAddress getIPSourceMask();
- void setSourcePortStart(short p);
+ /**
+ * Returns the IP Destination Mask value
+ * @return - the InetAddress object
+ */
+ InetAddress getIPDestinationMask();
- void setSourcePortEnd(short p);
+ /**
+ * Returns the Start Source Port value
+ * @return - the port number
+ */
+ short getSourcePortStart();
- void setDestinationPortStart(short p);
+ /**
+ * Returns the End Source Port value
+ * @return - the port number
+ */
+ short getSourcePortEnd();
- void setDestinationPortEnd(short p);
+ /**
+ * Returns the Start Destination Port value
+ * @return - the port number
+ */
+ short getDestinationPortStart();
- void setClassifierID(short p);
+ /**
+ * Returns the End Destination Port value
+ * @return - the port number
+ */
+ short getDestinationPortEnd();
/**
- * <pre>
- * 0x00 Inactive
- * 0x01 Active
- * </pre>
- *
- * @param s
+ * The ID value of this classifier
+ * @return - the ID
*/
- void setActivationState(byte s);
+ short getClassifierID();
/**
- * <pre>
- * 0x00 Add classifier
- * 0x01 Replace classifier
- * 0x02 Delete classifier
- * 0x03 No change
- * </pre>
- *
- * @param a
+ * The activation state
+ * @return
*/
- void setAction(byte a);
+ ActivationState getActivationState();
- InetAddress getIPSourceMask();
+ byte getAction();
- InetAddress getIPDestinationMask();
+ /**
+ * The valid activation state values
+ */
+ enum ActivationState {
- short getSourcePortStart();
+ INACTIVE((byte) 0), ACTIVE((byte) 1);
- short getSourcePortEnd();
+ ActivationState(byte value) {
+ this.value = value;
+ }
- short getDestinationPortStart();
+ public byte getValue() {
+ return value;
+ }
- short getDestinationPortEnd();
+ public static ActivationState valueOf(byte v) {
+ switch (v) {
+ case 0:
+ return ActivationState.INACTIVE;
+ case 1:
+ return ActivationState.ACTIVE;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
- short getClassifierID();
+ private byte value;
- byte getActivationState();
+ }
- byte getAction();
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
/**
+ * GateID is the handle for the Gate. The GateID is assigned by the CMTS and is used by the Application Manager,
+ * Policy Server, and client to reference the Gate.
+ *
+ * From the Packetcable Multimedia specification section 6.1.1
*
+ * A GateID is an identifier that is locally allocated by the CMTS where the Gate resides. A GateID MUST be
+ * associated with only one Gate. Whereas the PacketCable 1.x DQoS Gate Control model generally assumed a pair of
+ * unidirectional Gates (one upstream and one downstream) per GateID in support of a typical two-way voice session,
+ * here the Gate/GateID relationship is explicitly one-to-one, so that it is easier to support a wide range of Multimedia
+ * services.
+ *
+ * When the Application Manager issues a Gate-Set request, this triggers the Policy Server to issue a Gate-Set message
+ * to the CMTS. When the CMTS responds with an acknowledgment containing the GateID, the Policy Server
+ * forwards this response including the GateID back to the Application Manager. Note that since there can be a manyto-
+ * many relationship between a PS and CMTS, the GateID assigned by one CMTS cannot be guaranteed to be
+ * unique across the network, so the PSs may use the AMID of the AM along with the SubscriberID and GateID in
+ * order to uniquely identify the Gate.
+ *
+ * An algorithm that may be used to assign values of GateIDs is as follows. Partition the 32-bit word into two parts, an
+ * index part, and a random part. The index part identifies the Gate by indexing into a small table, while the random
+ * part provides some level of obscurity to the value. Regardless of the algorithm chosen, the CMTS SHOULD attempt
+ * to minimize the possibility of GateID ambiguities by ensuring that no GateID gets reused within three minutes of its
+ * prior closure or deletion. For the algorithm suggested this could be accomplished by simply incrementing the index
+ * part for each consecutively assigned GateID, wrapping around to zero when the maximum integer value of the index
+ * part is reached.
*/
public interface IGateID extends IPCMMBaseObject {
- static final short LENGTH = 8;
- static final byte SNUM = 4;
- static final byte STYPE = 1;
- void setGateID(int gateID);
+ /**
+ * The S-Type for Gate IDs
+ */
+ byte STYPE = 1;
+ /**
+ * Returns the gate ID value
+ * @return - the ID
+ */
int getGateID();
+
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
/**
- * <p>
- * The GateSpec describes some high-level attributes of the Gate, and contains
- * information regarding the treatment of other objects specified in the Gate
- * message.
- * </p>
+ * GateSpec describes specific authorization parameters defining a Gate (i.e., QoS limits, timers, etc.).
+ *
+ * From the Packetcable Multimedia specification section 6.1.4
+ *
+ * The GateSpec describes some high-level attributes of the Gate, and contains information regarding the treatment of
+ * other objects specified in the Gate message. Information contained in a GateSpec is outlined below.
+ *
+ * * SessionClassID
+ * * Direction
+ * * Authorized Timer
+ * * Reserved Timer
+ * * Committed Timer
+ * * Committed Recovery Timer
+ * * DSCP/TOS Overwrite
+ * * DSCP/TOS Mask
+ *
+ * SessionClassID provides a way for the Application Manager and the Policy Server to group Gates into different
+ * classes with different authorization characteristics. For example, one could use the SessionClassID to represent
+ * some prioritization or preemption scheme that would allow either the Policy Server or the CMTS to preempt a preauthorized
+ * Gate in favor of allowing a new Gate with a higher priority to be authorized.
+ *
+ * Direction indicates whether the Gate is for an upstream or downstream flow. Depending on this direction, the CMTS
+ * MUST reserve and activate the DOCSIS flows accordingly. For Multicast Gates the CMTS needs to only support
+ * flows or gates in the downstream direction.
+ *
+ * Authorized Timer limits the amount of time the authorization must remain valid before it is reserved (see
+ * Section 6.2).
+ *
+ * Reserved Timer limits the amount of time the reservation must remain valid before the resources are committed (see
+ * Section 6.2).
+ *
+ * Committed Timer limits the amount of time a committed service flow may remain idle.
+ *
+ * Committed Recovery Timer limits the amount of time that a committed service flow can remain without a
+ * subsequent refresh message from the PS/AM once the PS/AM has been notified of inactivity (see Section 6.2).
+ * DSCP/TOS Overwrite field can be used to overwrite the DSCP/TOS field of packets associated with the DOCSIS
+ * Service Flow that corresponds to the Gate. This field may be unspecified in which case the DSCP/TOS field in the
+ * packet is not over-written by the CMTS. This field may be used in both the upstream and downstream directions.
+ * The CMTS MUST support DSCP/TOS overwrite for upstream gates. The CMTS MAY support DSCP/TOS
+ * overwrite for downstream gates. If DSCP/TOS is enabled in a downstream gate and the CMTS does not support that
+ * function, then the field is ignored. The manner in which the CMTS interprets the DSCP/TOS Overwrite & Mask
+ * fields and transforms it into the corresponding DOCSIS Service Flow Parameters is defined in Section 6.4.2.5.
*/
public interface IGateSpec extends IPCMMBaseObject {
- byte SNUM = 5;
+ /**
+ * The S-Type for Gate Specifications
+ */
byte STYPE = 1;
- short LENGTH = 16;
/**
* <p>
}
- /**
- *
- */
- enum DSCPTOS {
-
- ENABLE((byte) 2), OVERRIDE((byte) 0);
-
- DSCPTOS(byte value) {
- this.value = value;
- }
-
- public byte getValue() {
- return value;
- }
-
- @Override
- public String toString() {
- switch (value) {
- case 1:
- return "Enable";
- default:
- return "Override";
- }
- }
-
- public static DSCPTOS valueOf(byte v) {
- switch (v) {
- case 0:
- return DSCPTOS.OVERRIDE;
- case 1:
- return DSCPTOS.ENABLE;
- default:
- throw new IllegalArgumentException("not supported value");
- }
- }
-
- private byte value;
-
- }
-
/**
* <p>
* provides a way for the Application Manager and the Policy Server to group
*/
ISessionClassID getSessionClassID();
- /**
- * <p>
- * sets the session class ID;
- * </p>
- * <p>
- * SessionClassID is a 1-byte unsigned integer value which identifies the
- * proper admission control policy or parameters to be applied for this
- * Gate. The SessionClassID is a bit field, defined as follows: Bit 0-2:
- * Priority, a number from 0 to 7, where 0 is low priority and 7 is high.
- * Bit 3: Preemption, set to enable preemption of bandwidth allocated to
- * lower priority sessions if necessary (if supported). Bit 4-7:
- * Configurable, default to 0
- * </p>
- */
- void setSessionClassID(ISessionClassID id);
-
/**
*
* @return direction.
*/
Direction getDirection();
- /**
- * sets the direction
- *
- * @param direction
- * Direction
- */
- void setDirection(Direction direction);
-
/**
* Authorized Timer limits the amount of time the authorization must remain
* valid before it is reserved
*/
short getTimerT1();
- /**
- * sets the authorized timer
- *
- * @param authTimer
- * : authorized timer
- */
- void setTimerT1(short authTimer);
-
/**
* Reserved Timer limits the amount of time the reservation must remain
* valid before the resources are committed
*/
short getTimerT2();
- /**
- * sets the reserved timer.
- *
- * @param timer
- */
- void setTimerT2(short timer);
-
/**
* Committed Timer limits the amount of time a committed service flow may
* remain idle.
*/
short getTimerT3();
- /**
- * sets the committed timer.
- *
- * @param t
- * timer
- */
- void setTimerT3(short t);
-
/**
* Committed Recovery Timer limits the amount of time that a committed
* service flow can remain without a subsequent refresh message from the
*/
short getTimerT4();
- /**
- * sets the Committed Recovery Timer.
- *
- * @param t
- * timer
- */
- void setTimerT4(short t);
-
- /**
- *
- * @param dscpTos - the object used to overwrite
- */
- void setDSCP_TOSOverwrite(DSCPTOS dscpTos);
-
- // set the DSCP_TOS value
- void setDSCP_TOSOverwrite(byte dscpTos);
-
/**
*
* @return DSCP/TOS
*/
- DSCPTOS getDSCP_TOSOverwrite();
+ byte getDSCP_TOSOverwrite();
/**
*
*/
byte getDSCP_TOSMask();
- /**
- *
- * @param dscp_tos_mask
- */
- void setDSCP_TOSMask(byte dscp_tos_mask);
-
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
-import java.net.InetAddress;
-
+/**
+ * The IPv6 Classifier object also specifies the packet matching rules associated with a Gate, when IPv6 Addresses are
+ * used. As defined in Sections 6.4.3.1 and 6.4.3.2, for Unicast Gates multiple IPv6 Classifier objects may be included
+ * in the Gate-Set to allow for complex classifier rules. However, since the ordering of objects in a message and the
+ * order of processing those objects is not mandated, an AM SHOULD NOT send a GateSet with multiple IPv6
+ * Classifiers with the same ClassificationID, yet different Actions. When an AM is using IPv6 Classifier objects, at
+ * least one IPv6 Classifier MUST be provided by the PDP in all Gate-Set messages. For Unicast Gates more than one
+ * IPv6 Classifier is allowed. For Multicast Gates only one IPv6 Classifier is required to be supported. Since the IPv6
+ * Classifier is based on the DOCSIS IPv6 Classifier, all DOCSIS classifier semantics apply, with the exeption that at
+ * least one IPv6 Classifier be present in a Gate-Set message.
+ */
public interface IIPv6Classifier extends IExtendedClassifier {
- short LENGTH = 64;
- byte SNUM = 6;
+// short LENGTH = 64;
+// byte SNUM = 6;
byte STYPE = 3;
// flags: Flow Label match enable flag
- void setFlowLabelEnableFlag(byte flag);
- byte getFlowLabelEnableFlag();
+ FlowLabel getFlowLabelEnableFlag();
// Tc-low
- void setTcLow(byte tcLow);
byte getTcLow();
// Tc-high
- void setTcHigh(byte tcHigh);
byte getTcHigh();
// Tc-mask
- void setTcMask(byte tcHigh);
byte getTcMask();
// Flow Label
- void setFlowLabel(Long flowLabel);
int getFlowLabel();
// Next Header Type
- void setNextHdr(short nxtHdr);
short getNextHdr();
// Source Prefix Length
- void setSourcePrefixLen(byte srcPrefixLen);
byte getSourcePrefixLen();
// Destination Prefix Length
- void setDestinationPrefixLen(byte dstPrefixLen);
byte getDestinationPrefixLen();
- // IPv6 Source Address
- void setSourceIPAddress(InetAddress a);
- InetAddress getSourceIPAddress();
-
- // IPv6 Destination Address
- void setDestinationIPAddress(InetAddress a);
- InetAddress getDestinationIPAddress();
-
- // Source Port Start
- short getSourcePortStart();
- void setSourcePortStart(short p);
+ /**
+ * The valid activation state values
+ */
+ enum FlowLabel {
- // Source Port End
- short getSourcePortEnd();
- void setSourcePortEnd(short p);
+ IRRELEVANT((byte) 0), VALID((byte) 1);
- // Destination Port Start
- short getDestinationPortStart();
- void setDestinationPortStart(short p);
+ FlowLabel(byte value) {
+ this.value = value;
+ }
- // Destination Port End
- short getDestinationPortEnd();
- void setDestinationPortEnd(short p);
+ public byte getValue() {
+ return value;
+ }
- // ClassifierID
- short getClassifierID();
- void setClassifierID(short p);
+ public static FlowLabel valueOf(byte v) {
+ switch (v) {
+ case 0:
+ return FlowLabel.IRRELEVANT;
+ case 1:
+ return FlowLabel.VALID;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
- // Priority
- void setPriority(byte p);
- byte getPriority();
+ private byte value;
- // Activation State
- void setActivationState(byte s);
- byte getActivationState();
+ }
- // Action
- void setAction(byte a);
- byte getAction();
}
import org.pcmm.base.IPCMMBaseObject;
/**
- *
+ * The aPacketCable Error object contains information on the type of error that has occurred. The error is generated in
+ * response to a Gate Control command and is contained in Gate-Set-Err, Gate-Info-Err and Gate-Delete-Err messages.
*/
public interface IPCMMError extends IPCMMBaseObject {
- short LENGTH = 8;
- byte SNUM = 14;
+
byte STYPE = 1;
- String[] errors = { "Insufficient Resources", "Unknown GateID",
- "Missing Required Object", "Invalid Object",
- "Volume Based Usage Limit Exceeded",
- "Time Based Usage Limit Exceeded", "Session Class Limit Exceeded",
- "Undefined Service Class Name", "Incompatible Envelope",
- "Invalid SubscriberID", "Unauthorized AMID",
- "Number of Classifiers Not Supported", "Policy Exception",
- "Invalid Field Value in Object", "Transport Error",
- "Unknown Gate Command", "DOCSIS 1.0 CM",
- "Number of SIDs exceeded in CM", "Number of SIDs exceeded in CMTS",
- "Unauthorized PSID", "No State for PDP", "Unsupported Synch Type",
- "State Data Incomplete", "Upstream Drop Unsupported",
- "Multicast Gate Error", "Multicast Volume Limit Unsupported",
- "Uncommitted Multicast Not Supported",
- "Multicast Gate Modification Not Supported",
- "Upstream Multicast Not Supported",
- "Multicast GateSpec incompatibility", "Multicast QoS Error",
- "Multicast Downstream Resequencing mismatch",
- "Other, Unspecified Error" };
- enum Description {
- ERROR_01((short) 1, errors[0]), ERROR_02((short) 2, errors[1]), ERROR_06(
- (short) 6, errors[2]), ERROR_07((short) 7, errors[3]), ERROR_08(
- (short) 8, errors[4]), ERROR_09((short) 9, errors[5]), ERROR_10(
- (short) 10, errors[6]), ERROR_11((short) 11, errors[7]), ERROR_12(
- (short) 12, errors[8]), ERROR_13((short) 13, errors[9]), ERROR_14(
- (short) 14, errors[10]), ERROR_15((short) 15, errors[11]), ERROR_16(
- (short) 16, errors[12]), ERROR_17((short) 17, errors[13]), ERROR_18(
- (short) 18, errors[14]), ERROR_19((short) 19, errors[15]), ERROR_20(
- (short) 20, errors[16]), ERROR_21((short) 21, errors[17]), ERROR_22(
- (short) 22, errors[18]), ERROR_23((short) 23, errors[19]), ERROR_24(
- (short) 24, errors[20]), ERROR_25((short) 25, errors[21]), ERROR_26(
- (short) 26, errors[22]), ERROR_27((short) 27, errors[23]), ERROR_28(
- (short) 28, errors[24]), ERROR_29((short) 29, errors[25]), ERROR_30(
- (short) 30, errors[26]), ERROR_31((short) 31, errors[27]), ERROR_32(
- (short) 32, errors[28]), ERROR_33((short) 33, errors[29]), ERROR_34(
- (short) 34, errors[30]), ERROR_35((short) 35, errors[31]), ERROR_127(
- (short) 127, errors[28]);
+ /**
+ * Returns the error code
+ * @return - not null or NA
+ */
+ ErrorCode getErrorCode();
+
+ /**
+ * Returns the error sub-code
+ * @return - not null (mostly will be NA)
+ */
+ ErrorCode getErrorSubcode();
+
+ /**
+ * Returns the error's description
+ * @return - not null
+ */
+ String getDescription();
+
+ /**
+ * The supported PCMM error codes with description.
+ */
+ enum ErrorCode {
+ NA((short) 0, "NA"),
+ INSUFF_RES((short) 1, "Insufficient Resources"),
+ UNK_GATE_ID((short) 2, "Unknown GateID"),
+ MISSING_REQ_OBJ((short) 6, "Missing Required Object"),
+ INVALID_OBJ((short) 7, "Invalid Object"),
+ VOL_USG_LMT((short) 8, "Volume Based Usage Limit Exceeded"),
+ TIME_USG_LMT((short) 9, "Time Based Usage Limit Exceeded"),
+ SESSN_CLASS_LMT((short) 10, "Session Class Limit Exceeded"),
+ UNDEF_SCN_NAME((short) 11, "Undefined Service Class Name"),
+ INCOMPAT_ENV((short) 12, "Incompatible Envelope"),
+ INVALID_SUB_ID((short) 13, "Invalid SubscriberID"),
+ UNAUTH_AMID((short) 14, "Unauthorized AMID"),
+ NUM_CLASSIFIERS((short) 15, "Number of Classifiers Not Supported"),
+ POLICY_EXCEPTION((short) 16, "Policy Exception"),
+ INVALID_FIELD((short) 17, "Invalid Field Value in Object"),
+ TRANSPORT_ERROR((short) 18, "Transport Error"),
+ UNK_GATE_CMD((short) 19, "Unknown Gate Command"),
+ DOCSIS_1_CM((short) 20, "DOCSIS 1.0 CM"),
+ NUM_CM_SID((short) 21, "Number of SIDs exceeded in CM"),
+ NUM_CMTS_SID((short) 22, "Number of SIDs exceeded in CMTS"),
+ UNAUTH_PSID((short) 23, "Unauthorized PSID"),
+ NO_STATE_PDP((short) 24, "No State for PDP"),
+ UNSUP_SYNC_TYPE((short) 25, "Unsupported Synch Type"),
+ STATE_INCMPL((short) 26, "State Data Incomplete"),
+ UP_DROP_UNSUPPORT((short) 27, "Upstream Drop Unsupported"),
+ MULTI_GATE_ERR((short) 28, "Multicast Gate Error"),
+ MULTI_VOL_LIMIT((short) 29, "Multicast Volume Limit Unsupported"),
+ MULTI_UNCOMMITTED((short) 30, "Uncommitted Multicast Not Supported"),
+ MULTI_GATE_MOD((short) 31, "Multicast Gate Modification Not Supported"),
+ MULTI_UP_ERR((short) 32, "Upstream Multicast Not Supported"),
+ MULTI_GATE_INCOMPAT((short) 33, "Multicast GateSpec incompatibility"),
+ MULTI_QOS_ERR((short) 34, "Multicast QoS Error"),
+ MULTI_DN_RESEQ((short) 35, "Multicast Downstream Resequencing mismatch"),
+ OTHER_UNSPECIFIED((short) 127, "Other, Unspecified Error");
private final short code;
private final String description;
- Description(short code, String description) {
+ ErrorCode(short code, String description) {
this.code = code;
this.description = description;
}
return code;
}
- public static String valueOf(short errCode) {
- switch (errCode) {
- case 1:
- case 2:
- case 4:
- return errors[errCode - 1];
- case 127:
- return errors[32];
- default:
- if (errCode > 35 || errCode < 1)
- throw new IllegalArgumentException("unrecongnized error code : " + errCode);
- return errors[errCode - 4];
+ public static ErrorCode valueOf(final short index) {
+ switch (index) {
+ case 0:
+ return NA;
+ case 1:
+ return INSUFF_RES;
+ case 2:
+ return UNK_GATE_ID;
+ case 6:
+ return MISSING_REQ_OBJ;
+ case 7:
+ return INVALID_OBJ;
+ case 8:
+ return VOL_USG_LMT;
+ case 9:
+ return TIME_USG_LMT;
+ case 10:
+ return SESSN_CLASS_LMT;
+ case 11:
+ return UNDEF_SCN_NAME;
+ case 12:
+ return INCOMPAT_ENV;
+ case 13:
+ return INVALID_SUB_ID;
+ case 14:
+ return UNAUTH_AMID;
+ case 15:
+ return NUM_CLASSIFIERS;
+ case 16:
+ return POLICY_EXCEPTION;
+ case 17:
+ return INVALID_FIELD;
+ case 18:
+ return TRANSPORT_ERROR;
+ case 19:
+ return UNK_GATE_CMD;
+ case 20:
+ return DOCSIS_1_CM;
+ case 21:
+ return NUM_CM_SID;
+ case 22:
+ return NUM_CMTS_SID;
+ case 23:
+ return UNAUTH_PSID;
+ case 24:
+ return NO_STATE_PDP;
+ case 25:
+ return UNSUP_SYNC_TYPE;
+ case 26:
+ return STATE_INCMPL;
+ case 27:
+ return UP_DROP_UNSUPPORT;
+ case 28:
+ return MULTI_GATE_ERR;
+ case 29:
+ return MULTI_VOL_LIMIT;
+ case 30:
+ return MULTI_UNCOMMITTED;
+ case 31:
+ return MULTI_GATE_MOD;
+ case 32:
+ return MULTI_UP_ERR;
+ case 33:
+ return MULTI_GATE_INCOMPAT;
+ case 34:
+ return MULTI_QOS_ERR;
+ case 35:
+ return MULTI_DN_RESEQ;
+ case 127:
+ return OTHER_UNSPECIFIED;
+ default:
+ return null;
}
}
}
- void setErrorCode(short ErrorCode);
-
- short getErrorCode();
-
- void setErrorSubcode(short ErrorSubcode);
-
- short getErrorSubcode();
-
- String getDescription();
}
*/
void setGateID(IGateID gateid);
- /**
- * AMID is the handle that identifies the Application Manager and
- * Application Type
- *
- */
- void setAMID(IAMID iamid);
-
- /**
- * SubscriberID uniquely identifies the Client for which the policy is being
- * set.
- *
- */
- void setSubscriberID(ISubscriberID subscriberID);
-
/**
* (i.e., QoS limits, timers, etc.).
*
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates;
/**
*/
byte getPriority();
- /**
- * sets the priority value (0-7)
- *
- * @param value
- * priority
- */
- void setPriority(byte value);
-
/**
* gets the preemption value;
*
*/
byte getPreemption();
- /**
- * * sets the preemption
- *
- * @param value
- * preemption
- */
- void setPreemption(byte value);
-
/**
* compress the priority and preemption to a single byte value;
*
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
-import java.net.InetAddress;
-
import org.pcmm.base.IPCMMBaseObject;
+import java.net.InetAddress;
+
/**
* <p>
* The SubscriberID, consisting of the IPv4 or IPv6 address of either the CM or
*/
public interface ISubscriberID extends IPCMMBaseObject {
- static final short LENGTH = 8;
- static final byte SNUM = 3;
- static final byte STYPE = 1;
+
+ byte STYPE = 1;
/**
* source IP address for the PCMM gate.
*/
InetAddress getSourceIPAddress();
- void setSourceIPAddress(InetAddress address);
-
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
public interface ITrafficProfile extends IPCMMBaseObject {
- static final byte SNUM = 7;
-
- /**
- * 0x001, 0x011 and 0x111 (Authorized, Reserved, and Committed) are allowed
- *
- * @param en
- */
- void setEnvelop(byte en);
+ // Authorized
+ byte DEFAULT_ENVELOP = 0x7;
byte getEnvelop();
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates;
import org.pcmm.base.IPCMMBaseObject;
/**
+ * TransactionID is a 2-byte unsigned integer quantity, which contains a token that is used by the Application Manager
+ * to match responses from the Policy Server and by the Policy Server to match responses from the CMTS to the
+ * previous requests. The TransactionID MUST also contain the command type that identifies the action to be taken or
+ * response.
*/
public interface ITransactionID extends IPCMMBaseObject {
- static final byte SNUM = 1;
- static final byte STYPE = 1;
- static final short LENGTH = 8;
-
- static final short GateSet = 4;
- static final short GateSetAck = 5;
- static final short GateSetErr = 6;
- static final short GateInfo = 7;
- static final short GateInfoAck = 8;
- static final short GateInfoErr = 9;
- static final short GateDelete = 10;
- static final short GateDeleteAck = 11;
- static final short GateDeleteErr = 12;
- static final short GateReportState = 15;
- static final short GateCmdErr = 16;
- static final short PDPConfig = 17;
- static final short PDPConfigAck = 18;
- static final short PDPConfigErr = 19;
- static final short SynchRequest = 20;
- static final short SynchReport = 21;
- static final short SynchComplete = 22;
- static final short MsgReceipt = 23;
-
- void setTransactionIdentifier(short id);
+ byte STYPE = 1;
+ /**
+ * Returns the transaction identifier value
+ * @return - the ID
+ */
short getTransactionIdentifier();
- void setGateCommandType(short type);
+ /**
+ * Returns the command type
+ * @return - the command type
+ */
+ GateCommandType getGateCommandType();
+
+ /**
+ * The supported Synchronization types
+ */
+ enum GateCommandType {
+
+ GATE_SET((short) 4),
+ GATE_SET_ACK((short) 5),
+ GATE_SET_ERR((short) 6),
+ GATE_INFO((short) 7),
+ GATE_INFO_ACK((short) 8),
+ GATE_INFO_ERR((short) 9),
+ GATE_DELETE((short) 10),
+ GATE_DELETE_ACK((short) 11),
+ GATE_DELETE_ERR((short) 12),
+ GATE_RPT_STATE((short) 15),
+ GATE_CMD_ERR((short) 16),
+ PDP_CONFIG((short) 17),
+ PDP_CONFIG_ACK((short) 18),
+ PDP_CONFIG_ERR((short) 19),
+ SYNC_REQUEST((short) 20),
+ SYNC_RPT((short) 21),
+ SYNC_COMPLETE((short) 22),
+ MSG_RECEIPT((short) 23);
+
+ GateCommandType(short value) {
+ this.value = value;
+ }
+
+ public short getValue() {
+ return value;
+ }
+
+ public static GateCommandType valueOf(short v) {
+ switch (v) {
+ case 4:
+ return GateCommandType.GATE_SET;
+ case 5:
+ return GateCommandType.GATE_SET_ACK;
+ case 6:
+ return GateCommandType.GATE_SET_ERR;
+ case 7:
+ return GateCommandType.GATE_INFO;
+ case 8:
+ return GateCommandType.GATE_INFO_ACK;
+ case 9:
+ return GateCommandType.GATE_INFO_ERR;
+ case 10:
+ return GateCommandType.GATE_DELETE;
+ case 11:
+ return GateCommandType.GATE_DELETE_ACK;
+ case 12:
+ return GateCommandType.GATE_DELETE_ERR;
+ case 15:
+ return GateCommandType.GATE_RPT_STATE;
+ case 16:
+ return GateCommandType.GATE_CMD_ERR;
+ case 17:
+ return GateCommandType.PDP_CONFIG;
+ case 18:
+ return GateCommandType.PDP_CONFIG_ACK;
+ case 19:
+ return GateCommandType.PDP_CONFIG_ERR;
+ case 20:
+ return GateCommandType.SYNC_REQUEST;
+ case 21:
+ return GateCommandType.SYNC_RPT;
+ case 22:
+ return GateCommandType.SYNC_COMPLETE;
+ case 23:
+ return GateCommandType.MSG_RECEIPT;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
+
+ private short value;
- short getGateCommandType();
+ }
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.IAMID;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
+ * Implementation of the IAMID interface
*/
public class AMID extends PCMMBaseObject implements IAMID {
/**
- *
+ * Application Type is a 2-byte unsigned integer value which identifies the type of application that this gate is
+ * associated with. The Application Manager MUST include this object in all messages it issues to the Policy Server.
+ * The Policy Server MUST include the received AMID in all messages it issues down the CMTS in response to the
+ * messages it receives from the Application Manager.
*/
- public AMID() {
- this(LENGTH, STYPE, SNUM);
- }
+ private final short appType;
/**
- * @param data
+ * The application manager tag
*/
- public AMID(byte[] data) {
- super(data);
- }
+ private final short appMgrTag;
/**
- * @param len
- * @param sType
- * @param sNum
+ * Constructor
+ * @param appType - the application type
+ * @param appMgrTag - the application manager tag
*/
- public AMID(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
+ public AMID(final short appType, final short appMgrTag) {
+ super(SNum.AMID, STYPE);
+ this.appType = appType;
+ this.appMgrTag = appMgrTag;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IAMID#setApplicationType(short)
- */
@Override
- public void setApplicationType(short type) {
- setShort(type, (short) 0);
+ public short getApplicationType() {
+ return appType;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IAMID#getApplicationType()
- */
@Override
- public short getApplicationType() {
- return getShort((short) 0);
+ public short getApplicationMgrTag() {
+ return appMgrTag;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IAMID#setApplicationMgrTag(short)
- */
@Override
- public void setApplicationMgrTag(short type) {
- setShort(type, (short) 2);
+ protected byte[] getBytes() {
+ final byte[] appTypeBytes = COPSMsgParser.shortToBytes(appType);
+ final byte[] appMgrBytes = COPSMsgParser.shortToBytes(appMgrTag);
+ final byte[] data = new byte[appTypeBytes.length + appMgrBytes.length];
+ System.arraycopy(appTypeBytes, 0, data, 0, appTypeBytes.length);
+ System.arraycopy(appMgrBytes, 0, data, appTypeBytes.length, appMgrBytes.length);
+ return data;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IAMID#getApplicationMgrTag()
- */
@Override
- public short getApplicationMgrTag() {
- return getShort((short) 2);
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AMID)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final AMID amid = (AMID) o;
+ return appType == amid.appType && appMgrTag == amid.appMgrTag;
}
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (int) appType;
+ result = 31 * result + (int) appMgrTag;
+ return result;
+ }
+
+ /**
+ * Returns an AMID object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static AMID parse(final byte[] data) {
+ return new AMID(COPSMsgParser.bytesToShort(data[0], data[1]), COPSMsgParser.bytesToShort(data[2], data[3]));
+ }
}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import com.google.common.primitives.Bytes;
+import org.umu.cops.stack.COPSMsgParser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class for use as member to the ITrafficProfile#BestEffortService class.
+ */
+public class BEEnvelop {
+
+ public static final byte DEFAULT_TRAFFIC_PRIORITY = 0;
+
+ public static final int DEFAULT_MAX_TRAFFIC_BURST = 3044;
+
+ /**
+ * Traffic Priority is a 1-byte unsigned integer field specifying the relative priority assigned to the Service Flow
+ * in comparison with other flows. This field is fully defined in section C.2.2.5.1 of [1]. A default Traffic
+ * Priority of SHOULD be used if a specific Traffic Priority value is not required.
+ */
+ private final byte trafficPriority;
+
+ /**
+ * Request/Transmission Policy is a 4-byte bit field as defined in section C.2.2.6.3. A default Request/Transmission
+ * policy of 0 SHOULD be used if a specific Request/Transmission Policy value is not required.
+ */
+ private final int transPolicy;
+
+ /**
+ * Maximum Sustained Traffic Rate is a 4-byte unsigned integer field specifying the rate parameter, in bits/sec.
+ * A value of 0 indicates that no explicitly-enforced Maximum Sustained Rate is requested. A default Maximum
+ * Sustained Traffic Rate of 0 SHOULD be used if a specific Maximum Sustained Traffic Rate is not required.
+ */
+ private final int maxSusTrafficRate;
+
+ /**
+ * Maximum Traffic Burst is a 4-byte unsigned integer field specifying the token bucket size, in bytes, for a
+ * tokenbucket-based rate limit for this Service Flow. This field is fully defined in section C.2.2.5.3 of [1].
+ * A default Maximum Traffic Burst of 3044 bytes SHOULD be used if a specific Maximum Traffic Burst is not required.
+ * The value of this parameter has no effect unless a non-zero value has been provided Rate parameter.
+ */
+ private final int maxTrafficBurst;
+
+ /**
+ * Minimum Reserved Traffic Rate is a 4-byte unsigned integer field specifying the minimum rate, in bits/sec,
+ * reserved for this Service Flow. This field is fully defined in section C.2.2.5.4. A default Mini Rate of 0 SHOULD
+ * be used if a specific Minimum Reserved Traffic Rate is not required.
+ */
+ private final int minResTrafficRate;
+
+ /**
+ * Assumed Minimum Reserved Traffic Rate Packet Size is a 2-byte unsigned integer field specifying an assumed
+ * minimum packet size, in bytes, for which the Minimum Reserved Traffic Rate will be provided for this flow. This
+ * field is fully defined in section C.2.2.5.5. A default Assumed Minimum Reserved Traffic Rate Packet Size of
+ * 0 SHOULD be used if a specific Assumed Minimum Reserved Traffic Rate Packet size is not required. Upon receip
+ * of a value of 0 the CMTS MUST utilize its implementation-specific default size for this parameter, not 0 bytes.
+ */
+ private final short assumedMinConcatBurst;
+
+ /**
+ * Maximum Concatenated Burst is a 2-byte unsigned integer specifying the maximum concatenated burst (in bytes)
+ * which a Service Flow is allowed. This field is fully defined in section C.2.2.6.1. A value of 0 means
+ * there is no limit. A default Maximum Concatenated Burst of 1522 bytes SHOULD be used if a specific Maximum
+ * Concatenated Burst is not required.
+ */
+ private final short maxConcatBurst;
+
+ /**
+ * Upstream Peak Traffic Rate is a 4-byte unsigned integer specifying the Peak traffic rate (in bits per second)
+ * which a Service Flow is allowed. This field is fully defined in section C.2.2.5.10.1.
+ */
+ private final int upPeakTrafficRate;
+
+ /*
+ * Attribute Masks define a specific set of attributes associated with a DOCSIS 3.0 service flow. The CMTS MUST
+ * ignore the bonded bit in the Required and Forbidden Attribute Mask objects if the cable modem associated with the
+ * service flow is operating in pre-3.0 DOCSIS mode. The Required Attribute Mask limits the set of channels and
+ * bonding groups to which the CMTS assigns the service flow by requiring certain attributes. This field is fully
+ * defined in section C.2.2.3.6 of [1]. The Forbidden Attribute Mask limits the set of channels and bonding groups
+ * to which the CMTS assigns the service flow by forbidding certain attributes. This field is fully defined in
+ * section C.2.2.3.7. The CMTS is free to assign the service flow to any channel that satisfies the traffic profile
+ * if no channel is available that satisfies the Required Attribute Mask and Forbidden Attribute Mask for the
+ * service flow. The Attribute Aggregation Rule Mask provides guidance to the CMTS as to how it might use the
+ * attribute masks of individual channels to construct a dynamic bonding group for this service flow. This field is
+ * fully described in section "Service Flow Attribute Aggregation Rule Mask". As described in that section a default
+ * Attribute Aggregation Rule Mask of 0 SHOULD be used if specific Attribute Aggregation Rules are not required.
+ * The Buffer Control parameters libit the maximum queue depth of a Service Flow. The service flow buffer holds the
+ * packets that are enqueued for transmission for the service flow. The size of the service flow buffer sets the
+ * maximum queue depth, and upper limit on the amount of data that can be enqueued for transmission at any time by
+ * the service flow. By providing the ability to control per-service flow buffers. the below Buffer Control
+ * parameters provide a means of balancing throughput and latency in a standardized and configurable manner.
+ */
+
+ /**
+ * Required Attribute Mask (see explanation above)
+ */
+ private final int reqAttrMask;
+
+ /**
+ * Forbidden Attribute Mask (see explanation above)
+ */
+ private final int forbidAttrMask;
+
+ /**
+ * Attribute Aggregation Rule Mask (see explanation above)
+ */
+ private final int attrAggRuleMask;
+
+ /**
+ * Minimum Buffer is a 4-byte unsigned integer parameter that defines a lower limit for the size of the buffer that
+ * is to be provided for a service flow. This field is fully defined in section C.2.2.5.11.3. If this parameter is
+ * omitted. The Minimum Buffer defaluts to a value of 0, which indicates that there is no lower limit.
+ */
+ private final int minBuffer;
+
+ /**
+ * Target Buffer is a 4-byte unsigned integer parameter that defines a desired value for the size of the buffer that
+ * is to be provided for a service flow. This field is fully defined in section C.2.2.5.11.4. If this parameter is
+ * omitted or set to a value of 0, the device selects any buffer size within the range of the Minimum and Maximum
+ * Buffers, via a vendor specific algorithm.
+ */
+ private final int targetBuffer;
+
+ /**
+ * Maximum Buffer is a 4-byte unsigned integer parameter that defines an upper limit for the size of the buffer that
+ * is to be provided for a service flow. This field is fully defined in section C.2.2.5.11.5. If this parameter is
+ * omitted or set to a value of 0, the Maximum Buffer defaults to a value of no limit.
+ */
+ private final int maxBuffer;
+
+ /**
+ * Constructor
+ * @param trafficPriority - the Traffic Priority
+ * @param transPolicy - the Requested Transmission Policy
+ * @param maxSusTrafficRate - the Maximum Sustained Traffic Rate
+ * @param maxTrafficBurst - the Maximum Traffic Burst Rate
+ * @param minResTrafficRate - the Minimum Reserved Traffic Rate
+ * @param assumedMinConcatBurst - the Assumed Minimum Reserved Traffic Rate Packet Size
+ * @param maxConcatBurst - the Maximum Concatenated Burst
+ * @param upPeakTrafficRate - the Upstream Peak Traffic Rate
+ * @param reqAttrMask - the Required Attribute Mask
+ * @param forbidAttrMask - the Forbidden Attribute Mask
+ * @param attrAggRuleMask - the Attribute Aggregation Rule Mask
+ * @param minBuffer - the Minimum Buffer
+ * @param targetBuffer - the Target Buffer
+ * @param maxBuffer - the Maximum Buffer
+ */
+ public BEEnvelop(byte trafficPriority, int transPolicy, int maxSusTrafficRate, int maxTrafficBurst,
+ int minResTrafficRate, short assumedMinConcatBurst, short maxConcatBurst, int upPeakTrafficRate,
+ int reqAttrMask, int forbidAttrMask, int attrAggRuleMask, int minBuffer, int targetBuffer,
+ int maxBuffer) {
+ this.trafficPriority = trafficPriority;
+ this.transPolicy = transPolicy;
+ this.maxSusTrafficRate = maxSusTrafficRate;
+ this.maxTrafficBurst = maxTrafficBurst;
+ this.minResTrafficRate = minResTrafficRate;
+ this.assumedMinConcatBurst = assumedMinConcatBurst;
+ this.maxConcatBurst = maxConcatBurst;
+ this.upPeakTrafficRate = upPeakTrafficRate;
+ this.reqAttrMask = reqAttrMask;
+ this.forbidAttrMask = forbidAttrMask;
+ this.attrAggRuleMask = attrAggRuleMask;
+ this.minBuffer = minBuffer;
+ this.targetBuffer = targetBuffer;
+ this.maxBuffer = maxBuffer;
+ }
+
+ /**
+ * Returns a List of Bytes which can be parsed back into an equivalent object. This method is generally used when
+ * streaming this object over a Socket
+ * @return - the byte translation of this object
+ */
+ public List<Byte> getBytes() {
+ final List<Byte> byteList = new ArrayList<>();
+ byteList.addAll(Bytes.asList(trafficPriority, (byte) 0, (byte) 0, (byte) 0));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(transPolicy)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(maxSusTrafficRate)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(maxTrafficBurst)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(minResTrafficRate)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(assumedMinConcatBurst)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(maxConcatBurst)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(upPeakTrafficRate)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(reqAttrMask)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(forbidAttrMask)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(attrAggRuleMask)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(minBuffer)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(targetBuffer)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(maxBuffer)));
+ return byteList;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof BEEnvelop)) {
+ return false;
+ }
+
+ final BEEnvelop beEnvelop = (BEEnvelop) o;
+
+ return trafficPriority == beEnvelop.trafficPriority && transPolicy == beEnvelop.transPolicy &&
+ maxSusTrafficRate == beEnvelop.maxSusTrafficRate && maxTrafficBurst == beEnvelop.maxTrafficBurst &&
+ minResTrafficRate == beEnvelop.minResTrafficRate &&
+ assumedMinConcatBurst == beEnvelop.assumedMinConcatBurst &&
+ maxConcatBurst == beEnvelop.maxConcatBurst && upPeakTrafficRate == beEnvelop.upPeakTrafficRate &&
+ reqAttrMask == beEnvelop.reqAttrMask && forbidAttrMask == beEnvelop.forbidAttrMask &&
+ attrAggRuleMask == beEnvelop.attrAggRuleMask && minBuffer == beEnvelop.minBuffer &&
+ targetBuffer == beEnvelop.targetBuffer && maxBuffer == beEnvelop.maxBuffer;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = (int) trafficPriority;
+ result = 31 * result + transPolicy;
+ result = 31 * result + maxSusTrafficRate;
+ result = 31 * result + maxTrafficBurst;
+ result = 31 * result + minResTrafficRate;
+ result = 31 * result + (int) assumedMinConcatBurst;
+ result = 31 * result + (int) maxConcatBurst;
+ result = 31 * result + upPeakTrafficRate;
+ result = 31 * result + reqAttrMask;
+ result = 31 * result + forbidAttrMask;
+ result = 31 * result + attrAggRuleMask;
+ result = 31 * result + minBuffer;
+ result = 31 * result + targetBuffer;
+ result = 31 * result + maxBuffer;
+ return result;
+ }
+
+ /**
+ * Returns an BEEnvelop object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static BEEnvelop parse(final byte[] data) {
+ if (data.length != 52) return null;
+ return new BEEnvelop(data[0],
+ COPSMsgParser.bytesToInt(data[4], data[5], data[6], data[7]),
+ COPSMsgParser.bytesToInt(data[8], data[9], data[10], data[11]),
+ COPSMsgParser.bytesToInt(data[12], data[13], data[14], data[15]),
+ COPSMsgParser.bytesToInt(data[16], data[17], data[18], data[19]),
+ COPSMsgParser.bytesToShort(data[20], data[21]),
+ COPSMsgParser.bytesToShort(data[22], data[23]),
+ COPSMsgParser.bytesToInt(data[24], data[25], data[26], data[27]),
+ COPSMsgParser.bytesToInt(data[28], data[29], data[30], data[31]),
+ COPSMsgParser.bytesToInt(data[32], data[33], data[34], data[35]),
+ COPSMsgParser.bytesToInt(data[36], data[37], data[38], data[39]),
+ COPSMsgParser.bytesToInt(data[40], data[41], data[42], data[43]),
+ COPSMsgParser.bytesToInt(data[44], data[45], data[46], data[47]),
+ COPSMsgParser.bytesToInt(data[48], data[49], data[50], data[51]));
+ }
+}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-package org.pcmm.gates.impl;
-import java.util.Arrays;
+package org.pcmm.gates.impl;
-// import org.junit.Assert;
+import com.google.common.primitives.Bytes;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.ITrafficProfile;
-import org.umu.cops.stack.COPSData;
+
+import java.util.ArrayList;
+import java.util.List;
/**
- *
+ * The Best Effort object defines the Traffic Profile associated with a gate through an upstream DOCSIS-specific
+ * parameterization scheme.
*/
-public class BestEffortService extends PCMMBaseObject implements
- ITrafficProfile {
+public class BestEffortService extends PCMMBaseObject implements ITrafficProfile {
+
public static final byte STYPE = 3;
// XXX -> 60=0x3C, 112 = 0x70, 164=0xA4
// Length = 44=0x2C, 80=0x50 or 116=0x74
- public static final short LENGTH = 44;
public static final byte DEFAULT_TRAFFIC_PRIORITY = 0;
- // Authorized
- public static final byte DEFAULT_ENVELOP = 0x7;
public static final int DEFAULT_MAX_TRAFFIC_BURST = 3044;
- private BEEnvelop authorizedEnvelop;
+ /**
+ * The envelope
+ */
+ private final byte envelope;
- private BEEnvelop reservedEnvelop;
+ /**
+ * The authorized envelope. See BEEnvelope for description of the attributes. MUST NOT be NULL.
+ */
+ private final BEEnvelop authorizedEnvelop;
- private BEEnvelop committedEnvelop;
+ /**
+ * The reserved envelope. See BEEnvelope for description of the attributes. CAN BE NULL.
+ */
+ private final BEEnvelop reservedEnvelop;
/**
- *
- * @param e
- * envelop
+ * The committed envelope. See BEEnvelope for description of the attributes. CAN BE NULL.
*/
- public BestEffortService(byte e) {
- super((short) (e == 1 ? LENGTH : (e == 7 ? 116 : 80)), STYPE, SNUM);
- setEnvelop(e);
- authorizedEnvelop = new BEEnvelop();
- if (e > 1) {
- reservedEnvelop = new BEEnvelop();
- if (e == 7)
- committedEnvelop = new BEEnvelop();
- }
- }
+ private final BEEnvelop committedEnvelop;
- public BestEffortService(byte[] bytes) {
- super(bytes);
- byte e = getEnvelop();
- authorizedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, 8, LENGTH)));
- if (e > 1) {
- reservedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, LENGTH, 80)));
- if (e == 7)
- committedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, 80, 116)));
- }
+ /**
+ * General use constructor
+ * @param auth - the authorized envelope (required)
+ * @param reserved - the reserved envelope (optional)
+ * @param committed - the committed envelope (optional)
+ */
+ public BestEffortService(final BEEnvelop auth, final BEEnvelop reserved, final BEEnvelop committed) {
+ this(DEFAULT_ENVELOP, auth, reserved, committed);
}
- @Override
- public void setEnvelop(byte e) {
- setLength((short) (e == 1 ? LENGTH : (e == 7 ? 116 : 80)));
- // reset cops data to fit the new length
- byte[] array = new byte[getLength() - offset];
- Arrays.fill(array, (byte) 0);
- setData(new COPSData(array, 0, array.length));
- setByte(e, (short) 0);
+ /**
+ * Constructor generally used for byte parsing only.
+ * @param envelope - the envelope value
+ * @param auth - the authorized envelope (required)
+ * @param reserved - the reserved envelope (optional)
+ * @param committed - the committed envelope (optional)
+ */
+ protected BestEffortService(final byte envelope, final BEEnvelop auth, final BEEnvelop reserved,
+ final BEEnvelop committed) {
+ super(SNum.TRAFFIC_PROFILE, STYPE);
+ if (auth == null) throw new IllegalArgumentException("Authorized envelope must not be null");
+
+ // TODO - Cannot figure out any other means to parse the bytes unless this is true. Determine if correct???
+ if (reserved == null && committed != null)
+ throw new IllegalArgumentException("Cannot have a committed envelope without a reserved");
+
+ this.envelope = envelope;
+ this.authorizedEnvelop = auth;
+ this.reservedEnvelop = reserved;
+ this.committedEnvelop = committed;
}
@Override
public byte getEnvelop() {
- return getByte((short) 0);
+ return envelope;
}
+ // Getters
public BEEnvelop getAuthorizedEnvelop() {
return authorizedEnvelop;
}
}
@Override
- public byte[] getAsBinaryArray() {
- byte[] returnBuffer = super.getAsBinaryArray();
-
- {// fill buffer with the Authorized Envelop
- byte[] authEnv = Arrays.copyOfRange(getAuthorizedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
- // offset + 4 since the Envelop data begin from byte nb 8
- System.arraycopy(authEnv, 0, returnBuffer, offset + 4, authEnv.length);
- }
- if (getReservedEnvelop() != null) {
- byte[] reservedEnv = Arrays.copyOfRange(getReservedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
- System.arraycopy(reservedEnv, 0, returnBuffer, LENGTH, reservedEnv.length);
- }
- if (getCommittedEnvelop() != null) {
- byte[] commitEnv = Arrays.copyOfRange(getCommittedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
- System.arraycopy(commitEnv, 0, returnBuffer, LENGTH + 36, commitEnv.length);
- }
- return returnBuffer;
+ public byte[] getBytes() {
+ final List<Byte> byteList = new ArrayList<>();
+ byteList.addAll(Bytes.asList(envelope, (byte) 0, (byte) 0, (byte) 0));
+ byteList.addAll(authorizedEnvelop.getBytes());
+ if (reservedEnvelop != null) byteList.addAll(reservedEnvelop.getBytes());
+ if (committedEnvelop != null) byteList.addAll(committedEnvelop.getBytes());
+ return Bytes.toArray(byteList);
}
- /**
- *
- *
- */
- public static class BEEnvelop extends PCMMBaseObject {
- // basically we need 36 bytes but since PCMMBasedObject needs 4 bytes
- // more we allocate 40 bytes and then subtract them when setting BE
- // data.
- private final static short LENGHT = 40;
-
- protected BEEnvelop() {
- super(LENGHT, (byte) 0, (byte) 0);
- setTrafficPriority(DEFAULT_TRAFFIC_PRIORITY);
- }
-
- protected BEEnvelop(byte[] buffer) {
- super(buffer);
- }
-
- public void setTrafficPriority(byte p) {
- setByte(p, (short) 0);
- }
-
- public byte getTrafficPriority() {
- return getByte((short) 0);
- }
-
- //
- public void setRequestTransmissionPolicy(int p) {
- setInt(p, (short) 4);
- }
-
- public int getRequestTransmissionPolicy() {
- return getInt((short) 4);
- }
-
- public int getMaximumSustainedTrafficRate() {
- return getInt((short) 8);
- }
-
- public void setMaximumSustainedTrafficRate(int p) {
- setInt(p, (short) 8);
- }
-
- public int getMaximumTrafficBurst() {
- return getInt((short) 12);
- }
-
- public void setMaximumTrafficBurst(int p) {
- setInt(p, (short) 12);
- }
-
- public int getMinimumReservedTrafficRate() {
- return getInt((short) 16);
- }
-
- public void setMinimumReservedTrafficRate(int p) {
- setInt(p, (short) 16);
- }
-
- public short getAssumedMinimumReservedTrafficRatePacketSize() {
- return getShort((short) 20);
- }
-
- public void setAssumedMinimumReservedTrafficRatePacketSize(short p) {
- setShort(p, (short) 20);
- }
-
- public short getMaximumConcatenatedBurst() {
- return getShort((short) 22);
- }
-
- public void setMaximumConcatenatedBurst(short p) {
- setShort(p, (short) 22);
- }
-
- public int getRequiredAttributeMask() {
- return getInt((short) 24);
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
}
-
- public void setRequiredAttributeMask(int p) {
- setInt(p, (short) 24);
+ if (!(o instanceof BestEffortService)) {
+ return false;
}
-
- public int getForbiddenAttributeMask() {
- return getInt((short) 28);
+ if (!super.equals(o)) {
+ return false;
}
+ final BestEffortService that = (BestEffortService) o;
+ return envelope == that.envelope && authorizedEnvelop.equals(that.authorizedEnvelop) &&
+ !(reservedEnvelop != null ? !reservedEnvelop.equals(that.reservedEnvelop) :
+ that.reservedEnvelop != null) &&
+ !(committedEnvelop != null ? !committedEnvelop.equals(that.committedEnvelop) :
+ that.committedEnvelop != null);
- public void setForbiddenAttributeMask(int p) {
- setInt(p, (short) 28);
- }
-
- public int getAttributeAggregationRuleMask() {
- return getInt((short) 32);
- }
+ }
- public void setAttributeAggregationRuleMask(int p) {
- setInt(p, (short) 32);
- }
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (int) envelope;
+ result = 31 * result + authorizedEnvelop.hashCode();
+ result = 31 * result + (reservedEnvelop != null ? reservedEnvelop.hashCode() : 0);
+ result = 31 * result + (committedEnvelop != null ? committedEnvelop.hashCode() : 0);
+ return result;
+ }
+ /**
+ * Returns a BestEffortService object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static BestEffortService parse(final byte[] data) {
+ final List<Byte> bytes = Bytes.asList(data);
+ bytes.subList(0, 51);
+ if (data.length >= 56 && data.length < 108)
+ return new BestEffortService(data[0], BEEnvelop.parse(Bytes.toArray(bytes.subList(4, 56))), null, null);
+ else if (data.length >= 108 && data.length < 160)
+ return new BestEffortService(data[0], BEEnvelop.parse(Bytes.toArray(bytes.subList(4, 56))),
+ BEEnvelop.parse(Bytes.toArray(bytes.subList(56, 108))), null);
+ else if (data.length >= 160)
+ return new BestEffortService(data[0], BEEnvelop.parse(Bytes.toArray(bytes.subList(4, 56))),
+ BEEnvelop.parse(Bytes.toArray(bytes.subList(56, 108))),
+ BEEnvelop.parse(Bytes.toArray(bytes.subList(108, 160))));
+ else return null;
}
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
+import com.google.common.primitives.Bytes;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.IClassifier;
+import org.umu.cops.stack.COPSMsgParser;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
/**
- * TODO - Cleanup this interface
+ * Implementation of the IClassifier interface
*/
public class Classifier extends PCMMBaseObject implements IClassifier {
/**
- *
+ * The classifier's protocol
*/
- public Classifier() {
- this(LENGTH, STYPE, SNUM);
- }
+ protected final Protocol protocol;
/**
- * @param data - the data to add
+ * When enabled, the CMTS must mark the packets traversing the CMTS DSCP/TOS value
*/
- public Classifier(byte[] data) {
- super(data);
- }
+ protected final byte tosOverwrite;
/**
- * @param len - the classifier's length
- * @param sType - the sType value
- * @param sNum - the sNum value
+ * The TOS mask value
*/
- public Classifier(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
- }
+ protected final byte tosMask;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getDestinationIPAddress()
+ // Instances of this and ExtendedClassifier require Inet4Address objects
+
+ /**
+ * The source address
*/
- @Override
- public InetAddress getDestinationIPAddress() {
- try {
- return Inet4Address.getByAddress(getBytes((short) 8, (short) 4));
- } catch (UnknownHostException e) {
- return null;
- }
- }
+ protected final InetAddress srcAddress;
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IClassifier#setDestinationIPAddress(java.net.InetAddress)
+ /**
+ * The destination address
*/
- @Override
- public void setDestinationIPAddress(InetAddress address) {
- setBytes(address.getAddress(), (short) 8);
- }
+ protected final InetAddress dstAddress;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getDestinationPort()
+ /**
+ * The source port number
*/
- @Override
- public short getDestinationPort() {
- return getShort((short) 14);
- }
+ protected final short srcPort;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setDestinationPort(short)
+ /**
+ * The destination port number
*/
- @Override
- public void setDestinationPort(short p) {
- setShort(p, (short) 14);
- }
+ protected final short dstPort;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getSourceIPAddress()
+ /**
+ * The priority value
*/
- @Override
- public InetAddress getSourceIPAddress() {
- try {
- return Inet4Address.getByAddress(getBytes((short) 4, (short) 4));
- } catch (UnknownHostException e) {
- return null;
- }
- }
+ protected final byte priority;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setSourceIPAddress(java.net.InetAddress)
+ /**
+ * Constructor for sub-classes
+ * @param protocol - the protocol being sent through the gate (can be null for IPv6Classifier instances)
+ * @param tosOverwrite - ENABLE/DISABLE
+ * @param tosMask - the mask
+ * @param srcAddress - the source IP
+ * @param dstAddress - the destination IP
+ * @param srcPort - the source port
+ * @param dstPort - the destination port
+ * @param priority - the priority value
*/
- @Override
- public void setSourceIPAddress(InetAddress a) {
- setBytes(a.getAddress(), (short) 4);
+ public Classifier(final Protocol protocol, final byte tosOverwrite, final byte tosMask,
+ final Inet4Address srcAddress, final Inet4Address dstAddress, final short srcPort,
+ final short dstPort, final byte priority) {
+ this(STYPE, protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPort, dstPort, priority);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getSourcePort()
+ /**
+ * Constructor for sub-classes
+ * @param sType - the type of classifier
+ * @param protocol - the protocol being sent through the gate
+ * @param tosOverwrite - ENABLE/DISABLE
+ * @param tosMask - the mask
+ * @param srcAddress - the source IP
+ * @param dstAddress - the destination IP
+ * @param srcPort - the source port
+ * @param dstPort - the destination port
+ * @param priority - the priority value
*/
+ protected Classifier(final byte sType, final Protocol protocol, final byte tosOverwrite, final byte tosMask,
+ final InetAddress srcAddress, final InetAddress dstAddress, final short srcPort,
+ final short dstPort, final byte priority) {
+ super(SNum.CLASSIFIERS, sType);
+
+ if (protocol == null && !(this instanceof IPv6Classifier))
+ throw new IllegalArgumentException("Protocol value must not be null");
+ if (srcAddress == null) throw new IllegalArgumentException("Source address value must not be null");
+ if (dstAddress == null) throw new IllegalArgumentException("Destination address value must not be null");
+
+ this.protocol = protocol;
+ this.tosOverwrite = tosOverwrite;
+ this.tosMask = tosMask;
+ this.srcAddress = srcAddress;
+ this.dstAddress = dstAddress;
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ this.priority = priority;
+ }
+
@Override
- public short getSourcePort() {
- return getShort((short) 12);
+ public InetAddress getDestinationIPAddress() {
+ return dstAddress;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setSourcePort(short)
- */
@Override
- public void setSourcePort(short p) {
- setShort(p, (short) 12);
+ public short getDestinationPort() {
+ return dstPort;
+ }
+ @Override
+ public InetAddress getSourceIPAddress() {
+ return srcAddress;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getProtocol()
- */
@Override
- public short getProtocol() {
- return getShort((short) 0);
+ public short getSourcePort() {
+ return srcPort;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setProtocol(short)
- */
@Override
- public void setProtocol(short p) {
- setShort(p, (short) 0);
+ public Protocol getProtocol() {
+ return protocol;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getPriority()
- */
@Override
public byte getPriority() {
- return getBytes((short) 16, (short) 1)[0];
+ return priority;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setPriority(byte)
- */
@Override
- public void setPriority(byte p) {
- setBytes(new byte[] { p }, (short) 16);
+ public byte getDSCPTOS() {
+ return tosOverwrite;
}
@Override
- public byte getDSCPTOS() {
- return getBytes((short) 2, (short) 1)[0];
+ public byte getDSCPTOSMask() {
+ return tosMask;
}
@Override
- public void setDSCPTOS(byte v) {
- setBytes(new byte[] { v }, (short) 2);
+ protected byte[] getBytes() {
+ final List<Byte> byteList = new ArrayList<>(Bytes.asList(COPSMsgParser.shortToBytes(protocol.getValue())));
+ byteList.add(tosOverwrite);
+ byteList.add(tosMask);
+ byteList.addAll(Bytes.asList(srcAddress.getAddress()));
+ byteList.addAll(Bytes.asList(dstAddress.getAddress()));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPort)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPort)));
+ byteList.add(priority);
+ // reserved padding
+ byteList.addAll(Bytes.asList((byte) 0, (byte) 0, (byte) 0));
+
+ return Bytes.toArray(byteList);
}
@Override
- public byte getDSCPTOSMask() {
- return getBytes((short) 3, (short) 1)[0];
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof Classifier)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final Classifier that = (Classifier) o;
+ return tosMask == that.tosMask && srcPort == that.srcPort && dstPort == that.dstPort &&
+ priority == that.priority && protocol == that.protocol && tosOverwrite == that.tosOverwrite &&
+ srcAddress.equals(that.srcAddress) && dstAddress.equals(that.dstAddress);
}
@Override
- public void setDSCPTOSMask(byte v) {
- setBytes(new byte[] { v }, (short) 3);
-
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (protocol != null ? protocol.hashCode() : 0);
+ result = 31 * result + (int) tosOverwrite;
+ result = 31 * result + (int) tosMask;
+ result = 31 * result + srcAddress.hashCode();
+ result = 31 * result + dstAddress.hashCode();
+ result = 31 * result + (int) srcPort;
+ result = 31 * result + (int) dstPort;
+ result = 31 * result + (int) priority;
+ return result;
}
+ /**
+ * Returns a Classifier object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as exceptions can be swallowed here.
+ */
+ public static Classifier parse(final byte[] data) {
+ final List<Byte> bytes = Bytes.asList(data);
+
+ try {
+ final byte[] srcAddrBytes = Bytes.toArray(bytes.subList(4, 8));
+ final byte[] dstAddrBytes = Bytes.toArray(bytes.subList(8, 12));
+ return new Classifier(Protocol.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])), data[2], data[3],
+ (Inet4Address)InetAddress.getByAddress(srcAddrBytes),
+ (Inet4Address)InetAddress.getByAddress(dstAddrBytes),
+ COPSMsgParser.bytesToShort(data[12], data[13]), COPSMsgParser.bytesToShort(data[14], data[15]),
+ data[16]);
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.ITrafficProfile;
+import java.util.Arrays;
+
/**
+ * The DOCSIS Service Class Name object defines the preconfigured Service Class Name associated with a Gate.
*
*/
-public class DOCSISServiceClassNameTrafficProfile extends PCMMBaseObject
- implements ITrafficProfile {
+public class DOCSISServiceClassNameTrafficProfile extends PCMMBaseObject implements ITrafficProfile {
public static final byte STYPE = 2;
- public static final short LENGTH = 24;
+ public static final int SCN_MAX_LEN = 16;
/**
- *
+ * The Service Class Name. REQUIRED and length must be >= 2 and <= 16 characters
*/
- public DOCSISServiceClassNameTrafficProfile() {
- this(LENGTH, STYPE, SNUM);
- }
+ private final String scnName;
/**
- * @param data - the data bytes to parse
+ * The envelope
*/
- public DOCSISServiceClassNameTrafficProfile(byte[] data) {
- super(data);
- }
+ private final byte envelope;
/**
- * @param len - the classifier's length
- * @param sType - the sType value
- * @param sNum - the sNum value
+ * Constructor using the default envelope value
+ * @param scnName - the service class name (required characters >=2 && <=16
*/
- public DOCSISServiceClassNameTrafficProfile(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
- setEnvelop((byte) 0x7);
+ public DOCSISServiceClassNameTrafficProfile(final String scnName) {
+ this(DEFAULT_ENVELOP, scnName);
}
/**
- * @return the serviceClassName
+ * Constructor to set all values
+ * @param envelope - the envelope value
+ * @param scnName - the service class name (required number of characters >=2 && <=16)
*/
- public String getServiceClassName() {
- return new String(getBytes((short) 4, (short) 4));
+ protected DOCSISServiceClassNameTrafficProfile(final byte envelope, final String scnName) {
+ super(SNum.TRAFFIC_PROFILE, STYPE);
+ if (scnName == null || scnName.length() < 2 || scnName.length() > SCN_MAX_LEN)
+ throw new IllegalArgumentException("Service class name must be between 2-16 characters");
+ this.scnName = scnName;
+ this.envelope = envelope;
+ }
+
+ @Override
+ public byte getEnvelop() {
+ return envelope;
}
/**
- * @param serviceClassName
- * the serviceClassName to set
+ * Returns the service class name value
+ * @return - the SCN value
*/
- public void setServiceClassName(String serviceClassName) {
- setBytes(serviceClassName.getBytes(), (short) 4);
+ public String getScnName() {
+ return scnName;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITrafficProfile#getEnvelop()
- */
@Override
- public byte getEnvelop() {
- return getBytes((short) 0, (short) 1)[0];
+ protected byte[] getBytes() {
+ final int padLen;
+ if ((scnName.length() % 4) != 0) padLen = 4 - (scnName.length() % 4);
+ else padLen = 0;
+
+ final byte[] data = new byte[4 + scnName.getBytes().length + padLen];
+ Arrays.fill(data, (byte) 0);
+ data[0] = envelope;
+
+ System.arraycopy(scnName.getBytes(), 0, data, 4, scnName.getBytes().length);
+ return data;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DOCSISServiceClassNameTrafficProfile)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final DOCSISServiceClassNameTrafficProfile that = (DOCSISServiceClassNameTrafficProfile) o;
+ return envelope == that.envelope && scnName.equals(that.scnName);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITrafficProfile#setEnvelop(byte)
- */
@Override
- public void setEnvelop(byte en) {
- setBytes(new byte[] { en }, (short) 0);
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + scnName.hashCode();
+ result = 31 * result + (int) envelope;
+ return result;
}
+
+ /**
+ * Returns a DOCSISServiceClassNameTrafficProfile object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static DOCSISServiceClassNameTrafficProfile parse(final byte[] data) {
+ // variable i will denote the index where the data padding starts (if any) or the end of the array
+ int i = 4;
+ for (; i < data.length; i++) {
+ if (data[i] == 0) {
+ break;
+ }
+ }
+ final int nameLength = i - 4;
+
+ final byte[] scnNameBytes = new byte[nameLength];
+ System.arraycopy(data, 4, scnNameBytes, 0, nameLength);
+ final String scnName = new String(scnNameBytes);
+ return new DOCSISServiceClassNameTrafficProfile(data[0], scnName);
+ }
+
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
-import org.pcmm.base.impl.PCMMBaseObject;
+import com.google.common.primitives.Bytes;
import org.pcmm.gates.IExtendedClassifier;
+import org.umu.cops.stack.COPSMsgParser;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
/**
- *
+ * Implementation of the IExtendedClassifier interface
*/
-public class ExtendedClassifier extends PCMMBaseObject implements
- IExtendedClassifier {
-
- public ExtendedClassifier() {
- this(LENGTH, STYPE, SNUM);
- }
+public class ExtendedClassifier extends Classifier implements IExtendedClassifier {
/**
- * @param data - the data bytes to parse
+ * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
+ * irrelevant else only packets with source IP address 'pkt.ip-src'
+ * will match if (pkt.ip-src AND classifier.ipmask-src) == classifier.ip-src.
*/
- public ExtendedClassifier(byte[] data) {
- super(data);
- }
+ protected final InetAddress srcMask;
/**
- * @param len - the classifier's length
- * @param sType - the sType value
- * @param sNum - the sNum value
- */
- public ExtendedClassifier(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getDestinationIPAddress()
+ * IPv4 (for this class) and IPv6 (for extended IPv6Classifier) mask. When the address is zero, the mask is
+ * irrelevant else only packets with source IP address 'pkt.ip-dst'
+ * will match if (pkt.ip-dst AND classifier.ipmask-dst) == classifier.ip-dst.
*/
- @Override
- public InetAddress getDestinationIPAddress() {
- try {
- return InetAddress.getByAddress(getBytes((short) 12, (short) 4));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- return null;
- }
+ protected final InetAddress dstMask;
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IClassifier#setDestinationIPAddress(java.net.InetAddress)
- */
- @Override
- public void setDestinationIPAddress(InetAddress address) {
- setBytes(address.getAddress(), (short) 12);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getDestinationPort()
- */
- @Override
- public short getDestinationPort() {
- return getShort((short) 24);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setDestinationPort(short)
+ /**
+ * Source Port End specifies the high-end TCP/UDP source port value. See super srcPort for low-end value.
*/
- @Override
- public void setDestinationPort(short p) {
- setShort(p, (short) 24);
- }
+ protected final short srcPortEnd;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getSourceIPAddress()
- */
- @Override
- public InetAddress getSourceIPAddress() {
- try {
- return InetAddress.getByAddress(getBytes((short) 4, (short) 4));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setSourceIPAddress(java.net.InetAddress)
+ /**
+ * Destination Port End specifies the high-end TCP/UDP source port value. See super dstPort for low-end value.
*/
- @Override
- public void setSourceIPAddress(InetAddress a) {
- setBytes(a.getAddress(), (short) 4);
- }
+ protected final short dstPortEnd;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getSourcePort()
+ /**
+ * The classifiers identifier
*/
- @Override
- public short getSourcePort() {
- return getShort((short) 20);
- }
+ protected final short classifierId;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setSourcePort(short)
+ /**
+ * Enumeration of the activation state
*/
- @Override
- public void setSourcePort(short p) {
- setShort(p, (short) 20);
- }
+ protected final ActivationState activationState;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getProtocol()
+ /**
+ * The action value
*/
- @Override
- public short getProtocol() {
- return getShort((short) 0);
- }
+ protected final byte action;
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setProtocol(short)
- */
- @Override
- public void setProtocol(short p) {
- setShort(p, (short) 0);
+ /**
+ * Constructor
+ * @param protocol - the protocol being sent through the gate
+ * @param tosOverwrite - ENABLE/DISABLE
+ * @param tosMask - the mask
+ * @param srcAddress - the source IP
+ * @param dstAddress - the destination IP
+ * @param srcPortBegin - the source begin port
+ * @param dstPortBegin - the destination begin port
+ * @param priority - the priority value
+ * @param srcMask - the source IP mask
+ * @param dstMask - the destination IP mask
+ * @param srcPortEnd - the source start port
+ * @param dstPortEnd - the destination end port
+ * @param classifierId - the classifier identifier
+ * @param activationState - denotes the activation state
+ * @param action - the action
+ */
+ public ExtendedClassifier(final Protocol protocol, final byte tosOverwrite, final byte tosMask,
+ final Inet4Address srcAddress, final Inet4Address dstAddress, final short srcPortBegin,
+ final short dstPortBegin, final byte priority, final Inet4Address srcMask,
+ final Inet4Address dstMask, final short srcPortEnd, final short dstPortEnd,
+ final short classifierId, final ActivationState activationState, final byte action) {
+ super(IExtendedClassifier.STYPE, protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPortBegin,
+ dstPortBegin, priority);
+ if (srcMask == null) throw new IllegalArgumentException("Source IP Mask cannot be null");
+ if (dstMask == null) throw new IllegalArgumentException("Destination IP Mask cannot be null");
+ if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
+ this.srcMask = srcMask;
+ this.dstMask = dstMask;
+ this.srcPortEnd = srcPortEnd;
+ this.dstPortEnd = dstPortEnd;
+ this.classifierId = classifierId;
+ this.activationState = activationState;
+ this.action = action;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#getPriority()
- */
- @Override
- public byte getPriority() {
- return getByte((short) 30);
+ /**
+ * Constructor for IPv6Classifier subclass
+ * @param sType - the type of classifier
+ * @param srcAddress - the source IP
+ * @param dstAddress - the destination IP
+ * @param srcPortBegin - the source begin port
+ * @param dstPortBegin - the destination begin port
+ * @param priority - the priority value
+ * @param srcPortEnd - the source start port
+ * @param dstPortEnd - the destination end port
+ * @param classifierId - the classifier identifier
+ * @param activationState - denotes the activation state
+ * @param action - the action
+ */
+ protected ExtendedClassifier(final byte sType, final InetAddress srcAddress, final InetAddress dstAddress,
+ final short srcPortBegin, final short dstPortBegin, final byte priority,
+ final short srcPortEnd, final short dstPortEnd, final short classifierId,
+ final ActivationState activationState, final byte action) {
+ super(sType, null, (byte)0, (byte)0, srcAddress, dstAddress, srcPortBegin, dstPortBegin, priority);
+ if (activationState == null) throw new IllegalArgumentException("Activation state must not be null");
+ this.srcMask = null;
+ this.dstMask = null;
+ this.srcPortEnd = srcPortEnd;
+ this.dstPortEnd = dstPortEnd;
+ this.classifierId = classifierId;
+ this.activationState = activationState;
+ this.action = action;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IClassifier#setPriority(byte)
- */
- @Override
- public void setPriority(byte p) {
- setByte(p, (short) 30);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getIPSourceMask()
- */
@Override
public InetAddress getIPSourceMask() {
- try {
- return InetAddress.getByAddress(getBytes((short) 8, (short) 4));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- return null;
+ return srcMask;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IExtendedClassifier#setIPSourceMask(java.net.InetAddress)
- */
- @Override
- public void setIPSourceMask(InetAddress a) {
- setBytes(a.getAddress(), (short) 8);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getIPDestinationMask()
- */
@Override
public InetAddress getIPDestinationMask() {
- try {
- return InetAddress.getByAddress(getBytes((short) 16, (short) 4));
- } catch (UnknownHostException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IExtendedClassifier#setIPDestinationMask(java.net.InetAddress
- * )
- */
- @Override
- public void setIPDestinationMask(InetAddress m) {
- setBytes(m.getAddress(), (short) 16);
+ return dstMask;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getSourcePortStart()
- */
@Override
public short getSourcePortStart() {
- return getShort((short) 20);
+ return super.getSourcePort();
}
- @Override
- public void setSourcePortStart(short p) {
- setShort(p, (short) 20);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getSourcePortEnd()
- */
@Override
public short getSourcePortEnd() {
- return getShort((short) 22);
- }
-
- @Override
- public void setSourcePortEnd(short p) {
- setShort(p, (short) 22);
+ return srcPortEnd;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getDestinationPortStart()
- */
@Override
public short getDestinationPortStart() {
- return getShort((short) 24);
- }
-
- @Override
- public void setDestinationPortStart(short p) {
- setShort(p, (short) 24);
+ return super.getDestinationPort();
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getDestinationPortEnd()
- */
@Override
public short getDestinationPortEnd() {
- return getShort((short) 26);
+ return dstPortEnd;
}
- @Override
- public void setDestinationPortEnd(short p) {
- setShort(p, (short) 26);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getClassifierID()
- */
@Override
public short getClassifierID() {
- return getShort((short) 28);
+ return classifierId;
}
@Override
- public void setClassifierID(short p) {
- setShort(p, (short) 28);
+ public ActivationState getActivationState() {
+ return activationState;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getActivationState()
- */
@Override
- public byte getActivationState() {
- return getByte((short) 31);
+ public byte getAction() {
+ return action;
}
@Override
- public void setActivationState(byte s) {
- setByte(s, (short) 31);
- }
+ protected byte[] getBytes() {
+ final List<Byte> byteList = new ArrayList<>(Bytes.asList(COPSMsgParser.shortToBytes(protocol.getValue())));
+ byteList.add(tosOverwrite);
+ byteList.add(tosMask);
+ byteList.addAll(Bytes.asList(srcAddress.getAddress()));
+ byteList.addAll(Bytes.asList(srcMask.getAddress()));
+ byteList.addAll(Bytes.asList(dstAddress.getAddress()));
+ byteList.addAll(Bytes.asList(dstMask.getAddress()));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPort)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPortEnd)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPort)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPortEnd)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(classifierId)));
+ byteList.add(priority);
+ byteList.add(activationState.getValue());
+ byteList.add(action);
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IExtendedClassifier#getAction()
- */
- @Override
- public byte getAction() {
- return getByte((short) 32);
- }
+ // reserved padding
+ byteList.addAll(Bytes.asList((byte) 0, (byte) 0, (byte) 0));
- @Override
- public void setAction(byte a) {
- setByte(a, (short) 32);
+ return Bytes.toArray(byteList);
}
@Override
- public byte getDSCPTOS() {
- return getByte((short) 2);
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ExtendedClassifier)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final ExtendedClassifier that = (ExtendedClassifier) o;
+ return srcPortEnd == that.srcPortEnd && dstPortEnd == that.dstPortEnd && classifierId == that.classifierId &&
+ activationState == that.activationState && action == that.action &&
+ !(srcMask != null ? !srcMask.equals(that.srcMask) : that.srcMask != null) &&
+ !(dstMask != null ? !dstMask.equals(that.dstMask) : that.dstMask != null);
}
@Override
- public void setDSCPTOS(byte v) {
- setByte(v, (short) 2);
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (srcMask != null ? srcMask.hashCode() : 0);
+ result = 31 * result + (dstMask != null ? dstMask.hashCode() : 0);
+ result = 31 * result + (int) srcPortEnd;
+ result = 31 * result + (int) dstPortEnd;
+ result = 31 * result + (int) classifierId;
+ result = 31 * result + (int) activationState.getValue();
+ result = 31 * result + (int) action;
+ return result;
}
- @Override
- public byte getDSCPTOSMask() {
- return getByte((short) 3);
- }
+ /**
+ * Returns a ExtendedClassifier object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as exceptions can be swallowed here.
+ */
+ public static ExtendedClassifier parse(final byte[] data) {
+ final List<Byte> bytes = new ArrayList<>(Bytes.asList(data));
- @Override
- public void setDSCPTOSMask(byte v) {
- setByte(v, (short) 3);
+ try {
+ return new ExtendedClassifier(Protocol.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
+ data[2], data[3],
+ (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(4, 8))),
+ (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(8, 12))),
+ COPSMsgParser.bytesToShort(data[20], data[21]), COPSMsgParser.bytesToShort(data[24], data[25]),
+ data[30], (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(12, 16))),
+ (Inet4Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(16, 20))),
+ COPSMsgParser.bytesToShort(data[22], data[23]), COPSMsgParser.bytesToShort(data[26], data[27]),
+ COPSMsgParser.bytesToShort(data[28], data[29]), ActivationState.valueOf(data[31]), data[32]);
+ } catch (UnknownHostException e) {
+ return null;
+ }
}
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.IGateID;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
+ * Implementation of the IGateID interface
*/
public class GateID extends PCMMBaseObject implements IGateID {
/**
- *
+ * The gate ID value
*/
- public GateID() {
- this(LENGTH, STYPE, SNUM);
- }
+ final int gateId;
/**
- * @param data
+ * Constructor
+ * @param gateId - the ID value
*/
- public GateID(byte[] data) {
- super(data);
+ public GateID(final int gateId) {
+ super(SNum.GATE_ID, STYPE);
+ this.gateId = gateId;
}
- /**
- * @param len
- * @param sType
- * @param sNum
- */
- public GateID(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
+ @Override
+ public int getGateID() {
+ return gateId;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IGateID#setGateID(int)
- */
@Override
- public void setGateID(int gateID) {
- setInt(gateID, (short) 0);
+ protected byte[] getBytes() {
+ return COPSMsgParser.intToBytes(gateId);
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IGateID#getGateID()
- */
@Override
- public int getGateID() {
- return getInt((short) 0);
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof GateID)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final GateID gateID = (GateID) o;
+ return gateId == gateID.gateId;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + gateId;
+ return result;
}
+ /**
+ * Returns a GateID object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static GateID parse(final byte[] data) {
+ return new GateID(COPSMsgParser.bytesToInt(data[0], data[1], data[2], data[3]));
+ }
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.IGateSpec;
import org.pcmm.gates.ISessionClassID;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
+ * Implementation of the IGateSpec interface
*/
public class GateSpec extends PCMMBaseObject implements IGateSpec {
- // GateSpec flags are Direction (bit 0) and DSCPTOS overwrite enable (bit 1)
- private byte flags = 0;
-
- public GateSpec() {
- super(LENGTH, STYPE, SNUM);
- }
-
- public GateSpec(byte[] data) {
- super(data);
+ /**
+ * The gate's direction
+ */
+ private final Direction direction;
+
+ /**
+ * The DSCP/TOS Overwrite is a 1-byte bit field [8] defined by the following alternative structures, depending upon
+ network management strategy.
+ *
+ * When enabled, the CMTS must mark the packets traversing the CMTS DSCP/TOS value
+ */
+ private final byte tosOverwrite;
+
+ /**
+ * tosOverwrite field with the TOS mask is used to identify particular bits within the IPv4 DSCP/TOS byte
+ */
+ private final byte tosMask;
+
+ /**
+ * Session Class ID identifies the proper admission control policy or parameters to be applied for this gate
+ */
+ private final SessionClassID sessionClassID;
+
+ /**
+ * Timer value in seconds. Value of 0 indicates that the CMTS provisioned value for the timer MUST be used.
+ */
+ private final short timer1;
+
+ /**
+ * DOCSIS Admitted timer in seconds
+ */
+ private final short timer2;
+
+ /**
+ * DOCSIS Active timer in seconds
+ */
+ private final short timer3;
+
+ /**
+ * The fourth timer value in seconds
+ */
+ private final short timer4;
+
+ /**
+ * General constructor
+ * @param direction - the gate direction
+ * @param tosOverwrite - ENABLE/DISABLE
+ * @param tosMask - the mask
+ */
+ public GateSpec(final Direction direction, final byte tosOverwrite, final byte tosMask) {
+ this(direction, tosOverwrite, tosMask, new SessionClassID((byte) 0), (short) 0, (short) 0, (short) 0, (short) 0);
+ }
+
+ /**
+ * Constructor generally for use when parsing a byte array to create an instance of this object.
+ * @param direction - the gate direction
+ * @param tosOverwrite - ENABLE/DISABLE
+ * @param tosMask - the mask
+ * @param sessionClassID - the session class ID
+ * @param timer1 - timer1 in seconds
+ * @param timer2 - timer2 in seconds
+ * @param timer3 - timer3 in seconds
+ * @param timer4 - timer4 in seconds
+ */
+ protected GateSpec(final Direction direction, final byte tosOverwrite, final byte tosMask,
+ final SessionClassID sessionClassID, final short timer1, final short timer2, final short timer3,
+ final short timer4) {
+
+ super(SNum.GATE_SPEC, STYPE);
+
+ if (direction == null) throw new IllegalArgumentException("Direction is required");
+// if (tosOverwrite == null) throw new IllegalArgumentException("TOS Overwrite is required");
+ if (sessionClassID == null) throw new IllegalArgumentException("Session class ID is required");
+
+ this.direction = direction;
+ this.tosOverwrite = tosOverwrite;
+ this.tosMask = tosMask;
+ this.sessionClassID = sessionClassID;
+ this.timer1 = timer1;
+ this.timer2 = timer2;
+ this.timer3 = timer3;
+ this.timer4 = timer4;
}
@Override
- public ISessionClassID getSessionClassID() {
- return new SessionClassID(getByte((short) 3));
+ public Direction getDirection() {
+ return direction;
}
@Override
- public void setSessionClassID(ISessionClassID id) {
- setByte(id.toSingleByte(), (short) 3);
+ public byte getDSCP_TOSOverwrite() {
+ return tosOverwrite;
}
@Override
- public Direction getDirection() {
- return Direction.valueOf(getByte((short) 0));
+ public byte getDSCP_TOSMask() {
+ return tosMask;
}
@Override
- public void setDirection(Direction direction) {
- // OR in the Direction flag with the DSCPTOS enable flag
- flags |= direction.getValue();
- setByte(flags, (short) 0);
+ public ISessionClassID getSessionClassID() {
+ return sessionClassID;
}
@Override
public short getTimerT1() {
- return getShort((short) 4);
- }
-
- @Override
- public void setTimerT1(short authTimer) {
- setShort(authTimer, (short) 4);
+ return timer1;
}
@Override
public short getTimerT2() {
- return getShort((short) 6);
- }
-
- @Override
- public void setTimerT2(short timer) {
- setShort(timer, (short) 6);
-
+ return timer2;
}
@Override
public short getTimerT3() {
- return getShort((short) 8);
- }
-
- @Override
- public void setTimerT3(short t) {
- setShort(t, (short) 8);
-
+ return timer3;
}
@Override
public short getTimerT4() {
- return getShort((short) 10);
+ return timer4;
}
@Override
- public void setTimerT4(short t) {
- setShort(t, (short) 10);
- }
+ protected byte[] getBytes() {
+ final byte[] data = new byte[12];
+ data[0] = direction.getValue();
+ data[1] = tosOverwrite;
+ data[2] = tosMask;
+ data[3] = sessionClassID.toSingleByte();
- @Override
- public void setDSCP_TOSOverwrite(DSCPTOS dscpTos) {
- // OR in the DSCPTOS enable flag with the Direction flag
- setDSCP_TOSOverwrite(dscpTos.getValue());
- }
+ final byte[] timer1Bytes = COPSMsgParser.shortToBytes(timer1);
+ data[4] = timer1Bytes[0];
+ data[5] = timer1Bytes[1];
- @Override
- public void setDSCP_TOSOverwrite(byte dscpTos) {
- flags |= dscpTos;
- setByte(flags, (short) 1);
- }
+ final byte[] timer2Bytes = COPSMsgParser.shortToBytes(timer2);
+ data[6] = timer2Bytes[0];
+ data[7] = timer2Bytes[1];
+ final byte[] timer3Bytes = COPSMsgParser.shortToBytes(timer3);
+ data[8] = timer3Bytes[0];
+ data[9] = timer3Bytes[1];
- @Override
- public DSCPTOS getDSCP_TOSOverwrite() {
- return DSCPTOS.valueOf(getByte((short) 1));
+ final byte[] timer4Bytes = COPSMsgParser.shortToBytes(timer4);
+ data[10] = timer4Bytes[0];
+ data[11] = timer4Bytes[1];
+
+ return data;
}
@Override
- public byte getDSCP_TOSMask() {
- return getByte((short) 2);
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof GateSpec)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final GateSpec gateSpec = (GateSpec) o;
+ return tosMask == gateSpec.tosMask && timer1 == gateSpec.timer1 && timer2 == gateSpec.timer2 &&
+ timer3 == gateSpec.timer3 && timer4 == gateSpec.timer4 && direction == gateSpec.direction &&
+ tosOverwrite == gateSpec.tosOverwrite && sessionClassID.equals(gateSpec.sessionClassID);
+
}
@Override
- public void setDSCP_TOSMask(byte dscp_tos_mask) {
- setByte(dscp_tos_mask, (short) 2);
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + direction.hashCode();
+ result = 31 * result + (int) tosOverwrite;
+ result = 31 * result + (int) tosMask;
+ result = 31 * result + sessionClassID.hashCode();
+ result = 31 * result + (int) timer1;
+ result = 31 * result + (int) timer2;
+ result = 31 * result + (int) timer3;
+ result = 31 * result + (int) timer4;
+ return result;
}
+ /**
+ * Returns a GateSpec object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static GateSpec parse(final byte[] data) {
+ return new GateSpec(Direction.valueOf(data[0]), data[1], data[2],
+ new SessionClassID(data[3]), COPSMsgParser.bytesToShort(data[4], data[5]),
+ COPSMsgParser.bytesToShort(data[6], data[7]), COPSMsgParser.bytesToShort(data[8], data[9]),
+ COPSMsgParser.bytesToShort(data[10], data[11]));
+ }
}
*/
package org.pcmm.gates.impl;
-import org.pcmm.base.impl.PCMMBaseObject;
+import com.google.common.primitives.Bytes;
import org.pcmm.gates.IIPv6Classifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.COPSMsgParser;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
/**
- *
+ * Implementation of the IIPv6Classifier interface
*/
-public class IPv6Classifier extends PCMMBaseObject implements
- IIPv6Classifier {
+public class IPv6Classifier extends ExtendedClassifier implements IIPv6Classifier {
- private Logger logger = LoggerFactory.getLogger(IPv6Classifier.class);
+ /**
+ * VALID when there is valid data for comparison with the IPv6 Flow label else IRRELEVANT
+ */
+ private final FlowLabel flowEnabled;
- public IPv6Classifier() {
- this(LENGTH, STYPE, SNUM);
- }
+ /**
+ * Allows for matching on the IPv6 Traffic Class value (with tcHigh & tcMask)
+ */
+ private final byte tcLow;
/**
- * @param data - the data bytes to parse
+ * Allows for matching on the IPv6 Traffic Class value (with tcLow & tcMask)
*/
- public IPv6Classifier(byte[] data) {
- super(data);
- }
+ private final byte tcHigh;
/**
- * @param len - the classifier's length
- * @param sType - the sType value
- * @param sNum - the sNum value
+ * Allows for matching on the IPv6 Traffic Class value (with tcLow & tcHigh)
*/
- public IPv6Classifier(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
- }
+ private final byte tcMask;
- // offset:length Field Name: Description
- // 00:01 Flags: 0000.0001 Flow Label enable match
- // 01:01 Tc-low
- // 02:01 Tc-high
- // 03:01 Tc-mask
- // 04:04 Flow Label: low order 20 bits; high order 12 bits ignored
- // 08:02 Next Header Type
- // 10:01 Source Prefix Length
- // 11:01 Destination Prefix Length
- // 12:16 IPv6 Source Address
- // 28:16 IPv6 Destination Address
- // 44:02 Source Port Start
- // 46:02 Source Port End
- // 48:02 Destination Port Start
- // 50:02 Destination Port End
- // 52:02 ClassifierID
- // 54:01 Priority
- // 55:01 Activation State
- // 56:01 Action
- // 57:03 Reserved
+ /**
+ * Contains data for comparison When flowEnabled == VALID else this value must be 0
+ */
+ private final int flowLabel;
- // 00:01 Flags: 0000.0001 Flow Label enable match
- @Override
- public void setFlowLabelEnableFlag(byte flag) {
- setByte(flag, (short) 0);
+ /**
+ * Next Header Type field specifies the desired next header type value for any header or extension header associated
+ * with the packet. Typically this value will specify the next layer protocol type. There are two special IPv6 next
+ * header type field values: "256" matches traffic with any IPv6 next header type value, and "257" matches both TCP
+ * and UDP traffic. Values greater than 257 are invalid for comparisons (i.e., no traffic can match this entry).
+ * For further discussion of the IPv6 Next Header Type field, refer to C.2.1.10.3
+ */
+ private final short nextHdr;
+
+ /**
+ * Source Prefix Length field specifies the fixed, most significant bits of an IPv6 address that are used to
+ * determine address range and subnet ID for the IPv6 Source Address.
+ */
+ private final byte srcPrefixLen;
+
+ /**
+ * Destination Prefix Length field specifies the fixed, most significant bits of an IPv6 address that are used to
+ * determine address range and subnet ID for the IPv6 Destination Address.
+ */
+ private final byte dstPrefixLen;
+
+ /**
+ * Constructor
+ * @param srcAddress - the source IP (not null)
+ * @param dstAddress - the destination IP (not null)
+ * @param srcPortBegin - the source begin port
+ * @param dstPortBegin - the destination begin port
+ * @param priority - the priority value
+ * @param srcPortEnd - the source start port
+ * @param dstPortEnd - the destination end port
+ * @param classifierId - the classifier identifier
+ * @param activationState - denotes the activation state (not null)
+ * @param action - the action
+ * @param flowEnabled - eumeration of FlowLabel (VALID|IRRELEVANT)
+ * @param tcLow - low matching on the IPv6 Traffic Class
+ * @param tcHigh - high matching on the IPv6 Traffic Class
+ * @param tcMask - mask matching on the IPv6 Traffic Class
+ * @param flowLabel - data for comparison
+ * @param nextHdr - the next header type value
+ * @param srcPrefixLen - source prefix length
+ * @param dstPrefixLen - destination prefix length
+ */
+ public IPv6Classifier(final Inet6Address srcAddress, final Inet6Address dstAddress, final short srcPortBegin,
+ final short dstPortBegin, final byte priority, final short srcPortEnd, final short dstPortEnd,
+ final short classifierId, final ActivationState activationState, final byte action,
+ final FlowLabel flowEnabled, final byte tcLow, final byte tcHigh, final byte tcMask,
+ final int flowLabel, final short nextHdr, final byte srcPrefixLen, final byte dstPrefixLen) {
+ super(IIPv6Classifier.STYPE, srcAddress, dstAddress, srcPortBegin, dstPortBegin, priority, srcPortEnd,
+ dstPortEnd, classifierId, activationState, action);
+ if (flowEnabled == null) throw new IllegalArgumentException("Flow enabled enumeration must not be null");
+ if (flowEnabled.equals(FlowLabel.IRRELEVANT)) this.flowLabel = 0;
+ else this.flowLabel = flowLabel;
+ this.flowEnabled = flowEnabled;
+ this.tcLow = tcLow;
+ this.tcHigh = tcHigh;
+ this.tcMask = tcMask;
+ this.nextHdr = nextHdr;
+ this.srcPrefixLen = srcPrefixLen;
+ this.dstPrefixLen = dstPrefixLen;
}
+
+ // 00:01 Flags: 0000.0001 Flow Label enable match
@Override
- public byte getFlowLabelEnableFlag() {
- return getByte((short) 0);
+ public FlowLabel getFlowLabelEnableFlag() {
+ return flowEnabled;
}
// 01:01 Tc-low
@Override
- public void setTcLow(byte tcLow) {
- setByte(tcLow, (short) 1);
- }
- @Override
public byte getTcLow() {
- return getByte((short) 1);
+ return tcLow;
}
// 02:01 Tc-high
@Override
- public void setTcHigh(byte tcHigh) {
- setByte(tcHigh, (short) 2);
- }
- @Override
public byte getTcHigh() {
- return getByte((short) 2);
+ return tcHigh;
}
// 03:01 Tc-mask
@Override
- public void setTcMask(byte tcMask) {
- setByte(tcMask, (short) 3);
- }
- @Override
public byte getTcMask() {
- return getByte((short) 3);
+ return tcMask;
}
// 04:04 Flow Label: low order 20 bits; high order 12 bits ignored
@Override
- public void setFlowLabel(Long flowLabel) {
- setInt(flowLabel.intValue(), (short) 4);
- }
- @Override
public int getFlowLabel() {
- return getInt((short) 4);
+ return flowLabel;
}
// 08:02 Next Header Type
@Override
- public void setNextHdr(short nxtHdr) {
- setShort(nxtHdr, (short) 8);
- }
- @Override
public short getNextHdr() {
- return getShort((short) 8);
+ return nextHdr;
}
// 10:01 Source Prefix Length
@Override
- public void setSourcePrefixLen(byte srcPrefixLen) {
- setByte(srcPrefixLen, (short) 10);
- }
- @Override
public byte getSourcePrefixLen() {
- return getByte((short) 10);
+ return srcPrefixLen;
}
// 11:01 Destination Prefix Length
@Override
- public void setDestinationPrefixLen(byte dstPrefixLen) {
- setByte(dstPrefixLen, (short) 11);
- }
- @Override
public byte getDestinationPrefixLen() {
- return getByte((short) 11);
- }
-
- // 12:16 IPv6 Source Address
- @Override
- public void setSourceIPAddress(InetAddress a) {
- setBytes(a.getAddress(), (short) 12);
- }
- @Override
- public InetAddress getSourceIPAddress() {
- try {
- return InetAddress.getByAddress(getBytes((short) 12, (short) 16));
- } catch (UnknownHostException e) {
- logger.error("getSourceIPAddress(): Malformed IPv6 address: {}", e.getMessage());
+ return dstPrefixLen;
+ }
+
+ @Override
+ protected byte[] getBytes() {
+ final List<Byte> byteList = new ArrayList<>();
+ byteList.add(flowEnabled.getValue());
+ byteList.add(tcLow);
+ byteList.add(tcHigh);
+ byteList.add(tcMask);
+ byteList.addAll(Bytes.asList(COPSMsgParser.intToBytes(flowLabel)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(nextHdr)));
+ byteList.add(srcPrefixLen);
+ byteList.add(dstPrefixLen);
+ byteList.addAll(Bytes.asList(srcAddress.getAddress()));
+ byteList.addAll(Bytes.asList(dstAddress.getAddress()));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPort)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(srcPortEnd)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPort)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(dstPortEnd)));
+ byteList.addAll(Bytes.asList(COPSMsgParser.shortToBytes(classifierId)));
+ byteList.add(priority);
+ byteList.add(activationState.getValue());
+ byteList.add(action);
+ return Bytes.toArray(byteList);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
}
- return null;
- }
-
- // 28:16 IPv6 Destination Address
- @Override
- public void setDestinationIPAddress(InetAddress a) {
- setBytes(a.getAddress(), (short) 28);
- }
- @Override
- public InetAddress getDestinationIPAddress() {
- try {
- return InetAddress.getByAddress(getBytes((short) 28, (short) 16));
- } catch (UnknownHostException e) {
- logger.error("getDestinationIPAddress(): Malformed IPv6 address: {}", e.getMessage());
+ if (!(o instanceof IPv6Classifier)) {
+ return false;
}
- return null;
- }
- // 44:02 Source Port Start
- @Override
- public short getSourcePortStart() {
- return getShort((short) 44);
- }
- @Override
- public void setSourcePortStart(short p) {
- setShort(p, (short) 44);
- }
-
- // 46:02 Source Port End
- @Override
- public short getSourcePortEnd() {
- return getShort((short) 46);
- }
- @Override
- public void setSourcePortEnd(short p) {
- setShort(p, (short) 46);
- }
-
- // 48:02 Destination Port Start
- @Override
- public short getDestinationPortStart() {
- return getShort((short) 48);
- }
- @Override
- public void setDestinationPortStart(short p) {
- setShort(p, (short) 48);
- }
-
- // 50:02 Destination Port End
- @Override
- public short getDestinationPortEnd() {
- return getShort((short) 50);
- }
- @Override
- public void setDestinationPortEnd(short p) {
- setShort(p, (short) 50);
- }
-
- // 52:02 ClassifierID
- @Override
- public short getClassifierID() {
- return getShort((short) 52);
- }
-
- @Override
- public void setClassifierID(short p) {
- setShort(p, (short) 52);
- }
-
- // 54:01 Priority
- @Override
- public void setPriority(byte p) {
- setByte(p, (short) 54);
- }
- @Override
- public byte getPriority() {
- return getByte((short) 54);
- }
-
- // 55:01 Activation State
- @Override
- public void setActivationState(byte s) {
- setByte(s, (short) 55);
- }
- @Override
- public byte getActivationState() {
- return getByte((short) 55);
- }
-
- // 56:01 Action
- @Override
- public void setAction(byte a) {
- setByte(a, (short) 56);
- }
- @Override
- public byte getAction() {
- return getByte((short) 56);
- }
-
-
-
- // baggage from IExtendedClassifier
- // not used in IPv6 classifiers
- @Override
- public void setIPSourceMask(InetAddress a) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setIPDestinationMask(InetAddress m) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public InetAddress getIPSourceMask() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public InetAddress getIPDestinationMask() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public short getDestinationPort() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setDestinationPort(short p) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public short getSourcePort() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setSourcePort(short p) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public short getProtocol() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setProtocol(short p) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public byte getDSCPTOS() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public void setDSCPTOS(byte v) {
- // TODO Auto-generated method stub
-
+ if (!super.equals(o)) {
+ return false;
+ }
+ final IPv6Classifier that = (IPv6Classifier) o;
+ return flowEnabled == that.flowEnabled && tcLow == that.tcLow && tcHigh == that.tcHigh &&
+ tcMask == that.tcMask && flowLabel == that.flowLabel && nextHdr == that.nextHdr &&
+ srcPrefixLen == that.srcPrefixLen && dstPrefixLen == that.dstPrefixLen;
}
@Override
- public byte getDSCPTOSMask() {
- // TODO Auto-generated method stub
- return 0;
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (int) flowEnabled.getValue();
+ result = 31 * result + (int) tcLow;
+ result = 31 * result + (int) tcHigh;
+ result = 31 * result + (int) tcMask;
+ result = 31 * result + flowLabel;
+ result = 31 * result + (int) nextHdr;
+ result = 31 * result + (int) srcPrefixLen;
+ result = 31 * result + (int) dstPrefixLen;
+ return result;
}
- @Override
- public void setDSCPTOSMask(byte v) {
- // TODO Auto-generated method stub
+ /**
+ * Returns a ExtendedClassifier object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as exceptions can be swallowed here.
+ */
+ public static IPv6Classifier parse(final byte[] data) {
+ final List<Byte> bytes = new ArrayList<>(Bytes.asList(data));
+ try {
+ final Inet6Address srcAddress = (Inet6Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(12, 28)));
+ final Inet6Address dstAddress = (Inet6Address)InetAddress.getByAddress(Bytes.toArray(bytes.subList(28, 44)));
+ final short srcPortBegin = COPSMsgParser.bytesToShort(data[44], data[45]);
+ final short srcPortEnd = COPSMsgParser.bytesToShort(data[46], data[47]);
+ final short dstPortBegin = COPSMsgParser.bytesToShort(data[48], data[49]);
+ final short dstPortEnd = COPSMsgParser.bytesToShort(data[50], data[51]);
+ final short classifierId = COPSMsgParser.bytesToShort(data[52], data[53]);
+ final byte priority = data[54];
+ final ActivationState activationState = ActivationState.valueOf(data[55]);
+ final byte action = data[56];
+ final FlowLabel flowEnabled = FlowLabel.valueOf(data[0]);
+ final byte tcLow = data[1];
+ final byte tcHigh = data[2];
+ final byte tcMask = data[3];
+ final int flowLabel = COPSMsgParser.bytesToInt(data[4], data[5], data[6], data[7]);
+ final short nextHdr = COPSMsgParser.bytesToShort(data[8], data[9]);
+ final byte srcPrefixLen = data[10];
+ final byte dstPrefixLen = data[11];
+
+ return new IPv6Classifier(srcAddress, dstAddress, srcPortBegin, dstPortBegin, priority, srcPortEnd,
+ dstPortEnd, classifierId, activationState, action, flowEnabled, tcLow, tcHigh, tcMask, flowLabel,
+ nextHdr, srcPrefixLen, dstPrefixLen);
+ } catch (UnknownHostException e) {
+ return null;
+ }
}
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.IPCMMError;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
+ * Implementation of the IPCMMError interface
*/
public class PCMMError extends PCMMBaseObject implements IPCMMError {
+
/**
- *
+ * The error code (cannot be NA)
*/
- public PCMMError() {
- this(LENGTH, STYPE, SNUM);
- }
+ private final ErrorCode errorCode;
- public PCMMError(short errorCode, short subErrCode) {
- this();
- setErrorCode(errorCode);
- setErrorSubcode(subErrCode);
- }
+ /**
+ * The error sub-code (defaults to NA)
+ */
+ private final ErrorCode subErrCode;
/**
- * @param data
+ * Constructor without a sub-code which will then be set to NA
+ * @param errorCode - the error code (required and not NA)
*/
- public PCMMError(byte[] data) {
- super(data);
+ public PCMMError(final ErrorCode errorCode) {
+ this(errorCode, null);
}
/**
- * @param len
- * @param sType
- * @param sNum
+ * Constructor with a sub-code
+ * @param errorCode - the error code (required and not NA)
+ * @param subErrCode - the sub-code (defaults to NA when null)
*/
- public PCMMError(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
+ public PCMMError(final ErrorCode errorCode, final ErrorCode subErrCode) {
+ super(SNum.PCMM_ERROR, STYPE);
+ if (errorCode == null || errorCode.equals(ErrorCode.NA))
+ throw new IllegalArgumentException("ErrorCode is required and must not be NA");
+ this.errorCode = errorCode;
+ if (subErrCode == null) this.subErrCode = ErrorCode.NA;
+ else this.subErrCode = subErrCode;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCError#setErrorCode(int)
- */
@Override
- public void setErrorCode(short errorCode) {
- setShort(errorCode, (short) 0);
+ public ErrorCode getErrorCode() {
+ return errorCode;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCError#getErrorCode()
- */
@Override
- public short getErrorCode() {
- return getShort((short) 0);
+ public ErrorCode getErrorSubcode() {
+ return subErrCode;
}
/*
* (non-Javadoc)
*
- * @see org.pcmm.gates.IPCError#setErrorSubcode(int)
+ * @see org.pcmm.gates.IPCError#getDescription()
*/
@Override
- public void setErrorSubcode(short errorSubcode) {
- setShort(errorSubcode, (short) 2);
+ public String getDescription() {
+ String hex = Integer.toHexString(subErrCode.getCode() & 0xFFFF);
+ return "Error Code: " + errorCode.getCode() + " Error Subcode : " + hex + " " + errorCode.getDescription();
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCError#getErrorCode()
- */
@Override
- public short getErrorSubcode() {
- return getShort((short) 2);
+ public String toString() {
+ return getDescription();
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCError#getDescription()
- */
@Override
- public String getDescription() {
- String hex = Integer.toHexString(getErrorSubcode() & 0xFFFF);
- return "Error Code: " + getErrorCode() + " Error Subcode : " + hex
- + " " + Description.valueOf(getErrorCode());
+ protected byte[] getBytes() {
+ final byte[] errorCodeBytes = COPSMsgParser.shortToBytes(errorCode.getCode());
+ final byte[] subErrCodeBytes = COPSMsgParser.shortToBytes(subErrCode.getCode());
+ final byte[] data = new byte[errorCodeBytes.length + subErrCodeBytes.length];
+ System.arraycopy(errorCodeBytes, 0, data, 0, errorCodeBytes.length);
+ System.arraycopy(subErrCodeBytes, 0, data, errorCodeBytes.length, subErrCodeBytes.length);
+ return data;
}
@Override
- public String toString() {
- return getDescription();
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof PCMMError)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final PCMMError pcmmError = (PCMMError) o;
+ return errorCode == pcmmError.errorCode && subErrCode == pcmmError.subErrCode;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + errorCode.hashCode();
+ result = 31 * result + subErrCode.hashCode();
+ return result;
+ }
+
+ /**
+ * Returns a PCMMError object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static PCMMError parse(final byte[] data) {
+ return new PCMMError(ErrorCode.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
+ ErrorCode.valueOf((COPSMsgParser.bytesToShort(data[2], data[3]))));
+
}
+
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
-import org.pcmm.base.IPCMMBaseObject;
+import com.google.common.primitives.Bytes;
+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>
public final static 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 IClassifier classifier;
+
+ // 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;
- public PCMMGateReq() {
+ /**
+ * 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 classifier - the classifier
+ * @param gateID - the gate ID
+ * @param error - the error
+ */
+ public PCMMGateReq(IAMID iamid, ISubscriberID subscriberID, ITransactionID transactionID,
+ IGateSpec gateSpec, ITrafficProfile trafficProfile, IClassifier classifier, IGateID gateID,
+ IPCMMError error) {
+ // TODO - determine if and when this attribute should be used
+ this.multicast = false;
+
+ this.iamid = iamid;
+ this.subscriberID = subscriberID;
+ this.transactionID = transactionID;
+ this.gateSpec = gateSpec;
+ this.trafficProfile = trafficProfile;
+ this.classifier = classifier;
+ this.gateID = gateID;
+ this.error = error;
}
- 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;
+ Classifier classifier = null;
+ PCMMError error = 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:
- // TODO - Will need to support other traffic profiles
- setTrafficProfile(new DOCSISServiceClassNameTrafficProfile(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:
+ classifier = Classifier.parse(dataBuffer);
+ break;
+ case IExtendedClassifier.STYPE:
+ classifier = ExtendedClassifier.parse(dataBuffer);
+ break;
+ case IIPv6Classifier.STYPE:
+ classifier = IPv6Classifier.parse(dataBuffer);
+ break;
+ }
+ break;
+ case PCMM_ERROR:
+ error = PCMMError.parse(dataBuffer);
+ 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, classifier, gateID, error);
}
- /*
- * (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 setTransactionID(ITransactionID transactionID) {
+ this.transactionID = transactionID;
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.IPCMMGate#getSubscriberID(org.pcmm.gates.ISubscriberID)
- */
- @Override
- public void setSubscriberID(ISubscriberID subscriberID) {
- this.subscriberID = subscriberID;
}
- /*
- * (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;
}
- /*
- * (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 IGateID getGateID() {
return gateID;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.IPCMMGate#getAMID()
- */
@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;
}
- /*
- * (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;
@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());
+ byteList.addAll(Bytes.asList(getClassifier().getAsBinaryArray()));
}
- return array;
+ 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;
}
+*/
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.gates.ISessionClassID;
/**
- *
+ * SessionClassID is a 1-byte unsigned integer value which identifies the proper admission control policy or
+ * parameters to be applied for this Gate. The SessionClassID is a bit field, defined as follows:
+ * Bit 0-2: Priority, a number from 0 to 7, where 0 is low priority and 7 is high.
+ * Bit 3: Preemption, set to enable preemption of bandwidth allocated to lower priority sessions if necessary
+ * (if supported).
+ * Bit 4-7: Configurable, default to 0
*/
public class SessionClassID implements ISessionClassID {
- private byte priority;
- private byte preemption;
+ /**
+ * The priority field describes the relative importance of the session as compared to other sessions generated by
+ * the same PDP. The PEP MAY use this value to both implement priority based admission (in conjunction with the
+ * Preemption bit), and to defend the resulting flow from being preempted.
+ */
+ private transient byte priority;
- // TODO check this;
- private byte session;
+ /**
+ * The preemption bit is used to by a PDP to direct the PEP to apply a priority-based admission control. Preemption
+ * support is optional; a PEP MAY ignore this bit. If preemption is not requested by the PDP or not implement by the
+ * PEP, then admission control policy will be on a first-come, first-served basis.
+ */
+ private transient byte preemption;
- public SessionClassID() {
- this((byte) 0);
- }
+ /**
+ * The session ID value
+ */
+ private byte session;
+ /**
+ * Constructor 1
+ * @param value - the session value
+ */
public SessionClassID(byte value) {
- session = value;
- priority = 0;
- preemption = 0;
+ this.session = value;
+ this.priority = 0;
+ this.preemption = 0;
priority |= value >> 2;
preemption |= value >> 3;
-
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISessionClassID#getPriority()
+ /**
+ * Constructor 2
+ * @param value - the session value
+ * @param priority - overrides the default priority value of 2
+ * @param preemption - overrides the default preemption value of 3
*/
+ public SessionClassID(byte value, final byte priority, final byte preemption) {
+ this.session = value;
+ this.priority = priority;
+ this.preemption = preemption;
+ }
+
@Override
public byte getPriority() {
return priority;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISessionClassID#setPriority(byte)
- */
@Override
- public void setPriority(byte value) {
- this.priority = value;
+ public byte getPreemption() {
+ return preemption;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISessionClassID#getPreemption()
- */
@Override
- public byte getPreemption() {
- return preemption;
+ public byte toSingleByte() {
+ return session;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISessionClassID#setPreemption(byte)
- */
@Override
- public void setPreemption(byte value) {
- this.preemption = value;
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SessionClassID)) {
+ return false;
+ }
+ final SessionClassID that = (SessionClassID) o;
+ return priority == that.priority && preemption == that.preemption && session == that.session;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISessionClassID#toSingleByte()
- */
@Override
- public byte toSingleByte() {
- // byte ret = 0;
- // ret |= (priority << 2);
- // ret |= (preemption & 0xf);
- // return ret;
- return session;
+ public int hashCode() {
+ int result = (int) priority;
+ result = 31 * result + (int) preemption;
+ result = 31 * result + (int) session;
+ return result;
}
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
-package org.pcmm.gates.impl;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.ISubscriberID;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
/**
- *
+ * Implementation of the ISubscriberID interface
*/
public class SubscriberID extends PCMMBaseObject implements ISubscriberID {
/**
- *
+ * The source IPv4 or IPv6 address
*/
- public SubscriberID() {
- this(LENGTH, STYPE, SNUM);
- }
+ private final InetAddress srcIp;
/**
- * @param data
+ * Constructor
+ * @param srcIp - the source host address
*/
- public SubscriberID(byte[] data) {
- super(data);
+ public SubscriberID(final InetAddress srcIp) {
+ super(SNum.SUBSCRIBER_ID, STYPE);
+ if (srcIp == null) throw new IllegalArgumentException("srcIp must not be null");
+ this.srcIp = srcIp;
}
- /**
- * @param len
- * @param sType
- * @param sNum
- */
- public SubscriberID(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
+ @Override
+ public InetAddress getSourceIPAddress() {
+ return srcIp;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ISubscriberID#getSourceIPAddress()
- */
@Override
- public InetAddress getSourceIPAddress() {
- try {
- return Inet4Address.getByAddress(getBytes((short) 0, (short) 4));
- } catch (UnknownHostException e) {
- return null;
+ protected byte[] getBytes() {
+ return srcIp.getAddress();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SubscriberID)) {
+ return false;
}
+ if (!super.equals(o)) {
+ return false;
+ }
+ final SubscriberID that = (SubscriberID) o;
+ return srcIp.equals(that.srcIp);
}
- /*
- * (non-Javadoc)
- *
- * @see
- * org.pcmm.gates.ISubscriberID#setSourceIPAddress(java.net.InetAddress)
- */
@Override
- public void setSourceIPAddress(InetAddress address) {
- setBytes(address.getAddress(), (short) 0);
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + srcIp.hashCode();
+ return result;
}
+ /**
+ * Returns a SubscriberID object from a byte array
+ * @param data - the data to parse
+ * @return - the object or null if cannot be parsed
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
+ */
+ public static SubscriberID parse(final byte[] data) {
+ try {
+ return new SubscriberID(InetAddress.getByAddress(data));
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.gates.impl;
import org.pcmm.base.impl.PCMMBaseObject;
import org.pcmm.gates.ITransactionID;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
+ * Implementation of the ITransactionID interface
*/
public class TransactionID extends PCMMBaseObject implements ITransactionID {
/**
- *
+ * The transaction identifier
*/
- public TransactionID() {
- this(LENGTH, STYPE, SNUM);
- }
+ private final short transId;
/**
- * @param data
+ * The gate command type
*/
- public TransactionID(byte[] data) {
- super(data);
- }
+ private final GateCommandType gateCommandType;
/**
- * @param len
- * @param sType
- * @param sNum
+ * Constructor
+ * @param transId - the transaction identifier
+ * @param gateCommandType - the gate command type
*/
- public TransactionID(short len, byte sType, byte sNum) {
- super(len, sType, sNum);
+ public TransactionID(final short transId, final GateCommandType gateCommandType) {
+ super(SNum.TRANSACTION_ID, STYPE);
+ if (gateCommandType == null)
+ throw new IllegalArgumentException("Invalid gate command type");
+ this.transId = transId;
+ this.gateCommandType = gateCommandType;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITransactionID#setTransactionIdentifier(short)
- */
@Override
- public void setTransactionIdentifier(short id) {
- setShort(id, (short) 0);
+ public short getTransactionIdentifier() {
+ return transId;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITransactionID#getTransactionIdentifier()
- */
@Override
- public short getTransactionIdentifier() {
- return getShort((short) 0);
+ public GateCommandType getGateCommandType() {
+ return gateCommandType;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITransactionID#setGateCommandType(short)
- */
@Override
- public void setGateCommandType(short type) {
- setShort(type, (short) 2);
+ protected byte[] getBytes() {
+ final byte[] transIdBytes = COPSMsgParser.shortToBytes(transId);
+ final byte[] data = new byte[transIdBytes.length + transIdBytes.length];
+ System.arraycopy(transIdBytes, 0, data, 0, transIdBytes.length);
+
+ final byte[] gateCmdBytes = COPSMsgParser.shortToBytes(gateCommandType.getValue());
+ System.arraycopy(gateCmdBytes, 0, data, transIdBytes.length, gateCmdBytes.length);
+ return data;
}
- /*
- * (non-Javadoc)
- *
- * @see org.pcmm.gates.ITransactionID#getGateCommandType()
+ /**
+ * Returns a TransactionID object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
*/
- @Override
- public short getGateCommandType() {
- return getShort((short) 2);
+ public static TransactionID parse(final byte[] data) {
+ return new TransactionID(COPSMsgParser.bytesToShort(data[0], data[1]),
+ GateCommandType.valueOf(COPSMsgParser.bytesToShort(data[2], data[3])));
}
-
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.objects;
import org.pcmm.base.impl.PCMMBaseObject;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
- * PCMM MM version info Object
- *
+ * The Version Info object is used to enable Multimedia applications to adapt their interactions with other devices so
+ * that interoperability can be achieved between products supporting different protocol versions. Both the Major
+ * Version Number and the Minor Version Number are 2 byte unsigned integers. Both the PDP and the PEP must include this
+ * object as specified in Section 6.5.1
*/
public class MMVersionInfo extends PCMMBaseObject {
- private short majorVersionNB;
- private short minorVersionNB;
public static final short DEFAULT_MAJOR_VERSION_INFO = (short) 5;
public static final short DEFAULT_MINOR_VERSION_INFO = (short) 0;
- public MMVersionInfo() {
- this(DEFAULT_MAJOR_VERSION_INFO, DEFAULT_MINOR_VERSION_INFO);
- }
+ /**
+ * The major version number
+ */
+ private final short majorVersionNB;
- public MMVersionInfo(short majorVersionNB, short minorVersionNB) {
- super((short) 8, (byte) 1, (byte) 16);
- setShort(this.majorVersionNB = majorVersionNB, (short) 0);
- setShort(this.minorVersionNB = minorVersionNB, (short) 2);
- }
+ /**
+ * The minor version number
+ */
+ private final short minorVersionNB;
/**
- * Parse data and create COPSHandle object
+ * Constructor
+ * @param majorVersionNB - the major version number
+ * @param minorVersionNB - the minor version number
*/
- public MMVersionInfo(byte[] dataPtr) {
- super(dataPtr);
- majorVersionNB = getShort((short) 0);
- minorVersionNB = getShort((short) 2);
+ public MMVersionInfo(short majorVersionNB, short minorVersionNB) {
+ super(SNum.VERSION_INFO, (byte)1);
+ this.majorVersionNB = majorVersionNB;
+ this.minorVersionNB = minorVersionNB;
}
/**
return majorVersionNB;
}
- /**
- * @param majorVersionNB
- * the majorVersionNB to set
- */
- public void setMajorVersionNB(short majorVersionNB) {
- this.majorVersionNB = majorVersionNB;
- }
-
/**
* @return the minorVersionNB
*/
return minorVersionNB;
}
+ @Override
+ protected byte[] getBytes() {
+ final byte[] majVerBytes = COPSMsgParser.shortToBytes(majorVersionNB);
+ final byte[] minVerBytes = COPSMsgParser.shortToBytes(minorVersionNB);
+ final byte[] data = new byte[majVerBytes.length + minVerBytes.length];
+ System.arraycopy(majVerBytes, 0, data, 0, majVerBytes.length);
+ System.arraycopy(minVerBytes, 0, data, majVerBytes.length, minVerBytes.length);
+ return data;
+ }
+
/**
- * @param minorVersionNB
- * the minorVersionNB to set
+ * Returns an MMVersionInfo object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
*/
- public void setMinorVersionNB(short minorVersionNB) {
- this.minorVersionNB = minorVersionNB;
+ public static MMVersionInfo parse(final byte[] data) {
+ return new MMVersionInfo(COPSMsgParser.bytesToShort(data[0], data[1]),
+ COPSMsgParser.bytesToShort(data[2], data[3]));
}
}
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
+
package org.pcmm.objects;
import org.pcmm.base.impl.PCMMBaseObject;
+import org.umu.cops.stack.COPSMsgParser;
/**
- *
* PCMM SyncOptions object
- *
*/
public class SyncOptions extends PCMMBaseObject {
- private byte synchType;
-
- private byte reportType;
-
- public static final byte STANDARD_REPORT_DATA = (byte) 0;
- public static final byte COMPLETE_GATE_DATA = (byte) 1;
- public static final byte FULL_SYNCHRONIZATION = (byte) 0;
- public static final byte INCREMENTAL_SYNCHRONIZATION = (byte) 1;
+ /**
+ * The requested report type
+ */
+ private final ReportType reportType;
- public SyncOptions() {
- this(STANDARD_REPORT_DATA, FULL_SYNCHRONIZATION);
- }
+ /**
+ * The requested type of synchronization
+ */
+ private final SyncType syncType;
- public SyncOptions(byte reportType, byte synchType) {
- super((short) 8, (byte) 1, (byte) 18);
- setByte(this.reportType = reportType, (short) 4);
- setByte(this.synchType = synchType, (short) 6);
+ /**
+ * Constructor
+ * @param reportType - the requested report type
+ * @param syncType - the requested synchronization type
+ */
+ public SyncOptions(final ReportType reportType, final SyncType syncType) {
+ super(SNum.SYNC_OPTS, (byte)1);
+ if (reportType == null) throw new IllegalArgumentException("Report type must not be null");
+ if (syncType == null) throw new IllegalArgumentException("Synchronization type must not be null");
+ this.reportType = reportType;
+ this.syncType = syncType;
}
/**
- * Parse data and create COPSHandle object
+ * @return the syncType
*/
- public SyncOptions(byte[] dataPtr) {
- super(dataPtr);
- reportType = getByte((short) 4);
- synchType = getByte((short) 6);
+ public SyncType getSyncType() {
+ return syncType;
}
/**
- * @return the synchType
+ * @return the reportType
*/
- public byte getSynchType() {
- return synchType;
+ public ReportType getReportType() {
+ return reportType;
+ }
+
+ @Override
+ protected byte[] getBytes() {
+ final byte[] rptTypeBytes = COPSMsgParser.shortToBytes(reportType.getValue());
+ final byte[] syncTypeBytes = COPSMsgParser.shortToBytes(syncType.getValue());
+ final byte[] data = new byte[rptTypeBytes.length + syncTypeBytes.length];
+ System.arraycopy(rptTypeBytes, 0, data, 0, rptTypeBytes.length);
+ System.arraycopy(syncTypeBytes, 0, data, rptTypeBytes.length, syncTypeBytes.length);
+ return data;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof SyncOptions)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+ final SyncOptions that = (SyncOptions) o;
+ return reportType == that.reportType && syncType == that.syncType;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + reportType.hashCode();
+ result = 31 * result + syncType.hashCode();
+ return result;
}
/**
- * @param synchType
- * the synchType to set
+ * Returns a SyncOptions object from a byte array
+ * @param data - the data to parse
+ * @return - the object
+ * TODO - make me more robust as RuntimeExceptions can be thrown here.
*/
- public void setSynchType(byte synchType) {
- this.synchType = synchType;
+ public static SyncOptions parse(final byte[] data) {
+ return new SyncOptions(ReportType.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
+ SyncType.valueOf(COPSMsgParser.bytesToShort(data[2], data[3])));
}
/**
- * @return the reportType
+ * The supported Report types
*/
- public byte getReportType() {
- return reportType;
+ public enum ReportType {
+
+ STANDARD_REPORT_DATA((short) 0), COMPLETE_GATE_DATA((short) 1);
+
+ ReportType(short value) {
+ this.value = value;
+ }
+
+ public short getValue() {
+ return value;
+ }
+
+ public static ReportType valueOf(short v) {
+ switch (v) {
+ case 0:
+ return ReportType.STANDARD_REPORT_DATA;
+ case 1:
+ return ReportType.COMPLETE_GATE_DATA;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
+
+ private short value;
+
}
/**
- * @param reportType
- * the reportType to set
+ * The supported Synchronization types
*/
- public void setReportType(byte reportType) {
- this.reportType = reportType;
+ public enum SyncType {
+
+ FULL_SYNCHRONIZATION((short) 0), INCREMENTAL_SYNCHRONIZATION((short) 1);
+
+ SyncType(short value) {
+ this.value = value;
+ }
+
+ public short getValue() {
+ return value;
+ }
+
+ public static SyncType valueOf(short v) {
+ switch (v) {
+ case 0:
+ return SyncType.FULL_SYNCHRONIZATION;
+ case 1:
+ return SyncType.INCREMENTAL_SYNCHRONIZATION;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
+
+ private short value;
+
}
}
data = installDecs.get(k);
break;
}
- final ITransactionID transactionID = new PCMMGateReq(new COPSData(data).getData()).getTransactionID();
- final IPCMMGate responseGate = new PCMMGateReq();
- responseGate.setTransactionID(transactionID);
+ final ITransactionID transactionID = PCMMGateReq.parse(new COPSData(data).getData()).getTransactionID();
+
+ // TODO - Determine how and why a response gate request can have only a transaction ID???
+ final IPCMMGate responseGate = new PCMMGateReq(null, null, transactionID, null, null, null, null, null);
// TODO FIXME - Why is the key always null??? What value should be used here???
final String key = null;
import org.pcmm.gates.IGateSpec.Direction;
import org.pcmm.gates.IPCMMError;
+import org.pcmm.gates.IPCMMError.ErrorCode;
import org.pcmm.gates.impl.GateID;
import org.pcmm.gates.impl.PCMMError;
import org.pcmm.gates.impl.PCMMGateReq;
logger.info("processing decision");
// This is assuming a gate set right or wrong
if (dMsg.getDecisions().size() == 1 && dMsg.getDecSI() != null) {
- final PCMMGateReq gateReq = new PCMMGateReq(dMsg.getDecSI().getData().getData());
+ final PCMMGateReq gateReq = PCMMGateReq.parse(dMsg.getDecSI().getData().getData());
if (gateReq.getGateSpec() != null) {
processGateReq(gateReq, _socket);
}
// Get direction here
final Direction gateDir = gateReq.getGateSpec().getDirection();
final Set<String> gateNames = gateConfig.get(gateDir);
- final String gateName = gateReq.getTrafficProfile().getData().str();
+ // TODO - Determine if this is the best means to derive the gate name???
+ final String gateName = new String(gateReq.getTrafficProfile().getAsBinaryArray());
- IPCMMError error = new PCMMError();
- if (subId == null || gateDir == null || gateNames == null || gateName == null) {
+ final IPCMMError error;
+ if (subId == null || gateDir == null || gateNames == null) {
// Missing required object
- error.setErrorCode((short)3);
+ // TODO - Determine if this is the correct code. 3 was being used previously and I don't see any corresponding code.
+ error = new PCMMError(ErrorCode.UNK_GATE_ID);
} else if (!cmStatus.keySet().contains(subId)
|| (cmStatus.keySet().contains(subId) && !cmStatus.get(subId))) {
// Invalid Object
- error.setErrorCode((short)13);
+ // TODO - Determine if this code is correct
+ error = new PCMMError(ErrorCode.INVALID_SUB_ID);
} else if (!gateNames.contains(gateName.trim())) {
- error.setErrorCode((short)11);
+ // TODO - Determine if this code is correct
+ error = new PCMMError(ErrorCode.UNDEF_SCN_NAME);
} else {
error = null;
gatesSetMap.get(gateName.trim()).add(subId);
data.add(val);
// Assign a gate ID
- final GateID gateID = new GateID();
- gateID.setGateID(UUID.randomUUID().hashCode());
+ final GateID gateID = new GateID(UUID.randomUUID().hashCode());
for (final byte val : gateID.getAsBinaryArray())
data.add(val);
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
*/
package org.pcmm.utils;
public class PCMMException extends Exception {
public PCMMException(IPCMMError error) {
- this(error.getDescription(), error.getErrorCode());
+ this(error.getDescription(), error.getErrorCode().getCode());
}
public PCMMException(String message, int code) {
sendCloseMessage(conn, ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA,
"Unsupported objects (PdpAddress, Integrity)");
} else {
- final MMVersionInfo _mminfo = new MMVersionInfo(cMsg.getClientSI().getData().getData());
+ final MMVersionInfo _mminfo = MMVersionInfo.parse(cMsg.getClientSI().getData().getData());
logger.debug("CMTS sent MMVersion info : major:" + _mminfo.getMajorVersionNB() + " minor:" +
_mminfo.getMinorVersionNB());
}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class AMID to ensure both construction and byte parsing result in correct object creation.
+ */
+public class AMIDTest {
+
+ @Test
+ public void construction() {
+ final AMID amid = new AMID((short)5, (short)6);
+ final byte[] dataBytes = amid.getBytes();
+ Assert.assertEquals((short)5, amid.getApplicationType());
+ Assert.assertEquals((short)6, amid.getApplicationMgrTag());
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(5, COPSMsgParser.bytesToShort(dataBytes[0], dataBytes[1]));
+ Assert.assertEquals(6, COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3]));
+ }
+
+ @Test
+ public void byteParsing() {
+ final AMID amid = new AMID((short)7, (short)8);
+ final AMID parsed = AMID.parse(amid.getBytes());
+ Assert.assertEquals(amid, parsed);
+ }
+
+}
--- /dev/null
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the data holder class BestEffortService to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class BestEffortServiceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAllEnvelopes() {
+ new BestEffortService(null, null, null);
+ }
+
+ @Test
+ public void requiredEnvelopeOnly() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BestEffortService service = new BestEffortService(auth, null, null);
+ Assert.assertNotNull(service.getAuthorizedEnvelop());
+ Assert.assertNull(service.getReservedEnvelop());
+ Assert.assertNull(service.getCommittedEnvelop());
+ // TODO - add more validation here
+ }
+
+ @Test
+ public void authAndReservedEnvelopes() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BEEnvelop resv = new BEEnvelop((byte)10, 11, 12, 13, 14, (short)15, (short)16, 17, 18, 19, 10, 11, 12, 13);
+ final BestEffortService service = new BestEffortService(auth, resv, null);
+ Assert.assertNotNull(service.getAuthorizedEnvelop());
+ Assert.assertNotNull(service.getReservedEnvelop());
+ Assert.assertNull(service.getCommittedEnvelop());
+ // TODO - add more validation here
+ }
+
+ @Test
+ public void allEnvelopes() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BEEnvelop resv = new BEEnvelop((byte)10, 11, 12, 13, 14, (short)15, (short)16, 17, 18, 19, 10, 11, 12, 13);
+ final BEEnvelop cmmt = new BEEnvelop((byte)20, 21, 22, 23, 24, (short)25, (short)26, 27, 28, 29, 20, 21, 22, 23);
+ final BestEffortService service = new BestEffortService(auth, resv, cmmt);
+ Assert.assertNotNull(service.getAuthorizedEnvelop());
+ Assert.assertNotNull(service.getReservedEnvelop());
+ Assert.assertNotNull(service.getCommittedEnvelop());
+ // TODO - add more validation here
+ }
+
+ @Test
+ public void byteParsingAuth() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BestEffortService service = new BestEffortService(auth, null, null);
+ final BestEffortService parsed = BestEffortService.parse(service.getBytes());
+ Assert.assertEquals(service, parsed);
+ }
+
+ @Test
+ public void byteParsingAuthReserved() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BEEnvelop resv = new BEEnvelop((byte)10, 11, 12, 13, 14, (short)15, (short)16, 17, 18, 19, 10, 11, 12, 13);
+ final BestEffortService service = new BestEffortService(auth, resv, null);
+ final BestEffortService parsed = BestEffortService.parse(service.getBytes());
+ Assert.assertEquals(service, parsed);
+ }
+
+ @Test
+ public void byteParsingAll() {
+ final BEEnvelop auth = new BEEnvelop((byte)0, 1, 2, 3, 4, (short)5, (short)6, 7, 8, 9, 0, 1, 2, 3);
+ final BEEnvelop resv = new BEEnvelop((byte)10, 11, 12, 13, 14, (short)15, (short)16, 17, 18, 19, 10, 11, 12, 13);
+ final BEEnvelop cmmt = new BEEnvelop((byte)20, 21, 22, 23, 24, (short)25, (short)26, 27, 28, 29, 20, 21, 22, 23);
+ final BestEffortService service = new BestEffortService(auth, resv, cmmt);
+ final BestEffortService parsed = BestEffortService.parse(service.getBytes());
+ Assert.assertEquals(service, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.IClassifier.Protocol;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests the data holder class Classifier to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class ClassifierTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullProtocol() throws UnknownHostException {
+ new Classifier(null, (byte)1, (byte)1, (Inet4Address)InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSrcAddr() throws UnknownHostException {
+ new Classifier(Protocol.NONE, (byte)1, (byte)1, null, (Inet4Address)InetAddress.getByName("localhost"),
+ (short)1, (short)2, (byte)4);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDstAddr() throws UnknownHostException {
+ new Classifier(Protocol.NONE, (byte)1, (byte)1, (Inet4Address)InetAddress.getByName("localhost"), null,
+ (short)1, (short)2, (byte)4);
+ }
+
+ @Test
+ public void construction() throws UnknownHostException {
+ final Classifier classifier = new Classifier(Protocol.NONE, (byte)1, (byte)1,
+ (Inet4Address)InetAddress.getByName("localhost"), (Inet4Address)InetAddress.getByName("localhost"),
+ (short)1, (short)2, (byte)4);
+ Assert.assertEquals(Protocol.NONE, classifier.getProtocol());
+ Assert.assertEquals((byte)1, classifier.getDSCPTOS());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getSourceIPAddress());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getDestinationIPAddress());
+ Assert.assertEquals((short) 1, classifier.getSourcePort());
+ Assert.assertEquals((short) 2, classifier.getDestinationPort());
+ Assert.assertEquals((byte) 4, classifier.getPriority());
+ }
+
+ @Test
+ public void byteParsing() throws UnknownHostException {
+ final Classifier classifier = new Classifier(Protocol.NONE, (byte)1, (byte)4,
+ (Inet4Address)InetAddress.getByName("localhost"), (Inet4Address)InetAddress.getByName("localhost"),
+ (short)5, (short)6, (byte)7);
+ final Classifier parsed = Classifier.parse(classifier.getBytes());
+ Assert.assertEquals(classifier, parsed);
+ }
+
+}
--- /dev/null
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the data holder class DOCSISServiceClassNameTrafficProfile to ensure both construction and byte parsing result
+ * in correct object creation.
+ */
+public class DOCSISServiceClassNameTrafficProfileTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullSCN() {
+ new DOCSISServiceClassNameTrafficProfile(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1ShortSCN() {
+ new DOCSISServiceClassNameTrafficProfile("1");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1LongSCN() {
+ new DOCSISServiceClassNameTrafficProfile("01234567891234567");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullSCN() {
+ new DOCSISServiceClassNameTrafficProfile((byte)1, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2ShortSCN() {
+ new DOCSISServiceClassNameTrafficProfile((byte)1, "1");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2LongSCN() {
+ new DOCSISServiceClassNameTrafficProfile((byte)1, "01234567891234567");
+ }
+
+ @Test
+ public void construction() {
+ final DOCSISServiceClassNameTrafficProfile profile =
+ new DOCSISServiceClassNameTrafficProfile((byte)5, "0123456789123456");
+ Assert.assertEquals((byte)5, profile.getEnvelop());
+ Assert.assertEquals("0123456789123456", profile.getScnName());
+ }
+
+ @Test
+ public void byteParsingWithoutPadding() {
+ // Name length % 4 == 0
+ final DOCSISServiceClassNameTrafficProfile profile =
+ new DOCSISServiceClassNameTrafficProfile((byte)25, "1234");
+ final DOCSISServiceClassNameTrafficProfile parsed =
+ DOCSISServiceClassNameTrafficProfile.parse(profile.getBytes());
+ Assert.assertEquals(profile, parsed);
+ }
+
+ @Test
+ public void byteParsingWithOnePaddedChar() {
+ // Name length % 4 == 1
+ final DOCSISServiceClassNameTrafficProfile profile =
+ new DOCSISServiceClassNameTrafficProfile((byte)25, "123");
+ final DOCSISServiceClassNameTrafficProfile parsed =
+ DOCSISServiceClassNameTrafficProfile.parse(profile.getBytes());
+ Assert.assertEquals(profile, parsed);
+ }
+
+ @Test
+ public void byteParsingWithThreePaddedChar() {
+ // Name length % 4 == 3
+ final DOCSISServiceClassNameTrafficProfile profile =
+ new DOCSISServiceClassNameTrafficProfile((byte)25, "12345");
+ final DOCSISServiceClassNameTrafficProfile parsed =
+ DOCSISServiceClassNameTrafficProfile.parse(profile.getBytes());
+ Assert.assertEquals(profile, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.IClassifier.Protocol;
+import org.pcmm.gates.IExtendedClassifier.ActivationState;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests the data holder class ExtendedClassifier to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class ExtendedClassifierTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullProtocol() throws UnknownHostException {
+ new ExtendedClassifier(null, (byte)1, (byte)1, (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSrcAddr() throws UnknownHostException {
+ new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)1, null,
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDstAddr() throws UnknownHostException {
+ new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)1, (Inet4Address) InetAddress.getByName("localhost"),
+ null, (short)1, (short)2, (byte)4,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSrcMask() throws UnknownHostException {
+ new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)1, (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4,
+ null, (Inet4Address) InetAddress.getByName("localhost"),
+ (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDstMask() throws UnknownHostException {
+ new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)1, (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4,
+ (Inet4Address) InetAddress.getByName("localhost"), null,
+ (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullActivationState() throws UnknownHostException {
+ new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)1, (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)1, (short)2, (byte)4,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)5, (short)6, (short)7, null, (byte)9);
+ }
+
+ @Test
+ public void constructionActive() throws UnknownHostException {
+ final ExtendedClassifier classifier = new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)10,
+ (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)11, (short)12, (byte)14,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)15, (short)16, (short)17, ActivationState.ACTIVE, (byte)19);
+ Assert.assertEquals(Protocol.NONE, classifier.getProtocol());
+ Assert.assertEquals((byte)1, classifier.getDSCPTOS());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getSourceIPAddress());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getDestinationIPAddress());
+ Assert.assertEquals((short) 11, classifier.getSourcePort());
+ Assert.assertEquals((short) 12, classifier.getDestinationPort());
+ Assert.assertEquals((byte) 14, classifier.getPriority());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getIPSourceMask());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getIPDestinationMask());
+ Assert.assertEquals((short) 15, classifier.getSourcePortEnd());
+ Assert.assertEquals((short) 16, classifier.getDestinationPortEnd());
+ Assert.assertEquals((short) 17, classifier.getClassifierID());
+ Assert.assertEquals(ActivationState.ACTIVE, classifier.getActivationState());
+ Assert.assertEquals((byte) 19, classifier.getAction());
+ }
+
+ @Test
+ public void constructionInactive() throws UnknownHostException {
+ final ExtendedClassifier classifier = new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)10,
+ (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)11, (short)12, (byte)14,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)15, (short)16, (short)17, ActivationState.INACTIVE, (byte)19);
+ Assert.assertEquals(Protocol.NONE, classifier.getProtocol());
+ Assert.assertEquals((byte)1, classifier.getDSCPTOS());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getSourceIPAddress());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getDestinationIPAddress());
+ Assert.assertEquals((short) 11, classifier.getSourcePort());
+ Assert.assertEquals((short) 12, classifier.getDestinationPort());
+ Assert.assertEquals((byte) 14, classifier.getPriority());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getIPSourceMask());
+ Assert.assertEquals(InetAddress.getByName("localhost"), classifier.getIPDestinationMask());
+ Assert.assertEquals((short) 15, classifier.getSourcePortEnd());
+ Assert.assertEquals((short) 16, classifier.getDestinationPortEnd());
+ Assert.assertEquals((short) 17, classifier.getClassifierID());
+ Assert.assertEquals(ActivationState.INACTIVE, classifier.getActivationState());
+ Assert.assertEquals((byte) 19, classifier.getAction());
+ }
+
+ @Test
+ public void byteParsingActive() throws UnknownHostException {
+ final ExtendedClassifier classifier = new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)20,
+ (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)21, (short)22, (byte)24,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)25, (short)26, (short)27, ActivationState.ACTIVE, (byte)29);
+ final ExtendedClassifier parsed = ExtendedClassifier.parse(classifier.getBytes());
+ Assert.assertEquals(classifier, parsed);
+ }
+
+ @Test
+ public void byteParsingInactive() throws UnknownHostException {
+ final ExtendedClassifier classifier = new ExtendedClassifier(Protocol.NONE, (byte)1, (byte)20,
+ (Inet4Address) InetAddress.getByName("localhost"),
+ (Inet4Address)InetAddress.getByName("localhost"), (short)21, (short)22, (byte)24,
+ (Inet4Address) InetAddress.getByName("localhost"), (Inet4Address) InetAddress.getByName("localhost"),
+ (short)25, (short)26, (short)27, ActivationState.INACTIVE, (byte)29);
+ final ExtendedClassifier parsed = ExtendedClassifier.parse(classifier.getBytes());
+ Assert.assertEquals(classifier, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class GateId to ensure both construction and byte parsing result in correct object creation.
+ */
+public class GateIDTest {
+
+ @Test
+ public void construction() {
+ final GateID gateID = new GateID(9);
+
+ // Check the object's bytes
+ final byte[] dataBytes = gateID.getBytes();
+ Assert.assertEquals(9, gateID.getGateID());
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(9, COPSMsgParser.bytesToInt(dataBytes[0], dataBytes[1], dataBytes[2], dataBytes[3]));
+
+ // Check the byte parsing
+ final GateID parsed = GateID.parse(dataBytes);
+ Assert.assertEquals(gateID, parsed);
+ }
+
+ @Test
+ public void byteParsing() {
+ final GateID gateID = new GateID(10);
+ final GateID parsed = GateID.parse(gateID.getBytes());
+ Assert.assertEquals(gateID, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.IGateSpec.Direction;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class GateSpec to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class GateSpecTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDirection() {
+ new GateSpec(null, (byte)1, (byte)1, new SessionClassID((byte)1),
+ (short)1, (short)2, (short)3, (short)4);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSessionClassID() {
+ new GateSpec(Direction.UPSTREAM, (byte)1, (byte)1, null,
+ (short)1, (short)2, (short)3, (short)4);
+ }
+
+ @Test
+ public void construction() {
+ final GateSpec spec = new GateSpec(Direction.UPSTREAM, (byte)1, (byte)1, new SessionClassID((byte)1),
+ (short)1, (short)2, (short)3, (short)4);
+ Assert.assertEquals(Direction.UPSTREAM, spec.getDirection());
+ Assert.assertEquals((byte)1, spec.getDSCP_TOSOverwrite());
+ Assert.assertEquals((byte)1, spec.getDSCP_TOSMask());
+ Assert.assertEquals(new SessionClassID((byte) 1), spec.getSessionClassID());
+ Assert.assertEquals((short)1, spec.getTimerT1());
+ Assert.assertEquals((short)2, spec.getTimerT2());
+ Assert.assertEquals((short)3, spec.getTimerT3());
+ Assert.assertEquals((short)4, spec.getTimerT4());
+
+ final byte[] data = spec.getBytes();
+
+ Assert.assertEquals(Direction.UPSTREAM, Direction.valueOf(data[0]));
+ Assert.assertEquals((byte)1, data[1]);
+ Assert.assertEquals((byte)1, data[2]);
+ Assert.assertEquals(new SessionClassID((byte)1), new SessionClassID(data[3]));
+ Assert.assertEquals((short)1, COPSMsgParser.bytesToShort(data[4], data[5]));
+ Assert.assertEquals((short)2, COPSMsgParser.bytesToShort(data[6], data[7]));
+ Assert.assertEquals((short)3, COPSMsgParser.bytesToShort(data[8], data[9]));
+ Assert.assertEquals((short)4, COPSMsgParser.bytesToShort(data[10], data[11]));
+ }
+
+ @Test
+ public void byteParsing() {
+ final GateSpec spec = new GateSpec(Direction.DOWNSTREAM, (byte)1, (byte)2, new SessionClassID((byte)3),
+ (short)4, (short)5, (short)6, (short)7);
+ final GateSpec parsed = GateSpec.parse(spec.getBytes());
+ Assert.assertEquals(spec, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.IExtendedClassifier.ActivationState;
+import org.pcmm.gates.IIPv6Classifier.FlowLabel;
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests the data holder class ExtendedClassifier.
+ */
+public class IPv6ClassifierTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSrcAddr() throws UnknownHostException {
+ new IPv6Classifier(null, (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (short)1, (short)2, (byte)4, (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9,
+ FlowLabel.VALID, (byte)11, (byte)12, (byte)13, 14, (short)15, (byte)16, (byte)17);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDstAddr() throws UnknownHostException {
+ new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ null, (short)1, (short)2, (byte)4, (short)5, (short)6, (short)7, ActivationState.ACTIVE, (byte)9,
+ FlowLabel.VALID, (byte)11, (byte)12, (byte)13, 14, (short)15, (byte)16, (byte)17);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullActivationState() throws UnknownHostException {
+ new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"), (short)1, (short)2, (byte)4, (short)5,
+ (short)6, (short)7, null, (byte)9, FlowLabel.VALID, (byte)11, (byte)12, (byte)13, 14, (short)15,
+ (byte)16, (byte)17);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlowLabel() throws UnknownHostException {
+ new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"), (short)1, (short)2, (byte)4, (short)5,
+ (short)6, (short)7, ActivationState.ACTIVE, (byte)9, null, (byte)11, (byte)12, (byte)13, 14, (short)15,
+ (byte)16, (byte)17);
+ }
+
+ @Test
+ public void constructionActiveValid() throws UnknownHostException {
+ final IPv6Classifier classifier = new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (short)11, (short)12, (byte)14, (short)15, (short)16, (short)17, ActivationState.ACTIVE, (byte)19,
+ FlowLabel.VALID, (byte)21, (byte)22, (byte)23, 24, (short)25, (byte)26, (byte)27);
+
+ Assert.assertNull(classifier.getProtocol());
+
+ Assert.assertEquals((byte) 0, classifier.getDSCPTOS());
+
+ Assert.assertEquals(InetAddress.getByName("00:00:00:00:00:00:00:01"), classifier.getSourceIPAddress());
+ Assert.assertEquals(InetAddress.getByName("00:00:00:00:00:00:00:01"), classifier.getDestinationIPAddress());
+ Assert.assertEquals((short) 11, classifier.getSourcePort());
+ Assert.assertEquals((short) 12, classifier.getDestinationPort());
+ Assert.assertEquals((byte) 14, classifier.getPriority());
+ Assert.assertEquals((short) 15, classifier.getSourcePortEnd());
+ Assert.assertEquals((short) 16, classifier.getDestinationPortEnd());
+ Assert.assertEquals((short) 17, classifier.getClassifierID());
+ Assert.assertEquals(ActivationState.ACTIVE, classifier.getActivationState());
+ Assert.assertEquals((byte) 19, classifier.getAction());
+ Assert.assertEquals(FlowLabel.VALID, classifier.getFlowLabelEnableFlag());
+ Assert.assertEquals((byte) 21, classifier.getTcLow());
+ Assert.assertEquals((byte) 22, classifier.getTcHigh());
+ Assert.assertEquals((byte) 23, classifier.getTcMask());
+ Assert.assertEquals(24, classifier.getFlowLabel());
+ Assert.assertEquals((short)25, classifier.getNextHdr());
+ Assert.assertEquals((byte)26, classifier.getSourcePrefixLen());
+ Assert.assertEquals((byte)27, classifier.getDestinationPrefixLen());
+ }
+
+ @Test
+ public void constructionInactiveIrrelevant() throws UnknownHostException {
+ final IPv6Classifier classifier = new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (short)11, (short)12, (byte)14, (short)15, (short)16, (short)17, ActivationState.INACTIVE, (byte)19,
+ FlowLabel.IRRELEVANT, (byte)21, (byte)22, (byte)23, 24, (short)25, (byte)26, (byte)27);
+
+ Assert.assertNull(classifier.getProtocol());
+
+ Assert.assertEquals((byte) 0, classifier.getDSCPTOS());
+
+ Assert.assertEquals(InetAddress.getByName("00:00:00:00:00:00:00:01"), classifier.getSourceIPAddress());
+ Assert.assertEquals(InetAddress.getByName("00:00:00:00:00:00:00:01"), classifier.getDestinationIPAddress());
+ Assert.assertEquals((short) 11, classifier.getSourcePort());
+ Assert.assertEquals((short) 12, classifier.getDestinationPort());
+ Assert.assertEquals((byte) 14, classifier.getPriority());
+ Assert.assertEquals((short) 15, classifier.getSourcePortEnd());
+ Assert.assertEquals((short) 16, classifier.getDestinationPortEnd());
+ Assert.assertEquals((short) 17, classifier.getClassifierID());
+ Assert.assertEquals(ActivationState.INACTIVE, classifier.getActivationState());
+ Assert.assertEquals((byte) 19, classifier.getAction());
+ Assert.assertEquals(FlowLabel.IRRELEVANT, classifier.getFlowLabelEnableFlag());
+ Assert.assertEquals((byte) 21, classifier.getTcLow());
+ Assert.assertEquals((byte) 22, classifier.getTcHigh());
+ Assert.assertEquals((byte) 23, classifier.getTcMask());
+
+ // Per specs, this value must be 0 when IRRELEVANT
+ Assert.assertEquals(0, classifier.getFlowLabel());
+
+ Assert.assertEquals((short)25, classifier.getNextHdr());
+ Assert.assertEquals((byte)26, classifier.getSourcePrefixLen());
+ Assert.assertEquals((byte)27, classifier.getDestinationPrefixLen());
+ }
+
+ @Test
+ public void byteParsingActiveValid() throws UnknownHostException {
+ final IPv6Classifier classifier = new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (short)21, (short)22, (byte)24, (short)25, (short)26, (short)27, ActivationState.ACTIVE, (byte)29,
+ FlowLabel.VALID, (byte)31, (byte)32, (byte)33, 34, (short)35, (byte)36, (byte)37);
+ final IPv6Classifier parsed = IPv6Classifier.parse(classifier.getBytes());
+ Assert.assertEquals(classifier, parsed);
+ }
+
+ @Test
+ public void byteParsingInactiveIrrelevant() throws UnknownHostException {
+ final IPv6Classifier classifier = new IPv6Classifier((Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (Inet6Address)InetAddress.getByName("00:00:00:00:00:00:00:01"),
+ (short)21, (short)22, (byte)24, (short)25, (short)26, (short)27, ActivationState.INACTIVE, (byte)29,
+ FlowLabel.IRRELEVANT, (byte)31, (byte)32, (byte)33, 34, (short)35, (byte)36, (byte)37);
+ final IPv6Classifier parsed = IPv6Classifier.parse(classifier.getBytes());
+ Assert.assertEquals(classifier, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.IPCMMError.ErrorCode;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class PCMMError to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class PCMMErrorTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorAndSubCodes() {
+ new PCMMError(null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorCode() {
+ new PCMMError(null, ErrorCode.DOCSIS_1_CM);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void naErrorCode() {
+ new PCMMError(ErrorCode.NA);
+ }
+
+ @Test
+ public void construction() {
+ final PCMMError error = new PCMMError(ErrorCode.TRANSPORT_ERROR, null);
+ Assert.assertEquals(ErrorCode.TRANSPORT_ERROR, error.getErrorCode());
+ Assert.assertEquals(ErrorCode.NA, error.getErrorSubcode());
+
+ final byte[] dataBytes = error.getBytes();
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(ErrorCode.TRANSPORT_ERROR,
+ ErrorCode.valueOf(COPSMsgParser.bytesToShort(dataBytes[0], dataBytes[1])));
+ final short subCodeVal = COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3]);
+ Assert.assertEquals(ErrorCode.NA,
+ ErrorCode.valueOf(COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3])));
+ }
+
+ @Test
+ public void byteParsing() {
+ final PCMMError error = new PCMMError(ErrorCode.INVALID_FIELD, ErrorCode.INVALID_SUB_ID);
+ final PCMMError parsed = PCMMError.parse(error.getBytes());
+ Assert.assertEquals(error, parsed);
+ }
+
+}
--- /dev/null
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests the data holder class SessionClassID to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class SessionClassIDTest {
+
+ @Test
+ public void constructor1() {
+ final SessionClassID sessionClassID = new SessionClassID((byte)1);
+ Assert.assertEquals((byte)1, sessionClassID.toSingleByte());
+ Assert.assertEquals((byte)1 >> 2, sessionClassID.getPriority());
+ Assert.assertEquals((byte)1 >> 3, sessionClassID.getPreemption());
+ }
+
+ @Test
+ public void constructor2() {
+ final SessionClassID sessionClassID = new SessionClassID((byte)1, (byte)3, (byte)4);
+ Assert.assertEquals((byte)1, sessionClassID.toSingleByte());
+ Assert.assertEquals((byte)3, sessionClassID.getPriority());
+ Assert.assertEquals((byte)4, sessionClassID.getPreemption());
+ }
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests the data holder class SubscriberId to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class SubscriberIDTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullConstArg() {
+ new SubscriberID(null);
+ }
+
+ @Test
+ public void constructorIpv4() {
+ final InetAddress addr;
+ try {
+ addr = InetAddress.getByName("127.0.0.1");
+ if (addr instanceof Inet6Address) Assert.fail("Address should be IPv4");
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("host not found");
+ }
+ final SubscriberID subId = new SubscriberID(addr);
+ Assert.assertEquals(addr, subId.getSourceIPAddress());
+ }
+
+ @Test
+ public void byteParsingIpv4() {
+ final InetAddress addr;
+ try {
+ addr = InetAddress.getByName("127.0.0.1");
+ if (addr instanceof Inet6Address) Assert.fail("Address should be IPv4");
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("host not found");
+ }
+ final SubscriberID subId = new SubscriberID(addr);
+ final SubscriberID parsed = SubscriberID.parse(subId.getBytes());
+ Assert.assertEquals(subId, parsed);
+ }
+
+ @Test
+ public void constructorIpv6() {
+ final InetAddress addr;
+ try {
+ addr = InetAddress.getByName("00:00:00:00:00:00:00:01");
+ if (addr instanceof Inet4Address) Assert.fail("Address should be IPv6");
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("host not found");
+ }
+ final SubscriberID subId = new SubscriberID(addr);
+ Assert.assertEquals(addr, subId.getSourceIPAddress());
+ }
+
+ @Test
+ public void byteParsingIpv6() {
+ final InetAddress addr;
+ try {
+ addr = InetAddress.getByName("00:00:00:00:00:00:00:01");
+ if (addr instanceof Inet4Address) Assert.fail("Address should be IPv6");
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("host not found");
+ }
+ final SubscriberID subId = new SubscriberID(addr);
+ final SubscriberID parsed = SubscriberID.parse(subId.getBytes());
+ Assert.assertEquals(subId, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.gates.impl;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.gates.ITransactionID.GateCommandType;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class TransactionID to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class TransactionIDTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullCommandType() {
+ new TransactionID((short)9, null);
+ }
+
+ @Test
+ public void construction() {
+ final TransactionID transID = new TransactionID((short)9, GateCommandType.GATE_CMD_ERR);
+ final byte[] dataBytes = transID.getBytes();
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(9, COPSMsgParser.bytesToShort(dataBytes[0], dataBytes[1]));
+ Assert.assertEquals(GateCommandType.GATE_CMD_ERR,
+ GateCommandType.valueOf(COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3])));
+ }
+
+ @Test
+ public void byteParsing() {
+ final TransactionID transID = new TransactionID((short)11, GateCommandType.GATE_DELETE_ACK);
+ final TransactionID parsed = TransactionID.parse(transID.getBytes());
+ Assert.assertEquals(transID, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.objects;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class MMVersionInfo to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class MMVersionInfoTest {
+
+ @Test
+ public void construction() {
+ final MMVersionInfo verInfo = new MMVersionInfo((short)5, (short)6);
+ final byte[] dataBytes = verInfo.getBytes();
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(5, COPSMsgParser.bytesToShort(dataBytes[0], dataBytes[1]));
+ Assert.assertEquals(6, COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3]));
+ }
+
+ @Test
+ public void byteParsing() {
+ final MMVersionInfo verInfo = new MMVersionInfo((short)7, (short)8);
+ final MMVersionInfo parsed = MMVersionInfo.parse(verInfo.getBytes());
+ Assert.assertEquals(verInfo, parsed);
+ }
+
+}
--- /dev/null
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm.objects;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.objects.SyncOptions.ReportType;
+import org.pcmm.objects.SyncOptions.SyncType;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * Tests the data holder class SyncOptions to ensure both construction and byte parsing result in correct object
+ * creation.
+ */
+public class SyncOptionsTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullReportType() {
+ new SyncOptions(null, SyncType.FULL_SYNCHRONIZATION);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSyncType() {
+ new SyncOptions(ReportType.STANDARD_REPORT_DATA, null);
+ }
+
+ @Test
+ public void construction() {
+ final SyncOptions syncOpts = new SyncOptions(ReportType.STANDARD_REPORT_DATA, SyncType.FULL_SYNCHRONIZATION);
+ final byte[] dataBytes = syncOpts.getBytes();
+ Assert.assertEquals(4, dataBytes.length);
+ Assert.assertEquals(ReportType.STANDARD_REPORT_DATA,
+ ReportType.valueOf(COPSMsgParser.bytesToShort(dataBytes[0], dataBytes[1])));
+ Assert.assertEquals(SyncType.FULL_SYNCHRONIZATION,
+ SyncType.valueOf(COPSMsgParser.bytesToShort(dataBytes[2], dataBytes[3])));
+ }
+
+ @Test
+ public void byteParsing() {
+ final SyncOptions syncOpts = new SyncOptions(ReportType.COMPLETE_GATE_DATA, SyncType.INCREMENTAL_SYNCHRONIZATION);
+ final SyncOptions parsed = SyncOptions.parse(syncOpts.getBytes());
+ Assert.assertEquals(syncOpts, parsed);
+ }
+
+}
+++ /dev/null
-package org.pcmm.test;
-
-import static org.junit.Assert.*;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.pcmm.gates.impl.BestEffortService;
-
-public class BestEffortServiceTest {
-
- private BestEffortService be;
-
- @Before
- public void init() {
- be = new BestEffortService((byte) 7);
- be.getAuthorizedEnvelop().setMinimumReservedTrafficRate(192);
- be.getCommittedEnvelop().setRequiredAttributeMask(938);
- be.getReservedEnvelop().setTrafficPriority((byte) 5);
- }
-
- @Test
- public void testGetAsBinaryArray() {
- assertTrue(be.getAsBinaryArray().length == 116);
- }
-
- @Test
- public void testBestEffortServiceByteArray() {
- assertTrue(new BestEffortService(be.getAsBinaryArray())
- .getAuthorizedEnvelop().getMinimumReservedTrafficRate() == 192);
- assertTrue(new BestEffortService(be.getAsBinaryArray())
- .getReservedEnvelop().getTrafficPriority() == 5);
- assertTrue(new BestEffortService(be.getAsBinaryArray())
- .getCommittedEnvelop().getRequiredAttributeMask() == 938);
-
- }
-
- @Test
- public void testGetEnvelop() {
- assertTrue(be.getEnvelop() == 7);
- }
-
-}
+++ /dev/null
-package org.pcmm.test;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.pcmm.gates.IPCMMError;
-import org.pcmm.gates.impl.PCMMError;
-
-public class PCErrorTest {
-
- IPCMMError error;
-
- @Before
- public void init() {
- error = new PCMMError();
- error.setErrorCode((short) 1);
- }
-
- @Test
- public void testGetDescription() {
- for (IPCMMError.Description d : IPCMMError.Description.values()) {
- error.setErrorCode(d.getCode());
- Assert.assertNotNull(error.getDescription());
- System.out.println(error.getDescription());
- }
-
- }
-
-}
+++ /dev/null
-/**
- *
- */
-package org.pcmm.test;
-
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-import org.pcmm.gates.impl.PCMMGateReq;
-import org.pcmm.utils.PCMMUtils;
-
-/**
- * @author RH030971
- *
- */
-public class PCMMGateReqTest {
-
- /**
- * Test method for
- * {@link org.pcmm.gates.impl.PCMMGateReq#PCMMGateReq(byte[])}.
- */
- @Test
- public void testPCMMGateReqByteArray() {
-/*
- new PCMMGateReq(
- PCMMUtils
- .ReadBinaryDump("traces/COPSReportClientSI09871088-5329-44ff-b1db-0ea3a544de1e.bin"));
-
-*/
- }
-
- /**
- * Test method for {@link org.pcmm.gates.impl.PCMMGateReq#getData()}.
- */
- @Test
- public void testGetData() {
- // fail("Not yet implemented");
- }
-
-}
+++ /dev/null
-This package contains the test set for the PCMM driver,
-To test the whole workflow use the junit based test : PCMMWorkflowTest.java
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.gate.spec.GateSpec;
import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.ipv6.classifier.Ipv6Classifier;
import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.traffic.profile.TrafficProfile;
-import org.pcmm.gates.*;
-import org.pcmm.gates.IGateSpec.DSCPTOS;
+import org.pcmm.gates.IClassifier;
+import org.pcmm.gates.IClassifier.Protocol;
+import org.pcmm.gates.IExtendedClassifier.ActivationState;
import org.pcmm.gates.IGateSpec.Direction;
-import org.pcmm.gates.impl.DOCSISServiceClassNameTrafficProfile;
-import org.pcmm.gates.impl.PCMMGateReq;
-import org.pcmm.gates.impl.SubscriberID;
+import org.pcmm.gates.IIPv6Classifier.FlowLabel;
+import org.pcmm.gates.ITrafficProfile;
+import org.pcmm.gates.impl.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
- *
* PacketCable data processor
- *
*/
public class PCMMGateReqBuilder {
- private Logger logger = LoggerFactory.getLogger(PCMMGateReqBuilder.class);
-
- private PCMMGateReq gateReq = null;
-
- public PCMMGateReqBuilder() {
- gateReq = new org.pcmm.gates.impl.PCMMGateReq();
- }
-
- public PCMMGateReq getGateReq() {
- return gateReq;
- }
-
- public void build(AmId qosAmId){
- IAMID amId = new org.pcmm.gates.impl.AMID();
- amId.setApplicationMgrTag(qosAmId.getAmTag().shortValue());
- amId.setApplicationType(qosAmId.getAmType().shortValue());
- gateReq.setAMID(amId);
- }
-
- public void build(InetAddress qosSubId){
- ISubscriberID subId = new SubscriberID();
- subId.setSourceIPAddress(qosSubId);
- gateReq.setSubscriberID(subId);
- }
-
- public void build(GateSpec qosGateSpec, ServiceFlowDirection scnDirection) {
- IGateSpec gateSpec = new org.pcmm.gates.impl.GateSpec();
- // service flow direction
- ServiceFlowDirection qosDir = null;
- Direction gateDir = null;
- if (scnDirection != null) {
- qosDir = scnDirection;
- } else if (qosGateSpec.getDirection() != null) {
- qosDir = qosGateSpec.getDirection();
- }
- if (qosDir == ServiceFlowDirection.Ds) {
- gateDir = Direction.DOWNSTREAM;
- } else if (qosDir == ServiceFlowDirection.Us) {
- gateDir = Direction.UPSTREAM;
- }
- gateSpec.setDirection(gateDir);
- // DSCP/TOS Overwrite
- TosByte tosOverwrite = qosGateSpec.getDscpTosOverwrite();
- if (tosOverwrite != null) {
- byte gateTos = tosOverwrite.getValue().byteValue();
- gateSpec.setDSCP_TOSOverwrite(DSCPTOS.ENABLE);
- gateSpec.setDSCP_TOSOverwrite(gateTos);
- TosByte tosMask = qosGateSpec.getDscpTosMask();
- if (tosMask != null) {
- byte gateTosMask = tosMask.getValue().byteValue();
- gateSpec.setDSCP_TOSMask(gateTosMask);
- } else {
- gateSpec.setDSCP_TOSMask((byte)0xff);
- }
- }
- gateReq.setGateSpec(gateSpec);
- }
-
- public void build(TrafficProfile qosTrafficProfile) {
- if (qosTrafficProfile.getServiceClassName() != null) {
- String scn = qosTrafficProfile.getServiceClassName().getValue();
- DOCSISServiceClassNameTrafficProfile trafficProfile = new DOCSISServiceClassNameTrafficProfile();
- if (scn.length() <= 16) { // NB.16 char SCN is max length per PCMM spec
- trafficProfile.setServiceClassName(scn);
- gateReq.setTrafficProfile(trafficProfile);
- }
- }
- }
-
- private InetAddress getByName(String ipAddressStr){
- InetAddress ipAddress = null;
- try {
- ipAddress = InetAddress.getByName(ipAddressStr);
- } catch (UnknownHostException e) {
- logger.error(e.getMessage());
- }
- return ipAddress;
- }
-
- public void build(Classifier qosClassifier) {
- // Legacy classifier
- IClassifier classifier = new org.pcmm.gates.impl.Classifier();
- classifier.setPriority((byte) 64);
- if (qosClassifier.getProtocol() != null){
- classifier.setProtocol(qosClassifier.getProtocol().getValue().shortValue());
- }
- if (qosClassifier.getSrcIp() != null) {
- InetAddress sip = getByName(qosClassifier.getSrcIp().getValue());
- if (sip != null) {
- classifier.setSourceIPAddress(sip);
- }
- }
- if (qosClassifier.getDstIp() != null) {
- InetAddress dip = getByName(qosClassifier.getDstIp().getValue());
- if (dip != null) {
- classifier.setDestinationIPAddress(dip);
- }
- }
- if (qosClassifier.getSrcPort() != null) {
- classifier.setSourcePort(qosClassifier.getSrcPort().getValue().shortValue());
- }
- if (qosClassifier.getDstPort() != null) {
- classifier.setDestinationPort(qosClassifier.getDstPort().getValue().shortValue());
- }
- if (qosClassifier.getTosByte() != null) {
- classifier.setDSCPTOS(qosClassifier.getTosByte().getValue().byteValue());
- if (qosClassifier.getTosMask() != null) {
- classifier.setDSCPTOSMask(qosClassifier.getTosMask().getValue().byteValue());
- } else {
- // set default TOS mask
- classifier.setDSCPTOSMask((byte)0xff);
- }
- }
- // push the classifier to the gate request
- gateReq.setClassifier(classifier);
- }
-
- public void build(ExtClassifier qosExtClassifier) {
- // Extended classifier
- IExtendedClassifier extClassifier = new org.pcmm.gates.impl.ExtendedClassifier();
- extClassifier.setPriority((byte) 64);
- extClassifier.setActivationState((byte) 0x01);
- // Protocol -- zero is match any
- if (qosExtClassifier.getProtocol() != null){
- extClassifier.setProtocol(qosExtClassifier.getProtocol().getValue().shortValue());
- } else {
- extClassifier.setProtocol((short)0);
- }
- // Source IP address & mask
- if (qosExtClassifier.getSrcIp() != null) {
- InetAddress sip = getByName(qosExtClassifier.getSrcIp().getValue());
- if (sip != null) {
- extClassifier.setSourceIPAddress(sip);
- if (qosExtClassifier.getSrcIpMask() != null) {
- InetAddress sipMask = getByName(qosExtClassifier.getSrcIpMask().getValue());
- extClassifier.setIPSourceMask(sipMask);
- } else {
- // default mask is /32
- extClassifier.setIPSourceMask(getByName("255.255.255.255"));
- }
- }
- }
- // Destination IP address & mask
- if (qosExtClassifier.getDstIp() != null) {
- InetAddress dip = getByName(qosExtClassifier.getDstIp().getValue());
- if (dip != null) {
- extClassifier.setDestinationIPAddress(dip);
- if (qosExtClassifier.getDstIpMask() != null) {
- InetAddress dipMask = getByName(qosExtClassifier.getDstIpMask().getValue());
- extClassifier.setIPDestinationMask(dipMask);
- } else {
- // default mask is /32
- extClassifier.setIPDestinationMask(getByName("255.255.255.255"));
- }
- }
- }
- // default source port range must be set to match any even if qosExtClassifier has no range
- // match any port range is 0-65535, NOT 0-0
- short startPort = (short)0;
- short endPort = (short)65535;
- if (qosExtClassifier.getSrcPortStart() != null) {
- startPort = qosExtClassifier.getSrcPortStart().getValue().shortValue();
- endPort = startPort;
- if (qosExtClassifier.getSrcPortEnd() != null) {
- endPort = qosExtClassifier.getSrcPortEnd().getValue().shortValue();
- }
- if (startPort > endPort) {
- logger.warn("Start port %d > End port %d in ext-classifier source port range -- forcing to same", startPort, endPort);
- endPort = startPort;
- }
- }
- extClassifier.setSourcePortStart(startPort);
- extClassifier.setSourcePortEnd(endPort);
- // default destination port range must be set to match any even if qosExtClassifier has no range
- // match any port range is 0-65535, NOT 0-0
- startPort = (short)0;
- endPort = (short)65535;
- if (qosExtClassifier.getDstPortStart() != null) {
- startPort = qosExtClassifier.getDstPortStart().getValue().shortValue();
- endPort = startPort;
- if (qosExtClassifier.getDstPortEnd() != null) {
- endPort = qosExtClassifier.getDstPortEnd().getValue().shortValue();
- }
- if (startPort > endPort) {
- logger.warn("Start port %d > End port %d in ext-classifier destination port range -- forcing to same", startPort, endPort);
- endPort = startPort;
- }
- }
- extClassifier.setDestinationPortStart(startPort);
- extClassifier.setDestinationPortEnd(endPort);
- // DSCP/TOP byte
- if (qosExtClassifier.getTosByte() != null) {
- // OR in the DSCP/TOS enable bit 0x01
- extClassifier.setDSCPTOS((byte) (qosExtClassifier.getTosByte().getValue().byteValue() | 0x01));
- if (qosExtClassifier.getTosMask() != null) {
- extClassifier.setDSCPTOSMask(qosExtClassifier.getTosMask().getValue().byteValue());
- } else {
- // set default TOS mask
- extClassifier.setDSCPTOSMask((byte)0xff);
- }
- }
- // push the extended classifier to the gate request
- gateReq.setClassifier(extClassifier);
- }
-
- public void build(Ipv6Classifier qosIpv6Classifier) {
- // IPv6 classifier
- IIPv6Classifier ipv6Classifier = new org.pcmm.gates.impl.IPv6Classifier();
- ipv6Classifier.setPriority((byte) 64);
- ipv6Classifier.setActivationState((byte) 0x01);
- // Flow Label
- if (qosIpv6Classifier.getFlowLabel() != null){
- ipv6Classifier.setFlowLabel(qosIpv6Classifier.getFlowLabel());
- ipv6Classifier.setFlowLabelEnableFlag((byte)0x01);
- }
- // Next Header
- if (qosIpv6Classifier.getNextHdr() != null){
- ipv6Classifier.setNextHdr(qosIpv6Classifier.getNextHdr().getValue().shortValue());
- } else {
- // default: match any nextHdr is 256 because nextHdr 0 is Hop-by-Hop option
- ipv6Classifier.setNextHdr((short)256);
- }
- // Source IPv6 address & prefix len
- byte prefLen;
- if (qosIpv6Classifier.getSrcIp6() != null) {
- String[] parts = qosIpv6Classifier.getSrcIp6().getValue().split("/");
- String Ipv6AddressStr = parts[0];
- InetAddress sip6 = getByName(Ipv6AddressStr);
- if (sip6 != null) {
- ipv6Classifier.setSourceIPAddress(sip6);
- }
- prefLen = (byte)128;
- if (parts.length > 1) {
- prefLen = (byte)Integer.parseInt(parts[1]);
- }
- ipv6Classifier.setSourcePrefixLen(prefLen);
- }
- // Destination IPv6 address & prefix len
- if (qosIpv6Classifier.getDstIp6() != null) {
- String[] parts = qosIpv6Classifier.getDstIp6().getValue().split("/");
- String Ipv6AddressStr = parts[0];
- InetAddress dip6 = getByName(Ipv6AddressStr);
- if (dip6 != null) {
- ipv6Classifier.setDestinationIPAddress(dip6);
- }
- prefLen = (byte)128;
- if (parts.length > 1) {
- prefLen = (byte)Integer.parseInt(parts[1]);
- }
- ipv6Classifier.setDestinationPrefixLen(prefLen);
- }
- // default source port range must be set to match any -- even if qosExtClassifier has no range value
- // match any port range is 0-65535, NOT 0-0
- short startPort = (short)0;
- short endPort = (short)65535;
- if (qosIpv6Classifier.getSrcPortStart() != null) {
- startPort = qosIpv6Classifier.getSrcPortStart().getValue().shortValue();
- endPort = startPort;
- if (qosIpv6Classifier.getSrcPortEnd() != null) {
- endPort = qosIpv6Classifier.getSrcPortEnd().getValue().shortValue();
- }
- if (startPort > endPort) {
- logger.warn("Start port %d > End port %d in ipv6-classifier source port range -- forcing to same", startPort, endPort);
- endPort = startPort;
- }
- }
- ipv6Classifier.setSourcePortStart(startPort);
- ipv6Classifier.setSourcePortEnd(endPort);
- // default destination port range must be set to match any -- even if qosExtClassifier has no range value
- // match any port range is 0-65535, NOT 0-0
- startPort = (short)0;
- endPort = (short)65535;
- if (qosIpv6Classifier.getDstPortStart() != null) {
- startPort = qosIpv6Classifier.getDstPortStart().getValue().shortValue();
- endPort = startPort;
- if (qosIpv6Classifier.getDstPortEnd() != null) {
- endPort = qosIpv6Classifier.getDstPortEnd().getValue().shortValue();
- }
- if (startPort > endPort) {
- logger.warn("Start port %d > End port %d in ipv6-classifier destination port range -- forcing to same", startPort, endPort);
- endPort = startPort;
- }
- }
- ipv6Classifier.setDestinationPortStart(startPort);
- ipv6Classifier.setDestinationPortEnd(endPort);
- // TC low, high, mask
- if (qosIpv6Classifier.getTcLow() != null) {
- ipv6Classifier.setTcLow(qosIpv6Classifier.getTcLow().getValue().byteValue());
- if (qosIpv6Classifier.getTcHigh() != null) {
- ipv6Classifier.setTcHigh(qosIpv6Classifier.getTcHigh().getValue().byteValue());
- }
- if (qosIpv6Classifier.getTcMask() != null) {
- ipv6Classifier.setTcMask(qosIpv6Classifier.getTcMask().getValue().byteValue());
- } else {
- // set default TOS mask
- ipv6Classifier.setTcMask((byte)0xff);
- }
- } else {
- // mask 0x00 is match any
- ipv6Classifier.setTcMask((byte)0x00);
- }
- // push the IPv6 classifier to the gate request
- gateReq.setClassifier(ipv6Classifier);
- }
+ private Logger logger = LoggerFactory.getLogger(PCMMGateReqBuilder.class);
+
+ private GateID gateID = null;
+ private AMID amid = null;
+ private SubscriberID subscriberID = null;
+ private TransactionID transactionID = null;
+ private org.pcmm.gates.impl.GateSpec gateSpec = null;
+ private ITrafficProfile trafficProfile = null;
+ private IClassifier classifier = null;
+ private PCMMError error = null;
+
+ public PCMMGateReq getGateReq() {
+ return new PCMMGateReq(amid, subscriberID, transactionID, gateSpec, trafficProfile, classifier, gateID, error);
+ }
+
+ public void build(final AmId qosAmId) {
+ amid = new AMID(qosAmId.getAmType().shortValue(), qosAmId.getAmTag().shortValue());
+ }
+
+ public void build(final InetAddress qosSubId) {
+ subscriberID = new SubscriberID(qosSubId);
+ }
+
+ public void build(final GateSpec qosGateSpec, final ServiceFlowDirection scnDirection) {
+
+ final ServiceFlowDirection qosDir;
+ if (scnDirection != null) {
+ qosDir = scnDirection;
+ } else {
+ if (qosGateSpec.getDirection() != null) {
+ qosDir = qosGateSpec.getDirection();
+ } else {
+ // TODO - determine if this is a valid default value
+ qosDir = ServiceFlowDirection.Ds;
+ }
+ }
+
+ final Direction gateDir;
+ if (qosDir == ServiceFlowDirection.Ds) {
+ gateDir = Direction.DOWNSTREAM;
+ } else {
+ gateDir = Direction.UPSTREAM;
+ }
+
+ // DSCP/TOS Overwrite
+ final byte dscptos;
+ final byte gateTosMask;
+
+ final TosByte tosOverwrite = qosGateSpec.getDscpTosOverwrite();
+ if (tosOverwrite != null) {
+ dscptos = 1;
+ TosByte tosMask = qosGateSpec.getDscpTosMask();
+ if (tosMask != null) {
+ gateTosMask = tosMask.getValue().byteValue();
+ } else {
+ gateTosMask = (byte) 0xff;
+ }
+ } else {
+ // TODO - These values appear to be required
+ dscptos = 0;
+ gateTosMask = 0;
+ }
+ gateSpec = new org.pcmm.gates.impl.GateSpec(gateDir, dscptos, gateTosMask);
+ }
+
+ public void build(final TrafficProfile qosTrafficProfile) {
+ if (qosTrafficProfile.getServiceClassName() != null) {
+ trafficProfile =
+ new DOCSISServiceClassNameTrafficProfile(qosTrafficProfile.getServiceClassName().getValue());
+ }
+ }
+
+ private InetAddress getByName(final String ipAddressStr) {
+ try {
+ return InetAddress.getByName(ipAddressStr);
+ } catch (UnknownHostException e) {
+ logger.error(e.getMessage());
+ }
+ return null;
+ }
+
+ public void build(final Classifier qosClassifier) {
+ // TODO - try and make these variables immutable
+ Protocol protocol = null;
+ byte tosOverwrite = 0;
+ byte tosMask = (byte)0x0;
+ Inet4Address srcAddress = null;
+ Inet4Address dstAddress = null;
+ short srcPort = (short) 0;
+ short dstPort = (short) 0;
+ byte priority = (byte) 64;
+
+ // Legacy classifier
+ if (qosClassifier.getProtocol() != null) {
+ protocol = Protocol.valueOf(qosClassifier.getProtocol().getValue().shortValue());
+ }
+ if (qosClassifier.getSrcIp() != null) {
+ final InetAddress sip = getByName(qosClassifier.getSrcIp().getValue());
+ if (sip != null && sip instanceof Inet4Address) {
+ srcAddress = (Inet4Address) sip;
+ }
+ }
+ if (qosClassifier.getDstIp() != null) {
+ final InetAddress dip = getByName(qosClassifier.getDstIp().getValue());
+ if (dip != null && dip instanceof Inet4Address) {
+ dstAddress = (Inet4Address) dip;
+ }
+ }
+ if (qosClassifier.getSrcPort() != null) {
+ srcPort = qosClassifier.getSrcPort().getValue().shortValue();
+ }
+ if (qosClassifier.getDstPort() != null) {
+ dstPort = qosClassifier.getDstPort().getValue().shortValue();
+ }
+ if (qosClassifier.getTosByte() != null) {
+ tosOverwrite = qosClassifier.getTosByte().getValue().byteValue();
+ if (qosClassifier.getTosMask() != null) {
+ tosMask = qosClassifier.getTosMask().getValue().byteValue();
+ } else {
+ // set default TOS mask
+ tosMask = (byte) 0xff;
+ }
+ }
+ // push the classifier to the gate request
+ classifier =
+ new org.pcmm.gates.impl.Classifier(protocol, tosOverwrite, tosMask, srcAddress, dstAddress, srcPort,
+ dstPort, priority);
+ }
+
+ public void build(final ExtClassifier qosExtClassifier) {
+ // Extended classifier
+ final byte priority = (byte) 64;
+ final ActivationState activationState = ActivationState.ACTIVE;
+ // Protocol -- zero is match any
+ final Protocol protocol;
+ if (qosExtClassifier.getProtocol() != null) {
+ protocol = Protocol.valueOf(qosExtClassifier.getProtocol().getValue().shortValue());
+ } else {
+ protocol = Protocol.NONE;
+ }
+
+ // default source port range must be set to match any even if qosExtClassifier has no range
+ // match any port range is 0-65535, NOT 0-0
+ // TODO - try to make these two variables immutable
+ short srcStartPort = (short) 0;
+ short srcEndPort = (short) 65535;
+ if (qosExtClassifier.getSrcPortStart() != null) {
+ srcStartPort = qosExtClassifier.getSrcPortStart().getValue().shortValue();
+ srcEndPort = srcStartPort;
+ if (qosExtClassifier.getSrcPortEnd() != null) {
+ srcEndPort = qosExtClassifier.getSrcPortEnd().getValue().shortValue();
+ }
+ if (srcStartPort > srcEndPort) {
+ logger.warn("Start port %d > End port %d in ext-classifier source port range -- forcing to same",
+ srcStartPort, srcEndPort);
+ srcEndPort = srcStartPort;
+ }
+ }
+ // default destination port range must be set to match any even if qosExtClassifier has no range
+ // match any port range is 0-65535, NOT 0-0
+ // TODO - try to make these two variables immutable
+ short dstStartPort = (short) 0;
+ short dstEndPort = (short) 65535;
+ if (qosExtClassifier.getDstPortStart() != null) {
+ dstStartPort = qosExtClassifier.getDstPortStart().getValue().shortValue();
+ dstEndPort = dstStartPort;
+ if (qosExtClassifier.getDstPortEnd() != null) {
+ dstEndPort = qosExtClassifier.getDstPortEnd().getValue().shortValue();
+ }
+ if (dstStartPort > dstEndPort) {
+ logger.warn("Start port %d > End port %d in ext-classifier destination port range -- forcing to same",
+ dstStartPort, dstEndPort);
+ dstEndPort = dstStartPort;
+ }
+ }
+
+ // DSCP/TOP byte
+ // TODO - try to make these two variables immutable
+ byte tosOverwrite = 0;
+ byte tosMask = (byte)0x00;
+ if (qosExtClassifier.getTosByte() != null) {
+ // OR in the DSCP/TOS enable bit 0x01
+ tosOverwrite = (byte) (qosExtClassifier.getTosByte().getValue().byteValue() | 0x01);
+ if (qosExtClassifier.getTosMask() != null) {
+ tosMask = qosExtClassifier.getTosMask().getValue().byteValue();
+ } else {
+ // set default TOS mask
+ tosMask = (byte) 0xff;
+ }
+ }
+
+ // TODO - find out what the classifier ID should really be. It was never getting set previously
+ final short classifierId = (short)0;
+
+ // TODO - find out what the action value should really be. It was never getting set previously
+ final byte action = (byte)0;
+
+ // push the extended classifier to the gate request
+ classifier = new org.pcmm.gates.impl.ExtendedClassifier(protocol, tosOverwrite, tosMask,
+ getInet4Address(qosExtClassifier.getSrcIp()), getInet4Address(qosExtClassifier.getDstIp()),
+ srcStartPort, dstStartPort, priority, getInet4Address(qosExtClassifier.getSrcIpMask()),
+ getInet4Address(qosExtClassifier.getDstIpMask()), srcEndPort, dstEndPort, classifierId, activationState,
+ action);
+ }
+
+ private Inet4Address getInet4Address(
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address address) {
+ if (address != null) {
+ final InetAddress out = getByName(address.getValue());
+ if (out != null && out instanceof Inet4Address) {
+ return (Inet4Address) out;
+ }
+ }
+ return null;
+ }
+
+ public void build(final Ipv6Classifier qosIpv6Classifier) {
+ // Next Header
+ final short nextHdr;
+ if (qosIpv6Classifier.getNextHdr() != null) {
+ nextHdr = qosIpv6Classifier.getNextHdr().getValue().shortValue();
+ }
+ // default: match any nextHdr is 256 because nextHdr 0 is Hop-by-Hop option
+ else {
+ nextHdr = (short) 256;
+ }
+
+ // Source IPv6 address & prefix len
+ // TODO - try to make these two variables immutable
+ byte srcPrefixLen = (byte) 128;
+ Inet6Address srcAddress = null;
+ if (qosIpv6Classifier.getSrcIp6() != null) {
+ String[] parts = qosIpv6Classifier.getSrcIp6().getValue().split("/");
+ String Ipv6AddressStr = parts[0];
+ srcAddress = (Inet6Address) getByName(Ipv6AddressStr);
+ if (parts.length > 1) {
+ srcPrefixLen = (byte) Integer.parseInt(parts[1]);
+ } else {
+ srcPrefixLen = (byte) 128;
+ }
+
+ }
+
+ // TODO - try to make these two variables immutable
+ Inet6Address dstAddress = null;
+ byte dstPrefLen = (byte) 128;
+ // Destination IPv6 address & prefix len
+ if (qosIpv6Classifier.getDstIp6() != null) {
+ final String[] parts = qosIpv6Classifier.getDstIp6().getValue().split("/");
+ final String Ipv6AddressStr = parts[0];
+ dstAddress = (Inet6Address)getByName(Ipv6AddressStr);
+ if (parts.length > 1) dstPrefLen = (byte) Integer.parseInt(parts[1]);
+ else dstPrefLen = (byte) 128;
+ }
+
+ // default source port range must be set to match any -- even if qosExtClassifier has no range value
+ // match any port range is 0-65535, NOT 0-0
+ short srcPortBegin = (short) 0;
+ short srcPortEnd = (short) 65535;
+ if (qosIpv6Classifier.getSrcPortStart() != null) {
+ srcPortBegin = qosIpv6Classifier.getSrcPortStart().getValue().shortValue();
+ srcPortEnd = srcPortBegin;
+ if (qosIpv6Classifier.getSrcPortEnd() != null) {
+ srcPortEnd = qosIpv6Classifier.getSrcPortEnd().getValue().shortValue();
+ }
+ if (srcPortBegin > srcPortEnd) {
+ logger.warn("Start port %d > End port %d in ipv6-classifier source port range -- forcing to same",
+ srcPortBegin, srcPortEnd);
+ srcPortEnd = srcPortBegin;
+ }
+ }
+
+ // default destination port range must be set to match any -- even if qosExtClassifier has no range value
+ // match any port range is 0-65535, NOT 0-0
+ short dstPortBegin = (short) 0;
+ short dstPortEnd = (short) 65535;
+ if (qosIpv6Classifier.getDstPortStart() != null) {
+ dstPortBegin = qosIpv6Classifier.getDstPortStart().getValue().shortValue();
+ dstPortEnd = dstPortBegin;
+ if (qosIpv6Classifier.getDstPortEnd() != null) {
+ dstPortEnd = qosIpv6Classifier.getDstPortEnd().getValue().shortValue();
+ }
+ if (dstPortBegin > dstPortEnd) {
+ logger.warn("Start port %d > End port %d in ipv6-classifier destination port range -- forcing to same",
+ dstPortBegin, dstPortEnd);
+ dstPortEnd = dstPortBegin;
+ }
+ }
+
+ final byte tcLow;
+ if (qosIpv6Classifier.getTcLow() != null)
+ tcLow = qosIpv6Classifier.getTcLow().getValue().byteValue();
+ else tcLow = (byte) 0x00;
+
+ final byte tcHigh;
+ if (qosIpv6Classifier.getTcHigh() != null)
+ tcHigh = qosIpv6Classifier.getTcHigh().getValue().byteValue();
+ else tcHigh = (byte) 0x00;
+
+ final byte tcMask;
+ if (qosIpv6Classifier.getTcHigh() != null)
+ tcMask = qosIpv6Classifier.getTcHigh().getValue().byteValue();
+ else if (qosIpv6Classifier.getTcLow() != null) tcMask = (byte) 0xff;
+ else tcMask = (byte) 0x00;
+
+ // TODO - find out what the classifier ID should really be. It was never getting set previously
+ final short classifierId = (short)0;
+
+ // TODO - find out what the action value should really be. It was never getting set previously
+ final byte action = (byte)0;
+
+ // push the IPv6 classifier to the gate request
+ classifier = new org.pcmm.gates.impl.IPv6Classifier(srcAddress, dstAddress, srcPortBegin, dstPortBegin,
+ (byte) 64, srcPortEnd, dstPortEnd, classifierId, ActivationState.ACTIVE, action, FlowLabel.VALID, tcLow,
+ tcHigh, tcMask, qosIpv6Classifier.getFlowLabel().intValue(), nextHdr, srcPrefixLen, dstPrefLen);
+ }
}
dstAddr = new Ipv4Address("10.32.99.99");
if (realCmts) {
- cmAddrInet = InetAddress.getByAddress(new byte[] {10, 32, 110, (byte)180});
+ cmAddrInet = InetAddress.getByAddress(new byte[] {10, 32, 110, (byte)172});
invalidCmAddrInet = InetAddress.getByAddress(new byte[] {99, 99, 99, 99});
// Use me when testing against a CMTS or emulator not running in the same JVM
@Test
public void testAddInvalidCcapBadPort() {
- ccap = makeCcapsObj((icmts.getPort() + 1), cmtsAddr, ccapId);
+ final int port;
+ if (icmts != null) port = icmts.getPort() + 1;
+ else port = PCMMPdpAgent.WELL_KNOWN_PDP_PORT + 1;
+ ccap = makeCcapsObj(port, cmtsAddr, ccapId);
service = new PCMMService(IPCMMClient.CLIENT_TYPE, ccap);
final String message = service.addCcap();
Assert.assertNotNull(message);
final String expectedMsg = "404 Not Found - CCAP " + ccapId + " failed to connect @ " + cmtsAddr.getValue()
- + ':' + (icmts.getPort() + 1) + " - ";
+ + ':' + port + " - ";
Assert.assertTrue(expectedMsg, message.startsWith(expectedMsg));
}
Mockito.when(classifier.getSrcIp()).thenReturn(srcAddr);
final PortNumber srcPort = new PortNumber(1234);
Mockito.when(classifier.getSrcPort()).thenReturn(srcPort);
- final TosByte tosByte = new TosByte((short)160);
+
+ // TODO - Can this value be any other value than 0 or 1 (See TosByte enumeration)
+ final TosByte tosByte = new TosByte((short)0);
Mockito.when(classifier.getTosByte()).thenReturn(tosByte);
final TosByte tosMask = new TosByte((short)224);
Mockito.when(classifier.getTosMask()).thenReturn(tosMask);