Refactor PCMM aspects of COPS message data objects. 61/25261/1
authorSteven Pisarski <s.pisarski@cablelabs.com>
Thu, 13 Aug 2015 18:52:28 +0000 (12:52 -0600)
committerSteven Pisarski <s.pisarski@cablelabs.com>
Thu, 13 Aug 2015 18:52:28 +0000 (12:52 -0600)
Made immutable, added enumerations & unit tests.

Change-Id: I47f44fe2a863d9d933902bc33bb11046613728ef
Signed-off-by: Steven Pisarski <s.pisarski@cablelabs.com>
57 files changed:
packetcable-driver/src/main/java/org/pcmm/PCMMPdpDataProcess.java
packetcable-driver/src/main/java/org/pcmm/PCMMPdpMsgSender.java
packetcable-driver/src/main/java/org/pcmm/PCMMPdpReqStateMan.java
packetcable-driver/src/main/java/org/pcmm/base/IPCMMBaseObject.java
packetcable-driver/src/main/java/org/pcmm/base/impl/PCMMBaseObject.java
packetcable-driver/src/main/java/org/pcmm/gates/IAMID.java
packetcable-driver/src/main/java/org/pcmm/gates/IClassifier.java
packetcable-driver/src/main/java/org/pcmm/gates/IExtendedClassifier.java
packetcable-driver/src/main/java/org/pcmm/gates/IGateID.java
packetcable-driver/src/main/java/org/pcmm/gates/IGateSpec.java
packetcable-driver/src/main/java/org/pcmm/gates/IIPv6Classifier.java
packetcable-driver/src/main/java/org/pcmm/gates/IPCMMError.java
packetcable-driver/src/main/java/org/pcmm/gates/IPCMMGate.java
packetcable-driver/src/main/java/org/pcmm/gates/ISessionClassID.java
packetcable-driver/src/main/java/org/pcmm/gates/ISubscriberID.java
packetcable-driver/src/main/java/org/pcmm/gates/ITrafficProfile.java
packetcable-driver/src/main/java/org/pcmm/gates/ITransactionID.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/AMID.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/BEEnvelop.java [new file with mode: 0644]
packetcable-driver/src/main/java/org/pcmm/gates/impl/BestEffortService.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/Classifier.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/DOCSISServiceClassNameTrafficProfile.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/ExtendedClassifier.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/GateID.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/GateSpec.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/IPv6Classifier.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/PCMMError.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/PCMMGateReq.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/SessionClassID.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/SubscriberID.java
packetcable-driver/src/main/java/org/pcmm/gates/impl/TransactionID.java
packetcable-driver/src/main/java/org/pcmm/objects/MMVersionInfo.java
packetcable-driver/src/main/java/org/pcmm/objects/SyncOptions.java
packetcable-driver/src/main/java/org/pcmm/rcd/impl/CmtsDataProcessor.java
packetcable-driver/src/main/java/org/pcmm/rcd/impl/CmtsPepReqStateMan.java
packetcable-driver/src/main/java/org/pcmm/utils/PCMMException.java
packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpAgent.java
packetcable-driver/src/test/java/org/pcmm/gates/impl/AMIDTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/BestEffortServiceTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/ClassifierTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/DOCSISServiceClassNameTrafficProfileTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/ExtendedClassifierTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/GateIDTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/GateSpecTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/IPv6ClassifierTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/PCMMErrorTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/SessionClassIDTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/SubscriberIDTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/gates/impl/TransactionIDTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/objects/MMVersionInfoTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/objects/SyncOptionsTest.java [new file with mode: 0644]
packetcable-driver/src/test/java/org/pcmm/test/BestEffortServiceTest.java [deleted file]
packetcable-driver/src/test/java/org/pcmm/test/PCErrorTest.java [deleted file]
packetcable-driver/src/test/java/org/pcmm/test/PCMMGateReqTest.java [deleted file]
packetcable-driver/src/test/java/org/pcmm/test/README.md [deleted file]
packetcable-policy-server/src/main/java/org/opendaylight/controller/packetcable/provider/PCMMGateReqBuilder.java
packetcable-policy-server/src/test/java/org/opendaylight/controller/packetcable/provider/PCMMServiceTest.java

index dd6e88da4573d5cd928d7e20c3a6a56cdd9a04f8..5c99ac27608e2424d457cfbb86612a893d0ebcb7 100644 (file)
@@ -1,10 +1,10 @@
-/**
- @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;
@@ -71,7 +71,7 @@ public class PCMMPdpDataProcess implements COPSPdpDataProcess {
     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);
@@ -79,7 +79,7 @@ public class PCMMPdpDataProcess implements COPSPdpDataProcess {
                 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());
index da1be394e942e58a769efcfd80103bb30045b6c2..4e19ffbe424dae5d76a423a6989e3a518a6f957c 100644 (file)
@@ -1,19 +1,20 @@
-/**
- @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;
@@ -22,9 +23,7 @@ import org.umu.cops.stack.COPSObjHeader.CNum;
 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;
@@ -49,7 +48,7 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
 
     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
@@ -72,19 +71,10 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
     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
      *
@@ -100,12 +90,8 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
      * @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
@@ -136,335 +122,6 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
 
     }
 
-    /**
-     * 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
@@ -475,9 +132,9 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
                 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...
@@ -494,94 +151,6 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
     }
 
 
-    /**
-     * 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
      *
@@ -589,10 +158,7 @@ public class PCMMPdpMsgSender extends COPSMsgSender {
      */
     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();
index 79470ff80f3bcbe0af86327a5eebecc4519a28e3..9aed78cf44d6fb1cb21a347703db80a8037f4748 100644 (file)
@@ -1,12 +1,14 @@
-/**
- @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;
@@ -69,7 +71,7 @@ public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
 
             // 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<>();
@@ -125,9 +127,9 @@ public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
                     _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
@@ -152,9 +154,8 @@ public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
                     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);
                     }
index 21140042e9822d56c81a98a3f9e34bc500bdd0e0..8c658671150c6cb8900581ad0542e977ffa5d172 100644 (file)
@@ -1,5 +1,5 @@
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
  */
 
 package org.pcmm.base;
@@ -7,8 +7,6 @@ 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
@@ -16,65 +14,10 @@ import org.umu.cops.stack.COPSData;
  */
 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();
 
 }
index 79e26dea1aa3d2cd0aae4e188e4acae1f09a42d3..586f2b9cb799162c935c8ec7b2d083a1e429a46e 100644 (file)
-/**
- * 
+/*
+ * (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;
-       }
+
+
 }
index 71e8116e738a74da3c081446287baeca43ff5640..6cfb72a1fbf50a5f0785e4cff82b50d81547d050 100644 (file)
@@ -1,13 +1,17 @@
-/**
- @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
@@ -36,16 +40,18 @@ import org.pcmm.base.IPCMMBaseObject;
  */
 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();
 
 }
index 3226f50fe7538afebc321cebda0d0c6def2c4600..dcac12ed032dd98d3561caa17f6cc9ed3afef210 100644 (file)
@@ -1,8 +1,7 @@
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
  */
 
-
 package org.pcmm.gates;
 
 import org.pcmm.base.IPCMMBaseObject;
@@ -10,47 +9,19 @@ 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
@@ -59,12 +30,12 @@ public interface IClassifier extends IPCMMBaseObject {
      */
     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
@@ -74,12 +45,12 @@ public interface IClassifier extends IPCMMBaseObject {
      */
     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
@@ -87,14 +58,7 @@ public interface IClassifier extends IPCMMBaseObject {
      *
      * @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
@@ -106,23 +70,49 @@ public interface IClassifier extends IPCMMBaseObject {
     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;
+        }
+    }
 
 }
index 635bf25b5941ea138bfd0c413276f0fce19fc047..e8ddd317e917d1c4a642c7f4e48bbc66f47a8066 100644 (file)
-/**
- @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();
 }
index d6d958256f21292734cb208dad1c98c01612b428..0a5da3b4930e19deab7d5b3cb92439961a21e389 100644 (file)
@@ -1,19 +1,49 @@
-/**
- @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();
+
 }
index e81d1dc98cca2b6b8417378aebb23020c79c6f26..b31c98e3eb6ff1f9704fbc7b77edad097a59e479 100644 (file)
@@ -1,24 +1,61 @@
-/**
- @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>
@@ -67,46 +104,6 @@ public interface IGateSpec extends IPCMMBaseObject {
 
     }
 
-    /**
-     *
-     */
-    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
@@ -121,36 +118,12 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     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
@@ -159,14 +132,6 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     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
@@ -175,13 +140,6 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     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.
@@ -190,14 +148,6 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     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
@@ -207,28 +157,11 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     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();
 
     /**
      *
@@ -236,10 +169,4 @@ public interface IGateSpec extends IPCMMBaseObject {
      */
     byte getDSCP_TOSMask();
 
-    /**
-     *
-     * @param dscp_tos_mask
-     */
-    void setDSCP_TOSMask(byte dscp_tos_mask);
-
 }
index 1a026dab958f608977eecf1293c76397d14536e1..bc6870dbcd8b5a1dfc9c955040c9e404d453b25b 100644 (file)
@@ -1,86 +1,77 @@
-/**
- @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();
 }
index 394f0bf061d2d8c03dbbb2e70c7a721228764b44..47dd0d67200acb902d0a798136e9e5cd39ede24f 100644 (file)
@@ -7,55 +7,74 @@ package org.pcmm.gates;
 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;
                }
@@ -68,29 +87,80 @@ public interface IPCMMError extends IPCMMBaseObject {
                        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();
 }
index ada6a51496f35095a7a19aefc6f5b8c5b8896c3d..f140675e2f8902954e3314c0d1498f51b619b1e5 100644 (file)
@@ -42,20 +42,6 @@ public interface IPCMMGate {
      */
     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.).
      *
index 11ca7f2746f01ecc1b6e9ea98f416e8e9392d790..fabe09761c69d66624c14193a0871043cc0a7f95 100644 (file)
@@ -1,6 +1,7 @@
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
  */
+
 package org.pcmm.gates;
 
 /**
@@ -15,14 +16,6 @@ public interface ISessionClassID {
      */
     byte getPriority();
 
-    /**
-     * sets the priority value (0-7)
-     *
-     * @param value
-     *            priority
-     */
-    void setPriority(byte value);
-
     /**
      * gets the preemption value;
      *
@@ -30,14 +23,6 @@ public interface ISessionClassID {
      */
     byte getPreemption();
 
-    /**
-     * * sets the preemption
-     *
-     * @param value
-     *            preemption
-     */
-    void setPreemption(byte value);
-
     /**
      * compress the priority and preemption to a single byte value;
      *
index d71e194542d98cf92a0c8f5dcfdf0f574476498a..48f1597ae4297ba909926c618e159366df5f3559 100644 (file)
@@ -1,14 +1,13 @@
-/**
- @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
@@ -33,9 +32,8 @@ import org.pcmm.base.IPCMMBaseObject;
  */
 
 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.
@@ -44,6 +42,4 @@ public interface ISubscriberID extends IPCMMBaseObject {
      */
     InetAddress getSourceIPAddress();
 
-    void setSourceIPAddress(InetAddress address);
-
 }
index 9e21675f42bf433f89489a0375ee34375eed47a0..3360ecd268c1f69bd941ca641072ae949a7cba79 100644 (file)
@@ -1,22 +1,15 @@
-/**
- @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();
 
index e835b39a87743a3c499842ae112a1949d3b471d7..f44618dcf548774112549cd3b90f8db297fd2bd4 100644 (file)
-/**
- @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();
+    }
 
 }
index 4f1c3af50d9366030aa9e562e7c9fb1adc1fa6cb..678dab26cda5f94b19b884ff5443db81df9ef7ad 100644 (file)
@@ -1,77 +1,93 @@
-/**
- @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]));
+    }
 }
diff --git a/packetcable-driver/src/main/java/org/pcmm/gates/impl/BEEnvelop.java b/packetcable-driver/src/main/java/org/pcmm/gates/impl/BEEnvelop.java
new file mode 100644 (file)
index 0000000..4552550
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * (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]));
+    }
+}
index 4e0e9b032f3ef97193f28027751b9383e6ff8e95..d7d7e8bc523fb4c302136d6bedce0f0826817de4 100644 (file)
@@ -1,79 +1,88 @@
-/**
- @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;
        }
@@ -87,125 +96,64 @@ public class BestEffortService extends PCMMBaseObject implements
        }
 
        @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;
        }
 
 }
index 6fa5d79a8bbdba0f9523ba243a247e8a61f1b536..d5d4d71d09a28859e1552ee1b4e49b7ab0b60e65 100644 (file)
-/**
- @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;
+        }
+    }
 }
index 382b08a3df81e764673cb06e8ec25a87028ad6cc..528bb2357aff19007a5268ead102f053528d3bd5 100644 (file)
-/**
- @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);
+    }
+
 }
index 2ebc2bcdb45b656b46fc2ae516129f4aedd01f23..2695309252ba01e1f1f30557b093fd7fb48e0624 100644 (file)
-/**
- @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;
+        }
     }
 
 }
index 26153a64e0014039355ac39e1ef8075b16d3a3f6..f45df91b3606fbee0011d52721da63188881aeea 100644 (file)
@@ -1,57 +1,71 @@
-/**
- @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]));
+    }
 }
index c802d32e954dd1e50788be17fe06c0d362d7e4a1..5be3c9fd6505f146c8682c7bd57080206b201c02 100644 (file)
-/**
- @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]));
+    }
 }
index 12808652058271a7534848921f69dd06dd6eafc0..f47cd608e63e22c7be1750b85aa77e8240d75b89 100644 (file)
  */
 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;
+        }
     }
 
 }
index da686efd2f30cd10fb54642f7cc43f5e80316c74..2e203eda39a0a7d1715d552f2a610a4395b44258 100644 (file)
-/**
- @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]))));
+
     }
+
 }
index 57121b055dbffae638a544368307bd7e661254da..1e2eaff625213cf24f8e8aea597c7207c2f2e510 100644 (file)
@@ -1,14 +1,18 @@
-/**
- @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>
@@ -20,205 +24,186 @@ public class PCMMGateReq implements IPCMMGate {
 
     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;
@@ -234,32 +219,32 @@ public class PCMMGateReq implements IPCMMGate {
 
     @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;
@@ -267,4 +252,5 @@ public class PCMMGateReq implements IPCMMGate {
         System.arraycopy(a, 0, array, offset, a.length);
         return array;
     }
+*/
 }
index 7b3ff2006c01ebe4c79fce15a659187d8c1fb00f..8c5ec22acf4be4cc74319a46868d8301f0ddd71a 100644 (file)
@@ -1,85 +1,96 @@
-/**
- @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;
     }
 }
index e933bb229fc178307f354b39728c6125376afd8f..e98b5dc982c1edbcfcd9d4f5de17fa75d56cbf0f 100644 (file)
@@ -1,66 +1,78 @@
-/**
- @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;
+        }
+    }
 }
index 16ae63df0e0d6823cfb527e23d39670b8df6b10d..29b2b64e54c52dc65d9da5a26b99b5e747e276cb 100644 (file)
@@ -1,77 +1,70 @@
-/**
- @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])));
     }
-
 }
index 4fa90a58502ea93ae667a9bd8d795e959496471d..47120f573a4ed5aa992c2f16d0b12a3898cc3162 100644 (file)
@@ -1,39 +1,42 @@
-/**
- @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;
     }
 
     /**
@@ -43,14 +46,6 @@ public class MMVersionInfo extends PCMMBaseObject {
         return majorVersionNB;
     }
 
-    /**
-     * @param majorVersionNB
-     *            the majorVersionNB to set
-     */
-    public void setMajorVersionNB(short majorVersionNB) {
-        this.majorVersionNB = majorVersionNB;
-    }
-
     /**
      * @return the minorVersionNB
      */
@@ -58,12 +53,25 @@ public class MMVersionInfo extends PCMMBaseObject {
         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]));
     }
 
 }
index 409862bcdbef3e1797bc1197e23353013da395d1..8a386f0e30b2934cdc19a68e681fb45786d54c7a 100644 (file)
-/**
- @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;
+
        }
 
 }
index c63f402fa93c7d8c5a37b5cef4373ed009ec9dd1..c13a15465f19b4111490920c5eb5bdd48dfd7d3c 100644 (file)
@@ -51,9 +51,10 @@ class CmtsDataProcessor implements COPSPepDataProcess {
                     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;
index 58dcfcca61333d51d62d4d89055144469c5c876d..19ef270202ea75a0aae8a7a17c6e1a3a23d73549 100644 (file)
@@ -6,6 +6,7 @@ package org.pcmm.rcd.impl;
 
 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;
@@ -88,7 +89,7 @@ public class CmtsPepReqStateMan extends COPSPepReqStateMan {
                             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);
                                 }
@@ -137,18 +138,22 @@ public class CmtsPepReqStateMan extends COPSPepReqStateMan {
         // 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);
@@ -171,8 +176,7 @@ public class CmtsPepReqStateMan extends COPSPepReqStateMan {
             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);
 
index 01e23e49e1db022cb48ceac1b9f517c8f141f609..3737e1b03b31383ddc8a82a40ffdf28fb6b36da7 100644 (file)
@@ -1,5 +1,5 @@
-/**
- @header@
+/*
+ * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
  */
 
 package org.pcmm.utils;
@@ -13,7 +13,7 @@ import org.pcmm.gates.IPCMMError;
 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) {
index 071a11c00692319592ec86045f740ea7251fea22..7ce4475a3a0615491e5abf6e359b530d26f51343 100644 (file)
@@ -228,7 +228,7 @@ public class COPSPdpAgent {
             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());
         }
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/AMIDTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/AMIDTest.java
new file mode 100644 (file)
index 0000000..57e5779
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/BestEffortServiceTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/BestEffortServiceTest.java
new file mode 100644 (file)
index 0000000..fd9fb7b
--- /dev/null
@@ -0,0 +1,77 @@
+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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/ClassifierTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/ClassifierTest.java
new file mode 100644 (file)
index 0000000..9c1590e
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/DOCSISServiceClassNameTrafficProfileTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/DOCSISServiceClassNameTrafficProfileTest.java
new file mode 100644 (file)
index 0000000..7edc025
--- /dev/null
@@ -0,0 +1,80 @@
+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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/ExtendedClassifierTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/ExtendedClassifierTest.java
new file mode 100644 (file)
index 0000000..8424622
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/GateIDTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/GateIDTest.java
new file mode 100644 (file)
index 0000000..32e87e8
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/GateSpecTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/GateSpecTest.java
new file mode 100644 (file)
index 0000000..e63e3f5
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/IPv6ClassifierTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/IPv6ClassifierTest.java
new file mode 100644 (file)
index 0000000..e43abef
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/PCMMErrorTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/PCMMErrorTest.java
new file mode 100644 (file)
index 0000000..6896805
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/SessionClassIDTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/SessionClassIDTest.java
new file mode 100644 (file)
index 0000000..67d3fa3
--- /dev/null
@@ -0,0 +1,27 @@
+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());
+    }
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/SubscriberIDTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/SubscriberIDTest.java
new file mode 100644 (file)
index 0000000..ba04fbd
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/gates/impl/TransactionIDTest.java b/packetcable-driver/src/test/java/org/pcmm/gates/impl/TransactionIDTest.java
new file mode 100644 (file)
index 0000000..2639c6f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/objects/MMVersionInfoTest.java b/packetcable-driver/src/test/java/org/pcmm/objects/MMVersionInfoTest.java
new file mode 100644 (file)
index 0000000..cc07747
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/objects/SyncOptionsTest.java b/packetcable-driver/src/test/java/org/pcmm/objects/SyncOptionsTest.java
new file mode 100644 (file)
index 0000000..65aee3e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * (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);
+    }
+
+}
diff --git a/packetcable-driver/src/test/java/org/pcmm/test/BestEffortServiceTest.java b/packetcable-driver/src/test/java/org/pcmm/test/BestEffortServiceTest.java
deleted file mode 100644 (file)
index defde2e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-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);
-    }
-
-}
diff --git a/packetcable-driver/src/test/java/org/pcmm/test/PCErrorTest.java b/packetcable-driver/src/test/java/org/pcmm/test/PCErrorTest.java
deleted file mode 100644 (file)
index d6f129a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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());
-               }
-
-       }
-
-}
diff --git a/packetcable-driver/src/test/java/org/pcmm/test/PCMMGateReqTest.java b/packetcable-driver/src/test/java/org/pcmm/test/PCMMGateReqTest.java
deleted file mode 100644 (file)
index bfd622c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- *
- */
-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");
-    }
-
-}
diff --git a/packetcable-driver/src/test/java/org/pcmm/test/README.md b/packetcable-driver/src/test/java/org/pcmm/test/README.md
deleted file mode 100644 (file)
index f32f06a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-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
index 5257632a2dae550fee00e0732a7855b83e710c0d..79523aba7c62f38f578ef80399bd67dbfdc7bdfb 100644 (file)
@@ -11,327 +11,340 @@ import org.opendaylight.yang.gen.v1.urn.packetcable.rev150327.pcmm.qos.ext.class
 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);
+    }
 }
index 12a609b8a5e0ca6ef1095f8c9b4d01354eb08b39..55b9e6e9ad94cb208247d94e5758ed17474290e3 100644 (file)
@@ -104,7 +104,7 @@ public class PCMMServiceTest {
         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
@@ -150,12 +150,15 @@ public class PCMMServiceTest {
 
     @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));
     }
 
@@ -413,7 +416,9 @@ public class PCMMServiceTest {
         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);