From 4f0f343be373c2a8c261a8b951b254ccea7fc022 Mon Sep 17 00:00:00 2001 From: Steven Pisarski Date: Mon, 20 Apr 2015 09:08:16 -0600 Subject: [PATCH] The second patch of an estimated 4 to complete the COPS message refactoring as described in Bugzilla report #2943. This patch completes the refactoring for all of the objects that can be contained within a COPS message. Although this changelist is quite large, it was not possible to subdivide it any further as it was necessary to refactor each of the classes being extended by COPSObjectBase. Most of the changes made at the service level are to the COPS object construction; however, a few fixes have also been made to address some of the compiler warnings. This patch also should have taken out all of the DOS CR characters in any of the source being altered at this time. Change-Id: I299f2360dac8455b2f4e87d9e8e751ae7c843f3b Signed-off-by: Steven Pisarski --- .../src/main/java/org/pcmm/PCMMPdpAgent.java | 23 +- .../main/java/org/pcmm/PCMMPdpMsgSender.java | 81 +- .../java/org/pcmm/PCMMPdpReqStateMan.java | 841 ++++++------ .../src/main/java/org/pcmm/PCMMPepAgent.java | 5 +- .../pcmm/messages/impl/COPSDecisionMsgEX.java | 39 +- .../pcmm/messages/impl/MessageFactory.java | 50 +- .../src/main/java/org/pcmm/rcd/impl/CMTS.java | 36 +- .../org/pcmm/rcd/impl/PCMMPolicyServer.java | 23 +- .../org/umu/cops/ospdp/COPSPdpOSAgent.java | 597 ++++----- .../umu/cops/ospdp/COPSPdpOSMsgSender.java | 553 ++++---- .../umu/cops/ospdp/COPSPdpOSReqStateMan.java | 600 ++++----- .../org/umu/cops/ospep/COPSPepOSAgent.java | 10 +- .../umu/cops/ospep/COPSPepOSMsgSender.java | 515 ++++---- .../java/org/umu/cops/prpdp/COPSPdpAgent.java | 649 ++++----- .../org/umu/cops/prpdp/COPSPdpMsgSender.java | 848 ++++++------ .../umu/cops/prpdp/COPSPdpReqStateMan.java | 752 +++++------ .../java/org/umu/cops/prpep/COPSPepAgent.java | 622 +++++---- .../org/umu/cops/prpep/COPSPepConnection.java | 10 +- .../org/umu/cops/prpep/COPSPepMsgSender.java | 735 +++++------ .../umu/cops/prpep/COPSPepReqStateMan.java | 791 +++++------ .../org/umu/cops/stack/COPSAcctTimer.java | 135 +- .../umu/cops/stack/COPSClientAcceptMsg.java | 504 +++---- .../umu/cops/stack/COPSClientCloseMsg.java | 440 ++++--- .../org/umu/cops/stack/COPSClientOpenMsg.java | 642 +++++---- .../java/org/umu/cops/stack/COPSClientSI.java | 309 +++-- .../java/org/umu/cops/stack/COPSContext.java | 401 +++--- .../java/org/umu/cops/stack/COPSDecision.java | 650 ++++----- .../org/umu/cops/stack/COPSDecisionMsg.java | 867 ++++++------ .../org/umu/cops/stack/COPSDeleteMsg.java | 564 ++++---- .../java/org/umu/cops/stack/COPSError.java | 411 +++--- .../java/org/umu/cops/stack/COPSHandle.java | 309 +++-- .../org/umu/cops/stack/COPSIntegrity.java | 401 +++--- .../org/umu/cops/stack/COPSInterface.java | 159 ++- .../org/umu/cops/stack/COPSIpAddress.java | 87 ++ .../org/umu/cops/stack/COPSIpv4Address.java | 162 +-- .../umu/cops/stack/COPSIpv4InInterface.java | 146 ++- .../org/umu/cops/stack/COPSIpv4Interface.java | 169 +-- .../umu/cops/stack/COPSIpv4LastPdpAddr.java | 119 +- .../umu/cops/stack/COPSIpv4OutInterface.java | 149 ++- .../umu/cops/stack/COPSIpv4PdpAddress.java | 189 +-- .../stack/COPSIpv4PdpRedirectAddress.java | 56 + .../org/umu/cops/stack/COPSIpv6Address.java | 146 +-- .../umu/cops/stack/COPSIpv6InInterface.java | 156 ++- .../org/umu/cops/stack/COPSIpv6Interface.java | 159 +-- .../umu/cops/stack/COPSIpv6LastPdpAddr.java | 119 +- .../umu/cops/stack/COPSIpv6OutInterface.java | 145 +- .../umu/cops/stack/COPSIpv6PdpAddress.java | 191 +-- .../stack/COPSIpv6PdpRedirectAddress.java | 57 + .../java/org/umu/cops/stack/COPSKAMsg.java | 378 +++--- .../java/org/umu/cops/stack/COPSKATimer.java | 126 +- .../org/umu/cops/stack/COPSLPDPDecision.java | 117 +- .../java/org/umu/cops/stack/COPSObjBase.java | 246 ++-- .../org/umu/cops/stack/COPSObjHeader.java | 504 ++++--- .../org/umu/cops/stack/COPSObjHeaderData.java | 30 + .../org/umu/cops/stack/COPSObjectParser.java | 71 + .../org/umu/cops/stack/COPSPdpAddress.java | 237 ++-- .../java/org/umu/cops/stack/COPSPepId.java | 266 ++-- .../java/org/umu/cops/stack/COPSReason.java | 366 +++--- .../org/umu/cops/stack/COPSReportMsg.java | 708 +++++----- .../org/umu/cops/stack/COPSReportType.java | 316 +++-- .../java/org/umu/cops/stack/COPSReqMsg.java | 1164 ++++++++--------- .../org/umu/cops/stack/COPSSyncStateMsg.java | 552 ++++---- .../java/org/umu/cops/stack/COPSTimer.java | 202 +-- .../java/org/umu/cops/stack/COPSUtil.java | 179 +-- .../org/umu/cops/stack/COPSAcctTimerTest.java | 84 ++ .../org/umu/cops/stack/COPSClientSITest.java | 113 ++ .../org/umu/cops/stack/COPSContextTest.java | 111 ++ .../org/umu/cops/stack/COPSDecisionTest.java | 361 +++++ .../org/umu/cops/stack/COPSErrorTest.java | 88 ++ .../stack/COPSHandleFirstConstructorTest.java | 24 +- .../COPSHandleSecondConstructorTest.java | 41 - .../org/umu/cops/stack/COPSHandleTest.java | 141 ++ .../org/umu/cops/stack/COPSIntegrityTest.java | 107 ++ .../umu/cops/stack/COPSIpv4AddressTest.java | 36 + .../cops/stack/COPSIpv4InInterfaceTest.java | 66 + .../cops/stack/COPSIpv4LastPdpAddrTest.java | 112 ++ .../cops/stack/COPSIpv4OutInterfaceTest.java | 66 + .../stack/COPSIpv4PdpRedirectAddressTest.java | 112 ++ .../umu/cops/stack/COPSIpv6AddressTest.java | 47 + .../cops/stack/COPSIpv6InInterfaceTest.java | 66 + .../cops/stack/COPSIpv6LastPdpAddrTest.java | 130 ++ .../cops/stack/COPSIpv6OutInterfaceTest.java | 66 + .../stack/COPSIpv6PdpRedirectAddressTest.java | 130 ++ .../org/umu/cops/stack/COPSKATimerTest.java | 84 ++ .../umu/cops/stack/COPSLPDPDecisionTest.java | 121 ++ .../org/umu/cops/stack/COPSPepIdTest.java | 94 ++ .../org/umu/cops/stack/COPSReasonTest.java | 88 ++ .../umu/cops/stack/COPSReportTypeTest.java | 96 ++ 88 files changed, 12999 insertions(+), 10469 deletions(-) create mode 100644 packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpAddress.java create mode 100644 packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddress.java create mode 100644 packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddress.java create mode 100644 packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeaderData.java create mode 100644 packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjectParser.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSAcctTimerTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSClientSITest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSContextTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSDecisionTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSErrorTest.java delete mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleSecondConstructorTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIntegrityTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4AddressTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4InInterfaceTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4LastPdpAddrTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4OutInterfaceTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddressTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6AddressTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6InInterfaceTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6LastPdpAddrTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6OutInterfaceTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddressTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSKATimerTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSLPDPDecisionTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSPepIdTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSReasonTest.java create mode 100644 packetcable-driver/src/test/java/org/umu/cops/stack/COPSReportTypeTest.java diff --git a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpAgent.java b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpAgent.java index 7c1f47c..de32491 100644 --- a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpAgent.java +++ b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpAgent.java @@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory; import org.umu.cops.prpdp.COPSPdpAgent; import org.umu.cops.prpdp.COPSPdpException; import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSError.ErrorTypes; import java.io.IOException; import java.net.InetAddress; @@ -43,9 +44,8 @@ public class PCMMPdpAgent extends COPSPdpAgent { * Policy data processing object */ private PCMMPdpDataProcess _process; - private MMVersionInfo _mminfo; private COPSHandle _handle; - private short _transactionID; +// private short _transactionID; /** * Creates a PDP Agent @@ -163,8 +163,7 @@ public class PCMMPdpAgent extends COPSPdpAgent { // Unsupported client type COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg .getHeader().getClientType()); - COPSError err = new COPSError( - COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0); + COPSError err = new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA); COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); closeMsg.add(cHdr); closeMsg.add(err); @@ -183,7 +182,7 @@ public class PCMMPdpAgent extends COPSPdpAgent { COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg .getHeader().getClientType()); COPSError err = new COPSError( - COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0); + ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA); COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); closeMsg.add(cHdr); closeMsg.add(err); @@ -198,18 +197,15 @@ public class PCMMPdpAgent extends COPSPdpAgent { setPepId(pepId); // Support if ((cMsg.getClientSI() != null) ) { - _mminfo = new MMVersionInfo(cMsg - .getClientSI().getData().getData()); - logger.info("CMTS sent MMVersion info : major:" - + _mminfo.getMajorVersionNB() + " minor:" - + _mminfo.getMinorVersionNB()); + final MMVersionInfo _mminfo = new MMVersionInfo(cMsg.getClientSI().getData().getData()); + logger.info("CMTS sent MMVersion info : major:" + _mminfo.getMajorVersionNB() + " minor:" + + _mminfo.getMinorVersionNB()); } else { // Unsupported objects COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg .getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, - (short) 0); + COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA); COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); closeMsg.add(cHdr); closeMsg.add(err); @@ -245,8 +241,7 @@ public class PCMMPdpAgent extends COPSPdpAgent { // close the socket COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg .getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, - (short) 0); + COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA); COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); closeMsg.add(cHdr); closeMsg.add(err); diff --git a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpMsgSender.java b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpMsgSender.java index 515b595..25e63bc 100644 --- a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpMsgSender.java +++ b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpMsgSender.java @@ -12,8 +12,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.umu.cops.prpdp.COPSPdpException; import org.umu.cops.stack.*; -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; +import org.umu.cops.stack.COPSClientSI.CSIType; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; import java.io.IOException; import java.net.InetAddress; @@ -127,7 +129,7 @@ public class PCMMPdpMsgSender { /** * Sends a PCMM GateSet COPS Decision message * - * @param + * @param gate - the gate to set * @throws COPSPdpException */ public void sendGateSet(IPCMMGate gate) @@ -150,18 +152,15 @@ public class PCMMPdpMsgSender { // new pcmm specific clientsi - COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); - byte[] data = gate.getData(); - clientSD.setData(new COPSData(data, 0, data.length)); + // TODO - determine if NAMED is correct. + COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(gate.getData(), 0, gate.getData().length)); try { decisionMsg.add(hdr); decisionMsg.add(handle); // Decisions (no flags supplied) // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - COPSDecision install = new COPSDecision(); - install.setCmdCode(COPSDecision.DEC_INSTALL); - install.setFlags(COPSDecision.F_REQERROR); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + COPSDecision install = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); decisionMsg.addDecision(install, cntxt); decisionMsg.add(clientSD); // setting up the gate /* @@ -189,11 +188,10 @@ public class PCMMPdpMsgSender { /** * Sends a PCMM GateSet COPS Decision message * - * @param + * @param num - parameter used to set the traffic rate * @throws COPSPdpException */ - public void sendGateSetDemo(int num) - throws COPSPdpException { + public void sendGateSetDemo(int num) throws COPSPdpException { // Common Header with the same ClientType as the request @@ -264,9 +262,6 @@ public class PCMMPdpMsgSender { - // new pcmm specific clientsi - COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); - final COPSHandle handle = new COPSHandle(getClientHandle().getId()); // set transaction ID to gate set @@ -351,16 +346,14 @@ public class PCMMPdpMsgSender { byte[] data = gate.getData(); // new pcmm specific clientsi - clientSD.setData(new COPSData(data, 0, data.length)); + COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length)); try { decisionMsg.add(hdr); decisionMsg.add(handle); // Decisions (no flags supplied) // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - COPSDecision install = new COPSDecision(); - install.setCmdCode(COPSDecision.DEC_INSTALL); - install.setFlags(COPSDecision.F_REQERROR); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + COPSDecision install = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); decisionMsg.addDecision(install, cntxt); decisionMsg.add(clientSD); // setting up the gate /* @@ -387,11 +380,9 @@ public class PCMMPdpMsgSender { /** * Sends a PCMM GateSet COPS Decision message * - * @param * @throws COPSPdpException */ - public void sendGateSetBestEffortWithExtendedClassifier() - throws COPSPdpException { + public void sendGateSetBestEffortWithExtendedClassifier() throws COPSPdpException { // Common Header with the same ClientType as the request COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType()); @@ -453,9 +444,6 @@ public class PCMMPdpMsgSender { - // new pcmm specific clientsi - COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); - // Client Handle with the same clientHandle as the request final COPSHandle handle = new COPSHandle(getClientHandle().getId()); @@ -541,16 +529,14 @@ public class PCMMPdpMsgSender { byte[] data = gate.getData(); // new pcmm specific clientsi - clientSD.setData(new COPSData(data, 0, data.length)); + COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length)); try { decisionMsg.add(hdr); decisionMsg.add(handle); // Decisions (no flags supplied) // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - COPSDecision install = new COPSDecision(); - install.setCmdCode(COPSDecision.DEC_INSTALL); - install.setFlags(COPSDecision.F_REQERROR); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + COPSDecision install = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); decisionMsg.addDecision(install, cntxt); decisionMsg.add(clientSD); // setting up the gate /* @@ -611,7 +597,6 @@ public class PCMMPdpMsgSender { /** * Sends a PCMM GateSet COPS Decision message * - * @param * @throws COPSPdpException */ public void sendGateSet() throws COPSPdpException { @@ -640,9 +625,6 @@ public class PCMMPdpMsgSender { .setRequestTransmissionPolicy( PCMMGlobalConfig.BETransmissionPolicy); - // new pcmm specific clientsi - COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); - // Client Handle with the same clientHandle as the request final COPSHandle handle = new COPSHandle(getClientHandle().getId()); // byte[] content = "1234".getBytes(); @@ -692,17 +674,15 @@ public class PCMMPdpMsgSender { byte[] data = gate.getData(); // new pcmm specific clientsi - clientSD.setData(new COPSData(data, 0, data.length)); + COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length)); try { decisionMsg.add(hdr); decisionMsg.add(handle); // Decisions (no flags supplied) // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - COPSDecision install = new COPSDecision(); - install.setCmdCode(COPSDecision.DEC_INSTALL); - install.setFlags(COPSDecision.F_REQERROR); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + COPSDecision install = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); decisionMsg.addDecision(install, cntxt); decisionMsg.add(clientSD); // setting up the gate /* @@ -753,9 +733,6 @@ public class PCMMPdpMsgSender { ISubscriberID subscriberID = new SubscriberID(); IGateID gateID = new GateID(); - // new pcmm specific clientsi - COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); - final COPSHandle handle = new COPSHandle(getClientHandle().getId()); // set transaction ID to gate set @@ -783,17 +760,14 @@ public class PCMMPdpMsgSender { byte[] data = gate.getData(); // new pcmm specific clientsi - clientSD.setData(new COPSData(data, 0, data.length)); - + COPSClientSI clientSD = new COPSClientSI(CSIType.NAMED, new COPSData(data, 0, data.length)); try { decisionMsg.add(hdr); decisionMsg.add(handle); // Decisions (no flags supplied) // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - COPSDecision install = new COPSDecision(); - install.setCmdCode(COPSDecision.DEC_INSTALL); - install.setFlags(COPSDecision.F_REQERROR); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + COPSDecision install = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); decisionMsg.addDecision(install, cntxt); decisionMsg.add(clientSD); // setting up the gate /* @@ -839,12 +813,9 @@ public class PCMMPdpMsgSender { // Decisions // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); // - COPSDecision dec = new COPSDecision(); - dec.setCmdCode(COPSDecision.DEC_INSTALL); - dec.setFlags(COPSDecision.F_REQSTATE); - + COPSDecision dec = new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE); COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); try { decisionMsg.add(hdr); diff --git a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpReqStateMan.java b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpReqStateMan.java index 1459c6c..08a8e2c 100644 --- a/packetcable-driver/src/main/java/org/pcmm/PCMMPdpReqStateMan.java +++ b/packetcable-driver/src/main/java/org/pcmm/PCMMPdpReqStateMan.java @@ -1,420 +1,421 @@ -/** - @header@ - */ - -package org.pcmm; - -import org.pcmm.gates.ITransactionID; -import org.pcmm.gates.impl.PCMMGateReq; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.umu.cops.prpdp.COPSPdpException; -import org.umu.cops.stack.*; - -import java.net.Socket; -import java.util.*; - -/** - * State manager class for provisioning requests, at the PDP side. - */ -public class PCMMPdpReqStateMan { - - public final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class); - - /** - * Request State created - */ - public final static short ST_CREATE = 1; - /** - * Request received - */ - public final static short ST_INIT = 2; - /** - * Decisions sent - */ - public final static short ST_DECS = 3; - /** - * Report received - */ - public final static short ST_REPORT = 4; - /** - * Request State finalized - */ - public final static short ST_FINAL = 5; - /** - * New Request State solicited - */ - public final static short ST_NEW = 6; - /** - * Delete Request State solicited - */ - public final static short ST_DEL = 7; - /** - * SYNC request sent - */ - public final static short ST_SYNC = 8; - /** - * SYNC completed - */ - public final static short ST_SYNCALL = 9; - /** - * Close connection received - */ - public final static short ST_CCONN = 10; - /** - * Keep-alive timeout - */ - public final static short ST_NOKA = 11; - /** - * Accounting timeout - */ - public final static short ST_ACCT = 12; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Object for performing policy data processing - */ - protected PCMMPdpDataProcess _process; - - /** - * Current state of the request being managed - */ - protected short _status; - - /** COPS message transceiver used to send COPS messages */ - protected PCMMPdpMsgSender _sender; - - /** - * Creates a request state manager - * @param clientType Client-type - * @param clientHandle Client handle - */ - public PCMMPdpReqStateMan(short clientType, String clientHandle) { - _handle = new COPSHandle(new COPSData(clientHandle)); - _clientType = clientType; - _status = ST_CREATE; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Gets the status of the request - * @return Request state value - */ - public short getStatus() { - return _status; - } - - /** - * Gets the policy data processing object - * @return Policy data processing object - */ - public PCMMPdpDataProcess getDataProcess() { - return _process; - } - - /** - * Sets the policy data processing object - * @param process Policy data processing object - */ - public void setDataProcess(PCMMPdpDataProcess process) { - _process = process; - } - - /** - * Called when COPS sync is completed - * @param repMsg COPS sync message - * @throws COPSPdpException - */ - protected void processSyncComplete(COPSSyncStateMsg repMsg) - throws COPSPdpException { - - _status = ST_SYNCALL; - - // maybe we should notifySyncComplete ... - } - - /** - * Initializes a new request state over a socket - * @param sock Socket to the PEP - * @throws COPSPdpException - */ - protected void initRequestState(Socket sock) - throws COPSPdpException { - // Inits an object for sending COPS messages to the PEP - _sender = new PCMMPdpMsgSender(_clientType, _handle, sock); - - // Initial state - _status = ST_INIT; - } - - - - /** - * Processes a COPS request - * @param msg COPS request received from the PEP - * @throws COPSPdpException - */ - protected void processRequest(COPSReqMsg msg) - throws COPSPdpException { - - COPSHeader hdrmsg = msg.getHeader(); - COPSHandle handlemsg = msg.getClientHandle(); - COPSContext contextmsg = msg.getContext(); - - //** Analyze the request - //** - - /* ::= - * - * - * *() - * [] - * ::= <*( )> - * - * Very important, this is actually being treated like this: - * ::= | - * - - // Named ClientSI - Vector clientSIs = msg.getClientSI(); - Hashtable reqSIs = new Hashtable(40); - String strobjprid = new String(); - for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); - switch (obj.getSNum()) - { - case COPSPrObjBase.PR_PRID: - strobjprid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - reqSIs.put(strobjprid, obj.getData().str()); - // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); - // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); - break; - default: - break; - } - } - - //** Here we must retrieve a decision depending on - //** the supplied ClientSIs - // reqSIs is a hashtable with the prid and epds - - // ................ - // - Hashtable removeDecs = new Hashtable(); - Hashtable installDecs = new Hashtable(); - _process.setClientData(this, reqSIs); - - removeDecs = _process.getRemovePolicy(this); - installDecs = _process.getInstallPolicy(this); - - //** We create the SOLICITED decision - //** - _sender.sendDecision(removeDecs, installDecs); - _status = ST_DECS; - */ - } - - /** - * Processes a report - * @param msg Report message from the PEP - * @throws COPSPdpException - */ - protected void processReport(COPSReportMsg msg) - throws COPSPdpException { - - //** Analyze the report - //** - - /* - * ::= - * - * - * *() - * [] - * ::= <[] *()> - * ::= *() - * - * Important, is not parsed - */ - - // COPSHeader hdrmsg = msg.getHeader(); - // COPSHandle handlemsg = msg.getClientHandle(); - - // WriteBinaryDump("COPSReportMessage", msg.getData().getData()); - // Report Type - COPSReportType rtypemsg = msg.getReport(); - - // Named ClientSI - Vector clientSIs = msg.getClientSI(); - COPSClientSI myclientSI = (COPSClientSI) msg.getClientSI().elementAt(0); - byte[] data = Arrays.copyOfRange(myclientSI.getData().getData(), 0, myclientSI.getData().getData().length ); - - // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data); - logger.info("PCMMGateReq Parse Gate Message"); - PCMMGateReq gateMsg = new PCMMGateReq(data); - - // TODO - Determine why this Map is being populated but never used??? - Map repSIs = new HashMap<>(); - String strobjprid = ""; - for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); - switch (obj.getSNum()) { - case COPSPrObjBase.PR_PRID: - logger.info("COPSPrObjBase.PR_PRID"); - strobjprid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - logger.info("COPSPrObjBase.PR_EPD"); - repSIs.put(strobjprid, obj.getData().str()); - // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); - // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); - break; - default: - logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType()); - logger.error("PRID: " + strobjprid); - logger.error("EPD: " + obj.getData().str()); - break; - } - } - - logger.info("rtypemsg process"); - //** Here we must act in accordance with - //** the report received - if (rtypemsg.isSuccess()) { - logger.info("rtypemsg success"); - _status = ST_REPORT; - if (_process != null) - _process.successReport(this, gateMsg); - else { - if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) { - logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID()); - if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1()) - PCMMGlobalConfig.setGateID1(0); - if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2()) - PCMMGlobalConfig.setGateID2(0); - - } - if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) { - logger.info("GateSetAck: GateID = " + gateMsg.getGateID().getGateID()); - if (0 == PCMMGlobalConfig.getGateID1()) - PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID()); - if (0 == PCMMGlobalConfig.getGateID2()) - PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID()); - } - } - } else if (rtypemsg.isFailure()) { - logger.info("rtypemsg failure"); - _status = ST_REPORT; - if (_process != null) - _process.failReport(this, gateMsg); - else - logger.info("Gate message error - " + gateMsg.getError().toString()); - } else if (rtypemsg.isAccounting()) { - logger.info("rtypemsg account"); - _status = ST_ACCT; - if (_process != null) - _process.acctReport(this, gateMsg); - } - logger.info("Out processReport"); - } - - /** - * Called when connection is closed - * @param error Reason - * @throws COPSPdpException - */ - protected void processClosedConnection(COPSError error) - throws COPSPdpException { - if (_process != null) - _process.notifyClosedConnection(this, error); - - _status = ST_CCONN; - } - - /** - * Called when no keep-alive is received - * @throws COPSPdpException - */ - protected void processNoKAConnection() - throws COPSPdpException { - if (_process != null) - _process.notifyNoKAliveReceived(this); - - _status = ST_NOKA; - } - - /** - * Deletes the request state - * @throws COPSPdpException - */ - protected void finalizeRequestState() - throws COPSPdpException { - _sender.sendDeleteRequestState(); - _status = ST_FINAL; - } - - /** - * Asks for a COPS sync - * @throws COPSPdpException - */ - protected void syncRequestState() - throws COPSPdpException { - _sender.sendSyncRequestState(); - _status = ST_SYNC; - } - - /** - * Opens a new request state - * @throws COPSPdpException - */ - protected void openNewRequestState() - throws COPSPdpException { - _sender.sendOpenNewRequestState(); - _status = ST_NEW; - } - - /** - * Processes a COPS delete message - * @param dMsg COPSDeleteMsg received from the PEP - * @throws COPSPdpException - */ - protected void processDeleteRequestState(COPSDeleteMsg dMsg) - throws COPSPdpException { - if (_process != null) - _process.closeRequestState(this); - - _status = ST_DEL; - } - -} +/** + @header@ + */ + +package org.pcmm; + +import org.pcmm.gates.ITransactionID; +import org.pcmm.gates.impl.PCMMGateReq; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.umu.cops.prpdp.COPSPdpException; +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSReportType.ReportType; + +import java.net.Socket; +import java.util.*; + +/** + * State manager class for provisioning requests, at the PDP side. + */ +public class PCMMPdpReqStateMan { + + public final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class); + + /** + * Request State created + */ + public final static short ST_CREATE = 1; + /** + * Request received + */ + public final static short ST_INIT = 2; + /** + * Decisions sent + */ + public final static short ST_DECS = 3; + /** + * Report received + */ + public final static short ST_REPORT = 4; + /** + * Request State finalized + */ + public final static short ST_FINAL = 5; + /** + * New Request State solicited + */ + public final static short ST_NEW = 6; + /** + * Delete Request State solicited + */ + public final static short ST_DEL = 7; + /** + * SYNC request sent + */ + public final static short ST_SYNC = 8; + /** + * SYNC completed + */ + public final static short ST_SYNCALL = 9; + /** + * Close connection received + */ + public final static short ST_CCONN = 10; + /** + * Keep-alive timeout + */ + public final static short ST_NOKA = 11; + /** + * Accounting timeout + */ + public final static short ST_ACCT = 12; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Object for performing policy data processing + */ + protected PCMMPdpDataProcess _process; + + /** + * Current state of the request being managed + */ + protected short _status; + + /** COPS message transceiver used to send COPS messages */ + protected PCMMPdpMsgSender _sender; + + /** + * Creates a request state manager + * @param clientType Client-type + * @param clientHandle Client handle + */ + public PCMMPdpReqStateMan(short clientType, String clientHandle) { + _handle = new COPSHandle(new COPSData(clientHandle)); + _clientType = clientType; + _status = ST_CREATE; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Gets the status of the request + * @return Request state value + */ + public short getStatus() { + return _status; + } + + /** + * Gets the policy data processing object + * @return Policy data processing object + */ + public PCMMPdpDataProcess getDataProcess() { + return _process; + } + + /** + * Sets the policy data processing object + * @param process Policy data processing object + */ + public void setDataProcess(PCMMPdpDataProcess process) { + _process = process; + } + + /** + * Called when COPS sync is completed + * @param repMsg COPS sync message + * @throws COPSPdpException + */ + protected void processSyncComplete(COPSSyncStateMsg repMsg) + throws COPSPdpException { + + _status = ST_SYNCALL; + + // maybe we should notifySyncComplete ... + } + + /** + * Initializes a new request state over a socket + * @param sock Socket to the PEP + * @throws COPSPdpException + */ + protected void initRequestState(Socket sock) + throws COPSPdpException { + // Inits an object for sending COPS messages to the PEP + _sender = new PCMMPdpMsgSender(_clientType, _handle, sock); + + // Initial state + _status = ST_INIT; + } + + + + /** + * Processes a COPS request + * @param msg COPS request received from the PEP + * @throws COPSPdpException + */ + protected void processRequest(COPSReqMsg msg) + throws COPSPdpException { + + COPSHeader hdrmsg = msg.getHeader(); + COPSHandle handlemsg = msg.getClientHandle(); + COPSContext contextmsg = msg.getContext(); + + //** Analyze the request + //** + + /* ::= + * + * + * *() + * [] + * ::= <*( )> + * + * Very important, this is actually being treated like this: + * ::= | + * + + // Named ClientSI + Vector clientSIs = msg.getClientSI(); + Hashtable reqSIs = new Hashtable(40); + String strobjprid = new String(); + for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); + switch (obj.getSNum()) + { + case COPSPrObjBase.PR_PRID: + strobjprid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + reqSIs.put(strobjprid, obj.getData().str()); + // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); + // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); + break; + default: + break; + } + } + + //** Here we must retrieve a decision depending on + //** the supplied ClientSIs + // reqSIs is a hashtable with the prid and epds + + // ................ + // + Hashtable removeDecs = new Hashtable(); + Hashtable installDecs = new Hashtable(); + _process.setClientData(this, reqSIs); + + removeDecs = _process.getRemovePolicy(this); + installDecs = _process.getInstallPolicy(this); + + //** We create the SOLICITED decision + //** + _sender.sendDecision(removeDecs, installDecs); + _status = ST_DECS; + */ + } + + /** + * Processes a report + * @param msg Report message from the PEP + * @throws COPSPdpException + */ + protected void processReport(COPSReportMsg msg) + throws COPSPdpException { + + //** Analyze the report + //** + + /* + * ::= + * + * + * *() + * [] + * ::= <[] *()> + * ::= *() + * + * Important, is not parsed + */ + + // COPSHeader hdrmsg = msg.getHeader(); + // COPSHandle handlemsg = msg.getClientHandle(); + + // WriteBinaryDump("COPSReportMessage", msg.getData().getData()); + // Report Type + COPSReportType rtypemsg = msg.getReport(); + + // Named ClientSI + Vector clientSIs = msg.getClientSI(); + COPSClientSI myclientSI = (COPSClientSI) msg.getClientSI().elementAt(0); + byte[] data = Arrays.copyOfRange(myclientSI.getData().getData(), 0, myclientSI.getData().getData().length ); + + // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data); + logger.info("PCMMGateReq Parse Gate Message"); + PCMMGateReq gateMsg = new PCMMGateReq(data); + + // TODO - Determine why this Map is being populated but never used??? + Map repSIs = new HashMap<>(); + String strobjprid = ""; + for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); + switch (obj.getSNum()) { + case COPSPrObjBase.PR_PRID: + logger.info("COPSPrObjBase.PR_PRID"); + strobjprid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + logger.info("COPSPrObjBase.PR_EPD"); + repSIs.put(strobjprid, obj.getData().str()); + // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); + // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); + break; + default: + logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType()); + logger.error("PRID: " + strobjprid); + logger.error("EPD: " + obj.getData().str()); + break; + } + } + + logger.info("rtypemsg process"); + //** Here we must act in accordance with + //** the report received + if (rtypemsg.getReportType().equals(ReportType.SUCCESS)) { + logger.info("rtypemsg success"); + _status = ST_REPORT; + if (_process != null) + _process.successReport(this, gateMsg); + else { + if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) { + logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID()); + if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1()) + PCMMGlobalConfig.setGateID1(0); + if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2()) + PCMMGlobalConfig.setGateID2(0); + + } + if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) { + logger.info("GateSetAck: GateID = " + gateMsg.getGateID().getGateID()); + if (0 == PCMMGlobalConfig.getGateID1()) + PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID()); + if (0 == PCMMGlobalConfig.getGateID2()) + PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID()); + } + } + } else if (rtypemsg.getReportType().equals(ReportType.FAILURE)) { + logger.info("rtypemsg failure"); + _status = ST_REPORT; + if (_process != null) + _process.failReport(this, gateMsg); + else + logger.info("Gate message error - " + gateMsg.getError().toString()); + } else if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) { + logger.info("rtypemsg account"); + _status = ST_ACCT; + if (_process != null) + _process.acctReport(this, gateMsg); + } + logger.info("Out processReport"); + } + + /** + * Called when connection is closed + * @param error Reason + * @throws COPSPdpException + */ + protected void processClosedConnection(COPSError error) + throws COPSPdpException { + if (_process != null) + _process.notifyClosedConnection(this, error); + + _status = ST_CCONN; + } + + /** + * Called when no keep-alive is received + * @throws COPSPdpException + */ + protected void processNoKAConnection() + throws COPSPdpException { + if (_process != null) + _process.notifyNoKAliveReceived(this); + + _status = ST_NOKA; + } + + /** + * Deletes the request state + * @throws COPSPdpException + */ + protected void finalizeRequestState() + throws COPSPdpException { + _sender.sendDeleteRequestState(); + _status = ST_FINAL; + } + + /** + * Asks for a COPS sync + * @throws COPSPdpException + */ + protected void syncRequestState() + throws COPSPdpException { + _sender.sendSyncRequestState(); + _status = ST_SYNC; + } + + /** + * Opens a new request state + * @throws COPSPdpException + */ + protected void openNewRequestState() + throws COPSPdpException { + _sender.sendOpenNewRequestState(); + _status = ST_NEW; + } + + /** + * Processes a COPS delete message + * @param dMsg COPSDeleteMsg received from the PEP + * @throws COPSPdpException + */ + protected void processDeleteRequestState(COPSDeleteMsg dMsg) + throws COPSPdpException { + if (_process != null) + _process.closeRequestState(this); + + _status = ST_DEL; + } + +} diff --git a/packetcable-driver/src/main/java/org/pcmm/PCMMPepAgent.java b/packetcable-driver/src/main/java/org/pcmm/PCMMPepAgent.java index 263a8db..0d948ac 100644 --- a/packetcable-driver/src/main/java/org/pcmm/PCMMPepAgent.java +++ b/packetcable-driver/src/main/java/org/pcmm/PCMMPepAgent.java @@ -124,10 +124,7 @@ public class PCMMPepAgent extends COPSPepAgent implements Runnable { // Build OPN COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, getClientType()); - COPSPepId pepId = new COPSPepId(); - COPSData d = new COPSData(getPepID()); - pepId.setData(d); - + COPSPepId pepId = new COPSPepId(new COPSData(getPepID())); COPSClientOpenMsg msg = new COPSClientOpenMsg(); msg.add(hdr); msg.add(pepId); diff --git a/packetcable-driver/src/main/java/org/pcmm/messages/impl/COPSDecisionMsgEX.java b/packetcable-driver/src/main/java/org/pcmm/messages/impl/COPSDecisionMsgEX.java index f2a48cf..b73680f 100644 --- a/packetcable-driver/src/main/java/org/pcmm/messages/impl/COPSDecisionMsgEX.java +++ b/packetcable-driver/src/main/java/org/pcmm/messages/impl/COPSDecisionMsgEX.java @@ -4,6 +4,8 @@ package org.pcmm.messages.impl; import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CNum; import java.io.IOException; import java.io.OutputStream; @@ -76,37 +78,32 @@ public class COPSDecisionMsgEX extends COPSMsg { byte[] buf = new byte[data.length - _dataStart]; System.arraycopy(data, _dataStart, buf, 0, data.length - _dataStart); - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { case HANDLE: - _clientHandle = new COPSHandle(buf) { - }; + _clientHandle = COPSHandle.parse(objHdrData, buf); _dataStart += _clientHandle.getDataLength(); break; case CONTEXT: // dec context - _decContext = new COPSContext(buf) { - }; + _decContext = COPSContext.parse(objHdrData, buf); _dataStart += _decContext.getDataLength(); break; case ERROR: - _error = new COPSError(buf) { - }; + _error = COPSError.parse(objHdrData, buf); _dataStart += _error.getDataLength(); break; case DEC: - COPSDecision decs = new COPSDecision(buf) { - }; + COPSDecision decs = COPSDecision.parse(objHdrData, buf); _dataStart += decs.getDataLength(); addDecision(decs, _decContext); break; case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); + _integrity = COPSIntegrity.parse(objHdrData, buf); _dataStart += _integrity.getDataLength(); break; case CSI: - clientSI = new COPSClientSI(buf) { - }; + clientSI = COPSClientSI.parse(objHdrData, buf); _dataStart += clientSI.getDataLength(); break; default: @@ -211,14 +208,14 @@ public class COPSDecisionMsgEX extends COPSMsg { if (_error != null) throw new COPSException("No null error"); - if (decision.isLocalDecision()) + if (decision.getHeader().getCNum().equals(CNum.LPDP_DEC)) throw new COPSException("Is local decision"); Vector v = (Vector) _decisions.get(context); if (v == null) v = new Vector(); - if (decision.isFlagSet()) {// Commented out as advised by Felix + if (!decision.getFlag().equals(DecisionFlag.NA)) {// Commented out as advised by Felix // if (v.size() != 0) // { // Only one set of decision flags is allowed @@ -253,8 +250,6 @@ public class COPSDecisionMsgEX extends COPSMsg { public void add(COPSIntegrity integrity) throws COPSException { if (integrity == null) throw new COPSException("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException("Error Integrity"); _integrity = integrity; setMsgLength(); } @@ -344,7 +339,7 @@ public class COPSDecisionMsgEX extends COPSMsg { */ public boolean hasError() { return (_error != null); - }; + } /** * Should check hasError() before calling @@ -354,7 +349,7 @@ public class COPSDecisionMsgEX extends COPSMsg { */ public COPSError getError() { return _error; - }; + } /** * Returns a map of decision for which is an arry of context and vector of @@ -365,7 +360,7 @@ public class COPSDecisionMsgEX extends COPSMsg { */ public Hashtable getDecisions() { return _decisions; - }; + } /** * Returns true if it has integrity object @@ -375,7 +370,7 @@ public class COPSDecisionMsgEX extends COPSMsg { */ public boolean hasIntegrity() { return (_integrity != null); - }; + } /** * Should check hasIntegrity() before calling @@ -385,7 +380,7 @@ public class COPSDecisionMsgEX extends COPSMsg { */ public COPSIntegrity getIntegrity() { return _integrity; - }; + } /** * Method setMsgLength diff --git a/packetcable-driver/src/main/java/org/pcmm/messages/impl/MessageFactory.java b/packetcable-driver/src/main/java/org/pcmm/messages/impl/MessageFactory.java index fdcbeac..14a88ac 100644 --- a/packetcable-driver/src/main/java/org/pcmm/messages/impl/MessageFactory.java +++ b/packetcable-driver/src/main/java/org/pcmm/messages/impl/MessageFactory.java @@ -11,8 +11,11 @@ import org.pcmm.rcd.IPCMMClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.umu.cops.stack.*; -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; +import org.umu.cops.stack.COPSClientSI.CSIType; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSError.ErrorTypes; import java.net.InetAddress; import java.util.Properties; @@ -93,17 +96,25 @@ public class MessageFactory implements IMessageFactory { final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, IPCMMClient.CLIENT_TYPE); // handle // context - final COPSContext context = new COPSContext(COPSContext.CONFIG, (short) 0); + final COPSContext context = new COPSContext(RType.CONFIG, (short) 0); // decision - final COPSDecision decision = new COPSDecision(); + + Command cmd = null; if (prop.get(MessageProperties.DECISION_CMD_CODE) != null) - decision.setCmdCode((byte) prop.get(MessageProperties.DECISION_CMD_CODE)); + cmd = (Command) prop.get(MessageProperties.DECISION_CMD_CODE); + + DecisionFlag flag = null; if (prop.get(MessageProperties.DECISION_FLAG) != null) - decision.setFlags((short) prop.get(MessageProperties.DECISION_FLAG)); + flag = (DecisionFlag) prop.get(MessageProperties.DECISION_FLAG); - final COPSClientSI si = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal()); + final COPSDecision decision = new COPSDecision(cmd, flag); + + COPSData data = null; if (prop.get(MessageProperties.GATE_CONTROL) != null) - si.setData((COPSData) prop.get(MessageProperties.GATE_CONTROL)); + data = (COPSData) prop.get(MessageProperties.GATE_CONTROL); + + // TODO - Determine the proper type here. + final COPSClientSI si = new COPSClientSI(CSIType.SIGNALED, data); try { msg.add(hdr); final COPSHandle handle; @@ -140,7 +151,6 @@ public class MessageFactory implements IMessageFactory { */ protected COPSMsg createOPNMessage(final Properties prop) { final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, IPCMMClient.CLIENT_TYPE); - final COPSPepId pepId = new COPSPepId(); // version infor object short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO; short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO; @@ -149,9 +159,9 @@ public class MessageFactory implements IMessageFactory { if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null) minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO); // Mandatory MM version. - final COPSClientSI clientSI = new COPSClientSI((byte) 1); byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray(); - clientSI.setData(new COPSData(versionInfo, 0, versionInfo.length)); + final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, + new COPSData(versionInfo, 0, versionInfo.length)); final COPSClientOpenMsg msg = new COPSClientOpenMsg(); try { final COPSData d; @@ -159,7 +169,7 @@ public class MessageFactory implements IMessageFactory { d = new COPSData((String) prop.get(MessageProperties.PEP_ID)); else d = new COPSData(InetAddress.getLocalHost().getHostName()); - pepId.setData(d); + final COPSPepId pepId = new COPSPepId(d); msg.add(hdr); msg.add(pepId); msg.add(clientSI); @@ -211,13 +221,13 @@ public class MessageFactory implements IMessageFactory { final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, IPCMMClient.CLIENT_TYPE); final COPSError err; if (prop.get(MessageProperties.ERR_MESSAGE) != null) { - short code = (short) 0; - final short error = (short) prop.get(MessageProperties.ERR_MESSAGE); + ErrorTypes code = ErrorTypes.NA; + final ErrorTypes error = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE); if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null) - code = (short) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE); + code = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE); err = new COPSError(error, code); } else - err = new COPSError(COPSError.COPS_ERR_UNKNOWN, (short) 0); + err = new COPSError(ErrorTypes.UNKNOWN, ErrorTypes.NA); final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); try { @@ -240,10 +250,10 @@ public class MessageFactory implements IMessageFactory { final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_REQ, IPCMMClient.CLIENT_TYPE); final COPSReqMsg req = new COPSReqMsg(); - final short rType; + final RType rType; if (prop.get(MessageProperties.R_TYPE) != null) - rType = (Short) prop.get(MessageProperties.R_TYPE); - else rType = ICMTS.DEFAULT_R_TYPE; + rType = (RType) prop.get(MessageProperties.R_TYPE); + else rType = RType.NA; //ICMTS.DEFAULT_R_TYPE; final short mType; if (prop.get(MessageProperties.M_TYPE) != null) @@ -282,7 +292,7 @@ public class MessageFactory implements IMessageFactory { if (prop.get(MessageProperties.KA_TIMER) != null) timer = new COPSKATimer((Short) prop.get(MessageProperties.KA_TIMER)); else - timer = new COPSKATimer(); + timer = new COPSKATimer((short)1); try { kaMsg.add(cHdr); } catch (COPSException e) { diff --git a/packetcable-driver/src/main/java/org/pcmm/rcd/impl/CMTS.java b/packetcable-driver/src/main/java/org/pcmm/rcd/impl/CMTS.java index fa89754..b2b8fb2 100644 --- a/packetcable-driver/src/main/java/org/pcmm/rcd/impl/CMTS.java +++ b/packetcable-driver/src/main/java/org/pcmm/rcd/impl/CMTS.java @@ -3,13 +3,6 @@ */ package org.pcmm.rcd.impl; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; -import java.util.Vector; -import java.util.concurrent.Callable; - import org.pcmm.gates.IPCMMGate; import org.pcmm.gates.ITransactionID; import org.pcmm.gates.impl.PCMMGateReq; @@ -19,20 +12,15 @@ import org.umu.cops.prpep.COPSPepConnection; import org.umu.cops.prpep.COPSPepDataProcess; import org.umu.cops.prpep.COPSPepException; import org.umu.cops.prpep.COPSPepReqStateMan; -import org.umu.cops.stack.COPSAcctTimer; -import org.umu.cops.stack.COPSClientAcceptMsg; -import org.umu.cops.stack.COPSClientCloseMsg; -import org.umu.cops.stack.COPSContext; -import org.umu.cops.stack.COPSData; -import org.umu.cops.stack.COPSDecision; -import org.umu.cops.stack.COPSDecisionMsg; -import org.umu.cops.stack.COPSError; -import org.umu.cops.stack.COPSException; -import org.umu.cops.stack.COPSHeader; -import org.umu.cops.stack.COPSKATimer; -import org.umu.cops.stack.COPSMsg; -import org.umu.cops.stack.COPSPrObjBase; -import org.umu.cops.stack.COPSReqMsg; +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSDecision.Command; + +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Vector; +import java.util.concurrent.Callable; /** * @@ -179,8 +167,8 @@ public class CMTS extends AbstractPCMMServer implements ICMTS { // cmddecision --> we must check whether it is an error! - if (cmddecision.isInstallDecision()) { - String prid = new String(); + if (cmddecision.getCommand().equals(Command.INSTALL)) { + String prid = ""; for (; ee.hasMoreElements();) { COPSDecision decision = (COPSDecision) ee.nextElement(); COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData()); @@ -200,7 +188,7 @@ public class CMTS extends AbstractPCMMServer implements ICMTS { } } } - if (cmddecision.isRemoveDecision()) { + if (cmddecision.getCommand().equals(Command.REMOVE)) { String prid = new String(); for (; ee.hasMoreElements();) { COPSDecision decision = (COPSDecision) ee.nextElement(); diff --git a/packetcable-driver/src/main/java/org/pcmm/rcd/impl/PCMMPolicyServer.java b/packetcable-driver/src/main/java/org/pcmm/rcd/impl/PCMMPolicyServer.java index 06419ea..af0f31f 100644 --- a/packetcable-driver/src/main/java/org/pcmm/rcd/impl/PCMMPolicyServer.java +++ b/packetcable-driver/src/main/java/org/pcmm/rcd/impl/PCMMPolicyServer.java @@ -20,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.umu.cops.prpdp.COPSPdpConnection; import org.umu.cops.prpdp.COPSPdpDataProcess; import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSDecision.Command; import java.io.IOException; import java.net.InetAddress; @@ -78,7 +79,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS if (opnMessage.getHeader().isAClientClose()) { COPSError error = ((COPSClientCloseMsg) opnMessage).getError(); logger.debug("CMTS requetsed Client-Close"); - throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode())); + throw new PCMMException(new PCMMError((short)error.getErrCode().ordinal(), + (short)error.getErrSubCode().ordinal())); } else // Client-Open { if (opnMessage.getHeader().isAClientOpen()) { @@ -111,7 +113,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS if (reqMsg.getHeader().isAClientClose()) { COPSError error = ((COPSClientCloseMsg) opnMessage).getError(); logger.debug("CMTS requetsed Client-Close"); - throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode())); + throw new PCMMException(new PCMMError((short)error.getErrCode().ordinal(), + (short)error.getErrSubCode().ordinal())); } else // Request { if (reqMsg.getHeader().isARequest()) { @@ -208,8 +211,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS // configure message properties Properties prop = new Properties(); prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle()); - prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL); - prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL); + prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL); + prop.put(MessageProperties.DECISION_FLAG, Command.NULL); prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length)); COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop); // ** Send the GateSet Decision @@ -284,8 +287,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS // configure message properties Properties prop = new Properties(); prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle()); - prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL); - prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL); + prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL); + prop.put(MessageProperties.DECISION_FLAG, Command.NULL); byte[] data = gate.getData(); prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length)); COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop); @@ -365,8 +368,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS // configure message properties Properties prop = new Properties(); prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle()); - prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL); - prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL); + prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL); + prop.put(MessageProperties.DECISION_FLAG, Command.NULL); byte[] data = gate.getData(); prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length)); COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop); @@ -459,8 +462,8 @@ public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyS // configure message properties Properties prop = new Properties(); prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle()); - prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL); - prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL); + prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL); + prop.put(MessageProperties.DECISION_FLAG, Command.NULL); byte[] data = gate.getData(); prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length)); COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop); diff --git a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSAgent.java b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSAgent.java index d701d8f..7069c93 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSAgent.java +++ b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSAgent.java @@ -1,298 +1,299 @@ -package org.umu.cops.ospdp; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.umu.cops.stack.*; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Core PDP agent for outsourcing. - */ -public class COPSPdpOSAgent extends Thread { - - public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSAgent.class); - - /** Well-known port for COPS */ - public static final int WELL_KNOWN_PDP_PORT = 3288; - /** Default keep-alive timer value (secs) */ - public static final short KA_TIMER_VALUE = 30; - /** Default accounting timer value (secs) */ - public static final short ACCT_TIMER_VALUE = 0; - - /** - PDP host port - */ - private int _serverPort; - - /** - Client-type of connecting PEP - */ - private short _clientType; - - /** - Accounting timer (secs) - */ - private short _acctTimer; - - /** - Keep-alive timer (secs) - */ - private short _kaTimer; - - /** - Maps a PEP-ID to a connection - */ - private final Map _connectionMap; - // map < String(PEPID), COPSPdpOSConnection > ConnectionMap; - - /** - * Policy data processing object - */ - private COPSPdpOSDataProcess _process; - - /** - * Creates a PDP Agent - * - * @param clientType COPS Client-type - * @param process Object to perform policy data processing - */ - public COPSPdpOSAgent(short clientType, COPSPdpOSDataProcess process) { - _serverPort = WELL_KNOWN_PDP_PORT; - _kaTimer = KA_TIMER_VALUE; - _acctTimer = ACCT_TIMER_VALUE; - - _clientType = clientType; - _connectionMap = new ConcurrentHashMap<>(); - _process = process; - } - - /** - * Creates a PDP Agent - * - * @param port Port to listen to - * @param clientType COPS Client-type - * @param process Object to perform policy data processing - */ - public COPSPdpOSAgent(int port, short clientType, COPSPdpOSDataProcess process) { - _serverPort = port; - - _kaTimer = KA_TIMER_VALUE; - _acctTimer = ACCT_TIMER_VALUE; - - _clientType = clientType; - _connectionMap = new ConcurrentHashMap<>(); - _process = process; - } - - /** - * Sets the keep-alive timer value - * @param kaTimer Keep alive timer value (secs) - */ - public void setKaTimer (short kaTimer) { - _kaTimer = kaTimer; - } - - /** - * Sets the accounting timer value - * @param acctTimer Accounting timer value (secs) - */ - public void setAcctTimer (short acctTimer) { - _acctTimer = acctTimer; - } - - /** - * Gets the value of the keep-alive timer - * @return Keep-alive timer value (secs) - */ - public short getKaTimer () { - return _kaTimer; - } - - /** - * Gets the accounting timer value - * @return Accounting timer value (secs) - */ - public short getAcctTimer () { - return _acctTimer; - } - - /** - * Gets the client-type - * @return The client-type - */ - public short getClientType() { - return _clientType; - } - - /** - * Disconnects a PEP - * @param pepID PEP-ID of the PEP to be disconnected - * @param error COPS Error to be reported as a reason - * @throws COPSException - * @throws IOException - */ - public void disconnect (String pepID, COPSError error) throws COPSException, IOException { - COPSPdpOSConnection pdpConn = _connectionMap.get(pepID); - - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - if (error != null) - closeMsg.add(error); - - closeMsg.writeData(pdpConn.getSocket()); - pdpConn.close(); - } - - /** - * Requests a COPS sync for a PEP - * @param pepID PEP-ID of the PEP to be synced - * @throws COPSException - * @throws COPSPdpException - */ - public void sync(String pepID) throws COPSException, COPSPdpException { - COPSPdpOSConnection pdpConn = _connectionMap.get(pepID); - pdpConn.syncAllRequestState(); - } - - /** - * Removes a PEP from the connection map - * @param pepID PEP-ID of the PEP to be removed - */ - public void delete (String pepID) { - _connectionMap.remove(pepID); - } - - /** - * Runs the PDP process - */ - public void run() { - try { - final ServerSocket serverSocket = new ServerSocket (_serverPort); - - //Loop through for Incoming messages - - // server infinite loop - while (true) { - // Wait for an incoming connection from a PEP - Socket socket = serverSocket.accept(); - - // COPSDebug.out(getClass().getName(),"New connection accepted " + - // socket.getInetAddress() + - // ":" + socket.getPort()); - - // We're waiting for an OPN message - try { - COPSMsg msg = COPSTransceiver.receiveMsg(socket); - if (msg.getHeader().isAClientOpen()) { - handleClientOpenMsg(socket, msg); - } else { - // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG); - try { - socket.close(); - } catch (Exception ex) { - logger.error("Error closing socket", ex); - } - } - } catch (Exception e) { // COPSException, IOException - // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION, - // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e); - try { - socket.close(); - } catch (Exception ex) { - logger.error("Error closing socket", ex); - } - } - } - } catch (IOException e) { - logger.error("Error processing socket messages", e); - } - } - - /** - * Handles a COPS client-open message - * @param conn Socket to the PEP - * @param msg COPSMsg holding the client-open message - * @throws COPSException - * @throws IOException - */ - private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException { - COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg; - COPSPepId pepId = cMsg.getPepId(); - - // Validate Client Type - if (msg.getHeader().getClientType() != _clientType) { - // Unsupported client type - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing data", unae); - } - - throw new COPSException("Unsupported client type"); - } - - // PEPId is mandatory - if (pepId == null) { - // Mandatory COPS object missing - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing data", unae); - } - - throw new COPSException("Mandatory COPS object missing (PEPId)"); - } - - // Support - if ( (cMsg.getClientSI() != null) || - (cMsg.getPdpAddress() != null) || - (cMsg.getIntegrity() != null)) { - - // Unsupported objects - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing data", unae); - } - - throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)"); - } - - // Connection accepted - COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType()); - COPSKATimer katimer = new COPSKATimer(_kaTimer); - COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer); - COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg(); - acceptMsg.add(ahdr); - acceptMsg.add(katimer) ; - if (_acctTimer != 0) acceptMsg.add(acctTimer); - acceptMsg.writeData(conn); - - COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process); - pdpConn.setKaTimer(_kaTimer); - if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer); - new Thread(pdpConn).start(); - _connectionMap.put(pepId.getData().str(),pdpConn); - } -} +package org.umu.cops.ospdp; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSError.ErrorTypes; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Core PDP agent for outsourcing. + */ +public class COPSPdpOSAgent extends Thread { + + public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSAgent.class); + + /** Well-known port for COPS */ + public static final int WELL_KNOWN_PDP_PORT = 3288; + /** Default keep-alive timer value (secs) */ + public static final short KA_TIMER_VALUE = 30; + /** Default accounting timer value (secs) */ + public static final short ACCT_TIMER_VALUE = 0; + + /** + PDP host port + */ + private int _serverPort; + + /** + Client-type of connecting PEP + */ + private short _clientType; + + /** + Accounting timer (secs) + */ + private short _acctTimer; + + /** + Keep-alive timer (secs) + */ + private short _kaTimer; + + /** + Maps a PEP-ID to a connection + */ + private final Map _connectionMap; + // map < String(PEPID), COPSPdpOSConnection > ConnectionMap; + + /** + * Policy data processing object + */ + private COPSPdpOSDataProcess _process; + + /** + * Creates a PDP Agent + * + * @param clientType COPS Client-type + * @param process Object to perform policy data processing + */ + public COPSPdpOSAgent(short clientType, COPSPdpOSDataProcess process) { + _serverPort = WELL_KNOWN_PDP_PORT; + _kaTimer = KA_TIMER_VALUE; + _acctTimer = ACCT_TIMER_VALUE; + + _clientType = clientType; + _connectionMap = new ConcurrentHashMap<>(); + _process = process; + } + + /** + * Creates a PDP Agent + * + * @param port Port to listen to + * @param clientType COPS Client-type + * @param process Object to perform policy data processing + */ + public COPSPdpOSAgent(int port, short clientType, COPSPdpOSDataProcess process) { + _serverPort = port; + + _kaTimer = KA_TIMER_VALUE; + _acctTimer = ACCT_TIMER_VALUE; + + _clientType = clientType; + _connectionMap = new ConcurrentHashMap<>(); + _process = process; + } + + /** + * Sets the keep-alive timer value + * @param kaTimer Keep alive timer value (secs) + */ + public void setKaTimer (short kaTimer) { + _kaTimer = kaTimer; + } + + /** + * Sets the accounting timer value + * @param acctTimer Accounting timer value (secs) + */ + public void setAcctTimer (short acctTimer) { + _acctTimer = acctTimer; + } + + /** + * Gets the value of the keep-alive timer + * @return Keep-alive timer value (secs) + */ + public short getKaTimer () { + return _kaTimer; + } + + /** + * Gets the accounting timer value + * @return Accounting timer value (secs) + */ + public short getAcctTimer () { + return _acctTimer; + } + + /** + * Gets the client-type + * @return The client-type + */ + public short getClientType() { + return _clientType; + } + + /** + * Disconnects a PEP + * @param pepID PEP-ID of the PEP to be disconnected + * @param error COPS Error to be reported as a reason + * @throws COPSException + * @throws IOException + */ + public void disconnect (String pepID, COPSError error) throws COPSException, IOException { + COPSPdpOSConnection pdpConn = _connectionMap.get(pepID); + + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + if (error != null) + closeMsg.add(error); + + closeMsg.writeData(pdpConn.getSocket()); + pdpConn.close(); + } + + /** + * Requests a COPS sync for a PEP + * @param pepID PEP-ID of the PEP to be synced + * @throws COPSException + * @throws COPSPdpException + */ + public void sync(String pepID) throws COPSException, COPSPdpException { + COPSPdpOSConnection pdpConn = _connectionMap.get(pepID); + pdpConn.syncAllRequestState(); + } + + /** + * Removes a PEP from the connection map + * @param pepID PEP-ID of the PEP to be removed + */ + public void delete (String pepID) { + _connectionMap.remove(pepID); + } + + /** + * Runs the PDP process + */ + public void run() { + try { + final ServerSocket serverSocket = new ServerSocket (_serverPort); + + //Loop through for Incoming messages + + // server infinite loop + while (true) { + // Wait for an incoming connection from a PEP + Socket socket = serverSocket.accept(); + + // COPSDebug.out(getClass().getName(),"New connection accepted " + + // socket.getInetAddress() + + // ":" + socket.getPort()); + + // We're waiting for an OPN message + try { + COPSMsg msg = COPSTransceiver.receiveMsg(socket); + if (msg.getHeader().isAClientOpen()) { + handleClientOpenMsg(socket, msg); + } else { + // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG); + try { + socket.close(); + } catch (Exception ex) { + logger.error("Error closing socket", ex); + } + } + } catch (Exception e) { // COPSException, IOException + // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION, + // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e); + try { + socket.close(); + } catch (Exception ex) { + logger.error("Error closing socket", ex); + } + } + } + } catch (IOException e) { + logger.error("Error processing socket messages", e); + } + } + + /** + * Handles a COPS client-open message + * @param conn Socket to the PEP + * @param msg COPSMsg holding the client-open message + * @throws COPSException + * @throws IOException + */ + private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException { + COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg; + COPSPepId pepId = cMsg.getPepId(); + + // Validate Client Type + if (msg.getHeader().getClientType() != _clientType) { + // Unsupported client type + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing data", unae); + } + + throw new COPSException("Unsupported client type"); + } + + // PEPId is mandatory + if (pepId == null) { + // Mandatory COPS object missing + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing data", unae); + } + + throw new COPSException("Mandatory COPS object missing (PEPId)"); + } + + // Support + if ( (cMsg.getClientSI() != null) || + (cMsg.getPdpAddress() != null) || + (cMsg.getIntegrity() != null)) { + + // Unsupported objects + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing data", unae); + } + + throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)"); + } + + // Connection accepted + COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType()); + COPSKATimer katimer = new COPSKATimer(_kaTimer); + COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer); + COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg(); + acceptMsg.add(ahdr); + acceptMsg.add(katimer) ; + if (_acctTimer != 0) acceptMsg.add(acctTimer); + acceptMsg.writeData(conn); + + COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process); + pdpConn.setKaTimer(_kaTimer); + if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer); + new Thread(pdpConn).start(); + _connectionMap.put(pepId.getData().str(),pdpConn); + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSMsgSender.java b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSMsgSender.java index 25cacd6..711c4fe 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSMsgSender.java +++ b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSMsgSender.java @@ -1,280 +1,273 @@ -package org.umu.cops.ospdp; - -import org.umu.cops.stack.*; - -import java.io.IOException; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Vector; - -/** - * COPS message transceiver class for outsourcing connections at the PDP side. - * - * TODO - change all references of Vector to List<> - */ -public class COPSPdpOSMsgSender { - /** - * Socket connected to PEP - */ - protected Socket _sock; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Creates a COPSPepMsgSender - * - * @param clientType COPS client-type - * @param clientHandle Client handle - * @param sock Socket to the PEP - */ - public COPSPdpOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { - // COPS Handle - _handle = clientHandle; - _clientType = clientType; - - _sock = sock; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Sends a decision message which was requested by the PEP - * @param removeDecs Decisions to be removed - * @param installDecs Decisions to be installed - * @throws COPSPdpException - */ - public void sendSolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException { - sendDecision(removeDecs, installDecs, true); - } - - /** - * Sends a decision message which was not requested by the PEP - * @param removeDecs Decisions to be removed - * @param installDecs Decisions to be installed - * @throws COPSPdpException - */ - public void sendUnsolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException { - sendDecision(removeDecs, installDecs, false); - } - - /** - * Sends a decision message to the PEP - * @param removeDecs Decisions to be removed - * @param installDecs Decisions to be installed - * @param solicited true if the PEP requested this decision, false otherwise - * @throws COPSPdpException - */ - public void sendDecision(Vector removeDecs, Vector installDecs, boolean solicited) throws COPSPdpException { - // Common Header holding the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - if (solicited) - hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED); - - // Client Handle with the same clientHandle as the request - final COPSHandle handle = new COPSHandle(getClientHandle().getId()); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(handle); - - // Decisions (no flags supplied) - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - - // Remove Decisions - // - if (removeDecs.size() > 0) { - COPSDecision rdec1 = new COPSDecision(); - rdec1.setCmdCode(COPSDecision.DEC_REMOVE); - - decisionMsg.addDecision(rdec1, cntxt); - - Enumeration removeDecsEnum = removeDecs.elements(); - while (removeDecsEnum.hasMoreElements()) - decisionMsg.addDecision((COPSDecision) removeDecsEnum.nextElement(), cntxt); - } - - // Install Decisions - // - if (installDecs.size() > 0) { - COPSDecision idec1 = new COPSDecision(); - idec1.setCmdCode(COPSDecision.DEC_INSTALL); - - decisionMsg.addDecision(idec1, cntxt); - - Enumeration installDecsEnum = installDecs.elements(); - while (installDecsEnum.hasMoreElements()) - decisionMsg.addDecision((COPSDecision) installDecsEnum.nextElement(), cntxt); - /** - COPSIntegrity intr = new COPSIntegrity(); - intr.setKeyId(19); - intr.setSeqNum(9); - intr.setKeyDigest(new COPSData("KEY DIGEST")); - decisionMsg.add(intr); - /**/ - } - } catch (COPSException e) { - e.printStackTrace(); - throw new COPSPdpException("Error making Msg"); - } - - //** Send decision - //** - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); - } - } - - /**FIXME: unused? - * Sends a message asking that the request state be deleted - * @throws COPSPdpException - */ - public void sendDeleteRequestState() throws COPSPdpException { - /* ::= - * - * *() - * [] - * ::= - * - * ::= Remove Request-State - * - */ - - // Common Header with the same ClientType as the request (default UNSOLICITED) - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - // Decisions - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - // - COPSDecision dec = new COPSDecision(); - dec.setCmdCode(COPSDecision.DEC_REMOVE); - dec.setFlags(COPSDecision.F_REQSTATE); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(clienthandle); - decisionMsg.addDecision(dec, cntxt); - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); - } - } - - /** - * Method sendOpenNewRequestState - * - * @throws COPSPdpException - * - */ - //FIXME: Unused? - public void sendOpenNewRequestState() throws COPSPdpException { - /* ::= - * - * *() - * [] - * ::= - * - * ::= Install Request-State - * - */ - - // Common Header with the same ClientType as the request (default UNSOLICITED) - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - // Decisions - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - // - COPSDecision dec = new COPSDecision(); - dec.setCmdCode(COPSDecision.DEC_INSTALL); - dec.setFlags(COPSDecision.F_REQSTATE); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(clienthandle); - decisionMsg.addDecision(dec, cntxt); - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); - } - } - - /** - * Sends a message asking for a COPS sync operation - * @throws COPSPdpException - */ - public void sendSyncRequestState() - throws COPSPdpException { - /* ::= - * [] - * [] - */ - - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - COPSSyncStateMsg msg = new COPSSyncStateMsg(); - try { - msg.add(hdr); - msg.add(clienthandle); - } catch (Exception e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage()); - } - } - -} +package org.umu.cops.ospdp; + +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; + +import java.io.IOException; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Vector; + +/** + * COPS message transceiver class for outsourcing connections at the PDP side. + * + * TODO - change all references of Vector to List<> + */ +public class COPSPdpOSMsgSender { + /** + * Socket connected to PEP + */ + protected Socket _sock; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Creates a COPSPepMsgSender + * + * @param clientType COPS client-type + * @param clientHandle Client handle + * @param sock Socket to the PEP + */ + public COPSPdpOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { + // COPS Handle + _handle = clientHandle; + _clientType = clientType; + + _sock = sock; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Sends a decision message which was requested by the PEP + * @param removeDecs Decisions to be removed + * @param installDecs Decisions to be installed + * @throws COPSPdpException + */ + public void sendSolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException { + sendDecision(removeDecs, installDecs, true); + } + + /** + * Sends a decision message which was not requested by the PEP + * @param removeDecs Decisions to be removed + * @param installDecs Decisions to be installed + * @throws COPSPdpException + */ + public void sendUnsolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException { + sendDecision(removeDecs, installDecs, false); + } + + /** + * Sends a decision message to the PEP + * @param removeDecs Decisions to be removed + * @param installDecs Decisions to be installed + * @param solicited true if the PEP requested this decision, false otherwise + * @throws COPSPdpException + */ + public void sendDecision(Vector removeDecs, Vector installDecs, boolean solicited) throws COPSPdpException { + // Common Header holding the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + if (solicited) + hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED); + + // Client Handle with the same clientHandle as the request + final COPSHandle handle = new COPSHandle(getClientHandle().getId()); + + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(handle); + + // Decisions (no flags supplied) + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + + // Remove Decisions + // + if (removeDecs.size() > 0) { + COPSDecision rdec1 = new COPSDecision(Command.REMOVE); + decisionMsg.addDecision(rdec1, cntxt); + + Enumeration removeDecsEnum = removeDecs.elements(); + while (removeDecsEnum.hasMoreElements()) + decisionMsg.addDecision((COPSDecision) removeDecsEnum.nextElement(), cntxt); + } + + // Install Decisions + // + if (installDecs.size() > 0) { + COPSDecision idec1 = new COPSDecision(Command.INSTALL); + decisionMsg.addDecision(idec1, cntxt); + + Enumeration installDecsEnum = installDecs.elements(); + while (installDecsEnum.hasMoreElements()) + decisionMsg.addDecision((COPSDecision) installDecsEnum.nextElement(), cntxt); + /** + COPSIntegrity intr = new COPSIntegrity(); + intr.setKeyId(19); + intr.setSeqNum(9); + intr.setKeyDigest(new COPSData("KEY DIGEST")); + decisionMsg.add(intr); + /**/ + } + } catch (COPSException e) { + e.printStackTrace(); + throw new COPSPdpException("Error making Msg"); + } + + //** Send decision + //** + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); + } + } + + /**FIXME: unused? + * Sends a message asking that the request state be deleted + * @throws COPSPdpException + */ + public void sendDeleteRequestState() throws COPSPdpException { + /* ::= + * + * *() + * [] + * ::= + * + * ::= Remove Request-State + * + */ + + // Common Header with the same ClientType as the request (default UNSOLICITED) + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + // Decisions + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + // + COPSDecision dec = new COPSDecision(Command.REMOVE, DecisionFlag.REQSTATE); + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(clienthandle); + decisionMsg.addDecision(dec, cntxt); + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); + } + } + + /** + * Method sendOpenNewRequestState + * + * @throws COPSPdpException + * + */ + //FIXME: Unused? + public void sendOpenNewRequestState() throws COPSPdpException { + /* ::= + * + * *() + * [] + * ::= + * + * ::= Install Request-State + * + */ + + // Common Header with the same ClientType as the request (default UNSOLICITED) + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + // Decisions + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + // + COPSDecision dec = new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE); + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(clienthandle); + decisionMsg.addDecision(dec, cntxt); + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); + } + } + + /** + * Sends a message asking for a COPS sync operation + * @throws COPSPdpException + */ + public void sendSyncRequestState() + throws COPSPdpException { + /* ::= + * [] + * [] + */ + + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + COPSSyncStateMsg msg = new COPSSyncStateMsg(); + try { + msg.add(hdr); + msg.add(clienthandle); + } catch (Exception e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage()); + } + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSReqStateMan.java b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSReqStateMan.java index 855a14c..2fcc99f 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSReqStateMan.java +++ b/packetcable-driver/src/main/java/org/umu/cops/ospdp/COPSPdpOSReqStateMan.java @@ -1,298 +1,302 @@ -package org.umu.cops.ospdp; - -import org.umu.cops.stack.*; - -import java.net.Socket; -import java.util.Vector; - -/** - * State manager class for outsourcing requests, at the PDP side. - */ -public class COPSPdpOSReqStateMan { - /** - * Request State created - */ - public final static short ST_CREATE = 1; - /** - * Request received - */ - public final static short ST_INIT = 2; - /** - * Decisions sent - */ - public final static short ST_DECS = 3; - /** - * Report received - */ - public final static short ST_REPORT = 4; - /** - * Request state finalized - */ - public final static short ST_FINAL = 5; - /** - * New request state solicited - */ - public final static short ST_NEW = 6; - /** - * Delete request state solicited - */ - public final static short ST_DEL = 7; - /** - * SYNC request sent - */ - public final static short ST_SYNC = 8; - /** - * SYNC completed - */ - public final static short ST_SYNCALL = 9; - /** - * Close connection received - */ - public final static short ST_CCONN = 10; - /** - * Keep-alive timeout - */ - public final static short ST_NOKA = 11; - /** - * Accounting timeout - */ - public final static short ST_ACCT = 12; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Object for performing policy data processing - */ - protected COPSPdpOSDataProcess _process; - - /** - * Current state of the request being managed - */ - protected short _status; - - /** COPS message transceiver used to send COPS messages */ - protected COPSPdpOSMsgSender _sender; - - /** - * Creates a request state manager - * @param clientType Client-type - * @param clientHandle Client handle - */ - public COPSPdpOSReqStateMan(short clientType, String clientHandle) { - _handle = new COPSHandle(new COPSData(clientHandle)); - _clientType = clientType; - _status = ST_CREATE; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Gets the status of the request - * @return Request state value - */ - public short getStatus() { - return _status; - } - - /** - * Gets the policy data processing object - * @return Policy data processing object - */ - public COPSPdpOSDataProcess getDataProcess() { - return _process; - } - - /** - * Sets the policy data processing object - * @param process Policy data processing object - */ - public void setDataProcess(COPSPdpOSDataProcess process) { - _process = process; - } - - /** - * Called when COPS sync is completed - * @param repMsg COPS sync message - * @throws COPSPdpException - */ - protected void processSyncComplete(COPSSyncStateMsg repMsg) - throws COPSPdpException { - - _status = ST_SYNCALL; - - // maybe we should notifySyncComplete ... - } - - /** - * Initializes a new request state over a socket - * @param sock Socket to the PEP - * @throws COPSPdpException - */ - protected void initRequestState(Socket sock) - throws COPSPdpException { - // Inits an object for sending COPS messages to the PDP - _sender = new COPSPdpOSMsgSender(_clientType, _handle, sock); - - // Initial state - _status = ST_INIT; - } - - /** - * Processes a COPS request - * @param msg COPS request received from the PEP - * @throws COPSPdpException - */ - protected void processRequest(COPSReqMsg msg) throws COPSPdpException { - Vector clientSIs = msg.getClientSI(); - - //** Here we must retrieve a decision depending on the - //** supplied ClientSIs - /*Vector removeDecs = new Vector(); - Vector installDecs = new Vector();*/ - _process.setClientData(this, clientSIs); - - Vector removeDecs = _process.getRemovePolicy(this); - Vector installDecs = _process.getInstallPolicy(this); - - //** We create a SOLICITED decision - //** - _sender.sendSolicitedDecision(removeDecs, installDecs); - _status = ST_DECS; - } - - /** - * Processes a report - * @param msg Report message from the PEP - * @throws COPSPdpException - */ - protected void processReport(COPSReportMsg msg) throws COPSPdpException { - //** Analyze the report - //** - - /* - * ::= - * - * - * *() - * [] - * ::= <[] *()> - * ::= *() - * - * Important, is not parsed - */ - - // COPSHeader hdrmsg = msg.getHeader(); - // COPSHandle handlemsg = msg.getClientHandle(); - - // Report Type - COPSReportType rtypemsg = msg.getReport(); - - // Named ClientSI - Vector clientSIs = msg.getClientSI(); - - //** We should act here in accordance with - //** the received report - if (rtypemsg.isSuccess()) { - _status = ST_REPORT; - _process.successReport(this, clientSIs); - } else if (rtypemsg.isFailure()) { - _status = ST_REPORT; - _process.failReport(this, clientSIs); - } else if (rtypemsg.isAccounting()) { - _status = ST_ACCT; - _process.acctReport(this, clientSIs); - } - } - - /** - * Called when connection is closed - * @param error Reason - * @throws COPSPdpException - */ - protected void processClosedConnection(COPSError error) - throws COPSPdpException { - if (_process != null) - _process.notifyClosedConnection(this, error); - - _status = ST_CCONN; - } - - /** - * Called when no keep-alive is received - * @throws COPSPdpException - */ - protected void processNoKAConnection() - throws COPSPdpException { - if (_process != null) - _process.notifyNoKAliveReceived(this); - - _status = ST_NOKA; - } - - /** - * Deletes the request state - * @throws COPSPdpException - */ - protected void finalizeRequestState() - throws COPSPdpException { - _sender.sendDeleteRequestState(); - _status = ST_FINAL; - } - - /** - * Asks for a COPS sync - * @throws COPSPdpException - */ - protected void syncRequestState() - throws COPSPdpException { - _sender.sendSyncRequestState(); - _status = ST_SYNC; - } - - /** - * Opens a new request state - * @throws COPSPdpException - */ - protected void openNewRequestState()//FIXME: unused? - throws COPSPdpException { - _sender.sendOpenNewRequestState(); - _status = ST_NEW; - } - - /** - * Processes a COPS delete message - * @param dMsg COPSDeleteMsg received from the PEP - * @throws COPSPdpException - */ - protected void processDeleteRequestState(COPSDeleteMsg dMsg) - throws COPSPdpException { - if (_process != null) - _process.closeRequestState(this); - - _status = ST_DEL; - } - -} +package org.umu.cops.ospdp; + +import org.umu.cops.stack.*; + +import java.net.Socket; +import java.util.Vector; + +/** + * State manager class for outsourcing requests, at the PDP side. + */ +public class COPSPdpOSReqStateMan { + /** + * Request State created + */ + public final static short ST_CREATE = 1; + /** + * Request received + */ + public final static short ST_INIT = 2; + /** + * Decisions sent + */ + public final static short ST_DECS = 3; + /** + * Report received + */ + public final static short ST_REPORT = 4; + /** + * Request state finalized + */ + public final static short ST_FINAL = 5; + /** + * New request state solicited + */ + public final static short ST_NEW = 6; + /** + * Delete request state solicited + */ + public final static short ST_DEL = 7; + /** + * SYNC request sent + */ + public final static short ST_SYNC = 8; + /** + * SYNC completed + */ + public final static short ST_SYNCALL = 9; + /** + * Close connection received + */ + public final static short ST_CCONN = 10; + /** + * Keep-alive timeout + */ + public final static short ST_NOKA = 11; + /** + * Accounting timeout + */ + public final static short ST_ACCT = 12; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Object for performing policy data processing + */ + protected COPSPdpOSDataProcess _process; + + /** + * Current state of the request being managed + */ + protected short _status; + + /** COPS message transceiver used to send COPS messages */ + protected COPSPdpOSMsgSender _sender; + + /** + * Creates a request state manager + * @param clientType Client-type + * @param clientHandle Client handle + */ + public COPSPdpOSReqStateMan(short clientType, String clientHandle) { + _handle = new COPSHandle(new COPSData(clientHandle)); + _clientType = clientType; + _status = ST_CREATE; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Gets the status of the request + * @return Request state value + */ + public short getStatus() { + return _status; + } + + /** + * Gets the policy data processing object + * @return Policy data processing object + */ + public COPSPdpOSDataProcess getDataProcess() { + return _process; + } + + /** + * Sets the policy data processing object + * @param process Policy data processing object + */ + public void setDataProcess(COPSPdpOSDataProcess process) { + _process = process; + } + + /** + * Called when COPS sync is completed + * @param repMsg COPS sync message + * @throws COPSPdpException + */ + protected void processSyncComplete(COPSSyncStateMsg repMsg) + throws COPSPdpException { + + _status = ST_SYNCALL; + + // maybe we should notifySyncComplete ... + } + + /** + * Initializes a new request state over a socket + * @param sock Socket to the PEP + * @throws COPSPdpException + */ + protected void initRequestState(Socket sock) + throws COPSPdpException { + // Inits an object for sending COPS messages to the PDP + _sender = new COPSPdpOSMsgSender(_clientType, _handle, sock); + + // Initial state + _status = ST_INIT; + } + + /** + * Processes a COPS request + * @param msg COPS request received from the PEP + * @throws COPSPdpException + */ + protected void processRequest(COPSReqMsg msg) throws COPSPdpException { + Vector clientSIs = msg.getClientSI(); + + //** Here we must retrieve a decision depending on the + //** supplied ClientSIs + /*Vector removeDecs = new Vector(); + Vector installDecs = new Vector();*/ + _process.setClientData(this, clientSIs); + + Vector removeDecs = _process.getRemovePolicy(this); + Vector installDecs = _process.getInstallPolicy(this); + + //** We create a SOLICITED decision + //** + _sender.sendSolicitedDecision(removeDecs, installDecs); + _status = ST_DECS; + } + + /** + * Processes a report + * @param msg Report message from the PEP + * @throws COPSPdpException + */ + protected void processReport(COPSReportMsg msg) throws COPSPdpException { + //** Analyze the report + //** + + /* + * ::= + * + * + * *() + * [] + * ::= <[] *()> + * ::= *() + * + * Important, is not parsed + */ + + // COPSHeader hdrmsg = msg.getHeader(); + // COPSHandle handlemsg = msg.getClientHandle(); + + // Report Type + COPSReportType rtypemsg = msg.getReport(); + + // Named ClientSI + Vector clientSIs = msg.getClientSI(); + + //** We should act here in accordance with + //** the received report + switch (rtypemsg.getReportType()) { + case SUCCESS: + _status = ST_REPORT; + _process.successReport(this, clientSIs); + break; + case FAILURE: + _status = ST_REPORT; + _process.failReport(this, clientSIs); + break; + case ACCOUNTING: + _status = ST_ACCT; + _process.acctReport(this, clientSIs); + break; + } + } + + /** + * Called when connection is closed + * @param error Reason + * @throws COPSPdpException + */ + protected void processClosedConnection(COPSError error) + throws COPSPdpException { + if (_process != null) + _process.notifyClosedConnection(this, error); + + _status = ST_CCONN; + } + + /** + * Called when no keep-alive is received + * @throws COPSPdpException + */ + protected void processNoKAConnection() + throws COPSPdpException { + if (_process != null) + _process.notifyNoKAliveReceived(this); + + _status = ST_NOKA; + } + + /** + * Deletes the request state + * @throws COPSPdpException + */ + protected void finalizeRequestState() + throws COPSPdpException { + _sender.sendDeleteRequestState(); + _status = ST_FINAL; + } + + /** + * Asks for a COPS sync + * @throws COPSPdpException + */ + protected void syncRequestState() + throws COPSPdpException { + _sender.sendSyncRequestState(); + _status = ST_SYNC; + } + + /** + * Opens a new request state + * @throws COPSPdpException + */ + protected void openNewRequestState()//FIXME: unused? + throws COPSPdpException { + _sender.sendOpenNewRequestState(); + _status = ST_NEW; + } + + /** + * Processes a COPS delete message + * @param dMsg COPSDeleteMsg received from the PEP + * @throws COPSPdpException + */ + protected void processDeleteRequestState(COPSDeleteMsg dMsg) + throws COPSPdpException { + if (_process != null) + _process.closeRequestState(this); + + _status = ST_DEL; + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSAgent.java b/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSAgent.java index 4cd8256..57fc78b 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSAgent.java +++ b/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSAgent.java @@ -7,7 +7,6 @@ import org.umu.cops.stack.*; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; -import java.net.UnknownHostException; import java.util.Hashtable; import java.util.Vector; @@ -244,20 +243,17 @@ public class COPSPepOSAgent { * * Not send [], [] * - * @throws UnknownHostException * @throws IOException * @throws COPSException * @throws COPSPepException * */ - private COPSPepOSConnection processConnection(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException { + private COPSPepOSConnection processConnection(String psHost, int psPort) throws IOException, COPSException, + COPSPepException { // Build OPN COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType); - COPSPepId pepId = new COPSPepId(); - COPSData d = new COPSData(_pepID); - pepId.setData(d); - + COPSPepId pepId = new COPSPepId(new COPSData(_pepID)); COPSClientOpenMsg msg = new COPSClientOpenMsg(); msg.add(hdr); msg.add(pepId); diff --git a/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSMsgSender.java b/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSMsgSender.java index 2f8526e..eab6ce5 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSMsgSender.java +++ b/packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSMsgSender.java @@ -1,261 +1,254 @@ -package org.umu.cops.ospep; - -import java.io.IOException; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Vector; - -import org.umu.cops.stack.COPSClientSI; -import org.umu.cops.stack.COPSContext; -import org.umu.cops.stack.COPSDeleteMsg; -import org.umu.cops.stack.COPSException; -import org.umu.cops.stack.COPSHandle; -import org.umu.cops.stack.COPSHeader; -import org.umu.cops.stack.COPSReason; -import org.umu.cops.stack.COPSReportMsg; -import org.umu.cops.stack.COPSReportType; -import org.umu.cops.stack.COPSReqMsg; -import org.umu.cops.stack.COPSSyncStateMsg; - -/** - * COPS message transceiver class for outsourcing connections at the PEP side. - */ -public class COPSPepOSMsgSender { - /** - * Socket connection to PDP - */ - protected Socket _sock; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Creates a COPSPepMsgSender - * - * @param clientType Client-type - * @param clientHandle Client handle - * @param sock Socket connected to the PDP - */ - public COPSPepOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { - // COPS Handle - _handle = clientHandle; - _clientType = clientType; - - _sock = sock; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Sends a request to the PDP. - * The PEP establishes a request state client handle for which the - * remote PDP may maintain state. - * @param clientSIs Client data - * @throws COPSPepException - */ - public void sendRequest(Vector clientSIs) throws COPSPepException { - // Create COPS Message - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType); - - COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0); - - COPSHandle handle = _handle; - - COPSReqMsg msg = new COPSReqMsg(); - try { - msg.add(hdr) ; - msg.add(handle) ; - msg.add(cntxt) ; - - Enumeration clientSIEnum = clientSIs.elements(); - while (clientSIEnum.hasMoreElements()) - msg.add( (COPSClientSI) clientSIEnum.nextElement()); - } catch (COPSException e) { - throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage()); - } - - // Send message - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the request, reason: " + e.getMessage()); - } - } - - /** - * Sends a failure report to the PDP. This report message notifies the PDP - * of failure when carrying out the PDP's decision, or when reporting - * an accounting related state change. - * @param clientSIs Report data - * @throws COPSPepException - */ - public void sendFailReport(Vector clientSIs) throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report FAIL - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.FAILURE); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - - Enumeration clientSIEnum = clientSIs.elements(); - while (clientSIEnum.hasMoreElements()) - msg.add( (COPSClientSI) clientSIEnum.nextElement()); - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - /** - * Sends a success report to the PDP. This report message notifies the PDP - * of success when carrying out the PDP's decision, or when reporting - * an accounting related state change. - * @param clientSIs Report data - * @throws COPSPepException - */ - public void sendSuccessReport(Vector clientSIs) throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report SUCESS - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.SUCCESS); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - - Enumeration clientSIEnum = clientSIs.elements(); - while (clientSIEnum.hasMoreElements()) - msg.add( (COPSClientSI) clientSIEnum.nextElement()); - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - /** - * Sends an accounting report to the PDP - * @param clientSIs Report data - * @throws COPSPepException - */ - public void sendAcctReport(Vector clientSIs) throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report SUCCESS - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.ACCT); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - - Enumeration clientSIEnum = clientSIs.elements(); - while (clientSIEnum.hasMoreElements()) - msg.add( (COPSClientSI) clientSIEnum.nextElement()); - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - /** - * Sends a sync-complete message to the PDP. This indicates the - * end of a synchronization requested by the PDP. - * @throws COPSPepException - */ - public void sendSyncComplete() throws COPSPepException { - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType); - - // Client Handle with the same clientHandle as the request - COPSHandle clienthandle = _handle; - - COPSSyncStateMsg msg = new COPSSyncStateMsg(); - try { - msg.add(hdr); - msg.add(clienthandle); - } catch (Exception e) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage()); - } - } - - /** - * Sends a delete request to the PDP. - * When sent from the PEP this message indicates to the remote PDP that - * the state identified by the client handle is no longer - * available/relevant. - * @throws COPSPepException - */ - public void sendDeleteRequest() throws COPSPepException { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType); - COPSHandle handle = _handle; - - // *** TODO: use real reason codes - COPSReason reason = new COPSReason((short) 234, (short) 345); - - COPSDeleteMsg msg = new COPSDeleteMsg(); - try { - msg.add(hdr); - msg.add(handle); - msg.add(reason); - msg.writeData(_sock); - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } catch (IOException e) { - throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage()); - } - } - -} +package org.umu.cops.ospep; + +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSReason.ReasonCode; +import org.umu.cops.stack.COPSReportType.ReportType; + +import java.io.IOException; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Vector; + +/** + * COPS message transceiver class for outsourcing connections at the PEP side. + */ +public class COPSPepOSMsgSender { + /** + * Socket connection to PDP + */ + protected Socket _sock; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Creates a COPSPepMsgSender + * + * @param clientType Client-type + * @param clientHandle Client handle + * @param sock Socket connected to the PDP + */ + public COPSPepOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { + // COPS Handle + _handle = clientHandle; + _clientType = clientType; + + _sock = sock; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Sends a request to the PDP. + * The PEP establishes a request state client handle for which the + * remote PDP may maintain state. + * @param clientSIs Client data + * @throws COPSPepException + */ + public void sendRequest(Vector clientSIs) throws COPSPepException { + // Create COPS Message + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType); + + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + + COPSHandle handle = _handle; + + COPSReqMsg msg = new COPSReqMsg(); + try { + msg.add(hdr) ; + msg.add(handle) ; + msg.add(cntxt) ; + + Enumeration clientSIEnum = clientSIs.elements(); + while (clientSIEnum.hasMoreElements()) + msg.add( (COPSClientSI) clientSIEnum.nextElement()); + } catch (COPSException e) { + throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage()); + } + + // Send message + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the request, reason: " + e.getMessage()); + } + } + + /** + * Sends a failure report to the PDP. This report message notifies the PDP + * of failure when carrying out the PDP's decision, or when reporting + * an accounting related state change. + * @param clientSIs Report data + * @throws COPSPepException + */ + public void sendFailReport(Vector clientSIs) throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report FAIL + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.FAILURE); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + + Enumeration clientSIEnum = clientSIs.elements(); + while (clientSIEnum.hasMoreElements()) + msg.add( (COPSClientSI) clientSIEnum.nextElement()); + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + /** + * Sends a success report to the PDP. This report message notifies the PDP + * of success when carrying out the PDP's decision, or when reporting + * an accounting related state change. + * @param clientSIs Report data + * @throws COPSPepException + */ + public void sendSuccessReport(Vector clientSIs) throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report SUCESS + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.SUCCESS); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + + Enumeration clientSIEnum = clientSIs.elements(); + while (clientSIEnum.hasMoreElements()) + msg.add( (COPSClientSI) clientSIEnum.nextElement()); + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + /** + * Sends an accounting report to the PDP + * @param clientSIs Report data + * @throws COPSPepException + */ + public void sendAcctReport(Vector clientSIs) throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report SUCCESS + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.ACCOUNTING); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + + Enumeration clientSIEnum = clientSIs.elements(); + while (clientSIEnum.hasMoreElements()) + msg.add( (COPSClientSI) clientSIEnum.nextElement()); + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + /** + * Sends a sync-complete message to the PDP. This indicates the + * end of a synchronization requested by the PDP. + * @throws COPSPepException + */ + public void sendSyncComplete() throws COPSPepException { + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType); + + // Client Handle with the same clientHandle as the request + COPSHandle clienthandle = _handle; + + COPSSyncStateMsg msg = new COPSSyncStateMsg(); + try { + msg.add(hdr); + msg.add(clienthandle); + } catch (Exception e) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage()); + } + } + + /** + * Sends a delete request to the PDP. + * When sent from the PEP this message indicates to the remote PDP that + * the state identified by the client handle is no longer + * available/relevant. + * @throws COPSPepException + */ + public void sendDeleteRequest() throws COPSPepException { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType); + COPSHandle handle = _handle; + + // *** TODO: use real reason codes + COPSReason reason = new COPSReason(ReasonCode.NA, ReasonCode.NA); + + COPSDeleteMsg msg = new COPSDeleteMsg(); + try { + msg.add(hdr); + msg.add(handle); + msg.add(reason); + msg.writeData(_sock); + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } catch (IOException e) { + throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage()); + } + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpAgent.java b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpAgent.java index be17440..3e4d1c4 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpAgent.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpAgent.java @@ -1,324 +1,325 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpdp; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.umu.cops.stack.*; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.Hashtable; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * Core PDP agent for provisioning - */ -public class COPSPdpAgent extends Thread { - - public final static Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class); - - /** Well-known port for COPS */ - public static final int WELL_KNOWN_PDP_PORT = 3288; - /** Default keep-alive timer value (secs) */ - public static final short KA_TIMER_VALUE = 30; - /** Default accounting timer value (secs) */ - public static final short ACCT_TIMER_VALUE = 0; - - /** - PDP host port - */ - private int _serverPort; - - /** - Client-type of connecting PEP - */ - private short _clientType; - - /** - Accounting timer (secs) - */ - private short _acctTimer; - - /** - Keep-alive timer (secs) - */ - private short _kaTimer; - - /** - Maps a PEP-ID to a connection - */ - private final Map _connectionMap; - // map < String(PEPID), COPSPdpConnection > ConnectionMap; - - /** - * Policy data processing object - */ - private COPSPdpDataProcess _process; - - /** - * Creates a PDP Agent - * - * @param clientType COPS Client-type - * @param process Object to perform policy data processing - */ - public COPSPdpAgent(short clientType, COPSPdpDataProcess process) { - _serverPort = WELL_KNOWN_PDP_PORT; - _kaTimer = KA_TIMER_VALUE; - _acctTimer = ACCT_TIMER_VALUE; - - _clientType = clientType; - _connectionMap = new ConcurrentHashMap<>(); - _process = process; - } - - /** - * Creates a PDP Agent - * - * @param port Port to listen to - * @param clientType COPS Client-type - * @param process Object to perform policy data processing - */ - public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) { - _serverPort = port; - - _kaTimer = KA_TIMER_VALUE; - _acctTimer = ACCT_TIMER_VALUE; - - _clientType = clientType; - _connectionMap = new ConcurrentHashMap<>(); - _process = process; - } - - /** - * Sets the keep-alive timer value - * @param kaTimer Keep alive timer value (secs) - */ - public void setKaTimer (short kaTimer) { - _kaTimer = kaTimer; - } - - /** - * Sets the accounting timer value - * @param acctTimer Accounting timer value (secs) - */ - public void setAcctTimer (short acctTimer) { - _acctTimer = acctTimer; - } - - /** - * Gets the value of the keep-alive timer - * @return Keep-alive timer value (secs) - */ - public short getKaTimer () { - return _kaTimer; - } - - /** - * Gets the accounting timer value - * @return Accounting timer value (secs) - */ - public short getAcctTimer () { - return _acctTimer; - } - - /** - * Gets the connection map - * @return A Hashtable holding the connection map - */ - public Hashtable getConnectionMap() { - return new Hashtable(_connectionMap); - } - - /** - * Gets the client-type - * @return The client-type - */ - public short getClientType() { - return _clientType; - } - - /** - * Disconnects a PEP - * @param pepID PEP-ID of the PEP to be disconnected - * @param error COPS Error to be reported as a reason - * @throws COPSException - * @throws IOException - */ - public void disconnect (String pepID, COPSError error) - throws COPSException, IOException { - - COPSPdpConnection pdpConn = _connectionMap.get(pepID); - - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - if (error != null) - closeMsg.add(error); - - closeMsg.writeData(pdpConn.getSocket()); - pdpConn.close(); - } - - /** - * Requests a COPS sync for a PEP - * @param pepID PEP-ID of the PEP to be synced - * @throws COPSException - * @throws COPSPdpException - */ - public void sync (String pepID) - throws COPSException, COPSPdpException { - - COPSPdpConnection pdpConn = _connectionMap.get(pepID); - pdpConn.syncAllRequestState(); - } - - /** - * Removes a PEP from the connection map - * @param pepID PEP-ID of the PEP to be removed - */ - public void delete (String pepID) { - _connectionMap.remove(pepID); - } - - - /** - * Runs the PDP process - */ - public void run() { - try { - final ServerSocket serverSocket = new ServerSocket (_serverPort); - - //Loop through for Incoming messages - - // server infinite loop - while (true) { - - // Wait for an incoming connection from a PEP - Socket socket = serverSocket.accept(); - - // COPSDebug.out(getClass().getName(),"New connection accepted " + - // socket.getInetAddress() + - // ":" + socket.getPort()); - - // We're waiting for an OPN message - try { - COPSMsg msg = COPSTransceiver.receiveMsg(socket); - if (msg.getHeader().isAClientOpen()) { - handleClientOpenMsg(socket, msg); - } else { - // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG); - try { - socket.close(); - } catch (Exception ex) { - logger.error("Error closing socket", ex); - } - } - } catch (Exception e) { // COPSException, IOException - // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION, - // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e); - try { - socket.close(); - } catch (Exception ex) { - logger.error("Error closing socket", ex); - } - } - } - } catch (IOException e) { - logger.error("Error caught while processing socket messages", e); - } - } - - /** - * Handles a COPS client-open message - * @param conn Socket to the PEP - * @param msg COPSMsg holding the client-open message - * @throws COPSException - * @throws IOException - */ - private void handleClientOpenMsg(Socket conn, COPSMsg msg) - throws COPSException, IOException { - COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg; - COPSPepId pepId = cMsg.getPepId(); - - // Validate Client Type - if (msg.getHeader().getClientType() != _clientType) { - // Unsupported client type - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing COPS data", unae); - } - - throw new COPSException("Unsupported client type"); - } - - // PEPId is mandatory - if (pepId == null) { - // Mandatory COPS object missing - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing close message", unae); - } - - throw new COPSException("Mandatory COPS object missing (PEPId)"); - } - - // Support - if ( (cMsg.getClientSI() != null) || - (cMsg.getPdpAddress() != null) || - (cMsg.getIntegrity() != null)) { - - // Unsupported objects - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); - COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - closeMsg.add(err); - try { - closeMsg.writeData(conn); - } catch (IOException unae) { - logger.error("Error writing close message", unae); - } - - throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)"); - } - - // Connection accepted - COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType()); - COPSKATimer katimer = new COPSKATimer(_kaTimer); - COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer); - COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg(); - acceptMsg.add(ahdr); - acceptMsg.add(katimer) ; - if (_acctTimer != 0) acceptMsg.add(acctTimer); - acceptMsg.writeData(conn); - - COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process); - pdpConn.setKaTimer(_kaTimer); - if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer); - new Thread(pdpConn).start(); - _connectionMap.put(pepId.getData().str(),pdpConn); - } - -} - - - +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpdp; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSError.ErrorTypes; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Core PDP agent for provisioning + */ +public class COPSPdpAgent extends Thread { + + public final static Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class); + + /** Well-known port for COPS */ + public static final int WELL_KNOWN_PDP_PORT = 3288; + /** Default keep-alive timer value (secs) */ + public static final short KA_TIMER_VALUE = 30; + /** Default accounting timer value (secs) */ + public static final short ACCT_TIMER_VALUE = 0; + + /** + PDP host port + */ + private int _serverPort; + + /** + Client-type of connecting PEP + */ + private short _clientType; + + /** + Accounting timer (secs) + */ + private short _acctTimer; + + /** + Keep-alive timer (secs) + */ + private short _kaTimer; + + /** + Maps a PEP-ID to a connection + */ + private final Map _connectionMap; + // map < String(PEPID), COPSPdpConnection > ConnectionMap; + + /** + * Policy data processing object + */ + private COPSPdpDataProcess _process; + + /** + * Creates a PDP Agent + * + * @param clientType COPS Client-type + * @param process Object to perform policy data processing + */ + public COPSPdpAgent(short clientType, COPSPdpDataProcess process) { + _serverPort = WELL_KNOWN_PDP_PORT; + _kaTimer = KA_TIMER_VALUE; + _acctTimer = ACCT_TIMER_VALUE; + + _clientType = clientType; + _connectionMap = new ConcurrentHashMap<>(); + _process = process; + } + + /** + * Creates a PDP Agent + * + * @param port Port to listen to + * @param clientType COPS Client-type + * @param process Object to perform policy data processing + */ + public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) { + _serverPort = port; + + _kaTimer = KA_TIMER_VALUE; + _acctTimer = ACCT_TIMER_VALUE; + + _clientType = clientType; + _connectionMap = new ConcurrentHashMap<>(); + _process = process; + } + + /** + * Sets the keep-alive timer value + * @param kaTimer Keep alive timer value (secs) + */ + public void setKaTimer (short kaTimer) { + _kaTimer = kaTimer; + } + + /** + * Sets the accounting timer value + * @param acctTimer Accounting timer value (secs) + */ + public void setAcctTimer (short acctTimer) { + _acctTimer = acctTimer; + } + + /** + * Gets the value of the keep-alive timer + * @return Keep-alive timer value (secs) + */ + public short getKaTimer () { + return _kaTimer; + } + + /** + * Gets the accounting timer value + * @return Accounting timer value (secs) + */ + public short getAcctTimer () { + return _acctTimer; + } + + /** + * Gets the connection map + * @return A Hashtable holding the connection map + */ + public Hashtable getConnectionMap() { + return new Hashtable(_connectionMap); + } + + /** + * Gets the client-type + * @return The client-type + */ + public short getClientType() { + return _clientType; + } + + /** + * Disconnects a PEP + * @param pepID PEP-ID of the PEP to be disconnected + * @param error COPS Error to be reported as a reason + * @throws COPSException + * @throws IOException + */ + public void disconnect (String pepID, COPSError error) + throws COPSException, IOException { + + COPSPdpConnection pdpConn = _connectionMap.get(pepID); + + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + if (error != null) + closeMsg.add(error); + + closeMsg.writeData(pdpConn.getSocket()); + pdpConn.close(); + } + + /** + * Requests a COPS sync for a PEP + * @param pepID PEP-ID of the PEP to be synced + * @throws COPSException + * @throws COPSPdpException + */ + public void sync (String pepID) + throws COPSException, COPSPdpException { + + COPSPdpConnection pdpConn = _connectionMap.get(pepID); + pdpConn.syncAllRequestState(); + } + + /** + * Removes a PEP from the connection map + * @param pepID PEP-ID of the PEP to be removed + */ + public void delete (String pepID) { + _connectionMap.remove(pepID); + } + + + /** + * Runs the PDP process + */ + public void run() { + try { + final ServerSocket serverSocket = new ServerSocket (_serverPort); + + //Loop through for Incoming messages + + // server infinite loop + while (true) { + + // Wait for an incoming connection from a PEP + Socket socket = serverSocket.accept(); + + // COPSDebug.out(getClass().getName(),"New connection accepted " + + // socket.getInetAddress() + + // ":" + socket.getPort()); + + // We're waiting for an OPN message + try { + COPSMsg msg = COPSTransceiver.receiveMsg(socket); + if (msg.getHeader().isAClientOpen()) { + handleClientOpenMsg(socket, msg); + } else { + // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG); + try { + socket.close(); + } catch (Exception ex) { + logger.error("Error closing socket", ex); + } + } + } catch (Exception e) { // COPSException, IOException + // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION, + // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e); + try { + socket.close(); + } catch (Exception ex) { + logger.error("Error closing socket", ex); + } + } + } + } catch (IOException e) { + logger.error("Error caught while processing socket messages", e); + } + } + + /** + * Handles a COPS client-open message + * @param conn Socket to the PEP + * @param msg COPSMsg holding the client-open message + * @throws COPSException + * @throws IOException + */ + private void handleClientOpenMsg(Socket conn, COPSMsg msg) + throws COPSException, IOException { + COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg; + COPSPepId pepId = cMsg.getPepId(); + + // Validate Client Type + if (msg.getHeader().getClientType() != _clientType) { + // Unsupported client type + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing COPS data", unae); + } + + throw new COPSException("Unsupported client type"); + } + + // PEPId is mandatory + if (pepId == null) { + // Mandatory COPS object missing + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing close message", unae); + } + + throw new COPSException("Mandatory COPS object missing (PEPId)"); + } + + // Support + if ( (cMsg.getClientSI() != null) || + (cMsg.getPdpAddress() != null) || + (cMsg.getIntegrity() != null)) { + + // Unsupported objects + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType()); + COPSError err = new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + closeMsg.add(err); + try { + closeMsg.writeData(conn); + } catch (IOException unae) { + logger.error("Error writing close message", unae); + } + + throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)"); + } + + // Connection accepted + COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType()); + COPSKATimer katimer = new COPSKATimer(_kaTimer); + COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer); + COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg(); + acceptMsg.add(ahdr); + acceptMsg.add(katimer) ; + if (_acctTimer != 0) acceptMsg.add(acctTimer); + acceptMsg.writeData(conn); + + COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process); + pdpConn.setKaTimer(_kaTimer); + if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer); + new Thread(pdpConn).start(); + _connectionMap.put(pepId.getData().str(),pdpConn); + } + +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpMsgSender.java b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpMsgSender.java index 956af9c..ebab18d 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpMsgSender.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpMsgSender.java @@ -1,429 +1,419 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpdp; - -import org.umu.cops.stack.*; - -import java.io.IOException; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; - -/** - * COPS message transceiver class for provisioning connections at the PDP side. - * - * TODO - Need to continue refactoring by removing all instances of Hashtable (change to Map<>) - */ -public class COPSPdpMsgSender { - - /** - * Socket connected to PEP - */ - protected Socket _sock; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Creates a COPSPepMsgSender - * - * @param clientType COPS client-type - * @param clientHandle Client handle - * @param sock Socket to the PEP - */ - public COPSPdpMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { - // COPS Handle - _handle = clientHandle; - _clientType = clientType; - - _sock = sock; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Sends a decision message - * @param removeDecs Decisions to be removed - * @param installDecs Decisions to be installed - * @throws COPSPdpException - */ - public void sendDecision(Hashtable removeDecs, Hashtable installDecs) - throws COPSPdpException { - /* ::= - * - * *() | - * [] - * ::= - * - * [] - * ::= NULLFlag - * ::= NULLDecision | Install | Remove - * ::= < | > - * ::= *( ) - * ::= *( | ) - * - * Very important, this is actually being treated like this: - * ::= | - * ::= | - * - */ - - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED); - - // Client Handle with the same clientHandle as the request - final COPSHandle handle = new COPSHandle(getClientHandle().getId()); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(handle); - - // Decisions (no flags supplied) - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - - // Remove Decisions - // - if (removeDecs.size() > 0) { - COPSDecision rdec1 = new COPSDecision(); - rdec1.setCmdCode(COPSDecision.DEC_REMOVE); - - decisionMsg.addDecision(rdec1, cntxt); - - for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) removeDecs.get(strprid); - - // (PRID) - COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - // (EPD) - COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - decisionMsg.addDecision(dec2, cntxt); - decisionMsg.addDecision(dec3, cntxt); - } - } - - // Install Decisions - // - if (installDecs.size() > 0) { - COPSDecision idec1 = new COPSDecision(); - idec1.setCmdCode(COPSDecision.DEC_INSTALL); - - decisionMsg.addDecision(idec1, cntxt); - - for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) installDecs.get(strprid); - - // (PRID) - COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - // (EPD) - COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - decisionMsg.addDecision(dec2, cntxt); - decisionMsg.addDecision(dec3, cntxt); - } - - /** - COPSIntegrity intr = new COPSIntegrity(); - intr.setKeyId(19); - intr.setSeqNum(9); - intr.setKeyDigest(new COPSData("KEY DIGEST")); - decisionMsg.add(intr); - /**/ - } - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - //** Send the decision - //** - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); - } - } - - /** - * Sends a decision message which was not requested by the PEP - * @param removeDecs Decisions to be removed - * @param installDecs Decisions to be installed - * @throws COPSPdpException - */ - public void sendUnsolicitedDecision(Hashtable removeDecs, Hashtable installDecs) - throws COPSPdpException { - //** Example of an UNSOLICITED decision - //** - - /* ::= - * - * *() | - * [] - * ::= - * - * [] - * ::= NULLFlag - * ::= NULLDecision | Install | Remove - * ::= < | > - * ::= *( ) - * ::= *( | ) - * - * Very important, this is actually being treated like this: - * ::= | - * ::= | - * - */ - - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle handle = new COPSHandle(getClientHandle().getId()); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(handle); - - // Decisions (no flags supplied) - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - - // Remove Decisions - // - COPSDecision rdec1 = new COPSDecision(); - rdec1.setCmdCode(COPSDecision.DEC_REMOVE); - - decisionMsg.addDecision(rdec1, cntxt); - - for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) removeDecs.get(strprid); - - // (PRID) - COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - // (EPD) - COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - decisionMsg.addDecision(dec2, cntxt); - decisionMsg.addDecision(dec3, cntxt); - } - - // Install Decisions - // - COPSDecision idec1 = new COPSDecision(); - idec1.setCmdCode(COPSDecision.DEC_INSTALL); - - decisionMsg.addDecision(idec1, cntxt); - - for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) installDecs.get(strprid); - - // (PRID) - COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - // (EPD) - COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - decisionMsg.addDecision(dec2, cntxt); - decisionMsg.addDecision(dec3, cntxt); - } - - /** - COPSIntegrity intr = new COPSIntegrity(); - intr.setKeyId(19); - intr.setSeqNum(9); - intr.setKeyDigest(new COPSData("KEY DIGEST")); - decisionMsg.add(intr); - /**/ - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - //** Send the decision - //** - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); - } - } - - /** - * Sends a message asking that the request state be deleted - * @throws COPSPdpException - */ - public void sendDeleteRequestState() - throws COPSPdpException { - /* ::= - * - * *() - * [] - * ::= - * - * ::= Remove Request-State - * - */ - - // Common Header with the same ClientType as the request (default UNSOLICITED) - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - // Decisions - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - // - COPSDecision dec = new COPSDecision(); - dec.setCmdCode(COPSDecision.DEC_REMOVE); - dec.setFlags(COPSDecision.F_REQSTATE); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(clienthandle); - decisionMsg.addDecision(dec, cntxt); - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); - } - } - - /** - * Sends a request asking that a new request state be created - * @throws COPSPdpException - */ - public void sendOpenNewRequestState() - throws COPSPdpException { - /* ::= - * - * *() - * [] - * ::= - * - * ::= Install Request-State - * - */ - - // Common Header with the same ClientType as the request (default UNSOLICITED) - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - // Decisions - // - COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0); - // - COPSDecision dec = new COPSDecision(); - dec.setCmdCode(COPSDecision.DEC_INSTALL); - dec.setFlags(COPSDecision.F_REQSTATE); - - COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); - try { - decisionMsg.add(hdr); - decisionMsg.add(clienthandle); - decisionMsg.addDecision(dec, cntxt); - } catch (COPSException e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - decisionMsg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); - } - } - - /** - * Sends a message asking for a COPS sync operation - * @throws COPSPdpException - */ - public void sendSyncRequestState() - throws COPSPdpException { - /* ::= - * [] - * [] - */ - - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType()); - - // Client Handle with the same clientHandle as the request - final COPSHandle clienthandle = new COPSHandle(_handle.getId()); - - COPSSyncStateMsg msg = new COPSSyncStateMsg(); - try { - msg.add(hdr); - msg.add(clienthandle); - } catch (Exception e) { - throw new COPSPdpException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage()); - } - } -} +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpdp; + +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * COPS message transceiver class for provisioning connections at the PDP side. + * + * TODO - Need to continue refactoring by removing all instances of Hashtable (change to Map<>) + */ +public class COPSPdpMsgSender { + + /** + * Socket connected to PEP + */ + protected Socket _sock; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Creates a COPSPepMsgSender + * + * @param clientType COPS client-type + * @param clientHandle Client handle + * @param sock Socket to the PEP + */ + public COPSPdpMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { + // COPS Handle + _handle = clientHandle; + _clientType = clientType; + + _sock = sock; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Sends a decision message + * @param removeDecs Decisions to be removed + * @param installDecs Decisions to be installed + * @throws COPSPdpException + */ + public void sendDecision(Hashtable removeDecs, Hashtable installDecs) + throws COPSPdpException { + /* ::= + * + * *() | + * [] + * ::= + * + * [] + * ::= NULLFlag + * ::= NULLDecision | Install | Remove + * ::= < | > + * ::= *( ) + * ::= *( | ) + * + * Very important, this is actually being treated like this: + * ::= | + * ::= | + * + */ + + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED); + + // Client Handle with the same clientHandle as the request + final COPSHandle handle = new COPSHandle(getClientHandle().getId()); + + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(handle); + + // Decisions (no flags supplied) + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + + // Remove Decisions + // + if (removeDecs.size() > 0) { + COPSDecision rdec1 = new COPSDecision(Command.REMOVE); + decisionMsg.addDecision(rdec1, cntxt); + + for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) removeDecs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSDecision dec2 = new COPSDecision(CType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSDecision dec3 = new COPSDecision(CType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + decisionMsg.addDecision(dec2, cntxt); + decisionMsg.addDecision(dec3, cntxt); + } + } + + // Install Decisions + // + if (installDecs.size() > 0) { + COPSDecision idec1 = new COPSDecision(Command.INSTALL); + decisionMsg.addDecision(idec1, cntxt); + + for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) installDecs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSDecision dec2 = new COPSDecision(CType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSDecision dec3 = new COPSDecision(CType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + decisionMsg.addDecision(dec2, cntxt); + decisionMsg.addDecision(dec3, cntxt); + } + + /** + COPSIntegrity intr = new COPSIntegrity(); + intr.setKeyId(19); + intr.setSeqNum(9); + intr.setKeyDigest(new COPSData("KEY DIGEST")); + decisionMsg.add(intr); + /**/ + } + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + //** Send the decision + //** + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); + } + } + + /** + * Sends a decision message which was not requested by the PEP + * @param removeDecs Decisions to be removed + * @param installDecs Decisions to be installed + * @throws COPSPdpException + */ + public void sendUnsolicitedDecision(Hashtable removeDecs, Hashtable installDecs) + throws COPSPdpException { + //** Example of an UNSOLICITED decision + //** + + /* ::= + * + * *() | + * [] + * ::= + * + * [] + * ::= NULLFlag + * ::= NULLDecision | Install | Remove + * ::= < | > + * ::= *( ) + * ::= *( | ) + * + * Very important, this is actually being treated like this: + * ::= | + * ::= | + * + */ + + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle handle = new COPSHandle(getClientHandle().getId()); + + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(handle); + + // Decisions (no flags supplied) + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + + // Remove Decisions + // + COPSDecision rdec1 = new COPSDecision(Command.REMOVE); + decisionMsg.addDecision(rdec1, cntxt); + + for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) removeDecs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSDecision dec2 = new COPSDecision(CType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSDecision dec3 = new COPSDecision(CType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + decisionMsg.addDecision(dec2, cntxt); + decisionMsg.addDecision(dec3, cntxt); + } + + // Install Decisions + // + COPSDecision idec1 = new COPSDecision(Command.INSTALL); + decisionMsg.addDecision(idec1, cntxt); + + for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) installDecs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSDecision dec2 = new COPSDecision(CType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSDecision dec3 = new COPSDecision(CType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + decisionMsg.addDecision(dec2, cntxt); + decisionMsg.addDecision(dec3, cntxt); + } + + /** + COPSIntegrity intr = new COPSIntegrity(); + intr.setKeyId(19); + intr.setSeqNum(9); + intr.setKeyDigest(new COPSData("KEY DIGEST")); + decisionMsg.add(intr); + /**/ + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + //** Send the decision + //** + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage()); + } + } + + /** + * Sends a message asking that the request state be deleted + * @throws COPSPdpException + */ + public void sendDeleteRequestState() + throws COPSPdpException { + /* ::= + * + * *() + * [] + * ::= + * + * ::= Remove Request-State + * + */ + + // Common Header with the same ClientType as the request (default UNSOLICITED) + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + // Decisions + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + // + COPSDecision dec = new COPSDecision(Command.REMOVE, DecisionFlag.REQSTATE); + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(clienthandle); + decisionMsg.addDecision(dec, cntxt); + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); + } + } + + /** + * Sends a request asking that a new request state be created + * @throws COPSPdpException + */ + public void sendOpenNewRequestState() + throws COPSPdpException { + /* ::= + * + * *() + * [] + * ::= + * + * ::= Install Request-State + * + */ + + // Common Header with the same ClientType as the request (default UNSOLICITED) + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + // Decisions + // + COPSContext cntxt = new COPSContext(RType.CONFIG, (short) 0); + // + COPSDecision dec = new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE); + COPSDecisionMsg decisionMsg = new COPSDecisionMsg(); + try { + decisionMsg.add(hdr); + decisionMsg.add(clienthandle); + decisionMsg.addDecision(dec, cntxt); + } catch (COPSException e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + decisionMsg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage()); + } + } + + /** + * Sends a message asking for a COPS sync operation + * @throws COPSPdpException + */ + public void sendSyncRequestState() + throws COPSPdpException { + /* ::= + * [] + * [] + */ + + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType()); + + // Client Handle with the same clientHandle as the request + final COPSHandle clienthandle = new COPSHandle(_handle.getId()); + + COPSSyncStateMsg msg = new COPSSyncStateMsg(); + try { + msg.add(hdr); + msg.add(clienthandle); + } catch (Exception e) { + throw new COPSPdpException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage()); + } + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpReqStateMan.java b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpReqStateMan.java index 2de386c..b2993a0 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpReqStateMan.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpdp/COPSPdpReqStateMan.java @@ -1,374 +1,378 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpdp; - -import org.umu.cops.stack.*; - -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -/** - * State manager class for provisioning requests, at the PDP side. - */ -public class COPSPdpReqStateMan { - - /** - * Request State created - */ - public final static short ST_CREATE = 1; - /** - * Request received - */ - public final static short ST_INIT = 2; - /** - * Decisions sent - */ - public final static short ST_DECS = 3; - /** - * Report received - */ - public final static short ST_REPORT = 4; - /** - * Request State finalized - */ - public final static short ST_FINAL = 5; - /** - * New Request State solicited - */ - public final static short ST_NEW = 6; - /** - * Delete Request State solicited - */ - public final static short ST_DEL = 7; - /** - * SYNC request sent - */ - public final static short ST_SYNC = 8; - /** - * SYNC completed - */ - public final static short ST_SYNCALL = 9; - /** - * Close connection received - */ - public final static short ST_CCONN = 10; - /** - * Keep-alive timeout - */ - public final static short ST_NOKA = 11; - /** - * Accounting timeout - */ - public final static short ST_ACCT = 12; - - /** - * COPS client-type that identifies the policy client - */ - protected short _clientType; - - /** - * COPS client handle used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Object for performing policy data processing - */ - protected COPSPdpDataProcess _process; - - /** - * Current state of the request being managed - */ - protected short _status; - - /** COPS message transceiver used to send COPS messages */ - protected COPSPdpMsgSender _sender; - - /** - * Creates a request state manager - * @param clientType Client-type - * @param clientHandle Client handle - */ - public COPSPdpReqStateMan(short clientType, String clientHandle) { - _handle = new COPSHandle(new COPSData(clientHandle)); - _clientType = clientType; - _status = ST_CREATE; - } - - /** - * Gets the client handle - * @return Client's COPSHandle - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Gets the client-type - * @return Client-type value - */ - public short getClientType() { - return _clientType; - } - - /** - * Gets the status of the request - * @return Request state value - */ - public short getStatus() { - return _status; - } - - /** - * Gets the policy data processing object - * @return Policy data processing object - */ - public COPSPdpDataProcess getDataProcess() { - return _process; - } - - /** - * Sets the policy data processing object - * @param process Policy data processing object - */ - public void setDataProcess(COPSPdpDataProcess process) { - _process = process; - } - - /** - * Called when COPS sync is completed - * @param repMsg COPS sync message - * @throws COPSPdpException - */ - protected void processSyncComplete(COPSSyncStateMsg repMsg) - throws COPSPdpException { - - _status = ST_SYNCALL; - - // maybe we should notifySyncComplete ... - } - - /** - * Initializes a new request state over a socket - * @param sock Socket to the PEP - * @throws COPSPdpException - */ - protected void initRequestState(Socket sock) - throws COPSPdpException { - // Inits an object for sending COPS messages to the PEP - _sender = new COPSPdpMsgSender(_clientType, _handle, sock); - - // Initial state - _status = ST_INIT; - } - - /** - * Processes a COPS request - * @param msg COPS request received from the PEP - * @throws COPSPdpException - */ - protected void processRequest(COPSReqMsg msg) - throws COPSPdpException { - - COPSHeader hdrmsg = msg.getHeader(); - COPSHandle handlemsg = msg.getClientHandle(); - COPSContext contextmsg = msg.getContext(); - - //** Analyze the request - //** - - /* ::= - * - * - * *() - * [] - * ::= <*( )> - * - * Very important, this is actually being treated like this: - * ::= | - * - - // Named ClientSI - Vector clientSIs = msg.getClientSI(); - Hashtable reqSIs = new Hashtable(40); - String strobjprid = new String(); - for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); - switch (obj.getSNum()) - { - case COPSPrObjBase.PR_PRID: - strobjprid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - reqSIs.put(strobjprid, obj.getData().str()); - // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); - // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); - break; - default: - break; - } - } - - //** Here we must retrieve a decision depending on - //** the supplied ClientSIs - // reqSIs is a hashtable with the prid and epds - - // ................ - // - Hashtable removeDecs = new Hashtable(); - Hashtable installDecs = new Hashtable(); - _process.setClientData(this, reqSIs); - - removeDecs = _process.getRemovePolicy(this); - installDecs = _process.getInstallPolicy(this); - - //** We create the SOLICITED decision - //** - _sender.sendDecision(removeDecs, installDecs); - _status = ST_DECS; - */ - } - - /** - * Processes a report - * @param msg Report message from the PEP - * @throws COPSPdpException - */ - protected void processReport(COPSReportMsg msg) - throws COPSPdpException { - - //** Analyze the report - //** - - /* - * ::= - * - * - * *() - * [] - * ::= <[] *()> - * ::= *() - * - * Important, is not parsed - */ - - // COPSHeader hdrmsg = msg.getHeader(); - // COPSHandle handlemsg = msg.getClientHandle(); - - // Report Type - COPSReportType rtypemsg = msg.getReport(); - - // Named ClientSI - Vector clientSIs = msg.getClientSI(); - Hashtable repSIs = new Hashtable(40); - String strobjprid = new String(); - for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); - switch (obj.getSNum()) { - case COPSPrObjBase.PR_PRID: - strobjprid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - repSIs.put(strobjprid, obj.getData().str()); - // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); - // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); - break; - default: - break; - } - } - - //** Here we must act in accordance with - //** the report received - if (rtypemsg.isSuccess()) { - _status = ST_REPORT; - _process.successReport(this, repSIs); - } else if (rtypemsg.isFailure()) { - _status = ST_REPORT; - _process.failReport(this, repSIs); - } else if (rtypemsg.isAccounting()) { - _status = ST_ACCT; - _process.acctReport(this, repSIs); - } - } - - /** - * Called when connection is closed - * @param error Reason - * @throws COPSPdpException - */ - protected void processClosedConnection(COPSError error) - throws COPSPdpException { - if (_process != null) - _process.notifyClosedConnection(this, error); - - _status = ST_CCONN; - } - - /** - * Called when no keep-alive is received - * @throws COPSPdpException - */ - protected void processNoKAConnection() - throws COPSPdpException { - if (_process != null) - _process.notifyNoKAliveReceived(this); - - _status = ST_NOKA; - } - - /** - * Deletes the request state - * @throws COPSPdpException - */ - protected void finalizeRequestState() - throws COPSPdpException { - _sender.sendDeleteRequestState(); - _status = ST_FINAL; - } - - /** - * Asks for a COPS sync - * @throws COPSPdpException - */ - protected void syncRequestState() - throws COPSPdpException { - _sender.sendSyncRequestState(); - _status = ST_SYNC; - } - - /** - * Opens a new request state - * @throws COPSPdpException - */ - protected void openNewRequestState() - throws COPSPdpException { - _sender.sendOpenNewRequestState(); - _status = ST_NEW; - } - - /** - * Processes a COPS delete message - * @param dMsg COPSDeleteMsg received from the PEP - * @throws COPSPdpException - */ - protected void processDeleteRequestState(COPSDeleteMsg dMsg) - throws COPSPdpException { - if (_process != null) - _process.closeRequestState(this); - - _status = ST_DEL; - } - -} +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpdp; + +import org.umu.cops.stack.*; + +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + * State manager class for provisioning requests, at the PDP side. + */ +public class COPSPdpReqStateMan { + + /** + * Request State created + */ + public final static short ST_CREATE = 1; + /** + * Request received + */ + public final static short ST_INIT = 2; + /** + * Decisions sent + */ + public final static short ST_DECS = 3; + /** + * Report received + */ + public final static short ST_REPORT = 4; + /** + * Request State finalized + */ + public final static short ST_FINAL = 5; + /** + * New Request State solicited + */ + public final static short ST_NEW = 6; + /** + * Delete Request State solicited + */ + public final static short ST_DEL = 7; + /** + * SYNC request sent + */ + public final static short ST_SYNC = 8; + /** + * SYNC completed + */ + public final static short ST_SYNCALL = 9; + /** + * Close connection received + */ + public final static short ST_CCONN = 10; + /** + * Keep-alive timeout + */ + public final static short ST_NOKA = 11; + /** + * Accounting timeout + */ + public final static short ST_ACCT = 12; + + /** + * COPS client-type that identifies the policy client + */ + protected short _clientType; + + /** + * COPS client handle used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Object for performing policy data processing + */ + protected COPSPdpDataProcess _process; + + /** + * Current state of the request being managed + */ + protected short _status; + + /** COPS message transceiver used to send COPS messages */ + protected COPSPdpMsgSender _sender; + + /** + * Creates a request state manager + * @param clientType Client-type + * @param clientHandle Client handle + */ + public COPSPdpReqStateMan(short clientType, String clientHandle) { + _handle = new COPSHandle(new COPSData(clientHandle)); + _clientType = clientType; + _status = ST_CREATE; + } + + /** + * Gets the client handle + * @return Client's COPSHandle + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Gets the client-type + * @return Client-type value + */ + public short getClientType() { + return _clientType; + } + + /** + * Gets the status of the request + * @return Request state value + */ + public short getStatus() { + return _status; + } + + /** + * Gets the policy data processing object + * @return Policy data processing object + */ + public COPSPdpDataProcess getDataProcess() { + return _process; + } + + /** + * Sets the policy data processing object + * @param process Policy data processing object + */ + public void setDataProcess(COPSPdpDataProcess process) { + _process = process; + } + + /** + * Called when COPS sync is completed + * @param repMsg COPS sync message + * @throws COPSPdpException + */ + protected void processSyncComplete(COPSSyncStateMsg repMsg) + throws COPSPdpException { + + _status = ST_SYNCALL; + + // maybe we should notifySyncComplete ... + } + + /** + * Initializes a new request state over a socket + * @param sock Socket to the PEP + * @throws COPSPdpException + */ + protected void initRequestState(Socket sock) + throws COPSPdpException { + // Inits an object for sending COPS messages to the PEP + _sender = new COPSPdpMsgSender(_clientType, _handle, sock); + + // Initial state + _status = ST_INIT; + } + + /** + * Processes a COPS request + * @param msg COPS request received from the PEP + * @throws COPSPdpException + */ + protected void processRequest(COPSReqMsg msg) + throws COPSPdpException { + + COPSHeader hdrmsg = msg.getHeader(); + COPSHandle handlemsg = msg.getClientHandle(); + COPSContext contextmsg = msg.getContext(); + + //** Analyze the request + //** + + /* ::= + * + * + * *() + * [] + * ::= <*( )> + * + * Very important, this is actually being treated like this: + * ::= | + * + + // Named ClientSI + Vector clientSIs = msg.getClientSI(); + Hashtable reqSIs = new Hashtable(40); + String strobjprid = new String(); + for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); + switch (obj.getSNum()) + { + case COPSPrObjBase.PR_PRID: + strobjprid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + reqSIs.put(strobjprid, obj.getData().str()); + // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); + // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); + break; + default: + break; + } + } + + //** Here we must retrieve a decision depending on + //** the supplied ClientSIs + // reqSIs is a hashtable with the prid and epds + + // ................ + // + Hashtable removeDecs = new Hashtable(); + Hashtable installDecs = new Hashtable(); + _process.setClientData(this, reqSIs); + + removeDecs = _process.getRemovePolicy(this); + installDecs = _process.getInstallPolicy(this); + + //** We create the SOLICITED decision + //** + _sender.sendDecision(removeDecs, installDecs); + _status = ST_DECS; + */ + } + + /** + * Processes a report + * @param msg Report message from the PEP + * @throws COPSPdpException + */ + protected void processReport(COPSReportMsg msg) + throws COPSPdpException { + + //** Analyze the report + //** + + /* + * ::= + * + * + * *() + * [] + * ::= <[] *()> + * ::= *() + * + * Important, is not parsed + */ + + // COPSHeader hdrmsg = msg.getHeader(); + // COPSHandle handlemsg = msg.getClientHandle(); + + // Report Type + COPSReportType rtypemsg = msg.getReport(); + + // Named ClientSI + Vector clientSIs = msg.getClientSI(); + Hashtable repSIs = new Hashtable(40); + String strobjprid = ""; + for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData()); + switch (obj.getSNum()) { + case COPSPrObjBase.PR_PRID: + strobjprid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + repSIs.put(strobjprid, obj.getData().str()); + // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid); + // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str()); + break; + default: + break; + } + } + + //** Here we must act in accordance with + //** the report received + switch (rtypemsg.getReportType()) { + case SUCCESS: + _status = ST_REPORT; + _process.successReport(this, repSIs); + break; + case FAILURE: + _status = ST_REPORT; + _process.failReport(this, repSIs); + break; + case ACCOUNTING: + _status = ST_ACCT; + _process.acctReport(this, repSIs); + break; + } + } + + /** + * Called when connection is closed + * @param error Reason + * @throws COPSPdpException + */ + protected void processClosedConnection(COPSError error) + throws COPSPdpException { + if (_process != null) + _process.notifyClosedConnection(this, error); + + _status = ST_CCONN; + } + + /** + * Called when no keep-alive is received + * @throws COPSPdpException + */ + protected void processNoKAConnection() + throws COPSPdpException { + if (_process != null) + _process.notifyNoKAliveReceived(this); + + _status = ST_NOKA; + } + + /** + * Deletes the request state + * @throws COPSPdpException + */ + protected void finalizeRequestState() + throws COPSPdpException { + _sender.sendDeleteRequestState(); + _status = ST_FINAL; + } + + /** + * Asks for a COPS sync + * @throws COPSPdpException + */ + protected void syncRequestState() + throws COPSPdpException { + _sender.sendSyncRequestState(); + _status = ST_SYNC; + } + + /** + * Opens a new request state + * @throws COPSPdpException + */ + protected void openNewRequestState() + throws COPSPdpException { + _sender.sendOpenNewRequestState(); + _status = ST_NEW; + } + + /** + * Processes a COPS delete message + * @param dMsg COPSDeleteMsg received from the PEP + * @throws COPSPdpException + */ + protected void processDeleteRequestState(COPSDeleteMsg dMsg) + throws COPSPdpException { + if (_process != null) + _process.closeRequestState(this); + + _status = ST_DEL; + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepAgent.java b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepAgent.java index 343d40c..ca6f2de 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepAgent.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepAgent.java @@ -1,319 +1,303 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpep; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.util.Hashtable; - -import org.umu.cops.stack.COPSAcctTimer; -import org.umu.cops.stack.COPSClientAcceptMsg; -import org.umu.cops.stack.COPSClientCloseMsg; -import org.umu.cops.stack.COPSClientOpenMsg; -import org.umu.cops.stack.COPSData; -import org.umu.cops.stack.COPSError; -import org.umu.cops.stack.COPSException; -import org.umu.cops.stack.COPSHeader; -import org.umu.cops.stack.COPSKATimer; -import org.umu.cops.stack.COPSMsg; -import org.umu.cops.stack.COPSPepId; -import org.umu.cops.stack.COPSTransceiver; - -/** - * This is a provisioning COPS PEP. Responsible for making - * connection to the PDP and maintaining it - */ -public class COPSPepAgent { - - /** - PEP's Identifier - */ - private String _pepID; - - /** - PEP's client-type - */ - private short _clientType; - - /** - PDP host name - */ - private String _psHost; - - /** - PDP port - */ - private int _psPort; - - /** - PEP-PDP connection manager - */ - private COPSPepConnection _conn; - - /** - COPS error returned by PDP - */ - private COPSError _error; - - /** - * Creates a PEP agent - * @param pepID PEP-ID - * @param clientType Client-type - */ - public COPSPepAgent(String pepID, short clientType) { - _pepID = pepID; - _clientType = clientType; - } - - /** - * Creates a PEP agent with a PEP-ID equal to "noname" - * @param clientType Client-type - */ - public COPSPepAgent(short clientType) { - - // PEPId - try { - _pepID = InetAddress.getLocalHost().getHostName(); - } catch (Exception e) { - _pepID = "noname"; - } - - _clientType = clientType; - } - - /** - * Gets the identifier of the PEP - * @return PEP-ID - */ - public String getPepID() { - return _pepID; - } - - /** - * Gets the COPS client-type - * @return PEP's client-type - */ - public short getClientType() { - return _clientType; - } - - /** - * Gets PDP host name - * @return PDP host name - */ - public String getPDPName() { - return _psHost; - } - - /** - * Gets the port of the PDP - * @return PDP port - */ - public int getPDPPort() { - return _psPort; - } - - /** - * Connects to a PDP - * @param psHost PDP host name - * @param psPort PDP port - * @return true if PDP accepts the connection; false otherwise - * @throws java.net.UnknownHostException - * @throws java.io.IOException - * @throws COPSException - * @throws COPSPepException - */ - public boolean connect(String psHost, int psPort) - throws UnknownHostException, IOException, COPSException, COPSPepException { - - // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP"); - _psHost = psHost; - _psPort = psPort; - - // Check whether it already exists - if (_conn == null) - _conn = processConnection(psHost,psPort); - else { - // Check if it's closed - if (_conn.isClosed()) { - _conn = processConnection(psHost,psPort); - } else { - disconnect(null); - _conn = processConnection(psHost,psPort); - } - } - - return (_conn != null); - } - - /** - * Gets the connection manager - * @return PEP-PDP connection manager object - */ - public COPSPepConnection getConnection () { - return (_conn); - } - - /** - * Gets the COPS error returned by the PDP - * @return COPSError returned by PDP - */ - public COPSError getConnectionError() { - return _error; - } - - /** - * Disconnects from the PDP - * @param error Reason - * @throws COPSException - * @throws IOException - */ - public void disconnect(COPSError error) - throws COPSException, IOException { - - COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); - COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); - closeMsg.add(cHdr); - if (error != null) - closeMsg.add(error); - - closeMsg.writeData(_conn.getSocket()); - _conn.close(); - _conn = null; - } - - /** - * Adds a request state to the connection manager. - * @return The newly created connection manager - * @throws COPSPepException - * @throws COPSException - */ - public COPSPepReqStateMan addRequestState (String handle, COPSPepDataProcess process) - throws COPSPepException, COPSException { - if (_conn != null) { - return _conn.addRequestState(handle, process); - } - return null; - } - - - /** - * Queries the connection manager to delete a request state - * @param man Request state manager - * @throws COPSPepException - * @throws COPSException - */ - public void deleteRequestState (COPSPepReqStateMan man) - throws COPSPepException, COPSException { - if (_conn != null) - _conn.deleteRequestState(man); - } - - /** - * Gets all the request state managers - * @return A Hashtable holding all active request state managers - */ - public Hashtable getReqStateMans() { - if (_conn != null) - return _conn.getReqStateMans(); - return null; - } - - /** - * Establish connection to PDP's IP address - * - * ::= - * - * [] - * [] - * [] - * - * Not support [], [], [] - * - * ::= - * - * [] - * [] - * - * Not send [] - * - * ::= - * - * [] - * [] - * - * Not send [], [] - * - * @throws UnknownHostException - * @throws IOException - * @throws COPSException - * @throws COPSPepException - * - */ - private COPSPepConnection processConnection(String psHost, int psPort) - throws UnknownHostException, IOException, COPSException, COPSPepException { - // Build OPN - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType); - - COPSPepId pepId = new COPSPepId(); - COPSData d = new COPSData(_pepID); - pepId.setData(d); - - COPSClientOpenMsg msg = new COPSClientOpenMsg(); - msg.add(hdr); - msg.add(pepId); - - // Create Socket and send OPN - InetAddress addr = InetAddress.getByName(psHost); - Socket socket = new Socket(addr,psPort); - msg.writeData(socket); - - // Receive the response - COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket); - - if (recvmsg.getHeader().isAClientAccept()) { - COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg; - - // Support - if (cMsg.getIntegrity() != null) { - throw new COPSPepException("Unsupported object (Integrity)"); - } - - // Mandatory KATimer - COPSKATimer kt = cMsg.getKATimer(); - if (kt == null) - throw new COPSPepException ("Mandatory COPS object missing (KA Timer)"); - short _kaTimeVal = kt.getTimerVal(); - - // ACTimer - COPSAcctTimer at = cMsg.getAcctTimer(); - short _acctTimer = 0; - if (at != null) - _acctTimer = at.getTimerVal(); - - // Create the connection manager - COPSPepConnection conn = new COPSPepConnection(_clientType, socket); - conn.setKaTimer(_kaTimeVal); - conn.setAcctTimer(_acctTimer); - new Thread(conn).start(); - - return conn; - } else if (recvmsg.getHeader().isAClientClose()) { - COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg; - _error = cMsg.getError(); - socket.close(); - return null; - } else { // messages of other types are not expected - throw new COPSPepException("Message not expected. Closing connection for " + socket.toString()); - } - } -} - - - +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpep; + +import org.umu.cops.stack.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Hashtable; + +/** + * This is a provisioning COPS PEP. Responsible for making + * connection to the PDP and maintaining it + */ +public class COPSPepAgent { + + /** + PEP's Identifier + */ + private String _pepID; + + /** + PEP's client-type + */ + private short _clientType; + + /** + PDP host name + */ + private String _psHost; + + /** + PDP port + */ + private int _psPort; + + /** + PEP-PDP connection manager + */ + private COPSPepConnection _conn; + + /** + COPS error returned by PDP + */ + private COPSError _error; + + /** + * Creates a PEP agent + * @param pepID PEP-ID + * @param clientType Client-type + */ + public COPSPepAgent(String pepID, short clientType) { + _pepID = pepID; + _clientType = clientType; + } + + /** + * Creates a PEP agent with a PEP-ID equal to "noname" + * @param clientType Client-type + */ + public COPSPepAgent(short clientType) { + + // PEPId + try { + _pepID = InetAddress.getLocalHost().getHostName(); + } catch (Exception e) { + _pepID = "noname"; + } + + _clientType = clientType; + } + + /** + * Gets the identifier of the PEP + * @return PEP-ID + */ + public String getPepID() { + return _pepID; + } + + /** + * Gets the COPS client-type + * @return PEP's client-type + */ + public short getClientType() { + return _clientType; + } + + /** + * Gets PDP host name + * @return PDP host name + */ + public String getPDPName() { + return _psHost; + } + + /** + * Gets the port of the PDP + * @return PDP port + */ + public int getPDPPort() { + return _psPort; + } + + /** + * Connects to a PDP + * @param psHost PDP host name + * @param psPort PDP port + * @return true if PDP accepts the connection; false otherwise + * @throws java.io.IOException + * @throws COPSException + * @throws COPSPepException + */ + public boolean connect(String psHost, int psPort) throws IOException, COPSException, COPSPepException { + + // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP"); + _psHost = psHost; + _psPort = psPort; + + // Check whether it already exists + if (_conn == null) + _conn = processConnection(psHost,psPort); + else { + // Check if it's closed + if (_conn.isClosed()) { + _conn = processConnection(psHost,psPort); + } else { + disconnect(null); + _conn = processConnection(psHost,psPort); + } + } + + return (_conn != null); + } + + /** + * Gets the connection manager + * @return PEP-PDP connection manager object + */ + public COPSPepConnection getConnection () { + return (_conn); + } + + /** + * Gets the COPS error returned by the PDP + * @return COPSError returned by PDP + */ + public COPSError getConnectionError() { + return _error; + } + + /** + * Disconnects from the PDP + * @param error Reason + * @throws COPSException + * @throws IOException + */ + public void disconnect(COPSError error) + throws COPSException, IOException { + + COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); + COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); + closeMsg.add(cHdr); + if (error != null) + closeMsg.add(error); + + closeMsg.writeData(_conn.getSocket()); + _conn.close(); + _conn = null; + } + + /** + * Adds a request state to the connection manager. + * @return The newly created connection manager + * @throws COPSPepException + * @throws COPSException + */ + public COPSPepReqStateMan addRequestState (String handle, COPSPepDataProcess process) + throws COPSPepException, COPSException { + if (_conn != null) { + return _conn.addRequestState(handle, process); + } + return null; + } + + + /** + * Queries the connection manager to delete a request state + * @param man Request state manager + * @throws COPSPepException + * @throws COPSException + */ + public void deleteRequestState (COPSPepReqStateMan man) + throws COPSPepException, COPSException { + if (_conn != null) + _conn.deleteRequestState(man); + } + + /** + * Gets all the request state managers + * @return A Hashtable holding all active request state managers + */ + public Hashtable getReqStateMans() { + if (_conn != null) + return _conn.getReqStateMans(); + return null; + } + + /** + * Establish connection to PDP's IP address + * + * ::= + * + * [] + * [] + * [] + * + * Not support [], [], [] + * + * ::= + * + * [] + * [] + * + * Not send [] + * + * ::= + * + * [] + * [] + * + * Not send [], [] + * + * @throws UnknownHostException + * @throws IOException + * @throws COPSException + * @throws COPSPepException + * + */ + private COPSPepConnection processConnection(String psHost, int psPort) throws IOException, COPSException, + COPSPepException { + // Build OPN + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType); + + COPSPepId pepId = new COPSPepId(new COPSData(_pepID)); + COPSClientOpenMsg msg = new COPSClientOpenMsg(); + msg.add(hdr); + msg.add(pepId); + + // Create Socket and send OPN + InetAddress addr = InetAddress.getByName(psHost); + Socket socket = new Socket(addr,psPort); + msg.writeData(socket); + + // Receive the response + COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket); + + if (recvmsg.getHeader().isAClientAccept()) { + COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg; + + // Support + if (cMsg.getIntegrity() != null) { + throw new COPSPepException("Unsupported object (Integrity)"); + } + + // Mandatory KATimer + COPSKATimer kt = cMsg.getKATimer(); + if (kt == null) + throw new COPSPepException ("Mandatory COPS object missing (KA Timer)"); + short _kaTimeVal = kt.getTimerVal(); + + // ACTimer + COPSAcctTimer at = cMsg.getAcctTimer(); + short _acctTimer = 0; + if (at != null) + _acctTimer = at.getTimerVal(); + + // Create the connection manager + COPSPepConnection conn = new COPSPepConnection(_clientType, socket); + conn.setKaTimer(_kaTimeVal); + conn.setAcctTimer(_acctTimer); + new Thread(conn).start(); + + return conn; + } else if (recvmsg.getHeader().isAClientClose()) { + COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg; + _error = cMsg.getError(); + socket.close(); + return null; + } else { // messages of other types are not expected + throw new COPSPepException("Message not expected. Closing connection for " + socket.toString()); + } + } +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepConnection.java b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepConnection.java index 89943dd..68e0ea5 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepConnection.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepConnection.java @@ -9,6 +9,8 @@ package org.umu.cops.prpep; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; import java.io.IOException; import java.net.Socket; @@ -398,8 +400,9 @@ public class COPSPepConnection implements Runnable { logger.warn("Unable to find state manager with key - " + handle.getId().str()); // Check message type - if (decision.getFlags() == COPSDecision.F_REQSTATE) { - if (decision.isRemoveDecision()) + // TODO FIXME - Use of manager object could result in a NPE + if (decision.getFlag().equals(DecisionFlag.REQSTATE)) { + if (decision.getCommand().equals(Command.REMOVE)) // Delete Request State manager.processDeleteRequestState(dMsg); else @@ -427,6 +430,7 @@ public class COPSPepConnection implements Runnable { if (manager == null) logger.warn("Unable to find state manager with key - " + handle.getId().str()); + // TODO FIXME - Use of manager object could result in a NPE manager.processOpenNewRequestState(); } @@ -452,7 +456,7 @@ public class COPSPepConnection implements Runnable { logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress()); } - COPSPepReqStateMan manager = (COPSPepReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str()); + COPSPepReqStateMan manager = _managerMap.get(cMsg.getClientHandle().getId().str()); if (manager == null) { logger.warn("Unable to find state manager with key - " + cMsg.getClientHandle().getId().str()); } else { diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepMsgSender.java b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepMsgSender.java index 010560c..d6d76ed 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepMsgSender.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepMsgSender.java @@ -1,372 +1,363 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpep; - -import java.io.IOException; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; - -import org.umu.cops.stack.COPSClientSI; -import org.umu.cops.stack.COPSContext; -import org.umu.cops.stack.COPSData; -import org.umu.cops.stack.COPSDeleteMsg; -import org.umu.cops.stack.COPSException; -import org.umu.cops.stack.COPSHandle; -import org.umu.cops.stack.COPSHeader; -import org.umu.cops.stack.COPSPrEPD; -import org.umu.cops.stack.COPSPrID; -import org.umu.cops.stack.COPSReason; -import org.umu.cops.stack.COPSReportMsg; -import org.umu.cops.stack.COPSReportType; -import org.umu.cops.stack.COPSReqMsg; -import org.umu.cops.stack.COPSSyncStateMsg; - -/** - * COPSPepMsgSender sends COPS messages to PDP. - * - * @version COPSPepMsgSender.java, v 2.00 2004 - * - */ -public class COPSPepMsgSender { - - /** - * Socket connection to PDP - */ - protected Socket _sock; - - /** - * The client-type identifies the policy client - */ - protected short _clientType; - - /** - * The client handle is used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - * Create a COPSPepMsgSender - * - * @param clientType client-type - * @param clientHandle client handle - * @param sock socket of PDP connection - */ - public COPSPepMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { - // COPS Handle - _handle = clientHandle; - _clientType = clientType; - - _sock = sock; - } - - /** - * Return client handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Return client-type - * - * @return a short - * - */ - public short getClientType() { - return _clientType; - } - - /** - * Send Request to PDP. - * The PEP establishes a request state client handle for which the - * remote PDP may maintain state. - * - * @param clientSIs a Hashtable - * - * @throws COPSPepException - * - */ - public void sendRequest(Hashtable clientSIs) - throws COPSPepException { - // Create COPS Message - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType); - COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0); - - COPSHandle handle = _handle; - - // Add the clientSIs - COPSReqMsg msg = new COPSReqMsg(); - try { - msg.add(hdr) ; - msg.add(handle) ; - msg.add(cntxt) ; - - if (clientSIs.size() > 0) { - for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) clientSIs.get(strprid); - - // (PRID) - COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - - // (EPD) - COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - msg.add(cSi); - msg.add(cSi2); - } - } - - } catch (COPSException e) { - throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage()); - } - - // Send message - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the request, reason: " + e.getMessage()); - } - } - - /** - * Send Fail Report to PDP. - * The RPT message is used by the PEP to communicate to the PDP its - * success or failure in carrying out the PDP's decision, or to report - * an accounting related change in state. - * - * @throws COPSPepException - * - */ - public void sendFailReport(Hashtable clientSIs) - throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report FAIL - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.FAILURE); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - if (clientSIs.size() > 0) { - for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) clientSIs.get(strprid); - - // (PRID) - COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - - // (EPD) - COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - msg.add(cSi); - msg.add(cSi2); - } - } - - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - /** - * Send Succes Report to PDP. - * The RPT message is used by the PEP to communicate to the PDP its - * success or failure in carrying out the PDP's decision, or to report - * an accounting related change in state. - * - * @throws COPSPepException - * - */ - public void sendSuccessReport(Hashtable clientSIs) - throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report SUCESS - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.SUCCESS); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - - if (clientSIs.size() > 0) { - for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) clientSIs.get(strprid); - - // (PRID) - COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - - // (EPD) - COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - msg.add(cSi); - msg.add(cSi2); - } - } - - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - public void sendAcctReport(Hashtable clientSIs) - throws COPSPepException { - COPSReportMsg msg = new COPSReportMsg(); - // Report SUCESS - try { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); - COPSHandle hnd = _handle; - - COPSReportType report = new COPSReportType(COPSReportType.ACCT); - - msg.add(hdr); - msg.add(hnd); - msg.add(report); - - if (clientSIs.size() > 0) { - for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { - String strprid = (String) e.nextElement(); - String strepd = (String) clientSIs.get(strprid); - - // (PRID) - COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrID prid = new COPSPrID(); - prid.setData(new COPSData(strprid)); - cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength())); - - // (EPD) - COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED); - COPSPrEPD epd = new COPSPrEPD(); - epd.setData(new COPSData(strepd)); - cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength())); - - msg.add(cSi); - msg.add(cSi2); - } - } - - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); - } - } - - /** - * Send Sync State Complete to PDP. - * The Synchronize State Complete is sent by the PEP to the PDP after - * the PDP sends a synchronize state request to the PEP and the PEP has - * finished synchronization. - * - * @throws COPSPepException - * - */ - public void sendSyncComplete() - throws COPSPepException { - // Common Header with the same ClientType as the request - COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType); - - // Client Handle with the same clientHandle as the request - COPSHandle clienthandle = _handle; - - COPSSyncStateMsg msg = new COPSSyncStateMsg(); - try { - msg.add(hdr); - msg.add(clienthandle); - } catch (Exception e) { - throw new COPSPepException("Error making Msg"); - } - - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage()); - } - } - - /** - * Send Delete Request to PDP. - * When sent from the PEP this message indicates to the remote PDP that - * the state identified by the client handle is no longer - * available/relevant. - * - * @throws COPSPepException - * - */ - public void sendDeleteRequest() - throws COPSPepException { - COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType); - COPSHandle handle = _handle; - - // *** TODO: send a real reason - COPSReason reason = new COPSReason((short) 234, (short) 345); - - COPSDeleteMsg msg = new COPSDeleteMsg(); - try { - msg.add(hdr); - msg.add(handle); - msg.add(reason); - } catch (COPSException ex) { - throw new COPSPepException("Error making Msg"); - } - try { - msg.writeData(_sock); - } catch (IOException e) { - throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage()); - } - } -} - - - - +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpep; + +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSClientSI.CSIType; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSReason.ReasonCode; +import org.umu.cops.stack.COPSReportType.ReportType; + +import java.io.IOException; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; + +/** + * COPSPepMsgSender sends COPS messages to PDP. + * + * @version COPSPepMsgSender.java, v 2.00 2004 + * + */ +public class COPSPepMsgSender { + + /** + * Socket connection to PDP + */ + protected Socket _sock; + + /** + * The client-type identifies the policy client + */ + protected short _clientType; + + /** + * The client handle is used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + * Create a COPSPepMsgSender + * + * @param clientType client-type + * @param clientHandle client handle + * @param sock socket of PDP connection + */ + public COPSPepMsgSender (short clientType, COPSHandle clientHandle, Socket sock) { + // COPS Handle + _handle = clientHandle; + _clientType = clientType; + + _sock = sock; + } + + /** + * Return client handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Return client-type + * + * @return a short + * + */ + public short getClientType() { + return _clientType; + } + + /** + * Send Request to PDP. + * The PEP establishes a request state client handle for which the + * remote PDP may maintain state. + * + * @param clientSIs a Hashtable + * + * @throws COPSPepException + * + */ + public void sendRequest(Hashtable clientSIs) + throws COPSPepException { + // Create COPS Message + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType); + COPSContext cntxt = new COPSContext(RType.CONFIG , (short) 0); + + COPSHandle handle = _handle; + + // Add the clientSIs + COPSReqMsg msg = new COPSReqMsg(); + try { + msg.add(hdr) ; + msg.add(handle) ; + msg.add(cntxt) ; + + if (clientSIs.size() > 0) { + for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) clientSIs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSClientSI cSi = new COPSClientSI(CSIType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSClientSI cSi2 = new COPSClientSI(CSIType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + msg.add(cSi); + msg.add(cSi2); + } + } + + } catch (COPSException e) { + throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage()); + } + + // Send message + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the request, reason: " + e.getMessage()); + } + } + + /** + * Send Fail Report to PDP. + * The RPT message is used by the PEP to communicate to the PDP its + * success or failure in carrying out the PDP's decision, or to report + * an accounting related change in state. + * + * @throws COPSPepException + * + */ + public void sendFailReport(Hashtable clientSIs) + throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report FAIL + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.FAILURE); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + if (clientSIs.size() > 0) { + for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) clientSIs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSClientSI cSi = new COPSClientSI(CSIType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSClientSI cSi2 = new COPSClientSI(CSIType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + msg.add(cSi); + msg.add(cSi2); + } + } + + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + /** + * Send Succes Report to PDP. + * The RPT message is used by the PEP to communicate to the PDP its + * success or failure in carrying out the PDP's decision, or to report + * an accounting related change in state. + * + * @throws COPSPepException + * + */ + public void sendSuccessReport(Hashtable clientSIs) + throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report SUCESS + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.SUCCESS); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + + if (clientSIs.size() > 0) { + for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) clientSIs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSClientSI cSi = new COPSClientSI(CSIType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSClientSI cSi2 = new COPSClientSI(CSIType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + msg.add(cSi); + msg.add(cSi2); + } + } + + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + public void sendAcctReport(Hashtable clientSIs) + throws COPSPepException { + COPSReportMsg msg = new COPSReportMsg(); + // Report SUCESS + try { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType); + COPSHandle hnd = _handle; + + COPSReportType report = new COPSReportType(ReportType.ACCOUNTING); + + msg.add(hdr); + msg.add(hnd); + msg.add(report); + + if (clientSIs.size() > 0) { + for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) { + String strprid = (String) e.nextElement(); + String strepd = (String) clientSIs.get(strprid); + + // (PRID) + COPSPrID prid = new COPSPrID(); + prid.setData(new COPSData(strprid)); + COPSClientSI cSi = new COPSClientSI(CSIType.NAMED, + new COPSData(prid.getDataRep(), 0, prid.getDataLength())); + + // (EPD) + COPSPrEPD epd = new COPSPrEPD(); + epd.setData(new COPSData(strepd)); + COPSClientSI cSi2 = new COPSClientSI(CSIType.NAMED, + new COPSData(epd.getDataRep(), 0, epd.getDataLength())); + + msg.add(cSi); + msg.add(cSi2); + } + } + + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the report, reason: " + e.getMessage()); + } + } + + /** + * Send Sync State Complete to PDP. + * The Synchronize State Complete is sent by the PEP to the PDP after + * the PDP sends a synchronize state request to the PEP and the PEP has + * finished synchronization. + * + * @throws COPSPepException + * + */ + public void sendSyncComplete() + throws COPSPepException { + // Common Header with the same ClientType as the request + COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType); + + // Client Handle with the same clientHandle as the request + COPSHandle clienthandle = _handle; + + COPSSyncStateMsg msg = new COPSSyncStateMsg(); + try { + msg.add(hdr); + msg.add(clienthandle); + } catch (Exception e) { + throw new COPSPepException("Error making Msg"); + } + + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage()); + } + } + + /** + * Send Delete Request to PDP. + * When sent from the PEP this message indicates to the remote PDP that + * the state identified by the client handle is no longer + * available/relevant. + * + * @throws COPSPepException + * + */ + public void sendDeleteRequest() + throws COPSPepException { + COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType); + COPSHandle handle = _handle; + + // *** TODO: send a real reason + COPSReason reason = new COPSReason(ReasonCode.NA, ReasonCode.NA); + + COPSDeleteMsg msg = new COPSDeleteMsg(); + try { + msg.add(hdr); + msg.add(handle); + msg.add(reason); + } catch (COPSException ex) { + throw new COPSPepException("Error making Msg"); + } + try { + msg.writeData(_sock); + } catch (IOException e) { + throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage()); + } + } +} + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepReqStateMan.java b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepReqStateMan.java index 5d09425..f29cdb2 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepReqStateMan.java +++ b/packetcable-driver/src/main/java/org/umu/cops/prpep/COPSPepReqStateMan.java @@ -1,395 +1,396 @@ -/* - * Copyright (c) 2004 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.prpep; - -import org.umu.cops.stack.*; - -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -/** - * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21) - * in PEP. - * - * The client handle is used to identify a unique request state for a - * single PEP per client-type. Client handles are chosen by the PEP and - * are opaque to the PDP. The PDP simply uses the request handle to - * uniquely identify the request state for a particular Client-Type over - * a particular TCP connection and generically tie its decisions to a - * corresponding request. Client handles are initiated in request - * messages and are then used by subsequent request, decision, and - * report messages to reference the same request state. When the PEP is - * ready to remove a local request state, it will issue a delete message - * to the PDP for the corresponding client handle. A handle MUST be - * explicitly deleted by the PEP before it can be used by the PEP to - * identify a new request state. Handles referring to different request - * states MUST be unique within the context of a particular TCP - * connection and client-type. - * - * @version COPSPepReqStateMan.java, v 2.00 2004 - * - */ -public class COPSPepReqStateMan { - - /** - * Request State created - */ - public final static short ST_CREATE = 1; - /** - * Request sent - */ - public final static short ST_INIT = 2; - /** - * Decisions received - */ - public final static short ST_DECS = 3; - /** - * Report sent - */ - public final static short ST_REPORT = 4; - /** - * Request State finalized - */ - public final static short ST_FINAL = 5; - /** - * New Request State solicited - */ - public final static short ST_NEW = 6; - /** - * Delete Request State solicited - */ - public final static short ST_DEL = 7; - /** - * SYNC Request received - */ - public final static short ST_SYNC = 8; - /** - * SYNC Completed - */ - public final static short ST_SYNCALL = 9; - /** - * Close Connection received - */ - public final static short ST_CCONN = 10; - /** - * KAlive Time out - */ - public final static short ST_NOKA = 11; - /** - * ACCT Time out - */ - public final static short ST_ACCT = 12; - - /** - * The client-type identifies the policy client - */ - protected short _clientType; - - /** - * The client handle is used to uniquely identify a particular - * PEP's request for a client-type - */ - protected COPSHandle _handle; - - /** - The PolicyDataProcess is used to process policy data in the PEP - */ - protected COPSPepDataProcess _process; - - /** - * State Request State - */ - protected short _status; - - /** - The Msg Sender is used to send COPS messages - */ - protected COPSPepMsgSender _sender; - - /** - * Sync State - */ - protected boolean _syncState; - - /** - * Create a State Request Manager - * - * @param clientHandle a Client Handle - * - */ - public COPSPepReqStateMan(short clientType, String clientHandle) { - _handle = new COPSHandle(new COPSData(clientHandle)); - _clientType = clientType; - _syncState = true; - _status = ST_CREATE; - } - - /** - * Return client handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _handle; - } - - /** - * Return client-type - * - * @return a short - * - */ - public short getClientType() { - return _clientType; - } - - /** - * Return Request State status - * - * @return s short - */ - public short getStatus() { - return _status; - } - - /** - * Return the Policy Data Process - * - * @return a PolicyConfigure - * - */ - public COPSPepDataProcess getDataProcess() { - return _process; - } - - /** - * Establish the Policy Data Process - * - * @param process a PolicyConfigure - * - */ - public void setDataProcess(COPSPepDataProcess process) { - _process = process; - } - - /** - * Init Request State - * - * @throws COPSPepException - * - */ - protected void initRequestState(Socket sock) - throws COPSPepException { - // Inits an object for sending COPS messages to the PDP - _sender = new COPSPepMsgSender(_clientType, _handle, sock); - - // If an object for retrieving PEP features exists, - // use it for retrieving them - Hashtable clientSIs; - if (_process != null) - clientSIs = _process.getClientData(this); - else - clientSIs = null; - - // Send the request - _sender.sendRequest(clientSIs); - - // Initial state - _status = ST_INIT; - } - - /** - * Finalize Request State - * - * @throws COPSPepException - * - */ - protected void finalizeRequestState() - throws COPSPepException { - _sender.sendDeleteRequest(); - _status = ST_FINAL; - } - - /** - * Process the message Decision - * - * @param dMsg a COPSDecisionMsg - * - * @throws COPSPepException - * - */ - protected void processDecision(COPSDecisionMsg dMsg) - throws COPSPepException { - // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str()); - - // COPSHandle handle = dMsg.getClientHandle(); - Hashtable decisions = dMsg.getDecisions(); - - Hashtable removeDecs = new Hashtable(40); - Hashtable installDecs = new Hashtable(40); - Hashtable errorDecs = new Hashtable(40); - for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) decisions.get(context); - Enumeration ee = v.elements(); - COPSDecision cmddecision = (COPSDecision) ee.nextElement(); - - // cmddecision --> we must check whether it is an error! - - if (cmddecision.isInstallDecision()) { - String prid = new String(); - for (; ee.hasMoreElements() ;) { - COPSDecision decision = (COPSDecision) ee.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData()); - switch (obj.getSNum()) { - case COPSPrObjBase.PR_PRID: - prid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - installDecs.put(prid, obj.getData().str()); - break; - default: - break; - } - } - } - - if (cmddecision.isRemoveDecision()) { - - String prid = new String(); - for (; ee.hasMoreElements() ;) { - COPSDecision decision = (COPSDecision) ee.nextElement(); - - COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData()); - switch (obj.getSNum()) { - case COPSPrObjBase.PR_PRID: - prid = obj.getData().str(); - break; - case COPSPrObjBase.PR_EPD: - removeDecs.put(prid, obj.getData().str()); - break; - default: - break; - } - } - } - } - - //** Apply decisions to the configuration - _process.setDecisions(this, removeDecs, installDecs, errorDecs); - _status = ST_DECS; - - - if (_process.isFailReport(this)) { - // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n"); - _sender.sendFailReport(_process.getReportData(this)); - } else { - // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n"); - _sender.sendSuccessReport(_process.getReportData(this)); - } - _status = ST_REPORT; - - if (!_syncState) { - _sender.sendSyncComplete(); - _syncState = true; - _status = ST_SYNCALL; - } - } - - /** - * Process the message NewRequestState - * - * @throws COPSPepException - * - */ - protected void processOpenNewRequestState() - throws COPSPepException { - - if (_process != null) - _process.newRequestState(this); - - _status = ST_NEW; - } - - /** - * Process the message DeleteRequestState - * - * @param dMsg a COPSDecisionMsg - * - * @throws COPSPepException - * - */ - protected void processDeleteRequestState(COPSDecisionMsg dMsg) - throws COPSPepException { - if (_process != null) - _process.closeRequestState(this); - - _status = ST_DEL; - } - - /** - * Process the message SycnStateRequest. - * The message SycnStateRequest indicates that the remote PDP - * wishes the client (which appears in the common header) - * to re-send its state. - * - * @param ssMsg a COPSSyncStateMsg - * - * @throws COPSPepException - * - */ - protected void processSyncStateRequest(COPSSyncStateMsg ssMsg) - throws COPSPepException { - _syncState = false; - // If an object for retrieving PEP features exists, - // use it for retrieving them - Hashtable clientSIs; - if (_process != null) - clientSIs = _process.getClientData(this); - else - clientSIs = null; - - // Send request - _sender.sendRequest(clientSIs); - - _status = ST_SYNC; - } - - protected void processClosedConnection(COPSError error) - throws COPSPepException { - if (_process != null) - _process.notifyClosedConnection(this, error); - - _status = ST_CCONN; - } - - protected void processNoKAConnection() - throws COPSPepException { - if (_process != null) - _process.notifyNoKAliveReceived(this); - - _status = ST_NOKA; - } - - protected void processAcctReport() - throws COPSPepException { - - Hashtable report = new Hashtable(); - if (_process != null) - report = _process.getAcctData(this); - - _sender.sendAcctReport(report); - - _status = ST_ACCT; - } - -} +/* + * Copyright (c) 2004 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.prpep; + +import org.umu.cops.stack.*; +import org.umu.cops.stack.COPSDecision.Command; + +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21) + * in PEP. + * + * The client handle is used to identify a unique request state for a + * single PEP per client-type. Client handles are chosen by the PEP and + * are opaque to the PDP. The PDP simply uses the request handle to + * uniquely identify the request state for a particular Client-Type over + * a particular TCP connection and generically tie its decisions to a + * corresponding request. Client handles are initiated in request + * messages and are then used by subsequent request, decision, and + * report messages to reference the same request state. When the PEP is + * ready to remove a local request state, it will issue a delete message + * to the PDP for the corresponding client handle. A handle MUST be + * explicitly deleted by the PEP before it can be used by the PEP to + * identify a new request state. Handles referring to different request + * states MUST be unique within the context of a particular TCP + * connection and client-type. + * + * @version COPSPepReqStateMan.java, v 2.00 2004 + * + */ +public class COPSPepReqStateMan { + + /** + * Request State created + */ + public final static short ST_CREATE = 1; + /** + * Request sent + */ + public final static short ST_INIT = 2; + /** + * Decisions received + */ + public final static short ST_DECS = 3; + /** + * Report sent + */ + public final static short ST_REPORT = 4; + /** + * Request State finalized + */ + public final static short ST_FINAL = 5; + /** + * New Request State solicited + */ + public final static short ST_NEW = 6; + /** + * Delete Request State solicited + */ + public final static short ST_DEL = 7; + /** + * SYNC Request received + */ + public final static short ST_SYNC = 8; + /** + * SYNC Completed + */ + public final static short ST_SYNCALL = 9; + /** + * Close Connection received + */ + public final static short ST_CCONN = 10; + /** + * KAlive Time out + */ + public final static short ST_NOKA = 11; + /** + * ACCT Time out + */ + public final static short ST_ACCT = 12; + + /** + * The client-type identifies the policy client + */ + protected short _clientType; + + /** + * The client handle is used to uniquely identify a particular + * PEP's request for a client-type + */ + protected COPSHandle _handle; + + /** + The PolicyDataProcess is used to process policy data in the PEP + */ + protected COPSPepDataProcess _process; + + /** + * State Request State + */ + protected short _status; + + /** + The Msg Sender is used to send COPS messages + */ + protected COPSPepMsgSender _sender; + + /** + * Sync State + */ + protected boolean _syncState; + + /** + * Create a State Request Manager + * + * @param clientHandle a Client Handle + * + */ + public COPSPepReqStateMan(short clientType, String clientHandle) { + _handle = new COPSHandle(new COPSData(clientHandle)); + _clientType = clientType; + _syncState = true; + _status = ST_CREATE; + } + + /** + * Return client handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _handle; + } + + /** + * Return client-type + * + * @return a short + * + */ + public short getClientType() { + return _clientType; + } + + /** + * Return Request State status + * + * @return s short + */ + public short getStatus() { + return _status; + } + + /** + * Return the Policy Data Process + * + * @return a PolicyConfigure + * + */ + public COPSPepDataProcess getDataProcess() { + return _process; + } + + /** + * Establish the Policy Data Process + * + * @param process a PolicyConfigure + * + */ + public void setDataProcess(COPSPepDataProcess process) { + _process = process; + } + + /** + * Init Request State + * + * @throws COPSPepException + * + */ + protected void initRequestState(Socket sock) + throws COPSPepException { + // Inits an object for sending COPS messages to the PDP + _sender = new COPSPepMsgSender(_clientType, _handle, sock); + + // If an object for retrieving PEP features exists, + // use it for retrieving them + Hashtable clientSIs; + if (_process != null) + clientSIs = _process.getClientData(this); + else + clientSIs = null; + + // Send the request + _sender.sendRequest(clientSIs); + + // Initial state + _status = ST_INIT; + } + + /** + * Finalize Request State + * + * @throws COPSPepException + * + */ + protected void finalizeRequestState() + throws COPSPepException { + _sender.sendDeleteRequest(); + _status = ST_FINAL; + } + + /** + * Process the message Decision + * + * @param dMsg a COPSDecisionMsg + * + * @throws COPSPepException + * + */ + protected void processDecision(COPSDecisionMsg dMsg) + throws COPSPepException { + // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str()); + + // COPSHandle handle = dMsg.getClientHandle(); + Hashtable decisions = dMsg.getDecisions(); + + Hashtable removeDecs = new Hashtable(40); + Hashtable installDecs = new Hashtable(40); + Hashtable errorDecs = new Hashtable(40); + for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) decisions.get(context); + Enumeration ee = v.elements(); + COPSDecision cmddecision = (COPSDecision) ee.nextElement(); + + // cmddecision --> we must check whether it is an error! + + if (cmddecision.getCommand().equals(Command.INSTALL)) { + String prid = ""; + for (; ee.hasMoreElements() ;) { + COPSDecision decision = (COPSDecision) ee.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData()); + switch (obj.getSNum()) { + case COPSPrObjBase.PR_PRID: + prid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + installDecs.put(prid, obj.getData().str()); + break; + default: + break; + } + } + } + + if (cmddecision.getCommand().equals(Command.REMOVE)) { + + String prid = ""; + for (; ee.hasMoreElements() ;) { + COPSDecision decision = (COPSDecision) ee.nextElement(); + + COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData()); + switch (obj.getSNum()) { + case COPSPrObjBase.PR_PRID: + prid = obj.getData().str(); + break; + case COPSPrObjBase.PR_EPD: + removeDecs.put(prid, obj.getData().str()); + break; + default: + break; + } + } + } + } + + //** Apply decisions to the configuration + _process.setDecisions(this, removeDecs, installDecs, errorDecs); + _status = ST_DECS; + + + if (_process.isFailReport(this)) { + // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n"); + _sender.sendFailReport(_process.getReportData(this)); + } else { + // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n"); + _sender.sendSuccessReport(_process.getReportData(this)); + } + _status = ST_REPORT; + + if (!_syncState) { + _sender.sendSyncComplete(); + _syncState = true; + _status = ST_SYNCALL; + } + } + + /** + * Process the message NewRequestState + * + * @throws COPSPepException + * + */ + protected void processOpenNewRequestState() + throws COPSPepException { + + if (_process != null) + _process.newRequestState(this); + + _status = ST_NEW; + } + + /** + * Process the message DeleteRequestState + * + * @param dMsg a COPSDecisionMsg + * + * @throws COPSPepException + * + */ + protected void processDeleteRequestState(COPSDecisionMsg dMsg) + throws COPSPepException { + if (_process != null) + _process.closeRequestState(this); + + _status = ST_DEL; + } + + /** + * Process the message SycnStateRequest. + * The message SycnStateRequest indicates that the remote PDP + * wishes the client (which appears in the common header) + * to re-send its state. + * + * @param ssMsg a COPSSyncStateMsg + * + * @throws COPSPepException + * + */ + protected void processSyncStateRequest(COPSSyncStateMsg ssMsg) + throws COPSPepException { + _syncState = false; + // If an object for retrieving PEP features exists, + // use it for retrieving them + Hashtable clientSIs; + if (_process != null) + clientSIs = _process.getClientData(this); + else + clientSIs = null; + + // Send request + _sender.sendRequest(clientSIs); + + _status = ST_SYNC; + } + + protected void processClosedConnection(COPSError error) + throws COPSPepException { + if (_process != null) + _process.notifyClosedConnection(this, error); + + _status = ST_CCONN; + } + + protected void processNoKAConnection() + throws COPSPepException { + if (_process != null) + _process.notifyNoKAliveReceived(this); + + _status = ST_NOKA; + } + + protected void processAcctReport() + throws COPSPepException { + + Hashtable report = new Hashtable(); + if (_process != null) + report = _process.getAcctData(this); + + _sender.sendAcctReport(report); + + _status = ST_ACCT; + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSAcctTimer.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSAcctTimer.java index e6a733a..fe5dadf 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSAcctTimer.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSAcctTimer.java @@ -1,47 +1,88 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -/** - * COPS Accounting Timer Object - * - * @version COPSAcctTimer.java, v 1.00 2003 - * - */ -public class COPSAcctTimer extends COPSTimer { - - public COPSAcctTimer() { - super(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), (short) 1); - } - - /// - public COPSAcctTimer(short timeVal) { - super(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), timeVal); - } - - /// - /** - * Method isAcctTimer - * - * @return a boolean - * - */ - public boolean isAcctTimer() { - return true; - } - - /// - protected COPSAcctTimer(byte[] dataPtr) { - super (dataPtr); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS Accounting Timer Object (RFC 2748) + * + * Times are encoded as 2 octet integer values and are in units of + * seconds. The timer value is treated as a delta. + * + * C-Num = 15, + * C-Type = 1, Accounting timer value + * + * Optional timer value used to determine the minimum interval between + * periodic accounting type reports. It is used by the PDP to describe + * to the PEP an acceptable interval between unsolicited accounting + * updates via Report messages where applicable. It provides a method + * for the PDP to control the amount of accounting traffic seen by the + * network. The range of finite time values is 1 to 65535 seconds + * represented as an unsigned two-octet integer. A value of zero means + * there SHOULD be no unsolicited accounting updates. + */ +public class COPSAcctTimer extends COPSTimer { + + /** + * Constructor generally used for sending messages + * @param timeVal - the timer value + * @throws java.lang.IllegalArgumentException when the id parameter is null + */ + public COPSAcctTimer(final short timeVal) { + this((short)0, timeVal); + } + + /** + * Constructor generally used for sending messages with some reserved value + * @param reserved - ??? + * @param timeVal - the timer value + * @throws java.lang.IllegalArgumentException when the id parameter is null + */ + protected COPSAcctTimer(final short reserved, final short timeVal) { + this(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), reserved, timeVal); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param header - the object header + * @param reserved - ??? + * @param timeVal - the timer value + * @throws java.lang.IllegalArgumentException + */ + protected COPSAcctTimer(final COPSObjHeader header, final short reserved, final short timeVal) { + super(header, reserved, timeVal); + if (!header.getCNum().equals(CNum.ACCT_TIMER)) + throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.ACCT_TIMER); + if (!header.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSAcctTimer parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + short reserved = 0; + reserved |= ((short) dataPtr[4]) << 8; + reserved |= ((short) dataPtr[5]) & 0xFF; + + short timerValue = 0; + timerValue |= ((short) dataPtr[6]) << 8; + timerValue |= ((short) dataPtr[7]) & 0xFF; + + return new COPSAcctTimer(objHdrData.header, reserved, timerValue); + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientAcceptMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientAcceptMsg.java index dde0963..694361a 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientAcceptMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientAcceptMsg.java @@ -1,252 +1,252 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Client Accept Message - * - * @version COPSClientAcceptMsg.java, v 1.00 2003 - * - */ -public class COPSClientAcceptMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSKATimer _kaTimer; - private COPSAcctTimer _acctTimer; - private COPSIntegrity _integrity; - - ///Constructor - public COPSClientAcceptMsg() { - _kaTimer = null; - _acctTimer = null; - _integrity = null; - } - - ///Create object from data - protected COPSClientAcceptMsg(byte[] data) throws COPSException { - parse(data); - } - - /** Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_kaTimer == null)) - throw new COPSException("Bad message format"); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT) - throw new COPSException ("Error Header (no COPS_OP_CAT)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Timer object to the message - * - * @param timer a COPSTimer - * - * @throws COPSException - * - */ - public void add (COPSTimer timer) throws COPSException { - if (timer.isKATimer()) { - _kaTimer = (COPSKATimer) timer; - } else { - _acctTimer = (COPSAcctTimer) timer; - } - setMsgLength(); - } - - /** - * Add Integrity objects - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Method getKATimer - * - * @return a COPSKATimer - * - */ - public COPSKATimer getKATimer() { - return _kaTimer; - }; - - /** - * Returns true if has a account timer object - * - * @return a boolean - * - */ - public boolean hasAcctTimer() { - return (_acctTimer != null); - }; - - /** - * Should check hasAcctTimer() before calling - * - * @return a COPSAcctTimer - * - */ - public COPSAcctTimer getAcctTimer() { - return (_acctTimer); - } - - /** - * Returns true if has a Integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - }; - - /** - * Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Writes data to a given socket id - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_kaTimer != null) _kaTimer.writeData(id); - if (_acctTimer != null) _acctTimer.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Method parse - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case KA: - _kaTimer = new COPSKATimer(buf); - _dataStart += _kaTimer.getDataLength(); - break; - case ACCT_TIMER: - _acctTimer = new COPSAcctTimer(buf); - _dataStart += _acctTimer.getDataLength(); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format"); - } - } - checkSanity(); - } - - /** - * Method parse - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT) - throw new COPSException("Error Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - if (_kaTimer != null) len += _kaTimer.getDataLength(); - if (_acctTimer != null) len += _acctTimer.getDataLength(); - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_kaTimer != null) - _kaTimer.dump(os); - - if (_acctTimer != null) - _acctTimer.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Client Accept Message + * + * @version COPSClientAcceptMsg.java, v 1.00 2003 + * + */ +public class COPSClientAcceptMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSKATimer _kaTimer; + private COPSAcctTimer _acctTimer; + private COPSIntegrity _integrity; + + ///Constructor + public COPSClientAcceptMsg() { + _kaTimer = null; + _acctTimer = null; + _integrity = null; + } + + ///Create object from data + protected COPSClientAcceptMsg(byte[] data) throws COPSException { + parse(data); + } + + /** Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_kaTimer == null)) + throw new COPSException("Bad message format"); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT) + throw new COPSException ("Error Header (no COPS_OP_CAT)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Timer object to the message + * + * @param timer a COPSTimer + * + * @throws COPSException + * + */ + public void add (COPSTimer timer) throws COPSException { + if (timer.getHeader().getCNum().equals(CNum.KA)) { + _kaTimer = (COPSKATimer) timer; + } else { + _acctTimer = (COPSAcctTimer) timer; + } + setMsgLength(); + } + + /** + * Add Integrity objects + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Method getKATimer + * + * @return a COPSKATimer + * + */ + public COPSKATimer getKATimer() { + return _kaTimer; + }; + + /** + * Returns true if has a account timer object + * + * @return a boolean + * + */ + public boolean hasAcctTimer() { + return (_acctTimer != null); + }; + + /** + * Should check hasAcctTimer() before calling + * + * @return a COPSAcctTimer + * + */ + public COPSAcctTimer getAcctTimer() { + return (_acctTimer); + } + + /** + * Returns true if has a Integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + }; + + /** + * Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Writes data to a given socket id + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_kaTimer != null) _kaTimer.writeData(id); + if (_acctTimer != null) _acctTimer.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Method parse + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case KA: + _kaTimer = COPSKATimer.parse(objHdrData, buf); + _dataStart += _kaTimer.getDataLength(); + break; + case ACCT_TIMER: + _acctTimer = COPSAcctTimer.parse(objHdrData, buf); + _dataStart += _acctTimer.getDataLength(); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format"); + } + } + checkSanity(); + } + + /** + * Method parse + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT) + throw new COPSException("Error Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + if (_kaTimer != null) len += _kaTimer.getDataLength(); + if (_acctTimer != null) len += _acctTimer.getDataLength(); + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_kaTimer != null) + _kaTimer.dump(os); + + if (_acctTimer != null) + _acctTimer.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientCloseMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientCloseMsg.java index 87f113a..ffa0524 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientCloseMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientCloseMsg.java @@ -1,221 +1,219 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Client Close Message - * - * @version COPSClientCloseMsg.java, v 1.00 2003 - * - */ -public class COPSClientCloseMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSError _error; - private COPSIntegrity _integrity; - - - public COPSClientCloseMsg() { - _error = null; - _integrity = null; - } - - protected COPSClientCloseMsg(byte[] data) throws COPSException { - parse (data); - } - - /** Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_error == null)) - throw new COPSException("Bad message format"); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_CC) - throw new COPSException ("Error Header (no COPS_OP_CC)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Error object - * - * @param error a COPSError - * - * @throws COPSException - * - */ - public void add (COPSError error) throws COPSException { - //Message integrity object should be the very last one - //If it is already added - if (_error != null) - throw new COPSException ("No null Error"); - _error = error; - setMsgLength(); - } - - /** - * Add Integrity objects - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Method getError - * - * @return a COPSError - * - */ - public COPSError getError() { - return (_error); - } - - /** - * Returns true If it has integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - }; - - /** - * Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Write object data to given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_error != null) _error.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Method parse - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case ERROR: - _error = new COPSError(buf); - _dataStart += _error.getDataLength(); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format"); - } - } - checkSanity(); - } - - /** - * Method parse - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_CC) - throw new COPSException("Error Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - int len = 0; - if (_error != null) len += _error.getDataLength(); - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_error != null) - _error.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Client Close Message + * + * @version COPSClientCloseMsg.java, v 1.00 2003 + * + */ +public class COPSClientCloseMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSError _error; + private COPSIntegrity _integrity; + + + public COPSClientCloseMsg() { + _error = null; + _integrity = null; + } + + protected COPSClientCloseMsg(byte[] data) throws COPSException { + parse (data); + } + + /** Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_error == null)) + throw new COPSException("Bad message format"); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_CC) + throw new COPSException ("Error Header (no COPS_OP_CC)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Error object + * + * @param error a COPSError + * + * @throws COPSException + * + */ + public void add (COPSError error) throws COPSException { + //Message integrity object should be the very last one + //If it is already added + if (_error != null) + throw new COPSException ("No null Error"); + _error = error; + setMsgLength(); + } + + /** + * Add Integrity objects + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Method getError + * + * @return a COPSError + * + */ + public COPSError getError() { + return (_error); + } + + /** + * Returns true If it has integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + }; + + /** + * Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Write object data to given network socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_error != null) _error.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Method parse + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case ERROR: + _error = COPSError.parse(objHdrData, buf); + _dataStart += _error.getDataLength(); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format"); + } + } + checkSanity(); + } + + /** + * Method parse + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_CC) + throw new COPSException("Error Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + int len = 0; + if (_error != null) len += _error.getDataLength(); + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_error != null) + _error.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientOpenMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientOpenMsg.java index 20faf0c..4cadc06 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientOpenMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientOpenMsg.java @@ -1,325 +1,317 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Client Open Message - * - * @version COPSClientOpenMsg.java, v 1.00 2003 - * - */ -public class COPSClientOpenMsg extends COPSMsg { - - private COPSPepId _pepId; - private COPSClientSI _clientSI; - private COPSPdpAddress _pdpAddress; - private COPSIntegrity _integrity; - - public COPSClientOpenMsg() { - _pepId = null; - _clientSI = null; - _pdpAddress = null; - _integrity = null; - _hdr = null; - } - - protected COPSClientOpenMsg(byte[] data) throws COPSException { - _pepId = null; - _clientSI = null; - _pdpAddress = null; - _integrity = null; - _hdr = null; - parse(data); - } - - /** - * Method writeData - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null)_hdr.writeData(id); - if (_pepId != null) _pepId.writeData(id); - if (_clientSI != null) _clientSI.writeData(id); - if (_pdpAddress != null) _pdpAddress.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN) - throw new COPSException ("Error Header (no COPS_OP_OPN)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add PEP Identification Object - * - * @param pepid a COPSPepId - * - * @throws COPSException - * - */ - public void add (COPSPepId pepid) throws COPSException { - if (pepid == null) - throw new COPSException ("Null COPSPepId"); - if (!pepid.isPepId()) - throw new COPSException ("Error COPSPepId"); - _pepId = pepid; - setMsgLength(); - } - - /** - * Add Client Specific Information Object - * - * @param clientSI a COPSClientSI - * - * @throws COPSException - * - */ - public void add (COPSClientSI clientSI) throws COPSException { - if (clientSI == null) - throw new COPSException ("Null COPSClientSI"); - if (!clientSI.isClientSI()) - throw new COPSException ("Error COPSClientSI"); - _clientSI = clientSI; - setMsgLength(); - } - - /** - * Add PDP Address - * - * @param pdpAddr a COPSPdpAddress - * - * @throws COPSException - * - */ - public void add (COPSPdpAddress pdpAddr) throws COPSException { - if (pdpAddr == null) - throw new COPSException ("Null COPSPdpAddress"); - if (!pdpAddr.isLastPdpAddress()) - throw new COPSException ("Error COPSPdpAddress"); - _pdpAddress = pdpAddr; - setMsgLength(); - } - - /** - * Add Integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_pepId == null)) - throw new COPSException("Bad message format"); - } - - /** - * Method getPepId - * - * @return a COPSPepId - * - */ - public COPSPepId getPepId() { - return _pepId; - } - - /** - * Method hasClientSI - * - * @return a boolean - * - */ - public boolean hasClientSI() { - return (_clientSI != null); - } - - /** - * Method getClientSI - * - * @return a COPSClientSI - * - */ - public COPSClientSI getClientSI() { - return (_clientSI); - } - - /** - * Method hasPdpAddress - * - * @return a boolean - * - */ - public boolean hasPdpAddress() { - return (_pdpAddress != null); - } - - /** - * Method getPdpAddress - * - * @return a COPSPdpAddress - * - */ - public COPSPdpAddress getPdpAddress() { - return _pdpAddress; - } - - /** - * Method hasIntegrity - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - } - - /** - * Method getIntegrity - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return _integrity; - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - private void setMsgLength() throws COPSException { - short len = 0; - if (_pepId != null) len += _pepId.getDataLength(); - if (_clientSI != null) len += _clientSI.getDataLength(); - if (_pdpAddress != null) len += _pdpAddress.getDataLength(); - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Method parse - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - parseHeader(data); - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case PEPID: - _pepId = new COPSPepId(buf); - _dataStart += _pepId.getDataLength(); - break; - case LAST_PDP_ADDR: - if (objHdr.getCType().ordinal() == 1) { - _pdpAddress = new COPSIpv4LastPdpAddr(buf); - } else if (objHdr.getCType().ordinal() == 2) { - _pdpAddress = new COPSIpv6LastPdpAddr(buf); - } - _dataStart += _pdpAddress.getDataLength(); - break; - case CSI: - _clientSI = new COPSClientSI(buf); - _dataStart += _clientSI.getDataLength(); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format"); - } - } - checkSanity(); - } - - /** - * Method parse - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN) - throw new COPSException("Error Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_pepId != null) - _pepId.dump(os); - - if (_clientSI != null) - _clientSI.dump(os); - - if (_pdpAddress != null) - _pdpAddress.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Client Open Message + * + * @version COPSClientOpenMsg.java, v 1.00 2003 + * + */ +public class COPSClientOpenMsg extends COPSMsg { + + private COPSPepId _pepId; + private COPSClientSI _clientSI; + private COPSPdpAddress _pdpAddress; + private COPSIntegrity _integrity; + + public COPSClientOpenMsg() { + _pepId = null; + _clientSI = null; + _pdpAddress = null; + _integrity = null; + _hdr = null; + } + + protected COPSClientOpenMsg(byte[] data) throws COPSException { + _pepId = null; + _clientSI = null; + _pdpAddress = null; + _integrity = null; + _hdr = null; + parse(data); + } + + /** + * Method writeData + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null)_hdr.writeData(id); + if (_pepId != null) _pepId.writeData(id); + if (_clientSI != null) _clientSI.writeData(id); + if (_pdpAddress != null) _pdpAddress.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN) + throw new COPSException ("Error Header (no COPS_OP_OPN)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add PEP Identification Object + * + * @param pepid a COPSPepId + * + * @throws COPSException + * + */ + public void add(COPSPepId pepid) throws COPSException { + if (pepid == null) + throw new COPSException ("Null COPSPepId"); + _pepId = pepid; + setMsgLength(); + } + + /** + * Add Client Specific Information Object + * + * @param clientSI a COPSClientSI + * + * @throws COPSException + * + */ + public void add (COPSClientSI clientSI) throws COPSException { + if (clientSI == null) + throw new COPSException ("Null COPSClientSI"); + _clientSI = clientSI; + setMsgLength(); + } + + /** + * Add PDP Address + * + * @param pdpAddr a COPSPdpAddress + * + * @throws COPSException + * + */ + public void add(COPSPdpAddress pdpAddr) throws COPSException { + if (pdpAddr == null) + throw new COPSException ("Null COPSPdpAddress"); + if (pdpAddr.getHeader().getCNum().equals(CNum.LAST_PDP_ADDR)) + throw new COPSException ("Error Last PDP address object added, invalid"); + _pdpAddress = pdpAddr; + setMsgLength(); + } + + /** + * Add Integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add(COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_pepId == null)) + throw new COPSException("Bad message format"); + } + + /** + * Method getPepId + * + * @return a COPSPepId + * + */ + public COPSPepId getPepId() { + return _pepId; + } + + /** + * Method hasClientSI + * + * @return a boolean + * + */ + public boolean hasClientSI() { + return (_clientSI != null); + } + + /** + * Method getClientSI + * + * @return a COPSClientSI + * + */ + public COPSClientSI getClientSI() { + return (_clientSI); + } + + /** + * Method hasPdpAddress + * + * @return a boolean + * + */ + public boolean hasPdpAddress() { + return (_pdpAddress != null); + } + + /** + * Method getPdpAddress + * + * @return a COPSPdpAddress + * + */ + public COPSPdpAddress getPdpAddress() { + return _pdpAddress; + } + + /** + * Method hasIntegrity + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + } + + /** + * Method getIntegrity + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return _integrity; + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + private void setMsgLength() throws COPSException { + short len = 0; + if (_pepId != null) len += _pepId.getDataLength(); + if (_clientSI != null) len += _clientSI.getDataLength(); + if (_pdpAddress != null) len += _pdpAddress.getDataLength(); + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Method parse + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + parseHeader(data); + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case PEPID: + _pepId = COPSPepId.parse(objHdrData, buf); + _dataStart += _pepId.getDataLength(); + break; + case LAST_PDP_ADDR: + _pdpAddress = COPSPdpAddress.parse(objHdrData, buf); + _dataStart += _pdpAddress.getDataLength(); + break; + case CSI: + _clientSI = COPSClientSI.parse(objHdrData, buf); + _dataStart += _clientSI.getDataLength(); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format"); + } + } + checkSanity(); + } + + /** + * Method parse + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN) + throw new COPSException("Error Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_pepId != null) + _pepId.dump(os); + + if (_clientSI != null) + _clientSI.dump(os); + + if (_pdpAddress != null) + _pdpAddress.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientSI.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientSI.java index 8b6bf23..e25fb91 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientSI.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSClientSI.java @@ -1,127 +1,182 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Client Specific Information Object - * - * @version COPSClientSI.java, v 1.00 2003 - * - */ -public class COPSClientSI extends COPSObjBase { - public final static byte CSI_SIGNALED = 1; - public final static byte CSI_NAMED = 2; - - private COPSObjHeader _objHdr; - private COPSData _data; - private COPSData _padding; - - /// - public COPSClientSI(byte type) { - _objHdr = new COPSObjHeader(CNum.CSI, COPSObjHeader.VAL_TO_CTYPE.get((int)type)); - } - - public COPSClientSI(byte cnum, byte ctype) { - _objHdr = new COPSObjHeader(COPSObjHeader.VAL_TO_CNUM.get((int)cnum), COPSObjHeader.VAL_TO_CTYPE.get((int)ctype)); - } - - /** - Parse the data and create a ClientSI object - */ - protected COPSClientSI(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - //Get the length of data following the obj header - short dLen = (short) (_objHdr.getDataLength() - 4); - COPSData d = new COPSData(dataPtr, 4, dLen); - setData(d); - } - - /** - * Method setData - * - * @param data a COPSData - * - */ - public void setData(COPSData data) { - _data = data; - if (_data.length() % 4 != 0) { - int padLen = 4 - _data.length() % 4; - _padding = getPadding(padLen); - } - _objHdr.setDataLength((short) _data.length()); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - int lpadding = 0; - if (_padding != null) lpadding = _padding.length(); - return (short) (_objHdr.getDataLength() + lpadding); - } - - /** - * Method getData - * - * @return a COPSData - * - */ - public COPSData getData() { - return _data; - }; - - /** - * Method isClientSI - * - * @return a boolean - * - */ - public boolean isClientSI() { - return true; - } - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - COPSUtil.writeData(id, _data.getData(), _data.length()); - if (_padding != null) { - COPSUtil.writeData(id, _padding.getData(), _padding.length()); - } - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("client-SI: " + _data.str() + "\n").getBytes()); - } -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Client Specific Information Object (RFC 2748) + * + * The various types of this object are required for requests, and used + * in reports and opens when required. It contains client-type specific + * information. + * + * C-Num = 9, + * + * C-Type = 1, Signaled ClientSI. + * + * Variable-length field. All objects/attributes specific to a client's + * signaling protocol or internal state are encapsulated within one or + * more signaled Client Specific Information Objects. The format of the + * data encapsulated in the ClientSI object is determined by the + * client-type. + * + * C-Type = 2, Named ClientSI. + * + * Variable-length field. Contains named configuration information + * useful for relaying specific information about the PEP, a request, or + * configured state to the PDP server. + */ +public class COPSClientSI extends COPSObjBase { + + private final static Map VAL_TO_CSI = new ConcurrentHashMap<>(); + static { + VAL_TO_CSI.put(CSIType.NA.ordinal(), CSIType.NA); + VAL_TO_CSI.put(CSIType.SIGNALED.ordinal(), CSIType.SIGNALED); + VAL_TO_CSI.put(CSIType.NAMED.ordinal(), CSIType.NAMED); + } + + /** + * This value is not being used here but stored only for clarity as it is being mapped directly to the + * ordinal value of the CType + */ + private final CSIType _csiType; + + /** + * The payload data + */ + private final COPSData _data; + + /** + * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes + */ + private final COPSData _padding; + + /** + * Constructor generally used for sending messages + * @param csitype - the CSIType + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSClientSI(final CSIType csitype, final COPSData data) { + /* The CSIType does not map directly to the CType, therefore the hook to map to a CType below is + required to ensure the header value outputs the correct value when streamed + */ + this(new COPSObjHeader(CNum.CSI, COPSObjHeader.VAL_TO_CTYPE.get(csitype.ordinal())), data); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + protected COPSClientSI(final COPSObjHeader hdr, final COPSData data) { + super(hdr); + _csiType = VAL_TO_CSI.get(hdr.getCType().ordinal()); + + if (!hdr.getCNum().equals(CNum.CSI)) + throw new IllegalArgumentException("CNum must be equal to " + CNum.CSI); + if (_csiType == null || _csiType.equals(CSIType.NA)) + throw new IllegalArgumentException("Invalid CSIType"); + if (_csiType.ordinal() != hdr.getCType().ordinal()) + throw new IllegalArgumentException("Error mapping CSIType " + _csiType + " to CType" + hdr.getCType()); + if (data == null) throw new IllegalArgumentException("Data must not be null"); + + _data = data; + if ((_data.length() % 4) != 0) { + final int padLen = 4 - (_data.length() % 4); + _padding = COPSObjectParser.getPadding(padLen); + } else { + _padding = new COPSData(); + } + } + + /** + * Returns the CSIType + * @return - the type + */ + public CSIType getCsiType() { return _csiType; } + + /** + * Returns the data + * @return - the data + */ + public COPSData getData() { return _data; } + + @Override + /* The super says protected but this needs to be public due to usage in COPSDecisionMsgEX.java which is currently + calling this method. */ + public int getDataLength() { + return _data.length() + _padding.length(); + } + + @Override + public void writeBody(final Socket socket) throws IOException { + COPSUtil.writeData(socket, _data.getData(), _data.length()); + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("CSI-type: " + _csiType + "\n").getBytes()); + os.write(("client-SI: " + _data.str() + "\n").getBytes()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSClientSI)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSClientSI that = (COPSClientSI) o; + return _data.equals(that._data) && _padding.equals(that._padding) || + COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (_data != null ? _data.hashCode() : 0); + result = 31 * result + (_padding != null ? _padding.hashCode() : 0); + return result; + } + + /** + * Parses bytes to return a COPSClientSI object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSClientSI parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + short dLen = (short) (objHdrData.msgByteCount - 4); + return new COPSClientSI(objHdrData.header, new COPSData(dataPtr, 4, dLen)); + } + + /** + * The different CSI types. NA does not exist but is a placeholder for 0 as the ordinal values will be used + * to determine which type for marshalling + */ + public enum CSIType { + NA, SIGNALED, NAMED + } +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSContext.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSContext.java index 4aa1821..828d8e8 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSContext.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSContext.java @@ -1,210 +1,191 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Context Object - * - * @version COPSContext.java, v 1.00 2003 - * - */ -public class COPSContext extends COPSObjBase { - - public final static byte IN_ADMIN = 0x01; - public final static byte RES_ALLOC = 0x02; - public final static byte OUT = 0x04; - public final static byte CONFIG = 0x08; - - private COPSObjHeader _objHdr; - private short _rType; - private short _mType; - - /// - public COPSContext(short rType, short mType ) { - _objHdr = new COPSObjHeader(CNum.CONTEXT, CType.DEF); - _rType = rType; - _mType = mType; - _objHdr.setDataLength((short) 4); - } - - /** - Parse the data and create a Context object - */ - protected COPSContext(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _rType |= ((short) dataPtr[4]) << 8; - _rType |= ((short) dataPtr[5]) & 0xFF; - - _mType |= ((short) dataPtr[6]) << 8; - _mType |= ((short) dataPtr[7]) & 0xFF; - - _objHdr.setDataLength( (short) 4); - } - - /** - * Write object in network byte order to a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - byte[] buf = new byte[4]; - - buf[0] = (byte) (_rType >> 8); - buf[1] = (byte) _rType; - - buf[2] = (byte) (_mType >> 8); - buf[3] = (byte) _mType; - - COPSUtil.writeData(id, buf, 4); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - /** - * Returns the detail description of the request type - * - * @return a String - * - */ - public String getDescription() { - String retStr = new String(); - if ((_rType & 0x01) != 0) { - retStr += (retStr.length() != 0) ? "," : ""; - retStr += "Incoming Message/Admission Control"; - } - if ((_rType & 0x02) != 0) { - retStr += (retStr.length() != 0) ? "," : ""; - retStr += "Resource allocation"; - } - if ((_rType & 0x04) != 0) { - retStr += (retStr.length() != 0) ? "," : ""; - retStr += "Outgoing message"; - } - if ((_rType & 0x08) != 0) { - retStr += (retStr.length() != 0) ? "," : ""; - retStr += "Configuration"; - } - return retStr; - } - - /** - * Method isIncomingMessage - * - * @return a boolean - * - */ - public boolean isIncomingMessage() { - return (_rType & IN_ADMIN) != 0; - }; - - /** - * Method isAdminControl - * - * @return a boolean - * - */ - public boolean isAdminControl() { - return (_rType & IN_ADMIN) != 0; - }; - - /** - * Method isResourceAllocationReq - * - * @return a boolean - * - */ - public boolean isResourceAllocationReq() { - return (_rType & RES_ALLOC) != 0; - }; - - /** - * Method isOutgoingMessage - * - * @return a boolean - * - */ - public boolean isOutgoingMessage() { - return (_rType & OUT) != 0; - }; - - /** - * Method isConfigRequest - * - * @return a boolean - * - */ - public boolean isConfigRequest() { - return (_rType & CONFIG) != 0; - }; - - /** - * Method getMessageType - * - * @return a short - * - */ - public short getMessageType() { - return (_mType) ; - }; - - /** - * Method getRequestType - * - * @return a short - * - */ - public short getRequestType() { - return (_rType); - }; - - /** - * Method isContext - * - * @return a boolean - * - */ - public boolean isContext() { - return true; - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("context: " + getDescription() + "," + _mType + "\n").getBytes()); - } -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Context Object (RFC 2748) + * + * Specifies the type of event(s) that triggered the query. Required for + * request messages. Admission control, resource allocation, and + * forwarding requests are all amenable to client-types that outsource + * their decision making facility to the PDP. For applicable client- + * types a PEP can also make a request to receive named configuration + * information from the PDP. This named configuration data may be in a + * form useful for setting system attributes on a PEP, or it may be in + * the form of policy rules that are to be directly verified by the PEP. + * + * Multiple flags can be set for the same request. This is only allowed, + * however, if the set of client specific information in the combined + * request is identical to the client specific information that would be + * specified if individual requests were made for each specified flag. + * + * C-num = 2, C-Type = 1 + * + * R-Type (Request Type Flag) + * + * 0x01 = Incoming-Message/Admission Control request + * 0x02 = Resource-Allocation request + * 0x04 = Outgoing-Message request + * 0x08 = Configuration request + * + * M-Type (Message Type) + * + * Client Specific 16 bit values of protocol message types + */ +public class COPSContext extends COPSObjBase { + + public final static Map VAL_TO_RTYPE = new ConcurrentHashMap<>(); + static { + VAL_TO_RTYPE.put(RType.NA.ordinal(), RType.NA); + VAL_TO_RTYPE.put(RType.IN_ADMIN.ordinal(), RType.IN_ADMIN); + VAL_TO_RTYPE.put(RType.RES_ALLOC.ordinal(), RType.RES_ALLOC); + VAL_TO_RTYPE.put(RType.OUT.ordinal(), RType.OUT); + VAL_TO_RTYPE.put(RType.CONFIG.ordinal(), RType.CONFIG); + } + + /** + * The request type + */ + private final RType _rType; + + /** + * The message type + * Cannot find a list of types in order to make this an enumeration + */ + private short _mType; + + /** + * Constructor generally used for sending messages + * @param rType - the type of request + * @param mType - the type of message + * @throws java.lang.IllegalArgumentException + */ + public COPSContext(final RType rType, final short mType ) { + this(new COPSObjHeader(CNum.CONTEXT, CType.DEF), rType, mType); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param rType - the type of request + * @param mType - the type of message + * @throws java.lang.IllegalArgumentException + */ + protected COPSContext(final COPSObjHeader objHdr, final RType rType, final short mType ) { + super(objHdr); + + if (!objHdr.getCNum().equals(CNum.CONTEXT)) + throw new IllegalArgumentException("CNum must be equal to " + CNum.CONTEXT); + if (!objHdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF); + if (rType == null || rType.ordinal() == 0) throw new IllegalArgumentException("Must have a valid RType"); + + _rType = rType; + _mType = mType; + } + + @Override + public void writeBody(final Socket socket) throws IOException { + byte[] buf = new byte[4]; + + buf[0] = (byte)((byte)_rType.ordinal() >> 8); + buf[1] = (byte)_rType.ordinal(); + + buf[2] = (byte)(_mType >> 8); + buf[3] = (byte)_mType; + + COPSUtil.writeData(socket, buf, 4); + } + + @Override + public int getDataLength() { + return 4; + } + + /** + * Returns the detail description of the request type + * @return a String + */ + public String getDescription() { + switch (_rType) { + case IN_ADMIN: return "Incoming Message/Admission Control"; + case RES_ALLOC: return "Resource allocation"; + case OUT: return "Outgoing message"; + case CONFIG: return "Configuration"; + default: return ""; + } + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("context: " + getDescription() + "," + _mType + "\n").getBytes()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSContext)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSContext that = (COPSContext) o; + + return _mType == that._mType && _rType == that._rType; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _rType.hashCode(); + result = 31 * result + (int) _mType; + return result; + } + + /** + * Parses bytes to return a COPSContext object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSContext parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + short rType = 0; + rType |= ((short) dataPtr[4]) << 8; + rType |= ((short) dataPtr[5]) & 0xFF; + + short mType = 0; + mType |= ((short) dataPtr[6]) << 8; + mType |= ((short) dataPtr[7]) & 0xFF; + + return new COPSContext(objHdrData.header, VAL_TO_RTYPE.get((int)rType), mType); + } + + /** + * The request type + */ + public enum RType { + NA, IN_ADMIN, RES_ALLOC, OUT, CONFIG, + } + +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecision.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecision.java index a572342..c7fe4b0 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecision.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecision.java @@ -1,294 +1,356 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Decision - * - * @version COPSDecision.java, v 1.00 2003 - * - */ -public class COPSDecision extends COPSObjBase { - - // CType - @Deprecated public final static byte DEC_DEF = 1; - @Deprecated public final static byte DEC_STATELESS = 2; - @Deprecated public final static byte DEC_REPL = 3; - @Deprecated public final static byte DEC_CSI = 4; - @Deprecated public final static byte DEC_NAMED = 5; - - // Command - @Deprecated public final static byte DEC_NULL = 0; - @Deprecated public final static byte DEC_INSTALL = 1; - @Deprecated public final static byte DEC_REMOVE = 2; - - // Flags - @Deprecated public final static byte F_REQERROR = 0x1; - @Deprecated public final static byte F_REQSTATE = 0x2; - - protected COPSObjHeader _objHdr; - private COPSData _data; - private short _cmdCode; - private short _flags; - private COPSData _padding; - - /** - Constructor to create a Decision object. By default creates - a decision object which is of fixed length. - */ - public COPSDecision(byte cType) { - _objHdr = new COPSObjHeader(CNum.DEC, COPSObjHeader.VAL_TO_CTYPE.get((int)cType)); - _cmdCode = 0; - _flags = 0; - if (cType == CType.DEF.ordinal()) _objHdr.setDataLength( (short) 4); - } - - public COPSDecision() { - _objHdr = new COPSObjHeader(CNum.DEC, CType.DEF); - _cmdCode = 0; - _flags = 0; - _objHdr.setDataLength( (short) 4); - } - - /** - Initialize the decision object with values from COPSObj header - */ - protected COPSDecision(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _cmdCode = 0; - _flags = 0; - if (_objHdr.getCType().equals(CType.DEF)) { - _cmdCode |= ((short) dataPtr[4]) << 8; - _cmdCode |= ((short) dataPtr[5]) & 0xFF; - _flags |= ((short) dataPtr[6]) << 8; - _flags |= ((short) dataPtr[7]) & 0xFF; - - _objHdr.setDataLength((short) 4); - } else { - int dLen = _objHdr.getDataLength() - 4; - COPSData d = new COPSData(dataPtr, 4, dLen); - setData(d); - } - } - - /** - * Method getDataLength - * - * @return a short - * - */ - public short getDataLength() { - int lpadding = 0; - if (_padding != null) lpadding = _padding.length(); - return ((short) (_objHdr.getDataLength() + lpadding)); - } - - - - /** - * Get the associated data if decision object is of cType 2 or higher - * - * @return a COPSData - * - */ - public COPSData getData() { - return (_data); - } - - /** - * Set the decision data if decision object is of cType 2 or higher - * - * @param data a COPSData - * - */ - public void setData(COPSData data) { - if (data.length() % 4 != 0) { - int padLen = 4 - data.length() % 4; - _padding = getPadding(padLen); - } - _data = data; - _objHdr.setDataLength((short) data.length()); - } - - /** - * Retruns true if cType = 1 - * - * @return a boolean - * - */ - public boolean isFlagSet() { - return ( _objHdr.getCType().ordinal() == 1); - }; - - /** - * If cType == 1 , get the flags associated - * - * @return a short - * - */ - public short getFlags() { - return (_flags); - }; - - /** - * If cType == 1 ,set the cmd code - * - * @param cCode a byte - * - */ - public void setCmdCode(byte cCode) { - _cmdCode = (short) cCode; - } - - /** - * If cType == 1 ,set the cmd flags - * - * @param flags a short - * - */ - public void setFlags(short flags) { - _flags = flags; - } - - /** - * Method isNullDecision - * - * @return a boolean - * - */ - public boolean isNullDecision() { - return ( _cmdCode == 0); - }; - - /** - * Method isInstallDecision - * - * @return a boolean - * - */ - public boolean isInstallDecision() { - return ( _cmdCode == 1); - }; - - /** - * Method isRemoveDecision - * - * @return a boolean - * - */ - public boolean isRemoveDecision() { - return ( _cmdCode == 2); - }; - - /** - * Method getTypeStr - * - * @return a String - * - */ - public String getTypeStr() { - switch (_objHdr.getCType()) { - case DEF: - return "Default"; - case STATELESS: - return "Stateless data"; - case REPL: - return "Replacement data"; - case CSI: - return "Client specific decision data"; - case NAMED: - return "Named decision data"; - default: - return "Unknown"; - } - } - - /** - * Method isDecision - * - * @return a boolean - * - */ - public boolean isDecision() { - return true; - }; - - /** - * Method isLocalDecision - * - * @return a boolean - * - */ - public boolean isLocalDecision() { - return false; - }; - - /** - * Writes data to a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - if (_objHdr.getCType().ordinal() >= 2) { - COPSUtil.writeData(id, _data.getData(), _data.length()); - if (_padding != null) { - COPSUtil.writeData(id, _padding.getData(), _padding.length()); - } - } else { - byte[] buf = new byte[4]; - buf[0] = (byte) (_cmdCode >> 8); - buf[1] = (byte) _cmdCode; - buf[2] = (byte) (_flags >> 8); - buf[3] = (byte) _flags; - COPSUtil.writeData(id, buf, 4); - } - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - - if (_objHdr.getCType().ordinal() == 1) { - os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes()); - os.write(new String("Command code: " + _cmdCode + "\n").getBytes()); - os.write(new String("Command flags: " + _flags + "\n").getBytes()); - } else { - os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes()); - os.write(new String("Data: " + _data.str() + "\n").getBytes()); - } - } -} - - - - - - - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Decision (RFC 2748) + * + * Decision made by the PDP. Appears in replies. The specific non- + * mandatory decision objects required in a decision to a particular + * request depend on the type of client. + * + * C-Num = 6 + * C-Type = 1, Decision Flags (Mandatory) + * + * Commands: + * 0 = NULL Decision (No configuration data available) + * 1 = Install (Admit request/Install configuration) + * 2 = Remove (Remove request/Remove configuration) + * + * Flags: + * 0x01 = Trigger Error (Trigger error message if set) + * Note: Trigger Error is applicable to client-types that + * are capable of sending error notifications for signaled + * messages. + * + * Flag values not applicable to a given context's R-Type or + * client-type MUST be ignored by the PEP. + * + * C-Type = 2, Stateless Data + * + * This type of decision object carries additional stateless + * information that can be applied by the PEP locally. It is a + * variable length object and its internal format SHOULD be + * specified in the relevant COPS extension document for the given + * client-type. This object is optional in Decision messages and is + * interpreted relative to a given context. + * + * It is expected that even outsourcing PEPs will be able to make + * some simple stateless policy decisions locally in their LPDP. As + * this set is well known and implemented ubiquitously, PDPs are + * aware of it as well (either universally, through configuration, + * or using the Client-Open message). The PDP may also include this + * information in its decision, and the PEP MUST apply it to the + * resource allocation event that generated the request. + * + * C-Type = 3, Replacement Data + * + * This type of decision object carries replacement data that is to + * replace existing data in a signaled message. It is a variable + * length object and its internal format SHOULD be specified in the + * relevant COPS extension document for the given client-type. It is + * optional in Decision messages and is interpreted relative to a + * given context. + * + * C-Type = 4, Client Specific Decision Data + * + * Additional decision types can be introduced using the Client + * Specific Decision Data Object. It is a variable length object and + * its internal format SHOULD be specified in the relevant COPS + * extension document for the given client-type. It is optional in + * Decision messages and is interpreted relative to a given context. + * + * C-Type = 5, Named Decision Data + * + * Named configuration information is encapsulated in this version + * of the decision object in response to configuration requests. It + * is a variable length object and its internal format SHOULD be + * specified in the relevant COPS extension document for the given + * client-type. It is optional in Decision messages and is + * interpreted relative to both a given context and decision flags. + */ +public class COPSDecision extends COPSObjBase { + + static Map VAL_TO_CMD = new ConcurrentHashMap<>(); + static { + VAL_TO_CMD.put(Command.NULL.ordinal(), Command.NULL); + VAL_TO_CMD.put(Command.INSTALL.ordinal(), Command.INSTALL); + VAL_TO_CMD.put(Command.REMOVE.ordinal(), Command.REMOVE); + } + + static Map VAL_TO_FLAG = new ConcurrentHashMap<>(); + static { + VAL_TO_FLAG.put(DecisionFlag.NA.ordinal(), DecisionFlag.NA); + VAL_TO_FLAG.put(DecisionFlag.REQERROR.ordinal(), DecisionFlag.REQERROR); + VAL_TO_FLAG.put(DecisionFlag.REQSTATE.ordinal(), DecisionFlag.REQSTATE); + } + + /** + * All CTypes are supported except NA + */ + private final Command _cmdCode; + private final DecisionFlag _flags; + private final COPSData _data; + private final COPSData _padding; + + /** + * Constructor generally used for sending messages without any extra data + * @param cmdCode - the command + * @throws java.lang.IllegalArgumentException + */ + public COPSDecision(final Command cmdCode) { + this(CType.DEF, cmdCode, DecisionFlag.NA, new COPSData()); + } + + /** + * Constructor generally used for sending messages with a specific CType and extra data and a NA decision flag + * @param cType - the CType + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSDecision(final CType cType, final COPSData data) { + this(cType, Command.NULL, DecisionFlag.NA, data); + } + + /** + * Constructor generally used for sending messages with a specific Command and DecisionFlag + * @param cmdCode - the command + * @param flags - the flags + * @throws java.lang.IllegalArgumentException + */ + public COPSDecision(final Command cmdCode, final DecisionFlag flags) { + this(CType.DEF, cmdCode, flags, new COPSData()); + } + + /** + * Constructor generally used for sending messages with a specific, CType, Command and DecisionFlag + * @param cType - the CType + * @param cmdCode - the command + * @param flags - the flags + * @throws java.lang.IllegalArgumentException + */ + public COPSDecision(final CType cType, final Command cmdCode, final DecisionFlag flags) { + this(cType, cmdCode, flags, new COPSData()); + } + + /** + * Constructor generally used for sending messages with a specific, CType, Command, DecisionFlag and data + * @param cType - the CType + * @param cmdCode - the command + * @param flags - the flags + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSDecision(final CType cType, final Command cmdCode, final DecisionFlag flags, + final COPSData data) { + this(new COPSObjHeader(CNum.DEC, cType), cmdCode, flags, data); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param cmdCode - the command + * @param flags - the flags + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + protected COPSDecision(final COPSObjHeader hdr, final Command cmdCode, final DecisionFlag flags, + final COPSData data) { + super(hdr); + // TODO - find a better way to make this check + if (this.getClass().getName().equals("org.umu.cops.stack.COPSDecision") && !hdr.getCNum().equals(CNum.DEC)) + throw new IllegalArgumentException("CNum must be equal to " + CNum.DEC); + + if (hdr.getCType().equals(CType.NA)) throw new IllegalArgumentException("CType must not be " + CType.NA); + if (cmdCode == null) throw new IllegalArgumentException("Command code must not be null"); + if (flags == null) throw new IllegalArgumentException("Flags must not be null"); + if (data == null) throw new IllegalArgumentException("Data object must not be null"); + + _cmdCode = cmdCode; + _flags = flags; + _data = data; + + if ((_data.length() % 4) != 0) { + final int padLen = 4 - (_data.length() % 4); + _padding = COPSObjectParser.getPadding(padLen); + } else { + _padding = new COPSData(); + } + } + + /** + * Returns the command + * @return - the command + */ + public Command getCommand() { return _cmdCode; } + + @Override + public int getDataLength() { + return 4 + _data.length() + _padding.length(); + } + + /** + * Get the associated data if decision object is of cType 2 or higher + * @return a COPSData + */ + public COPSData getData() { + return (_data); + } + + /** + * If cType == 1 , get the flags associated + * @return a short + */ + public DecisionFlag getFlag() { + return _flags; + } + + /** + * Method getTypeStr + * @return a String + */ + public String getTypeStr() { + switch (this.getHeader().getCType()) { + case DEF: + return "Default"; + case STATELESS: + return "Stateless data"; + case REPL: + return "Replacement data"; + case CSI: + return "Client specific decision data"; + case NAMED: + return "Named decision data"; + default: + return "Unknown"; + } + } + + @Override + protected void writeBody(final Socket socket) throws IOException { +/* + if (this.getHeader().getCType().ordinal() >= 2) { + COPSUtil.writeData(socket, _data.getData(), _data.length()); + if (_padding != null) { + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + } else { + byte[] buf = new byte[4]; + buf[0] = (byte) (_cmdCode.ordinal() >> 8); + buf[1] = (byte) _cmdCode.ordinal(); + buf[2] = (byte) (_flags.ordinal() >> 8); + buf[3] = (byte) _flags.ordinal(); + COPSUtil.writeData(socket, buf, 4); + } +*/ + final byte[] buf = new byte[4]; + buf[0] = (byte) (_cmdCode.ordinal() >> 8); + buf[1] = (byte) _cmdCode.ordinal(); + buf[2] = (byte) (_flags.ordinal() >> 8); + buf[3] = (byte) _flags.ordinal(); + COPSUtil.writeData(socket, buf, 4); + + COPSUtil.writeData(socket, _data.getData(), _data.length()); + if (_padding != null) { + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + } + + @Override + protected void dumpBody(final OutputStream os) throws IOException { + if (this.getHeader().getCType().equals(CType.DEF)) { + os.write(("Decision (" + getTypeStr() + ")\n").getBytes()); + os.write(("Command code: " + _cmdCode + "\n").getBytes()); + os.write(("Command flags: " + _flags + "\n").getBytes()); + } else { + os.write(("Decision (" + getTypeStr() + ")\n").getBytes()); + os.write(("Data: " + _data.str() + "\n").getBytes()); + } + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSDecision)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSDecision that = (COPSDecision) o; + + return _cmdCode == that._cmdCode && _flags == that._flags && + (_data.equals(that._data) && _padding.equals(that._padding) || + COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding)); + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _data.hashCode(); + result = 31 * result + _cmdCode.hashCode(); + result = 31 * result + _flags.hashCode(); + result = 31 * result + _padding.hashCode(); + return result; + } + + /** + * Parses bytes to return a COPSDecision object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSDecision parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + int _cmdCode = 0; + _cmdCode |= ((short) dataPtr[4]) << 8; + _cmdCode |= ((short) dataPtr[5]) & 0xFF; + + int _flags = 0; + _flags |= ((short) dataPtr[6]) << 8; + _flags |= ((short) dataPtr[7]) & 0xFF; + + final COPSData d; + if (objHdrData.header.getCType().equals(CType.DEF)) { + d = null; + } else { + d = new COPSData(dataPtr, 8, objHdrData.msgByteCount - 8); + } + return new COPSDecision(objHdrData.header, COPSDecision.VAL_TO_CMD.get(_cmdCode), + COPSDecision.VAL_TO_FLAG.get(_flags), d); + } + + /** + * Supported command types + */ + public enum Command { + NULL, // No configuration data available + INSTALL, // Admit request/install configuration + REMOVE // Remove request/remove configuration + } + + public enum DecisionFlag { + NA, + REQERROR, // = Trigger error + REQSTATE, // = ??? + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecisionMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecisionMsg.java index 1b85cf7..488168b 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecisionMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDecisionMsg.java @@ -1,433 +1,434 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -/** - * COPS Decision Message - * - * @version COPSDecisionMsg.java, v 1.00 2003 - * - */ -public class COPSDecisionMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSHandle _clientHandle; - private COPSError _error; - private Hashtable _decisions; - private COPSIntegrity _integrity; - private COPSContext _decContext; - private COPSClientSI _decSI; - - /// - public COPSDecisionMsg() { - _clientHandle = null; - _error = null; - _decisions = new Hashtable(20); - _integrity = null; - _decContext = null; - _decSI = null; - } - - /** Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) { - throw new COPSException("Bad message format"); - } - } - - /// - protected COPSDecisionMsg(byte[] data) throws COPSException { - _decisions = new Hashtable(20); - _clientHandle = null; - _error = null; - _integrity = null; - _decContext = null; - _decSI = null; - - parse(data); - } - - /** - * Parses the data and fills COPSDecisionMsg with its constituents - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case HANDLE: - _clientHandle = new COPSHandle(buf); - _dataStart += _clientHandle.getDataLength(); - break; - case CONTEXT: - //dec context - _decContext = new COPSContext(buf); - _dataStart += _decContext.getDataLength(); - break; - case ERROR: - _error = new COPSError(buf); - _dataStart += _error.getDataLength(); - break; - case DEC: - COPSDecision decs = new COPSDecision(buf); - _dataStart += decs.getDataLength(); - addDecision(decs, _decContext); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: { - throw new COPSException("Bad Message format, unknown object type"); - } - } - } - checkSanity(); - } - - /** - * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC) - throw new COPSException ("Error Header (no COPS_OP_DEC)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add client handle to the message - * - * @param handle a COPSHandle - * - * @throws COPSException - * - */ - public void add (COPSHandle handle) throws COPSException { - if (handle == null) - throw new COPSException ("Null Handle"); - _clientHandle = handle; - setMsgLength(); - } - - /** - * Add an Error object - * - * @param error a COPSError - * - * @throws COPSException - * - */ - public void add (COPSError error) throws COPSException { - if (_decisions.size() != 0) - throw new COPSException ("No null decisions"); - if (_error != null) - throw new COPSException ("No null error"); - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("No null integrity"); - _error = error; - setMsgLength(); - } - - /** - * Add one or more local decision object for a given decision context - * the context is optional, if null all decision object are tided to - * message context - * - * @param decision a COPSDecision - * @param context a COPSContext - * - * @throws COPSException - * - */ - public void addDecision(COPSDecision decision, COPSContext context) throws COPSException { - //Either error or decision can be added - //If error is aleady there assert - if (_error != null) - throw new COPSException ("No null error"); - - if (decision.isLocalDecision()) - throw new COPSException ("Is local decision"); - - Vector v = (Vector) _decisions.get(context); - if (v == null) v = new Vector(); - - if (decision.isFlagSet()) {//Commented out as advised by Felix - //if (v.size() != 0) - //{ - //Only one set of decision flags is allowed - //for each context - // throw new COPSException ("Bad Message format, only one set of decision flags is allowed."); - //} - } else { - if (v.size() == 0) { - //The flags decision must precede any other - //decision message, since the decision is not - //flags throw exception - throw new COPSException ("Bad Message format, flags decision must precede any other decision object."); - } - } - v.add(decision); - _decisions.put(context,v); - - setMsgLength(); - } - - /** - * Add integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - /** - * Add clientSI object - * - * @param clientSI a COPSClientSI - * - * @throws COPSException - * - */ - public void add (COPSClientSI clientSI) throws COPSException { - if (clientSI == null) - throw new COPSException ("Null clientSI"); - /* - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - */ - _decSI = clientSI; - setMsgLength(); - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_clientHandle != null) _clientHandle.writeData(id); - if (_error != null) _error.writeData(id); - - //Display decisions - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - context.writeData(id); - - for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { - COPSDecision decision = (COPSDecision) ee.nextElement(); - decision.writeData(id); - } - } - - if (_decSI != null) _decSI.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Method getHeader - * - * @return a COPSHeader - * - */ - public COPSHeader getHeader() { - return _hdr; - } - - /** - * Method getClientHandle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _clientHandle; - } - - /** - * Returns true if it has error object - * - * @return a boolean - * - */ - public boolean hasError() { - return (_error != null); - }; - - /** - * Should check hasError() before calling - * - * @return a COPSError - * - */ - public COPSError getError() { - return _error; - }; - - /** - * Returns a map of decision for which is an arry of context and vector - * of associated decision object. - * - * @return a Hashtable - * - */ - public Hashtable getDecisions() { - return _decisions; - }; - - /** - * Returns true if it has integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - }; - - /** - * Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return _integrity; - }; - - /** - * Method setMsgLength - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - if (_clientHandle != null) - len += _clientHandle.getDataLength(); - if (_error != null) - len += _error.getDataLength(); - - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - len += context.getDataLength(); - - for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { - COPSDecision decision = (COPSDecision) ee.nextElement(); - len += decision.getDataLength(); - } - } - if (_decSI != null) { - len += _decSI.getDataLength(); - } - if (_integrity != null) { - len += _integrity.getDataLength(); - } - - _hdr.setMsgLength((int) len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_clientHandle != null) - _clientHandle.dump(os); - if (_error != null) - _error.dump(os); - - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - context.dump(os); - - for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { - COPSDecision decision = (COPSDecision) ee.nextElement(); - decision.dump(os); - } - } - if (_decSI != null) { - _decSI.dump(os); - } - if (_integrity != null) { - _integrity.dump(os); - } - } -} - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CNum; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + * COPS Decision Message + * + * @version COPSDecisionMsg.java, v 1.00 2003 + * + */ +public class COPSDecisionMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSHandle _clientHandle; + private COPSError _error; + private Hashtable _decisions; + private COPSIntegrity _integrity; + private COPSContext _decContext; + private COPSClientSI _decSI; + + /// + public COPSDecisionMsg() { + _clientHandle = null; + _error = null; + _decisions = new Hashtable(20); + _integrity = null; + _decContext = null; + _decSI = null; + } + + /** Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) { + throw new COPSException("Bad message format"); + } + } + + /// + protected COPSDecisionMsg(byte[] data) throws COPSException { + _decisions = new Hashtable(20); + _clientHandle = null; + _error = null; + _integrity = null; + _decContext = null; + _decSI = null; + + parse(data); + } + + /** + * Parses the data and fills COPSDecisionMsg with its constituents + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case HANDLE: + _clientHandle = COPSHandle.parse(objHdrData, buf); + _dataStart += _clientHandle.getDataLength(); + break; + case CONTEXT: + //dec context + _decContext = COPSContext.parse(objHdrData, buf); + _dataStart += _decContext.getDataLength(); + break; + case ERROR: + _error = COPSError.parse(objHdrData, buf); + _dataStart += _error.getDataLength(); + break; + case DEC: + COPSDecision decs = COPSDecision.parse(objHdrData, buf); + _dataStart += decs.getDataLength(); + addDecision(decs, _decContext); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: { + throw new COPSException("Bad Message format, unknown object type"); + } + } + } + checkSanity(); + } + + /** + * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC) + throw new COPSException ("Error Header (no COPS_OP_DEC)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add client handle to the message + * + * @param handle a COPSHandle + * + * @throws COPSException + * + */ + public void add (COPSHandle handle) throws COPSException { + if (handle == null) + throw new COPSException ("Null Handle"); + _clientHandle = handle; + setMsgLength(); + } + + /** + * Add an Error object + * + * @param error a COPSError + * + * @throws COPSException + * + */ + public void add (COPSError error) throws COPSException { + if (_decisions.size() != 0) + throw new COPSException ("No null decisions"); + if (_error != null) + throw new COPSException ("No null error"); + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("No null integrity"); + _error = error; + setMsgLength(); + } + + /** + * Add one or more local decision object for a given decision context + * the context is optional, if null all decision object are tided to + * message context + * + * @param decision a COPSDecision + * @param context a COPSContext + * + * @throws COPSException + * + */ + public void addDecision(COPSDecision decision, COPSContext context) throws COPSException { + //Either error or decision can be added + //If error is aleady there assert + if (_error != null) + throw new COPSException ("No null error"); + + if (decision.getHeader().getCNum().equals(CNum.LPDP_DEC)) + throw new COPSException ("Is local decision"); + + Vector v = (Vector) _decisions.get(context); + if (v == null) v = new Vector(); + + if (!decision.getFlag().equals(DecisionFlag.NA)) {//Commented out as advised by Felix + //if (v.size() != 0) + //{ + //Only one set of decision flags is allowed + //for each context + // throw new COPSException ("Bad Message format, only one set of decision flags is allowed."); + //} + } else { + if (v.size() == 0) { + //The flags decision must precede any other + //decision message, since the decision is not + //flags throw exception + throw new COPSException ("Bad Message format, flags decision must precede any other decision object."); + } + } + v.add(decision); + _decisions.put(context,v); + + setMsgLength(); + } + + /** + * Add integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + /** + * Add clientSI object + * + * @param clientSI a COPSClientSI + * + * @throws COPSException + * + */ + public void add (COPSClientSI clientSI) throws COPSException { + if (clientSI == null) + throw new COPSException ("Null clientSI"); + /* + if (!integrity.isMessageIntegrity()) + throw new COPSException ("Error Integrity"); + */ + _decSI = clientSI; + setMsgLength(); + } + + /** + * Writes data to given socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_clientHandle != null) _clientHandle.writeData(id); + if (_error != null) _error.writeData(id); + + //Display decisions + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + context.writeData(id); + + for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { + COPSDecision decision = (COPSDecision) ee.nextElement(); + decision.writeData(id); + } + } + + if (_decSI != null) _decSI.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Method getHeader + * + * @return a COPSHeader + * + */ + public COPSHeader getHeader() { + return _hdr; + } + + /** + * Method getClientHandle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _clientHandle; + } + + /** + * Returns true if it has error object + * + * @return a boolean + * + */ + public boolean hasError() { + return (_error != null); + } + + /** + * Should check hasError() before calling + * + * @return a COPSError + * + */ + public COPSError getError() { + return _error; + } + + /** + * Returns a map of decision for which is an arry of context and vector + * of associated decision object. + * + * @return a Hashtable + * + */ + public Hashtable getDecisions() { + return _decisions; + } + + /** + * Returns true if it has integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + } + + /** + * Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return _integrity; + } + + /** + * Method setMsgLength + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + if (_clientHandle != null) + len += _clientHandle.getDataLength(); + if (_error != null) + len += _error.getDataLength(); + + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + len += context.getDataLength(); + + for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { + COPSDecision decision = (COPSDecision) ee.nextElement(); + len += decision.getDataLength(); + } + } + if (_decSI != null) { + len += _decSI.getDataLength(); + } + if (_integrity != null) { + len += _integrity.getDataLength(); + } + + _hdr.setMsgLength((int) len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_clientHandle != null) + _clientHandle.dump(os); + if (_error != null) + _error.dump(os); + + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + context.dump(os); + + for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) { + COPSDecision decision = (COPSDecision) ee.nextElement(); + decision.dump(os); + } + } + if (_decSI != null) { + _decSI.dump(os); + } + if (_integrity != null) { + _integrity.dump(os); + } + } +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDeleteMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDeleteMsg.java index 2022d1d..b61ba56 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDeleteMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSDeleteMsg.java @@ -1,283 +1,281 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Delete Message (RFC 2748 pag. 24) - * - * When sent from the PEP this message indicates to the remote PDP that - * the state identified by the client handle is no longer - * available/relevant. This information will then be used by the remote - * PDP to initiate the appropriate housekeeping actions. The reason code - * object is interpreted with respect to the client-type and signifies - * the reason for the removal. - * - * The format of the Delete Request State message is as follows: - * - * ::= - * - * - * [] - * - * - * @version COPSDeleteMsg.java, v 1.00 2003 - * - */ -public class COPSDeleteMsg extends COPSMsg { - /* COPSHeader coming from base class */ - private COPSHandle _clientHandle; - private COPSReason _reason; - private COPSIntegrity _integrity; - - public COPSDeleteMsg() { - _clientHandle = null; - _reason = null; - _integrity = null; - } - - /** - Parse data and create COPSDeleteMsg object - */ - protected COPSDeleteMsg(byte[] data) throws COPSException { - _clientHandle = null; - _reason = null; - _integrity = null; - parse(data); - } - - /** - * Checks the sanity of COPS message and throw an - * COPSException when data is bad. - * - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_clientHandle == null) || (_reason == null)) - throw new COPSException("Bad message format"); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ) - throw new COPSException ("Error Header (no COPS_OP_DRQ)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Reason object to the message - * - * @param reason a COPSReason - * - * @throws COPSException - * - */ - public void add (COPSReason reason) throws COPSException { - if (_reason != null) - throw new COPSException ("No null Reason"); - - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("No null Integrity"); - _reason = reason; - setMsgLength(); - } - - /** - * Add Handle object - * - * @param handle a COPSHandle - * - * @throws COPSException - * - */ - public void add (COPSHandle handle) throws COPSException { - if (handle == null) - throw new COPSException ("Null Handle"); - _clientHandle = handle; - setMsgLength(); - } - - /** - * Add Integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Get Client Handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _clientHandle; - }; - - /** - * Get Reason - * - * @return a COPSReason - * - */ - public COPSReason getReason() { - return _reason; - }; - - /** - * Returns true if it has integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - }; - - /** - * Get Integrity. Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Writes data to given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - if (_hdr != null) _hdr.writeData(id); - if (_clientHandle != null) _clientHandle.writeData(id); - if (_reason != null) _reason.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Parse data - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case HANDLE: - _clientHandle = new COPSHandle(buf); - _dataStart += _clientHandle.getDataLength(); - break; - case REASON_CODE: - _reason = new COPSReason(buf); - _dataStart += _reason.getDataLength(); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format, unknown object type"); - } - } - checkSanity(); - } - - /** - * Parse data - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ) - throw new COPSException("Error Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - if (_clientHandle != null) len += _clientHandle.getDataLength(); - if (_reason != null) len += _reason.getDataLength(); - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_clientHandle != null) - _clientHandle.dump(os); - - if (_reason != null) - _reason.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } - -} - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Delete Message (RFC 2748 pag. 24) + * + * When sent from the PEP this message indicates to the remote PDP that + * the state identified by the client handle is no longer + * available/relevant. This information will then be used by the remote + * PDP to initiate the appropriate housekeeping actions. The reason code + * object is interpreted with respect to the client-type and signifies + * the reason for the removal. + * + * The format of the Delete Request State message is as follows: + * + * ::= + * + * + * [] + * + * + * @version COPSDeleteMsg.java, v 1.00 2003 + * + */ +public class COPSDeleteMsg extends COPSMsg { + /* COPSHeader coming from base class */ + private COPSHandle _clientHandle; + private COPSReason _reason; + private COPSIntegrity _integrity; + + public COPSDeleteMsg() { + _clientHandle = null; + _reason = null; + _integrity = null; + } + + /** + Parse data and create COPSDeleteMsg object + */ + protected COPSDeleteMsg(byte[] data) throws COPSException { + _clientHandle = null; + _reason = null; + _integrity = null; + parse(data); + } + + /** + * Checks the sanity of COPS message and throw an + * COPSException when data is bad. + * + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_clientHandle == null) || (_reason == null)) + throw new COPSException("Bad message format"); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ) + throw new COPSException ("Error Header (no COPS_OP_DRQ)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Reason object to the message + * + * @param reason a COPSReason + * + * @throws COPSException + * + */ + public void add (COPSReason reason) throws COPSException { + if (_reason != null) + throw new COPSException ("No null Reason"); + + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("No null Integrity"); + _reason = reason; + setMsgLength(); + } + + /** + * Add Handle object + * + * @param handle a COPSHandle + * + * @throws COPSException + * + */ + public void add (COPSHandle handle) throws COPSException { + if (handle == null) + throw new COPSException ("Null Handle"); + _clientHandle = handle; + setMsgLength(); + } + + /** + * Add Integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Get Client Handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _clientHandle; + } + + /** + * Get Reason + * + * @return a COPSReason + * + */ + public COPSReason getReason() { + return _reason; + } + + /** + * Returns true if it has integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + } + + /** + * Get Integrity. Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Writes data to given network socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + if (_hdr != null) _hdr.writeData(id); + if (_clientHandle != null) _clientHandle.writeData(id); + if (_reason != null) _reason.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Parse data + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case HANDLE: + _clientHandle = COPSHandle.parse(objHdrData, buf); + _dataStart += _clientHandle.getDataLength(); + break; + case REASON_CODE: + _reason = COPSReason.parse(objHdrData, buf); + _dataStart += _reason.getDataLength(); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format, unknown object type"); + } + } + checkSanity(); + } + + /** + * Parse data + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ) + throw new COPSException("Error Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + if (_clientHandle != null) len += _clientHandle.getDataLength(); + if (_reason != null) len += _reason.getDataLength(); + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_clientHandle != null) + _clientHandle.dump(os); + + if (_reason != null) + _reason.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } + +} + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSError.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSError.java index 06b09c3..3898653 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSError.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSError.java @@ -1,161 +1,250 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Error - * - * @version COPSError.java, v 1.00 2003 - * - */ -public class COPSError extends COPSObjBase { - - public final static byte COPS_ERR_BAD_HANDLE = 1; - public final static byte COPS_ERR_BAD_HANDLE_REF = 2; - public final static byte COPS_ERR_BAD_MSG_FORMAT = 3; - public final static byte COPS_ERR_FAIL_PROCESS = 4; - public final static byte COPS_ERR_MISSING_INFO = 5; - public final static byte COPS_ERR_UNSUPPORTED_CLIENT_TYPE = 6; - public final static byte COPS_ERR_MANDATORY_OBJECT_MISSING = 7; - public final static byte COPS_ERR_CLIENT_FAILURE = 8; - public final static byte COPS_ERR_COMM_FAILURE = 9; - public final static byte COPS_ERR_UNKNOWN = 10; - public final static byte COPS_ERR_SHUTTING_DOWN = 11; - public final static byte COPS_ERR_PDP_REDIRECT = 12; - public final static byte COPS_ERR_UNKNOWN_OBJECT = 13; - public final static byte COPS_ERR_AUTH_FAILURE = 14; - public final static byte COPS_ERR_AUTH_REQUIRED = 15; - public final static byte COPS_ERR_MA = 16; - - private final static String G_errmsgArray[] = { - "Unknown.", - "Bad handle.", - "Invalid handle reference.", - "Bad message format (Malformed message).", - "Unable to process.", - "Mandatory client-specific info missing.", - "Unsupported client-type", - "Mandatory COPS object missing.", - "Client failure.", - "Communication failure.", - "Unknown.", - "Shutting down.", - "Redirect to preferred server.", - "Unknown COPS object", - "Authentication failure.", - "Authentication required.", - }; - - private COPSObjHeader _objHdr; - private short _errCode; - private short _errSubCode; - - public COPSError(short errCode, short subCode) { - _objHdr = new COPSObjHeader(CNum.ERROR, CType.DEF); - _errCode = errCode; - _errSubCode = subCode; - _objHdr.setDataLength((short) 4); - } - - protected COPSError(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - _errCode |= ((short) dataPtr[4]) << 8; - _errCode |= ((short) dataPtr[5]) & 0xFF; - _errSubCode |= ((short) dataPtr[6]) << 8; - _errSubCode |= ((short) dataPtr[7]) & 0xFF; - - // _objHdr.setDataLength(sizeof(u_int32_t)); - _objHdr.setDataLength((short) 4); - } - - public short getErrCode() { - return _errCode; - } - - public short getErrSubCode() { - return _errSubCode; - } - /** - * Returns size in number of octects - * - * @return a short - * - */ - public short getDataLength() { - return (_objHdr.getDataLength()); - }; - - /** - * Method getDescription - * - * @return a String - * - */ - public String getDescription() { - String errStr1; - String errStr2; - - ///Get the details from the error code - errStr1 = G_errmsgArray[_errCode]; - //TODO - define error sub-codes - errStr2 = ""; - return (errStr1 + ":" + errStr2); - } - - /** - * Method isError - * - * @return a boolean - * - */ - public boolean isError() { - return true; - }; - - /** - * Writes object to given network socket in network byte order - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - byte[] buf = new byte[4]; - - buf[0] = (byte) (_errCode >> 8); - buf[1] = (byte) _errCode; - buf[2] = (byte) (_errSubCode >> 8); - buf[3] = (byte) _errSubCode; - - COPSUtil.writeData(id, buf, 4); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Error Code: " + _errCode + "\n").getBytes()); - os.write(new String("Error Sub Code: " + _errSubCode + "\n").getBytes()); - } -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Error (RFC 2748) + * + * This object is used to identify a particular COPS protocol error. + * The error sub-code field contains additional detailed client specific + * error codes. The appropriate Error Sub-codes for a particular + * client-type SHOULD be specified in the relevant COPS extensions + * document. + * + * C-Num = 8, C-Type = 1 + * + * Error-Code: + * + * 1 = Bad handle + * 2 = Invalid handle reference + * 3 = Bad message format (Malformed Message) + * 4 = Unable to process (server gives up on query) + * 5 = Mandatory client-specific info missing + * 6 = Unsupported client-type + * 7 = Mandatory COPS object missing + * 8 = Client Failure + * 9 = Communication Failure + * 10= Unspecified + * 11= Shutting down + * 12= Redirect to Preferred Server + * 13= Unknown COPS Object: + * Sub-code (octet 2) contains unknown object's C-Num + * and (octet 3) contains unknown object's C-Type. + * 14= Authentication Failure + * 15= Authentication Required + */ +public class COPSError extends COPSObjBase { + + public final static Map ERROR_CODE_TO_TYPE = new ConcurrentHashMap<>(); + static { + ERROR_CODE_TO_TYPE.put(ErrorTypes.NA.ordinal(), ErrorTypes.NA); + ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE.ordinal(), ErrorTypes.BAD_HANDLE); + ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE_REF.ordinal(), ErrorTypes.BAD_HANDLE_REF); + ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_MSG_FORMAT.ordinal(), ErrorTypes.BAD_MSG_FORMAT); + ERROR_CODE_TO_TYPE.put(ErrorTypes.FAIL_PROCESS.ordinal(), ErrorTypes.FAIL_PROCESS); + ERROR_CODE_TO_TYPE.put(ErrorTypes.MISSING_INFO.ordinal(), ErrorTypes.MISSING_INFO); + ERROR_CODE_TO_TYPE.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE.ordinal(), ErrorTypes.UNSUPPORTED_CLIENT_TYPE); + ERROR_CODE_TO_TYPE.put(ErrorTypes.MANDATORY_OBJECT_MISSING.ordinal(), ErrorTypes.MANDATORY_OBJECT_MISSING); + ERROR_CODE_TO_TYPE.put(ErrorTypes.CLIENT_FAILURE.ordinal(), ErrorTypes.CLIENT_FAILURE); + ERROR_CODE_TO_TYPE.put(ErrorTypes.COMM_FAILURE.ordinal(), ErrorTypes.COMM_FAILURE); + ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN.ordinal(), ErrorTypes.UNKNOWN); + ERROR_CODE_TO_TYPE.put(ErrorTypes.SHUTTING_DOWN.ordinal(), ErrorTypes.SHUTTING_DOWN); + ERROR_CODE_TO_TYPE.put(ErrorTypes.PDP_REDIRECT.ordinal(), ErrorTypes.PDP_REDIRECT); + ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN_OBJECT.ordinal(), ErrorTypes.UNKNOWN_OBJECT); + ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_FAILURE.ordinal(), ErrorTypes.AUTH_FAILURE); + ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_REQUIRED.ordinal(), ErrorTypes.AUTH_REQUIRED); + ERROR_CODE_TO_TYPE.put(ErrorTypes.MA.ordinal(), ErrorTypes.MA); + } + + private final static Map ERROR_TYPE_TO_STRING = new ConcurrentHashMap<>(); + static { + ERROR_TYPE_TO_STRING.put(ErrorTypes.NA, "Unknown."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE, "Bad handle."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE_REF, "Invalid handle reference."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_MSG_FORMAT, "Bad message format (Malformed message)."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.FAIL_PROCESS, "Unable to process."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.MISSING_INFO, "Mandatory client-specific info missing."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, "Unsupported client-type"); + ERROR_TYPE_TO_STRING.put(ErrorTypes.MANDATORY_OBJECT_MISSING, "Mandatory COPS object missing."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.CLIENT_FAILURE, "Client failure."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.COMM_FAILURE, "Communication failure."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN, "Unknown."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.SHUTTING_DOWN, "Shutting down."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.PDP_REDIRECT, "Redirect to preferred server."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN_OBJECT, "Unknown COPS object"); + ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_FAILURE, "Authentication failure."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_REQUIRED, "Authentication required."); + ERROR_TYPE_TO_STRING.put(ErrorTypes.MA, "Authentication required."); + } + + /** + * The error code + */ + private ErrorTypes _errCode; + + /** + * Additional detailed client specific error codes + */ + private ErrorTypes _errSubCode; + + /** + * Constructor generally used for sending messages + * @param errCode - the error code + * @param subCode - the type of message + * @throws java.lang.IllegalArgumentException + */ + public COPSError(final ErrorTypes errCode, final ErrorTypes subCode) { + this(new COPSObjHeader(CNum.ERROR, CType.DEF), errCode, subCode); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param errCode - the error code + * @param subCode - the type of message + * @throws java.lang.IllegalArgumentException + */ + protected COPSError(final COPSObjHeader hdr, final ErrorTypes errCode, final ErrorTypes subCode) { + super(hdr); + if (!hdr.getCNum().equals(CNum.ERROR)) + throw new IllegalArgumentException("Must have a CNum value of " + CNum.ERROR); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Must have a CType value of " + CType.DEF); + if (errCode == null || subCode == null) throw new IllegalArgumentException("Error codes must not be null"); + if (errCode.equals(ErrorTypes.NA)) + throw new IllegalArgumentException("Error code must not be of type " + ErrorTypes.NA); + + _errCode = errCode; + _errSubCode = subCode; + } + + public ErrorTypes getErrCode() { + return _errCode; + } + + public ErrorTypes getErrSubCode() { + return _errSubCode; + } + + @Override + public int getDataLength() { + return 4; + } + + /** + * Method getDescription + * @return a String + */ + public String getDescription() { + String errStr1; + String errStr2; + + ///Get the details from the error code + errStr1 = ERROR_TYPE_TO_STRING.get(_errCode); + //TODO - define error sub-codes + errStr2 = ""; + return (errStr1 + ":" + errStr2); + } + + @Override + public void writeBody(final Socket socket) throws IOException { + final byte[] buf = new byte[4]; + + buf[0] = (byte) ((byte)_errCode.ordinal() >> 8); + buf[1] = (byte)_errCode.ordinal(); + buf[2] = (byte) ((byte)_errSubCode.ordinal() >> 8); + buf[3] = (byte)_errSubCode.ordinal(); + + COPSUtil.writeData(socket, buf, 4); + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("Error Code: " + _errCode + "\n").getBytes()); + os.write(("Error Sub Code: " + _errSubCode + "\n").getBytes()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSError)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSError copsError = (COPSError) o; + + return _errCode == copsError._errCode && _errSubCode == copsError._errSubCode; + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (_errCode != null ? _errCode.hashCode() : 0); + result = 31 * result + (_errSubCode != null ? _errSubCode.hashCode() : 0); + return result; + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSError parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + int errCode = 0; + errCode |= ((short) dataPtr[4]) << 8; + errCode |= ((short) dataPtr[5]) & 0xFF; + + int errSubCode = 0; + errSubCode |= ((short) dataPtr[6]) << 8; + errSubCode |= ((short) dataPtr[7]) & 0xFF; + + return new COPSError(objHdrData.header, ERROR_CODE_TO_TYPE.get(errCode), ERROR_CODE_TO_TYPE.get(errSubCode)); + } + + /** + * The different error types and the ordinal value will be serialized + */ + public enum ErrorTypes { + NA, + BAD_HANDLE, + BAD_HANDLE_REF, + BAD_MSG_FORMAT, + FAIL_PROCESS, + MISSING_INFO, + UNSUPPORTED_CLIENT_TYPE, + MANDATORY_OBJECT_MISSING, + CLIENT_FAILURE, + COMM_FAILURE, + UNKNOWN, + SHUTTING_DOWN, + PDP_REDIRECT, + UNKNOWN_OBJECT, + AUTH_FAILURE, + AUTH_REQUIRED, + MA + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSHandle.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSHandle.java index b4bc14f..5028f34 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSHandle.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSHandle.java @@ -1,155 +1,154 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Handle Object (RFC 2748 pag. 9) - * - * The Handle Object encapsulates a unique value that identifies an - * installed state. This identification is used by most COPS operations. - * - * C-Num = 1 - * - * C-Type = 1, Client Handle. - * - * Variable-length field, no implied format other than it is unique from - * other client handles from the same PEP (a.k.a. COPS TCP connection) - * for a particular client-type. It is always initially chosen by the - * PEP and then deleted by the PEP when no longer applicable. The client - * handle is used to refer to a request state initiated by a particular - * PEP and installed at the PDP for a client-type. A PEP will specify a - * client handle in its Request messages, Report messages and Delete - * messages sent to the PDP. In all cases, the client handle is used to - * uniquely identify a particular PEP's request for a client-type. - * - * The client handle value is set by the PEP and is opaque to the PDP. - * The PDP simply performs a byte-wise comparison on the value in this - * object with respect to the handle object values of other currently - * installed requests. - * - * @version COPSHandle.java, v 1.00 2003 - * - */ -public class COPSHandle extends COPSObjBase { - - private final COPSObjHeader _objHdr; - private final COPSData _id; - private final COPSData _padding; - - /** - * Constructor - * @param id - the identifier (must not be null) - * @throws java.lang.IllegalArgumentException when the id parameter is null - */ - public COPSHandle(final COPSData id) { - if (id == null) throw new IllegalArgumentException("COPSData must not be null"); - _objHdr = new COPSObjHeader(CNum.HANDLE, CType.DEF); - _id = id; - if ((_id.length() % 4) != 0) { - final int padLen = 4 - (_id.length() % 4); - _padding = getPadding(padLen); - } else { - _padding = new COPSData(); - } - _objHdr.setDataLength((short) _id.length()); - } - - /** - * Constructor - * @param dataPtr - the data to parse for setting this object's attributes - */ - protected COPSHandle(final byte[] dataPtr) { - if (dataPtr == null || dataPtr.length < 5) - throw new IllegalArgumentException("Data cannot be null or fewer than 5 bytes"); - - _objHdr = COPSObjHeader.parse(dataPtr); - - //Get the length of data following the obj header - final int dLen = _objHdr.getDataLength() - 4; - _id = new COPSData(dataPtr, 4, dLen); - if ((_id.length() % 4) != 0) { - final int padLen = 4 - (_id.length() % 4); - _padding = getPadding(padLen); - } else { - _padding = new COPSData(); - } - _objHdr.setDataLength((short) _id.length()); - } - - /** - * Returns size in number of octects, including header - * @return a short - */ - public short getDataLength() { - //Add the size of the header also - final int lpadding; - if (_padding != null) lpadding = _padding.length(); - else lpadding = 0; - return ((short) (_objHdr.getDataLength() + lpadding)); - } - - /** - * Get handle value - * @return a COPSData - */ - public COPSData getId() { - return _id; - } - - @Override - public boolean isClientHandle() { - return true; - } - - @Override - public void writeData(final Socket socket) throws IOException { - _objHdr.writeData(socket); - - COPSUtil.writeData(socket, _id.getData(), _id.length()); - if (_padding != null) { - COPSUtil.writeData(socket, _padding.getData(), _padding.length()); - } - } - - /** - * Write an object textual description in the output stream - * @param os an OutputStream - * @throws IOException - */ - public void dump(final OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(("client-handle: " + _id.str() + "\n").getBytes()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof COPSHandle)) { - return false; - } - final COPSHandle that = (COPSHandle) o; - return _id.equals(that._id) && _objHdr.equals(that._objHdr); - } - - @Override - public int hashCode() { - int result = _objHdr.hashCode(); - result = 31 * result + _id.hashCode(); - return result; - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Handle Object (RFC 2748 pag. 9) + * + * The Handle Object encapsulates a unique value that identifies an + * installed state. This identification is used by most COPS operations. + * + * C-Num = 1 + * + * C-Type = 1, Client Handle. + * + * Variable-length field, no implied format other than it is unique from + * other client handles from the same PEP (a.k.a. COPS TCP connection) + * for a particular client-type. It is always initially chosen by the + * PEP and then deleted by the PEP when no longer applicable. The client + * handle is used to refer to a request state initiated by a particular + * PEP and installed at the PDP for a client-type. A PEP will specify a + * client handle in its Request messages, Report messages and Delete + * messages sent to the PDP. In all cases, the client handle is used to + * uniquely identify a particular PEP's request for a client-type. + * + * The client handle value is set by the PEP and is opaque to the PDP. + * The PDP simply performs a byte-wise comparison on the value in this + * object with respect to the handle object values of other currently + * installed requests. + * + * @version COPSHandle.java, v 1.00 2003 + * + */ +public class COPSHandle extends COPSObjBase { + + /** + * The payload data + */ + private final COPSData _id; + + /** + * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes + */ + private final COPSData _padding; + + /** + * Constructor + * @param id - the identifier (must not be null) + * @throws java.lang.IllegalArgumentException when the id parameter is null + */ + public COPSHandle(final COPSData id) { + this(new COPSObjHeader(CNum.HANDLE, CType.DEF), id); + } + + /** + * Constructor + * @param id - the identifier (must not be null) + * @throws java.lang.IllegalArgumentException when the id parameter is null + */ + protected COPSHandle(final COPSObjHeader objHeader, final COPSData id) { + super(objHeader); + if (! objHeader.getCNum().equals(CNum.HANDLE)) + throw new IllegalArgumentException("CNum on header must be of type HANDLE"); + if (! objHeader.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF); + if (id == null) throw new IllegalArgumentException("COPSData must not be null"); + + _id = id; + if ((_id.length() % 4) != 0) { + final int padLen = 4 - (_id.length() % 4); + _padding = COPSObjectParser.getPadding(padLen); + } else { + _padding = new COPSData(); + } + } + + @Override + public int getDataLength() { + return _id.length() + _padding.length(); + } + + /** + * Get handle value + * @return a COPSData + */ + public COPSData getId() { + return _id; + } + + @Override + public void writeBody(final Socket socket) throws IOException { + COPSUtil.writeData(socket, _id.getData(), _id.length()); + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("client-handle: " + _id.str() + "\n").getBytes()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSHandle)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSHandle that = (COPSHandle) o; + + return _id.equals(that._id) && _padding.equals(that._padding); + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _id.hashCode(); + result = 31 * result + _padding.hashCode(); + return result; + } + + /** + * Parses bytes to return a COPSHandle object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSHandle parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + if (dataPtr == null || dataPtr.length < 5) + throw new IllegalArgumentException("Data cannot be null or fewer than 5 bytes"); + + //Get the length of data following the obj header + final COPSData id = new COPSData(dataPtr, 4, objHdrData.msgByteCount - objHdrData.header.getHdrLength()); + return new COPSHandle(objHdrData.header, id); + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIntegrity.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIntegrity.java index b5e6d41..53fc2ad 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIntegrity.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIntegrity.java @@ -1,186 +1,215 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Integrity Object - * - * @version COPSIntegrity.java, v 1.00 2003 - * - */ -public class COPSIntegrity extends COPSObjBase { - private COPSObjHeader _objHdr; - private int _keyId; - private int _seqNum; - private COPSData _keyDigest; - private COPSData _padding; - - public COPSIntegrity() { - _objHdr = new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF); - _keyId = 0; - _seqNum = 0; - } - - public COPSIntegrity(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _keyId |= ((short) dataPtr[4]) << 24; - _keyId |= ((short) dataPtr[5]) << 16; - _keyId |= ((short) dataPtr[6]) << 8; - _keyId |= ((short) dataPtr[7]) & 0xFF; - _seqNum |= ((short) dataPtr[8]) << 24; - _seqNum |= ((short) dataPtr[9]) << 16; - _seqNum |= ((short) dataPtr[10]) << 8; - _seqNum |= ((short) dataPtr[11]) & 0xFF; - - int dLen = _objHdr.getDataLength() - 12; - COPSData d = new COPSData(dataPtr, 12, dLen); - setKeyDigest(d); - } - - /** - * Method setKeyId - * - * @param keyId an int - * - */ - public void setKeyId(int keyId) { - _keyId = keyId; - }; - - /** - * Method setSeqNum - * - * @param seqNum an int - * - */ - public void setSeqNum(int seqNum) { - _seqNum = seqNum; - }; - - /** - * Method setKeyDigest - * - * @param keyDigest a COPSData - * - */ - public void setKeyDigest(COPSData keyDigest) { - _keyDigest = keyDigest; - if (_keyDigest.length() % 4 != 0) { - int padLen = 4 - _keyDigest.length() % 4; - _padding = getPadding(padLen); - } - // _objHdr.setDataLength(sizeof(u_int32_t) - // + sizeof(u_int32_t) + _keyDigest.length()); - _objHdr.setDataLength((short) (8 + _keyDigest.length())); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - int lpadding = 0; - if (_padding != null) lpadding = _padding.length(); - return ((short) (_objHdr.getDataLength() + lpadding)); - } - - /** - * Method getKeyId - * - * @return an int - * - */ - public int getKeyId() { - return _keyId; - }; - - /** - * Method getSeqNum - * - * @return an int - * - */ - public int getSeqNum() { - return _seqNum; - }; - - /** - * Method getKeyDigest - * - * @return a COPSData - * - */ - public COPSData getKeyDigest() { - return _keyDigest; - }; - - /** - * Method isMessageIntegrity - * - * @return a boolean - * - */ - public boolean isMessageIntegrity() { - return true; - }; - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - byte[] buf = new byte[8]; - buf[0] = (byte) (_keyId >> 24); - buf[1] = (byte) (_keyId >> 16); - buf[2] = (byte) (_keyId >> 8); - buf[3] = (byte) _keyId; - buf[4] = (byte) (_seqNum >> 24); - buf[5] = (byte) (_seqNum >> 16); - buf[6] = (byte) (_seqNum >> 8); - buf[7] = (byte) _seqNum; - COPSUtil.writeData(id, buf, 8); - - COPSUtil.writeData(id, _keyDigest.getData(), _keyDigest.length()); - if (_padding != null) { - COPSUtil.writeData(id, _padding.getData(), _padding.length()); - } - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Key Id: " + _keyId + "\n").getBytes()); - os.write(new String("Sequence: " + _seqNum + "\n").getBytes()); - os.write(new String("Key digest: " + _keyDigest.str() + "\n").getBytes()); - } -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Integrity Object (RFC 2748) + * + * The integrity object includes a sequence number and a message digest + * useful for authenticating and validating the integrity of a COPS + * message. When used, integrity is provided at the end of a COPS + * message as the last COPS object. The digest is then computed over all + * of a particular COPS message up to but not including the digest value + * itself. The sender of a COPS message will compute and fill in the + * digest portion of the Integrity object. The receiver of a COPS + * message will then compute a digest over the received message and + * verify it matches the digest in the received Integrity object. + * + * C-Num = 16, + * + * C-Type = 1, HMAC digest + * + * The HMAC integrity object employs HMAC (Keyed-Hashing for Message + * Authentication) [HMAC] to calculate the message digest based on a key + * shared between the PEP and its PDP. + * + * This Integrity object specifies a 32-bit Key ID used to identify a + * specific key shared between a particular PEP and its PDP and the + * cryptographic algorithm to be used. The Key ID allows for multiple + * simultaneous keys to exist on the PEP with corresponding keys on the + * PDP for the given PEPID. The key identified by the Key ID was used to + * compute the message digest in the Integrity object. All + * implementations, at a minimum, MUST support HMAC-MD5-96, which is + * HMAC employing the MD5 Message-Digest Algorithm [MD5] truncated to + * 96-bits to calculate the message digest. + * + * This object also includes a sequence number that is a 32-bit unsigned + * integer used to avoid replay attacks. The sequence number is + * initiated during an initial Client-Open Client-Accept message + * exchange and is then incremented by one each time a new message is + * sent over the TCP connection in the same direction. If the sequence + * number reaches the value of 0xFFFFFFFF, the next increment will + * simply rollover to a value of zero. + * + * The variable length digest is calculated over a COPS message starting + * with the COPS Header up to the Integrity Object (which MUST be the + * last object in a COPS message) INCLUDING the Integrity object's + * header, Key ID, and Sequence Number. The Keyed Message Digest field + * is not included as part of the digest calculation. In the case of + * HMAC-MD5-96, HMAC-MD5 will produce a 128-bit digest that is then to + * be truncated to 96-bits before being stored in or verified against + * the Keyed Message Digest field as specified in [HMAC]. The Keyed + * Message Digest MUST be 96-bits when HMAC-MD5-96 is used. + */ +public class COPSIntegrity extends COPSObjBase { + + private final int _keyId; + private final int _seqNum; + private final COPSData _keyDigest; + private final COPSData _padding; + + /** + * Constructor generally used for sending messages + * // TODO - why aren't any classes requiring injection of the keyId, seqNum, or keyDigest members??? + * @throws java.lang.IllegalArgumentException + */ + public COPSIntegrity() { + this(0, 0, new COPSData()); + } + + public COPSIntegrity(final int keyId, final int seqNum, final COPSData keyDigest) { + this(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), keyId, seqNum, keyDigest); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param keyId - the keyId + * @param seqNum - the sequence number + * @param keyDigest - the data + * @throws java.lang.IllegalArgumentException + */ + protected COPSIntegrity(final COPSObjHeader hdr, final int keyId, final int seqNum, final COPSData keyDigest) { + super(hdr); + if (!hdr.getCNum().equals(CNum.MSG_INTEGRITY)) + throw new IllegalArgumentException("CNum must be of type - " + CNum.MSG_INTEGRITY); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("CType must be of type - " + CType.DEF); + + _keyId = keyId; + _seqNum = seqNum; + + if (keyDigest == null) _keyDigest = new COPSData(); + else _keyDigest = keyDigest; + if ((_keyDigest.length() % 4) != 0) { + final int padLen = 4 - (_keyDigest.length() % 4); + _padding = COPSObjectParser.getPadding(padLen); + } else { + _padding = new COPSData(); + } + } + + // Getters + public int getKeyId() { return _keyId; } + public int getSeqNum() { return _seqNum; } + public COPSData getKeyDigest() { return _keyDigest; } + + @Override + public int getDataLength() { + return 8 + _keyDigest.length() + _padding.length(); + } + + @Override + public void writeBody(final Socket socket) throws IOException { + final byte[] buf = new byte[8]; + buf[0] = (byte) (_keyId >> 24); + buf[1] = (byte) (_keyId >> 16); + buf[2] = (byte) (_keyId >> 8); + buf[3] = (byte) _keyId; + buf[4] = (byte) (_seqNum >> 24); + buf[5] = (byte) (_seqNum >> 16); + buf[6] = (byte) (_seqNum >> 8); + buf[7] = (byte) _seqNum; + COPSUtil.writeData(socket, buf, 8); + + COPSUtil.writeData(socket, _keyDigest.getData(), _keyDigest.length()); + if (_padding != null) { + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("Key Id: " + _keyId + "\n").getBytes()); + os.write(("Sequence: " + _seqNum + "\n").getBytes()); + os.write(("Key digest: " + _keyDigest.str() + "\n").getBytes()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSIntegrity)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSIntegrity integrity = (COPSIntegrity) o; + + if (_keyId != integrity._keyId) { + return false; + } + if (_seqNum != integrity._seqNum) { + return false; + } + if (_keyDigest.equals(integrity._keyDigest) && _padding.equals(integrity._padding)) return true; + else + return COPSUtil.copsDataPaddingEquals(this._keyDigest, this._padding, + integrity._keyDigest, integrity._padding); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _keyId; + result = 31 * result + _seqNum; + result = 31 * result + _keyDigest.hashCode(); + result = 31 * result + _padding.hashCode(); + return result; + } + + /** + * Parses bytes to return a COPSIntegrity object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSIntegrity parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + int keyId = 0; + keyId |= ((short) dataPtr[4]) << 24; + keyId |= ((short) dataPtr[5]) << 16; + keyId |= ((short) dataPtr[6]) << 8; + keyId |= ((short) dataPtr[7]) & 0xFF; + + int seqNum = 0; + seqNum |= ((short) dataPtr[8]) << 24; + seqNum |= ((short) dataPtr[9]) << 16; + seqNum |= ((short) dataPtr[10]) << 8; + seqNum |= ((short) dataPtr[11]) & 0xFF; + + final int usedBytes = objHdrData.header.getHdrLength() + 8; + if (objHdrData.msgByteCount > usedBytes) + return new COPSIntegrity(objHdrData.header, keyId, seqNum, + new COPSData(dataPtr, usedBytes, objHdrData.msgByteCount - usedBytes)); + else return new COPSIntegrity(objHdrData.header, keyId, seqNum, new COPSData()); + } + +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSInterface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSInterface.java index 7d6b746..44b92e5 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSInterface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSInterface.java @@ -1,67 +1,92 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - - - -/** - * COPS Interface - * - * @version COPSInterface.java, v 1.00 2003 - * - */ -abstract class COPSInterface extends COPSObjBase { - /** - * Method isIpv4Address - * - * @return a boolean - * - */ - protected boolean isIpv4Address() { - return false; - }; - - /** - * Method isIpv6Address - * - * @return a boolean - * - */ - protected boolean isIpv6Address() { - return false; - }; - - /** - * Method isInInterface - * - * @return a boolean - * - */ - protected boolean isInInterface() { - return false; - }; - - /** - * Method isOutInterface - * - * @return a boolean - * - */ - protected boolean isOutInterface() { - return false; - }; - - /** - * Method isInterface - * - * @return a boolean - * - */ - protected boolean isInterface() { - return true; - } -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * Abstract COPS Interface for extension of all COPS interface types + */ +abstract class COPSInterface extends COPSObjBase { + + /** + * The associated address object for a given COPS Interfaace + */ + protected final COPSIpAddress _addr; + + /** + * The interface on which the protocol message was received + */ + protected final int _ifindex; + + /** + * Constructor + * @param objHdr - the object's header + * @param ifindex - the interface value + * @throws java.lang.IllegalArgumentException + */ + protected COPSInterface(final COPSObjHeader objHdr, final COPSIpAddress addr, final int ifindex) { + super(objHdr); + if (addr == null) throw new IllegalArgumentException("Address object cannot be null"); + _addr = addr; + _ifindex = ifindex; + } + + public abstract boolean isInInterface(); + public abstract boolean isIPv6(); + + @Override + protected int getDataLength() { + return _addr.getDataLength() + 4; + } + + @Override + protected void writeBody(final Socket socket) throws IOException { + _addr.writeData(socket); + final byte[] buf = new byte[4]; + buf[0] = (byte) (_ifindex >> 24); + buf[1] = (byte) (_ifindex >> 16); + buf[2] = (byte) (_ifindex >> 8); + buf[3] = (byte) _ifindex; + COPSUtil.writeData(socket, buf, 4); + } + + @Override + protected void dumpBody(final OutputStream os) throws IOException { + os.write(("Address: " + _addr.getIpName() + "\n").getBytes()); + os.write(("ifindex: " + _ifindex + "\n").getBytes()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSInterface)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSInterface that = (COPSInterface) o; + + return _ifindex == that._ifindex && _addr.equals(that._addr); + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _addr.hashCode(); + result = 31 * result + _ifindex; + return result; + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpAddress.java new file mode 100644 index 0000000..2093fff --- /dev/null +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpAddress.java @@ -0,0 +1,87 @@ +package org.umu.cops.stack; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.Arrays; + +/** + * Abstract superclass for all COPS IP Addresses. + */ +public abstract class COPSIpAddress { + + /** + * The byte array representation of an IP address + */ + protected final byte[] _addr; + + /** + * Creates an address for a given host + * @param hostName - the host name + * @throws java.net.UnknownHostException + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpAddress(final String hostName) throws UnknownHostException { + if (hostName == null) throw new IllegalArgumentException("Hostname must not be null"); + _addr = deriveIpAddress(hostName); + } + + protected COPSIpAddress(final byte[] addr) { + if (addr == null) throw new IllegalArgumentException("The addr parameter must not be null"); + _addr = addr; + } + + protected byte[] getAddressBytes() { return _addr; } + + /** + * Derives the IP address in a byte array from the host name + * @param hostName a String + * @throws UnknownHostException + */ + protected abstract byte[] deriveIpAddress(final String hostName) throws UnknownHostException; + + /** + * Method getIpName + * @return a String + * @throws UnknownHostException + */ + public abstract String getIpName() throws UnknownHostException; + + /** + * Returns the number of bytes that will be written + * @return a short + */ + public int getDataLength() { + return _addr.length; + } + + /** + * Write data on a given network socket + * @param socket a Socket + * @throws IOException + */ + public void writeData(Socket socket) throws IOException { + COPSUtil.writeData(socket, _addr, _addr.length); + } + + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSIpAddress)) { + return false; + } + + final COPSIpAddress that = (COPSIpAddress) o; + + return Arrays.equals(_addr, that._addr); + + } + + @Override + public int hashCode() { + return Arrays.hashCode(_addr); + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Address.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Address.java index 2bb7d87..3ed9397 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Address.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Address.java @@ -1,107 +1,55 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -/** - * COPS IPv4 Address - * - * @version COPSIpv4Address.java, v 1.00 2003 - * - */ -public class COPSIpv4Address { - - private byte[] _addr; - - public COPSIpv4Address() { - _addr = new byte[4]; - } - - public COPSIpv4Address(String hostName) throws UnknownHostException { - setIpAddress(hostName); - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr = InetAddress.getByName(hostName).getAddress(); - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return InetAddress.getByAddress(_addr).getHostName(); - } - - /** - * Method getIpAddress - * - * @return an int - * - */ - public int getIpAddress() { - int ipaddr = 0; - - ipaddr |= ((int) _addr[0]) << 24; - ipaddr |= ((int) _addr[1]) << 16; - ipaddr |= ((int) _addr[2]) << 8; - ipaddr |= ((int) _addr[3]) & 0xFF; - - return ipaddr; - } - - /** - * Method parse - * - * @param dataPtr a byte[] - * - */ - public void parse(byte[] dataPtr) { - new ByteArrayInputStream(dataPtr).read(_addr,0,4); - } - - /** - * Method getDataLength - * - * @return a short - * - */ - public short getDataLength() { - return (4); - } - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - COPSUtil.writeData(id, _addr, 4); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.net.Inet4Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * COPS IPv4 Address + */ +public class COPSIpv4Address extends COPSIpAddress { + + /** + * Creates an address for a given host + * @param hostName - the host name + * @throws UnknownHostException + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4Address(final String hostName) throws UnknownHostException { + super(hostName); + } + + /** + * Creates an address for a given IP address contained within a byte array + * @param addr - the host name + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4Address(final byte[] addr) { + super(addr); + if (addr.length != 4) throw new IllegalArgumentException("The address must be 4 bytes"); + } + + @Override + protected byte[] deriveIpAddress(final String hostName) throws UnknownHostException { + final InetAddress[] addrs = Inet4Address.getAllByName(hostName); + for (final InetAddress addr : addrs) { + if (addr instanceof Inet4Address) { + return addr.getAddress(); + } + } + throw new UnknownHostException("InetAddress could not be found"); + } + + @Override + public String getIpName() throws UnknownHostException { + return Inet4Address.getByAddress(_addr).getHostName(); + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4InInterface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4InInterface.java index e243dc7..7c20f41 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4InInterface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4InInterface.java @@ -1,60 +1,86 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.net.Socket; - -/** - * COPS IPv4 Input Address - * - * @version COPSIpv4InInterface.java, v 1.00 2003 - * - */ -public class COPSIpv4InInterface extends COPSIpv4Interface { - public COPSIpv4InInterface() { - super(new COPSObjHeader(CNum.ININTF, CType.DEF)); - } - - public COPSIpv4InInterface(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method className - * - * @return a String - * - */ - public String className() { - return "COPSIpv4InInterface"; - } - - /** - * Method isInInterface - * - * @return a boolean - * - */ - public boolean isInInterface() { - return true; - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - } -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS IPv4 Input Address (RFC 2748) + * + * The In-Interface Object is used to identify the incoming interface on + * which a particular request applies and the address where the received + * message originated. For flows or messages generated from the PEP's + * local host, the loop back address and ifindex are used. + * + * This Interface object is also used to identify the incoming + * (receiving) interface via its ifindex. The ifindex may be used to + * differentiate between sub-interfaces and unnumbered interfaces (see + * RSVP's LIH for an example). When SNMP is supported by the PEP, this + * ifindex integer MUST correspond to the same integer value for the + * interface in the SNMP MIB-II interface index table. + * + * Note: The ifindex specified in the In-Interface is typically relative + * to the flow of the underlying protocol messages. The ifindex is the + * interface on which the protocol message was received. + * + * C-Num = 3 + * + * C-Type = 1, IPv4 Address + Interface + * + * 0 1 2 3 + * +--------------+--------------+--------------+--------------+ + * | IPv4 Address format | + * +--------------+--------------+--------------+--------------+ + * | ifindex | + * +--------------+--------------+--------------+--------------+ + * + * For this type of the interface object, the IPv4 address specifies the + * IP address that the incoming message came from. + */ +public class COPSIpv4InInterface extends COPSIpv4Interface { + + /** + * Constructor generally used for sending messages + * @param ifindex - the interface value + * @param addr - the IPv4 address + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4InInterface(final COPSIpv4Address addr, final int ifindex) { + this(new COPSObjHeader(CNum.ININTF, CType.DEF), addr, ifindex); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param ifindex - the interface value + * @param addr - the IPv4 address + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4InInterface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + if (!objHdr.getCNum().equals(CNum.ININTF)) + throw new IllegalArgumentException("CNum must be of type - " + CNum.ININTF); + if (!objHdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("CType must be of type - " + CType.DEF); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSIpv4InInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + return new COPSIpv4InInterface(objHdrData.header, COPSIpv4Interface.parseAddress(dataPtr), + COPSIpv4Interface.parseIfIndex(dataPtr)); + } + + public boolean isInInterface() { return true; } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Interface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Interface.java index a9fbc3b..86ff35f 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Interface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4Interface.java @@ -1,105 +1,64 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.net.UnknownHostException; - -/** - * COPS IPv4 Interface - * - * @version COPSIpv4Interface.java, v 1.00 2003 - * - */ -public abstract class COPSIpv4Interface extends COPSInterface { - - protected COPSObjHeader _objHdr; - private COPSIpv4Address _addr; - private int _ifindex; - - - /** - * Method isIpv4Address - * - * @return a boolean - * - */ - public boolean isIpv4Address() { - return true; - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr.setIpAddress(hostName); - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return (_addr.getIpName()); - } - - /** - * Method getIpAddress - * - * @return an int - * - */ - public int getIpAddress() { - return (_addr.getIpAddress()); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - protected COPSIpv4Interface(COPSObjHeader hdr) { - _objHdr = hdr; -// _objHdr.setCType((byte) 1); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - protected COPSIpv4Interface(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - byte[] buf = new byte[4]; - System.arraycopy(dataPtr,4,buf,0,4); - - _addr.parse(buf); - - _ifindex |= ((int) dataPtr[8]) << 24; - _ifindex |= ((int) dataPtr[9]) << 16; - _ifindex |= ((int) dataPtr[10]) << 8; - _ifindex |= ((int) dataPtr[11]) & 0xFF; - - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - -} - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +/** + * COPS IPv4 Interface + * + * @version COPSIpv4Interface.java, v 1.00 2003 + * + */ +public abstract class COPSIpv4Interface extends COPSInterface { + + /** + * Constructor + * @param objHdr - the header + * @param ifindex - the interface value + * @param addr - the address object + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4Interface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + } + + @Override + public boolean isIPv6() { return false; } + + /** + * Creates a COPSIpv4Address object from a byte array. + * @param dataPtr - the byte array + * @return - the address + * @throws java.lang.IllegalArgumentException + */ + protected static COPSIpv4Address parseAddress(final byte[] dataPtr) { + byte[] buf = new byte[4]; + buf[0] = dataPtr[4]; + buf[1] = dataPtr[5]; + buf[2] = dataPtr[6]; + buf[3] = dataPtr[7]; + return new COPSIpv4Address(buf); + } + + /** + * Parses the ifindex value from a byte array. + * @param dataPtr - the byte array + * @return - the index value + */ + protected static int parseIfIndex(final byte[] dataPtr) { + int ifindex = 0; + ifindex |= ((int) dataPtr[8]) << 24; + ifindex |= ((int) dataPtr[9]) << 16; + ifindex |= ((int) dataPtr[10]) << 8; + ifindex |= ((int) dataPtr[11]) & 0xFF; + return ifindex; + } + +} + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4LastPdpAddr.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4LastPdpAddr.java index 25ee04f..f86e1fd 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4LastPdpAddr.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4LastPdpAddr.java @@ -1,55 +1,64 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * COPS IPv4 Last PDP Address - * - * @version COPSIpv4LastPdpAddr.java, v 1.00 2003 - * - */ -public class COPSIpv4LastPdpAddr extends COPSIpv4PdpAddress { - - public COPSIpv4LastPdpAddr() { - super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF)); - } - - public COPSIpv4LastPdpAddr(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method isLastPdpAddress - * - * @return a boolean - * - */ - public boolean isLastPdpAddress() { - return true; - }; - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Ipv4PdpAddress" + "\n").getBytes()); - os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes()); - os.write(new String("Port: " + _tcpPort + "\n").getBytes()); - } -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.UnknownHostException; + +/** + * Last PDP Address (RFC 2748) + * + * When a PEP sends a Client-Open message for a particular client-type + * the PEP SHOULD specify the last PDP it has successfully opened + * (meaning it received a Client-Accept) since the PEP last rebooted. + * If no PDP was used since the last reboot, the PEP will simply not + * include this object in the Client-Open message. + * + * C-Num = 14, + * + * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr) + * + * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr) + */ +public class COPSIpv4LastPdpAddr extends COPSIpv4PdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param port - the associated port + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4LastPdpAddr(final String host, final int port, final short reserved) throws UnknownHostException { + super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), host, port, reserved); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4LastPdpAddr(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, + final short reserved) { + super(objHdr, addr, tcpPort, reserved); + if (!objHdr.getCNum().equals(CNum.LAST_PDP_ADDR)) + throw new IllegalArgumentException("CNum must be equal to - " + CNum.LAST_PDP_ADDR); + } + + @Override + public void dumpBody(OutputStream os) throws IOException { + os.write(("Ipv4LastPdpAddress" + "\n").getBytes()); + super.dumpBody(os); + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4OutInterface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4OutInterface.java index 572e680..b436081 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4OutInterface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4OutInterface.java @@ -1,63 +1,86 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.net.Socket; - -/** - * COPS IPv4 Output Interface - * - * @version COPSIpv4OutInterface.java, v 1.00 2003 - * - */ -public class COPSIpv4OutInterface extends COPSIpv4Interface { - public COPSIpv4OutInterface() { - super(new COPSObjHeader(CNum.ININTF, CType.DEF)); - } - - public COPSIpv4OutInterface(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method className - * - * @return a String - * - */ - public String className() { - return "COPSIpv4OutInterface"; - } - - /** - * Method isInInterface - * - * @return a boolean - * - */ - public boolean isInInterface() { - return true; - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - } - -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS IPv4 Output Interface (RFC 2748) + * + * The Out-Interface is used to identify the outgoing interface to which + * a specific request applies and the address for where the forwarded + * message is to be sent. For flows or messages destined to the PEP's + * local host, the loop back address and ifindex are used. The Out- + * Interface has the same formats as the In-Interface Object. + * + * This Interface object is also used to identify the outgoing + * (forwarding) interface via its ifindex. The ifindex may be used to + * differentiate between sub-interfaces and unnumbered interfaces (see + * RSVP's LIH for an example). When SNMP is supported by the PEP, this + * ifindex integer MUST correspond to the same integer value for the + * interface in the SNMP MIB-II interface index table. + * + * Note: The ifindex specified in the Out-Interface is typically + * relative to the flow of the underlying protocol messages. The ifindex + * is the one on which a protocol message is about to be forwarded. + * + * C-Num = 4 + * + * C-Type = 1, IPv4 Address + Interface + * + * Same C-Type format as the In-Interface object. The IPv4 address + * specifies the IP address to which the outgoing message is going. The + * ifindex is used to refer to the MIB-II defined local outgoing + * interface on the PEP. + * C-Type = 2, IPv6 Address + Interface + * + * Same C-Type format as the In-Interface object. For this type of the + * interface object, the IPv6 address specifies the IP address to which + * the outgoing message is going. The ifindex is used to refer to the + * MIB-II defined local outgoing interface on the PEP. + */ +public class COPSIpv4OutInterface extends COPSIpv4Interface { + + /** + * Constructor generally used for sending messages + * @param ifindex - the interface value + * @param addr - the IPv4 address + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4OutInterface(final COPSIpv4Address addr, final int ifindex) { + this(new COPSObjHeader(CNum.OUTINTF, CType.DEF), addr, ifindex); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param ifindex - the interface value + * @param addr - the IPv4 address + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4OutInterface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSIpv4OutInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + return new COPSIpv4OutInterface(objHdrData.header, COPSIpv4Interface.parseAddress(dataPtr), + COPSIpv4Interface.parseIfIndex(dataPtr)); + } + + public boolean isInInterface() { return false; } +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpAddress.java index 98b0042..f49a79c 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpAddress.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpAddress.java @@ -1,139 +1,50 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.net.Socket; -import java.net.UnknownHostException; - -/** - * COPS IPv4 PDP Address - * - * @version COPSIpv4PdpAddress.java, v 1.00 2003 - * - */ -abstract public class COPSIpv4PdpAddress extends COPSPdpAddress { - - protected COPSObjHeader _objHdr; - protected COPSIpv4Address _addr; - private short _reserved; - protected short _tcpPort; - - protected COPSIpv4PdpAddress(COPSObjHeader hdr) { - _addr = new COPSIpv4Address(); - _objHdr = hdr; -// _objHdr.setCType((byte) 1); - // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t)); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - protected COPSIpv4PdpAddress(byte[] dataPtr) { - _addr = new COPSIpv4Address(); - _objHdr = COPSObjHeader.parse(dataPtr); - - byte[] buf = new byte[4]; - System.arraycopy(dataPtr,2,buf,0,4); - _addr.parse(buf); - - _reserved |= ((short) dataPtr[8]) << 8; - _reserved |= ((short) dataPtr[9]) & 0xFF; - _tcpPort |= ((short) dataPtr[10]) << 8; - _tcpPort |= ((short) dataPtr[11]) & 0xFF; - - // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t)); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr.setIpAddress(hostName); - } - - /** - * Method setTcpPort - * - * @param port a short - * - */ - public void setTcpPort(short port) { - _tcpPort = port; - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return (_addr.getIpName()); - } - - /** - * Method getTcpPort - * - * @return a short - * - */ - short getTcpPort() { - return _tcpPort; - }; - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - /** - * Method isIpv6PdpAddress - * - * @return a boolean - * - */ - public boolean isIpv6PdpAddress() { - return true; - } - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // - _objHdr.writeData(id); - _addr.writeData(id); - - byte[] buf = new byte[4]; - buf[0] = (byte) (_reserved & 0xFF); - buf[1] = (byte) (_reserved << 8); - buf[2] = (byte) (_tcpPort & 0xFF); - buf[3] = (byte) (_tcpPort << 8); - - COPSUtil.writeData(id, buf, 4); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.net.UnknownHostException; + +/** + * Super for IPv4 PDP Addresses + */ +abstract public class COPSIpv4PdpAddress extends COPSPdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param tcpPort - the associated port + * @param reserved - not in use + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4PdpAddress(final COPSObjHeader objHdr, final String host, final int tcpPort, final short reserved) + throws UnknownHostException { + super(objHdr, new COPSIpv4Address(host), tcpPort, reserved); + if (!objHdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Must have a CType value of " + CType.DEF); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @param reserved - not in use + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4PdpAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, + final short reserved) { + super(objHdr, new COPSIpv4Address(addr), tcpPort, reserved); + if (!objHdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Must have a CType value of " + CType.DEF); + } + + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddress.java new file mode 100644 index 0000000..33bb1bc --- /dev/null +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddress.java @@ -0,0 +1,56 @@ +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.UnknownHostException; + +/** + * PDP Redirect Address (RFC 2748 pg. 15) + * + * A PDP when closing a PEP session for a particular client-type may + optionally use this object to redirect the PEP to the specified PDP + server address and TCP port number: + * + * C-Num = 13, + * + * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr) + * + * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr) + */ +public class COPSIpv4PdpRedirectAddress extends COPSIpv4PdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param port - the associated port + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv4PdpRedirectAddress(final String host, final int port, final short reserved) throws UnknownHostException { + super(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), host, port, reserved); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv4PdpRedirectAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, + final short reserved) { + super(objHdr, addr, tcpPort, reserved); + if (!objHdr.getCNum().equals(CNum.PDP_REDIR)) + throw new IllegalArgumentException("CNum must be equal to - " + CNum.PDP_REDIR); + } + + @Override + public void dumpBody(OutputStream os) throws IOException { + os.write(("Ipv4PdpRedirectAddress" + "\n").getBytes()); + super.dumpBody(os); + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Address.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Address.java index 0364359..7d62b0b 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Address.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Address.java @@ -1,90 +1,56 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; - -/** - * COPS IPv6 Address - * - * @version COPSIpv6Address.java, v 1.00 2003 - * - */ -public class COPSIpv6Address { - - private byte[] _addr; - - public COPSIpv6Address() { - _addr = new byte[16]; - } - - public COPSIpv6Address(String hostName) throws UnknownHostException { - setIpAddress(hostName); - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr = InetAddress.getByName(hostName).getAddress(); - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return InetAddress.getByAddress(_addr).getHostName(); - } - - /** - * Method parse - * - * @param dataPtr a byte[] - * - */ - public void parse(byte[] dataPtr) { - new ByteArrayInputStream(dataPtr).read(_addr,0,16); - } - - /** - * Method getDataLength - * - * @return a short - * - */ - public short getDataLength() { - return (16); - } - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - COPSUtil.writeData(id, _addr, 16); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * COPS IPv6 Address + */ +public class COPSIpv6Address extends COPSIpAddress { + + /** + * Creates an address for a given host + * @param hostName - the host name + * @throws UnknownHostException + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6Address(final String hostName) throws UnknownHostException { + super(hostName); + } + + /** + * Creates an address for a given IP address contained within a byte array + * @param addr - the host name + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6Address(final byte[] addr) { + super(addr); + if (addr.length != 16) throw new IllegalArgumentException("The address must be 16 bytes"); + } + + + @Override + protected byte[] deriveIpAddress(final String hostName) throws UnknownHostException { + final InetAddress[] addrs = Inet4Address.getAllByName(hostName); + for (final InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + return addr.getAddress(); + } + } + throw new UnknownHostException("InetAddress could not be found"); + } + + @Override + public String getIpName() throws UnknownHostException { + return Inet6Address.getByAddress(_addr).getHostName(); + } +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6InInterface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6InInterface.java index b49716b..51c93e0 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6InInterface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6InInterface.java @@ -1,62 +1,94 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.net.Socket; - -/** - * COPS IPv6 Input Interface - * - * @version COPSIpv6InInterface.java, v 1.00 2003 - * - */ -public class COPSIpv6InInterface extends COPSIpv6Interface { - public COPSIpv6InInterface() { - super(new COPSObjHeader(CNum.ININTF, CType.STATELESS)); - } - - public COPSIpv6InInterface(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method className - * - * @return a String - * - */ - public String className() { - return "COPSIpv6InInterface"; - } - - /** - * Method isInInterface - * - * @return a boolean - * - */ - public boolean isInInterface() { - return true; - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - } -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS IPv6 Input Address (RFC 2748) + * + * The In-Interface Object is used to identify the incoming interface on + * which a particular request applies and the address where the received + * message originated. For flows or messages generated from the PEP's + * local host, the loop back address and ifindex are used. + * + * This Interface object is also used to identify the incoming + * (receiving) interface via its ifindex. The ifindex may be used to + * differentiate between sub-interfaces and unnumbered interfaces (see + * RSVP's LIH for an example). When SNMP is supported by the PEP, this + * ifindex integer MUST correspond to the same integer value for the + * interface in the SNMP MIB-II interface index table. + * + * Note: The ifindex specified in the In-Interface is typically relative + * to the flow of the underlying protocol messages. The ifindex is the + * interface on which the protocol message was received. + * + * C-Type = 2, IPv6 Address + Interface + * + * 0 1 2 3 + * +--------------+--------------+--------------+--------------+ + * | | + * + + + * | | + * + IPv6 Address format + + * | | + * + + + * | | + * +--------------+--------------+--------------+--------------+ + * | ifindex | + * +--------------+--------------+--------------+--------------+ + * + * For this type of the interface object, the IPv6 address specifies the + * IP address that the incoming message came from. The ifindex is used + * to refer to the MIB-II defined local incoming interface on the PEP as + * described above. + */ +public class COPSIpv6InInterface extends COPSIpv6Interface { + + /** + * Constructor generally used for sending messages + * @param ifindex - the interface value + * @param addr - the IPv6 address + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6InInterface(final COPSIpv6Address addr, final int ifindex) { + super(new COPSObjHeader(CNum.ININTF, CType.STATELESS), addr, ifindex); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param ifindex - the interface value + * @param addr - the IPv6 address + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6InInterface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + if (!objHdr.getCNum().equals(CNum.ININTF)) + throw new IllegalArgumentException("CNum must be of type - " + CNum.ININTF); + if (!objHdr.getCType().equals(CType.STATELESS)) + throw new IllegalArgumentException("CType must be of type - " + CType.STATELESS); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSIpv6InInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + return new COPSIpv6InInterface(objHdrData.header, COPSIpv6Interface.parseAddress(dataPtr), + COPSIpv6Interface.parseIfIndex(dataPtr)); + } + + public boolean isInInterface() { return true; } +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Interface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Interface.java index 2165aee..9bff413 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Interface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6Interface.java @@ -1,95 +1,64 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.net.UnknownHostException; - -/** - * COPS IPv6 Interface - * - * @version COPSIpv6Interface.java, v 1.00 2003 - * - */ -public abstract class COPSIpv6Interface extends COPSInterface { - - /** - * Method isIpv6Address - * - * @return a boolean - * - */ - public boolean isIpv6Address() { - return true; - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr.setIpAddress(hostName); - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return (_addr.getIpName()); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - protected COPSIpv6Interface(COPSObjHeader hdr) { - _objHdr = hdr; -// _objHdr.setCType((byte) 2); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - protected COPSIpv6Interface(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - _objHdr.parse(dataPtr); - // _objHdr.checkDataLength(); - - byte[] buf = new byte[4]; - System.arraycopy(dataPtr,4,buf,0,16); - - _addr.parse(buf); - - _ifindex |= ((int) dataPtr[20]) << 24; - _ifindex |= ((int) dataPtr[21]) << 16; - _ifindex |= ((int) dataPtr[22]) << 8; - _ifindex |= ((int) dataPtr[23]) & 0xFF; - - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - private COPSObjHeader _objHdr; - private COPSIpv6Address _addr; - private int _ifindex; -} - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.ByteArrayInputStream; + +/** + * COPS IPv6 Interface + * + * @version COPSIpv6Interface.java, v 1.00 2003 + * + */ +public abstract class COPSIpv6Interface extends COPSInterface { + + /** + * Constructor + * @param objHdr - the header + * @param ifindex - the interface value + * @param addr - the address object + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6Interface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + } + + @Override + public boolean isIPv6() { return true; } + + /** + * Creates a COPSIpv6Address object from a byte array. + * @param dataPtr - the byte array + * @return - the address + * @throws java.lang.IllegalArgumentException + */ + protected static COPSIpv6Address parseAddress(final byte[] dataPtr) { + byte[] buf = new byte[16]; + System.arraycopy(dataPtr, 4, buf, 0, 16); + new ByteArrayInputStream(dataPtr).read(buf, 0, 16); + return new COPSIpv6Address(buf); + } + + /** + * Parses the ifindex value from a byte array. + * @param dataPtr - the byte array + * @return - the index value + */ + protected static int parseIfIndex(final byte[] dataPtr) { + int ifindex = 0; + ifindex |= ((int) dataPtr[20]) << 24; + ifindex |= ((int) dataPtr[21]) << 16; + ifindex |= ((int) dataPtr[22]) << 8; + ifindex |= ((int) dataPtr[23]) & 0xFF; + return ifindex; + } + +} + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6LastPdpAddr.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6LastPdpAddr.java index 0840392..81f3355 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6LastPdpAddr.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6LastPdpAddr.java @@ -1,54 +1,65 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * COPS IPv6 Last PDP Address - * - * @version COPSIpv6LastPdpAddr.java, v 1.00 2003 - * - */ -public class COPSIpv6LastPdpAddr extends COPSIpv6PdpAddress { - - public COPSIpv6LastPdpAddr() { - super(); - // TODO - FIXME later, currently not in use and the header is now immutable -// _objHdr.setCNum(COPSObjHeader.COPS_LAST_PDP_ADDR); - } - - public COPSIpv6LastPdpAddr(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method isLastPdpAddress - * - * @return a boolean - * - */ - public boolean isLastPdpAddress() { - return true; - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Ipv6PdpAddress" + "\n").getBytes()); - os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes()); - os.write(new String("Port: " + _tcpPort + "\n").getBytes()); - } -}; +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.UnknownHostException; + +/** + * Last PDP Address (RFC 2748) + * + * When a PEP sends a Client-Open message for a particular client-type + * the PEP SHOULD specify the last PDP it has successfully opened + * (meaning it received a Client-Accept) since the PEP last rebooted. + * If no PDP was used since the last reboot, the PEP will simply not + * include this object in the Client-Open message. + * + * C-Num = 14, + * + * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr) + * + * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr) + */ +public class COPSIpv6LastPdpAddr extends COPSIpv6PdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param tcpPort - the associated port + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6LastPdpAddr(final String host, final int tcpPort, final short reserved) throws UnknownHostException { + super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), host, tcpPort, reserved); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6LastPdpAddr(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, final short reserved) { + super(objHdr, addr, tcpPort, reserved); + if (!objHdr.getCNum().equals(CNum.LAST_PDP_ADDR)) + throw new IllegalArgumentException("CNum must be equal to - " + CNum.LAST_PDP_ADDR); + } + + @Override + public void dumpBody(OutputStream os) throws IOException { + os.write(("Ipv6LastPdpAddr" + "\n").getBytes()); + super.dumpBody(os); + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6OutInterface.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6OutInterface.java index 1908874..94d4204 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6OutInterface.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6OutInterface.java @@ -1,61 +1,84 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.net.Socket; - -/** - * COPS IPv6 Output Interface - * - * @version COPSIpv6OutInterface.java, v 1.00 2003 - * - */ -public class COPSIpv6OutInterface extends COPSIpv6Interface { - public COPSIpv6OutInterface() { - super(new COPSObjHeader(CNum.ININTF, CType.STATELESS)); - } - - public COPSIpv6OutInterface(byte[] dataPtr) { - super(dataPtr); - } - - /** - * Method className - * - * @return a String - * - */ - public String className() { - return "COPSIpv6OutInterface"; - } - - /** - * Method isInInterface - * - * @return a boolean - * - */ - public boolean isInInterface() { - return true; - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - } - -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS IPv6 Output Interface (RFC 2748) + * + * The Out-Interface is used to identify the outgoing interface to which + * a specific request applies and the address for where the forwarded + * message is to be sent. For flows or messages destined to the PEP's + * local host, the loop back address and ifindex are used. The Out- + * Interface has the same formats as the In-Interface Object. + * + * This Interface object is also used to identify the outgoing + * (forwarding) interface via its ifindex. The ifindex may be used to + * differentiate between sub-interfaces and unnumbered interfaces (see + * RSVP's LIH for an example). When SNMP is supported by the PEP, this + * ifindex integer MUST correspond to the same integer value for the + * interface in the SNMP MIB-II interface index table. + * + * Note: The ifindex specified in the Out-Interface is typically + * relative to the flow of the underlying protocol messages. The ifindex + * is the one on which a protocol message is about to be forwarded. + * + * C-Num = 4 + * + * C-Type = 1, IPv4 Address + Interface + * + * Same C-Type format as the In-Interface object. The IPv4 address + * specifies the IP address to which the outgoing message is going. The + * ifindex is used to refer to the MIB-II defined local outgoing + * interface on the PEP. + * C-Type = 2, IPv6 Address + Interface + * + * Same C-Type format as the In-Interface object. For this type of the + * interface object, the IPv6 address specifies the IP address to which + * the outgoing message is going. The ifindex is used to refer to the + * MIB-II defined local outgoing interface on the PEP. + */ +public class COPSIpv6OutInterface extends COPSIpv6Interface { + + /** + * Constructor generally used for sending messages + * @param ifindex - the interface value + * @param addr - the IPv6 address + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6OutInterface(final COPSIpv6Address addr, final int ifindex) { + this(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), addr, ifindex); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param ifindex - the interface value + * @param addr - the IPv6 address + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6OutInterface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) { + super(objHdr, addr, ifindex); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSIpv6OutInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + return new COPSIpv6OutInterface(objHdrData.header, COPSIpv6Interface.parseAddress(dataPtr), + COPSIpv6Interface.parseIfIndex(dataPtr)); + } + + public boolean isInInterface() { return false; } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpAddress.java index 698e2ec..2c3734f 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpAddress.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpAddress.java @@ -1,141 +1,50 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.net.Socket; -import java.net.UnknownHostException; - -/** - * COPS IPv6 PDP Address - * - * @version COPSIpv6PdpAddress.java, v 1.00 2003 - * - */ -abstract public class COPSIpv6PdpAddress extends COPSPdpAddress { - - protected COPSObjHeader _objHdr; - protected COPSIpv6Address _addr; - private short _reserved; - protected short _tcpPort; - - protected COPSIpv6PdpAddress() { - _addr = new COPSIpv6Address(); - _objHdr = new COPSObjHeader(CNum.NA, CType.STATELESS); - // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t)); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - protected COPSIpv6PdpAddress(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - // _objHdr.checkDataLength(); - - byte[] buf = new byte[16]; - System.arraycopy(dataPtr,2,buf,0,16); - _addr.parse(buf); - - _reserved |= ((short) dataPtr[20]) << 8; - _reserved |= ((short) dataPtr[21]) & 0xFF; - _tcpPort |= ((short) dataPtr[22]) << 8; - _tcpPort |= ((short) dataPtr[23]) & 0xFF; - - // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t)); - _objHdr.setDataLength((short) (_addr.getDataLength() + 4)); - } - - /** - * Method setIpAddress - * - * @param hostName a String - * - * @throws UnknownHostException - * - */ - public void setIpAddress(String hostName) throws UnknownHostException { - _addr.setIpAddress(hostName); - } - - /** - * Method setTcpPort - * - * @param port a short - * - */ - public void setTcpPort(short port) { - _tcpPort = port; - } - - /** - * Method getIpName - * - * @return a String - * - * @throws UnknownHostException - * - */ - public String getIpName() throws UnknownHostException { - return (_addr.getIpName()); - } - - /** - * Method getTcpPort - * - * @return a short - * - */ - short getTcpPort() { - return _tcpPort; - }; - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - /** - * Method isIpv6PdpAddress - * - * @return a boolean - * - */ - public boolean isIpv6PdpAddress() { - return true; - } - - /** - * Write data on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // - _objHdr.writeData(id); - _addr.writeData(id); - - byte[] buf = new byte[4]; - buf[0] = (byte) (_reserved >> 8); - buf[1] = (byte) _reserved; - buf[2] = (byte) (_tcpPort >> 8); - buf[3] = (byte) _tcpPort ; - - COPSUtil.writeData(id, buf, 4); - } -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.net.UnknownHostException; + +/** + * Super for IPv6 PDP Addresses + */ +abstract public class COPSIpv6PdpAddress extends COPSPdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param tcpPort - the associated port + * @param reserved - not in use + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6PdpAddress(final COPSObjHeader objHdr, final String host, final int tcpPort, final short reserved) + throws UnknownHostException { + super(objHdr, new COPSIpv6Address(host), tcpPort, reserved); + if (!objHdr.getCType().equals(CType.STATELESS)) + throw new IllegalArgumentException("Must have a CType value of " + CType.STATELESS); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @param reserved - not in use + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6PdpAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, + final short reserved) { + super(objHdr, new COPSIpv6Address(addr), tcpPort, reserved); + if (!objHdr.getCType().equals(CType.STATELESS)) + throw new IllegalArgumentException("Must have a CType value of " + CType.STATELESS); + } + +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddress.java new file mode 100644 index 0000000..a5f2bc7 --- /dev/null +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddress.java @@ -0,0 +1,57 @@ +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.UnknownHostException; + +/** + * PDP Redirect Address (RFC 2748 pg. 15) + * + * A PDP when closing a PEP session for a particular client-type may + optionally use this object to redirect the PEP to the specified PDP + server address and TCP port number: + * + * C-Num = 13, + * + * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr) + * + * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr) + */ +public final class COPSIpv6PdpRedirectAddress extends COPSIpv6PdpAddress { + + /** + * Constructor generally used for sending messages + * @param host - the host name + * @param port - the associated port + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + public COPSIpv6PdpRedirectAddress(final String host, final int port, final short reserved) throws UnknownHostException { + super(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), host, port, reserved); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param objHdr - the object header + * @param addr - the byte array representation of a host + * @param tcpPort - the associated port + * @throws java.lang.IllegalArgumentException + */ + protected COPSIpv6PdpRedirectAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, + final short reserved) { + super(objHdr, addr, tcpPort, reserved); + if (!objHdr.getCNum().equals(CNum.PDP_REDIR)) + throw new IllegalArgumentException("CNum must be equal to - " + CNum.PDP_REDIR); + } + + @Override + public void dumpBody(OutputStream os) throws IOException { + os.write(("Ipv6PdpRedirectAddress" + "\n").getBytes()); + super.dumpBody(os); + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKAMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKAMsg.java index a640be6..9d584a7 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKAMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKAMsg.java @@ -1,190 +1,188 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Keep Alive Message - * - * @version COPSKAMsg.java, v 1.00 2003 - * - */ -public class COPSKAMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSIntegrity _integrity; - - public COPSKAMsg() { - _integrity = null; - } - - protected COPSKAMsg(byte[] data) throws COPSException { - _integrity = null; - parse(data); - } - - /** Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - //The client type in the header MUST always be set to 0 - //as KA is used for connection verification.RFC 2748 - if ((_hdr == null) && (_hdr.getClientType() != 0)) - throw new COPSException("Bad message format"); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_KA) - throw new COPSException ("Error Header (no COPS_OP_KA)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Integrity objects - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Returns true if it has Integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - }; - - /** - * Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Writes data to given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Method parse - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: { - throw new COPSException("Bad Message format, unknown object type"); - } - } - } - checkSanity(); - } - - /** - * Method parse - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_KA) - throw new COPSException("Error Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - private void setMsgLength() throws COPSException { - short len = 0; - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - - - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Keep Alive Message + * + * @version COPSKAMsg.java, v 1.00 2003 + * + */ +public class COPSKAMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSIntegrity _integrity; + + public COPSKAMsg() { + _integrity = null; + } + + protected COPSKAMsg(byte[] data) throws COPSException { + _integrity = null; + parse(data); + } + + /** Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + //The client type in the header MUST always be set to 0 + //as KA is used for connection verification.RFC 2748 + if ((_hdr == null) && (_hdr.getClientType() != 0)) + throw new COPSException("Bad message format"); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_KA) + throw new COPSException ("Error Header (no COPS_OP_KA)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Integrity objects + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Returns true if it has Integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + }; + + /** + * Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Writes data to given network socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Method parse + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: { + throw new COPSException("Bad Message format, unknown object type"); + } + } + } + checkSanity(); + } + + /** + * Method parse + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_KA) + throw new COPSException("Error Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + private void setMsgLength() throws COPSException { + short len = 0; + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + + + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKATimer.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKATimer.java index 86db031..afb24af 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKATimer.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSKATimer.java @@ -1,45 +1,81 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -/** - * COPS Keep Alive Timer - * - * @version COPSKATimer.java, v 1.00 2003 - * - */ -public class COPSKATimer extends COPSTimer { - - public COPSKATimer() { - super(new COPSObjHeader(CNum.KA, CType.DEF), (short) 1); - } - - /// - public COPSKATimer(short timeVal) { - super(new COPSObjHeader(CNum.KA, CType.DEF), timeVal); - } - - /** - * Method isKATimer - * - * @return a boolean - * - */ - public boolean isKATimer() { - return true; - } - - protected COPSKATimer(byte[] dataPtr) { - super (dataPtr); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS Keep Alive Timer (RFC 2748) + * + * Times are encoded as 2 octet integer values and are in units of + * seconds. The timer value is treated as a delta. + * + * C-Num = 10, + * + * C-Type = 1, Keep-alive timer value + * Timer object used to specify the maximum time interval over which a + * COPS message MUST be sent or received. The range of finite timeouts + * is 1 to 65535 seconds represented as an unsigned two-octet integer. + * The value of zero implies infinity. + */ +public class COPSKATimer extends COPSTimer { + + /** + * Constructor generally used for sending messages + * @throws java.lang.IllegalArgumentException + */ + public COPSKATimer(final short timeVal) { + this((short)0, timeVal); + } + + /** + * Constructor to override the reserved member value from 0 + * @throws java.lang.IllegalArgumentException + */ + public COPSKATimer(final short reserved, final short timeVal) { + this(new COPSObjHeader(CNum.KA, CType.DEF), reserved, timeVal); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param reserved - ??? + * @param timeVal - the timer value + * @throws java.lang.IllegalArgumentException + */ + protected COPSKATimer(final COPSObjHeader hdr, final short reserved, final short timeVal) { + super(hdr, reserved, timeVal); + if (!hdr.getCNum().equals(CNum.KA)) + throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.KA); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSKATimer parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + short reserved = 0; + reserved |= ((short) dataPtr[4]) << 8; + reserved |= ((short) dataPtr[5]) & 0xFF; + + short timerValue = 0; + timerValue |= ((short) dataPtr[6]) << 8; + timerValue |= ((short) dataPtr[7]) & 0xFF; + + return new COPSKATimer(objHdrData.header, reserved, timerValue); + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSLPDPDecision.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSLPDPDecision.java index 2fb4a5c..a06ed92 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSLPDPDecision.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSLPDPDecision.java @@ -1,48 +1,69 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - - - -/** - * COPS LPDP Decision Object - * - * @version COPSLPDPDecision.java, v 1.00 2003 - * - */ -public class COPSLPDPDecision extends COPSDecision { - - /** - Constructor to create a Local Decision object. - */ - public COPSLPDPDecision(byte cType) { - super (cType); -// TODO - FIXME later, currently not in use and the header is now immutable -// _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC); - } - - public COPSLPDPDecision() { - super (); -// TODO - FIXME later, currently not in use and the header is now immutable -// _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC); - } - - /** - * Method isLocalDecision - * - * @return a boolean - * - */ - public boolean isLocalDecision() { - return true; - } - - protected COPSLPDPDecision(byte[] data) { - super (data); - } - -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +/** + * COPS LPDP Decision Object (local decision) (RFC 2748) + * + * Decision made by the PEP's local policy decision point (LPDP). May + * appear in requests. These objects correspond to and are formatted the + * same as the client specific decision objects defined above. + * + * C-Num = 7 + * + * C-Type = (same C-Type as for Decision objects) + */ +public class COPSLPDPDecision extends COPSDecision { + + /** + * Constructor generally used for sending messages with a specific, CType, Command and DecisionFlag + * @param cType - the CType + * @param cmdCode - the command + * @param flags - the flags + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSLPDPDecision(final CType cType, final Command cmdCode, final DecisionFlag flags, final COPSData data) { + this(new COPSObjHeader(CNum.LPDP_DEC, cType), cmdCode, flags, data); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param cmdCode - the command + * @param flags - the flags + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + protected COPSLPDPDecision(final COPSObjHeader hdr, final Command cmdCode, final DecisionFlag flags, + final COPSData data) { + super(hdr, cmdCode, flags, data); + + if (!hdr.getCNum().equals(CNum.LPDP_DEC)) + throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.LPDP_DEC); + } + + /** + * Parses bytes to return a COPSLPDPDecision object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSLPDPDecision parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + final COPSObjHeader tempHdr = new COPSObjHeader(CNum.DEC, objHdrData.header.getCType()); + final COPSObjHeaderData tempObjHdrData = new COPSObjHeaderData(tempHdr, objHdrData.msgByteCount); + final COPSDecision decision = COPSDecision.parse(tempObjHdrData, dataPtr); + return new COPSLPDPDecision(objHdrData.header, decision.getCommand(), decision.getFlag(), decision.getData()); + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjBase.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjBase.java index ecdd39a..495a499 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjBase.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjBase.java @@ -1,159 +1,87 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.net.Socket; -import java.util.Arrays; - -/** - * COPS Object - * - * TODO - this should be an interface and all of these default return values can be dangerous - * @version COPSObjBase.java, v 1.00 2003 - * - */ -public abstract class COPSObjBase { - /** - * Add padding in the data, if the data does not fall on 32-bit boundary - * @param len an int - * @return a COPSData - */ - static COPSData getPadding(final int len) { - byte[] padBuf = new byte[len]; - Arrays.fill(padBuf, (byte) 0); - return new COPSData(padBuf, 0, len); - } - - /** - * Writes data to a given network _socket - * @param id a Socket - * @throws IOException - */ - public abstract void writeData(Socket id) throws IOException; - - /** - * Method getDataLength - * @return a short - */ - short getDataLength() { - return 0; - } - - /** - * Method isCOPSHeader - * @return a boolean - */ - boolean isCOPSHeader() { - return false; - } - - /** - * Method isClientHandle - * @return a boolean - */ - boolean isClientHandle() { - return false; - } - - /** - * Method isContext - * @return a boolean - */ - boolean isContext() { - return false; - } - - /** - * Method isInterface - * @return a boolean - */ - boolean isInterface() { - return false; - } - - /** - * Method isDecision - * @return a boolean - */ - boolean isDecision() { - return false; - } - - /** - * Method isLocalDecision - * @return a boolean - */ - boolean isLocalDecision() { - return false; - } - - /** - * Method isReport - * @return a boolean - */ - boolean isReport() { - return false; - } - - /** - * Method isError - * @return a boolean - */ - boolean isError() { - return false; - } - - /** - * Method isTimer - * @return a boolean - */ - boolean isTimer() { - return false; - } - - /** - * Method isPepId - * @return a boolean - */ - boolean isPepId() { - return false; - } - - /** - * Method isReason - * @return a boolean - */ - boolean isReason() { - return false; - } - - /** - * Method isPdpAddress - * @return a boolean - */ - boolean isPdpAddress() { - return false; - } - - /** - * Method isClientSI - * @return a boolean - */ - boolean isClientSI() { - return false; - } - - /** - * Method isMessageIntegrity - * @return a boolean - */ - boolean isMessageIntegrity() { - return false; - } - -} +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * Represents objects that can be contained within COPS messages. + */ +public abstract class COPSObjBase { + + /** + * Generally used to determine the type of message + */ + private final COPSObjHeader _objHdr; + + /** + * The base object constructor + * @param objHdr - the header (required) + */ + public COPSObjBase(final COPSObjHeader objHdr) { + if (objHdr == null) throw new IllegalArgumentException("Object header must not be null"); + this._objHdr = objHdr; + } + + /** + * Returns the header + * @return - the header + */ + public COPSObjHeader getHeader() { return _objHdr; } + + /** + * Writes data to a given network _socket + * @param socket a Socket + * @throws IOException + */ + final public void writeData(final Socket socket) throws IOException { + _objHdr.writeData(socket, getDataLength()); + writeBody(socket); + } + + protected abstract void writeBody(Socket socket) throws IOException; + + /** + * Returns the length of the body data to be output (not including header) + * @return a short + */ + protected abstract int getDataLength(); + + /** + * Write an object textual description in the output stream + * @param os an OutputStream + * @throws IOException + */ + final public void dump(final OutputStream os) throws IOException { + _objHdr.dump(os); + dumpBody(os); + } + + protected abstract void dumpBody(OutputStream os) throws IOException; + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSObjBase)) { + return false; + } + + final COPSObjBase that = (COPSObjBase) o; + + return !(!_objHdr.equals(that._objHdr)); + + } + + @Override + public int hashCode() { + return _objHdr.hashCode(); + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeader.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeader.java index d3b580e..971c0b0 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeader.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeader.java @@ -1,281 +1,223 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * COPS Object Header - * - * @version COPSObjHeader.java, v 1.00 2003 - * - */ -public class COPSObjHeader { - - static Map VAL_TO_CNUM = new ConcurrentHashMap<>(); - static { - VAL_TO_CNUM.put(CNum.NA.ordinal(), CNum.NA); - VAL_TO_CNUM.put(CNum.HANDLE.ordinal(), CNum.HANDLE); - VAL_TO_CNUM.put(CNum.CONTEXT.ordinal(), CNum.CONTEXT); - VAL_TO_CNUM.put(CNum.ININTF.ordinal(), CNum.ININTF); - VAL_TO_CNUM.put(CNum.OUTINTF.ordinal(), CNum.OUTINTF); - VAL_TO_CNUM.put(CNum.REASON_CODE.ordinal(), CNum.REASON_CODE); - VAL_TO_CNUM.put(CNum.DEC.ordinal(), CNum.DEC); - VAL_TO_CNUM.put(CNum.LPDP_DEC.ordinal(), CNum.LPDP_DEC); - VAL_TO_CNUM.put(CNum.ERROR.ordinal(), CNum.ERROR); - VAL_TO_CNUM.put(CNum.CSI.ordinal(), CNum.CSI); - VAL_TO_CNUM.put(CNum.KA.ordinal(), CNum.KA); - VAL_TO_CNUM.put(CNum.PEPID.ordinal(), CNum.PEPID); - VAL_TO_CNUM.put(CNum.RPT.ordinal(), CNum.RPT); - VAL_TO_CNUM.put(CNum.PDP_REDIR.ordinal(), CNum.PDP_REDIR); - VAL_TO_CNUM.put(CNum.LAST_PDP_ADDR.ordinal(), CNum.LAST_PDP_ADDR); - VAL_TO_CNUM.put(CNum.ACCT_TIMER.ordinal(), CNum.ACCT_TIMER); - VAL_TO_CNUM.put(CNum.MSG_INTEGRITY.ordinal(), CNum.MSG_INTEGRITY); - } - - static Map VAL_TO_CTYPE = new ConcurrentHashMap<>(); - static { - VAL_TO_CTYPE.put(CType.NA.ordinal(), CType.NA); - VAL_TO_CTYPE.put(CType.DEF.ordinal(), CType.DEF); - VAL_TO_CTYPE.put(CType.STATELESS.ordinal(), CType.STATELESS); - VAL_TO_CTYPE.put(CType.REPL.ordinal(), CType.REPL); - VAL_TO_CTYPE.put(CType.CSI.ordinal(), CType.CSI); - VAL_TO_CTYPE.put(CType.NAMED.ordinal(), CType.NAMED); - } - - /** - * Denotes the type of COPSMsg - */ - private final CNum _cNum; - - /** - * Subtype or version of the information. - */ - private final CType _cType; - - /** - * TODO - remove this attribute as the body of the COPS message should return the body length - */ - @Deprecated - private short _len; - - /** - * Constructor - * @param cNum - the cNum value - * @param cType - the cType value - * @throws java.lang.IllegalArgumentException - */ - public COPSObjHeader(final CNum cNum, final CType cType) { - if (cNum == null || cType == null) throw new IllegalArgumentException("CNum and CType must not be null"); - _cNum = cNum; - _cType = cType; - _len = 4; - } - - /** - * Get the data length in number of octets - * @return a short - */ - public short getHdrLength() { - return (short)4; - } - - /** - * Get the class information identifier cNum - * @return a byte - */ - - public CNum getCNum() { - return _cNum; - } - - /** - * Get the type per cNum - * @return a byte - */ - public CType getCType() { - return _cType; - } - - /** - * Get stringified CNum - * @return a String - */ - public String getStrCNum() { - switch (_cNum) { - case HANDLE: - return ("Client-handle"); - case CONTEXT: - return ("Context"); - case ININTF: - return ("In-Interface"); - case OUTINTF: - return ("Out-Interface"); - case REASON_CODE: - return ("Reason"); - case DEC: - return ("Decision"); - case LPDP_DEC: - return ("Local-Decision"); - case ERROR: - return ("Error"); - case CSI: - return ("Client-SI"); - case KA: - return ("KA-timer"); - case PEPID: - return ("PEP-id"); - case RPT: - return ("Report"); - case PDP_REDIR: - return ("Redirect PDP addr"); - case LAST_PDP_ADDR: - return ("Last PDP addr"); - case ACCT_TIMER: - return ("Account-Timer"); - case MSG_INTEGRITY: - return ("Message-Integrity"); - default: - return ("Unknown"); - } - } - - /** - * Set the obj length, the length is the length of the data following - * the object header.The length of the object header (4 bytes) is added - * to the length passed. - * - * TODO - The data length will be removed from the header in a subsequent patch - * - * @param len a short - */ - @Deprecated - public void setDataLength(short len) { - //Add the length of the header also - _len = (short) (len + 4); - } - - /** - * Get the data length in number of octets - * - * @return a short - * - */ - public short getDataLength() { - return _len; - } - - /** - * Writes data to a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - byte[] buf = new byte[4]; - - buf[0] = (byte) (_len >> 8); - buf[1] = (byte) _len; - buf[2] = (byte) _cNum.ordinal(); - buf[3] = (byte) _cType.ordinal(); - - COPSUtil.writeData(id, buf, 4); - } - - /** - * Write an object textual description in the output stream - * @param os an OutputStream - * @throws IOException - */ - public void dump(final OutputStream os) throws IOException { - os.write(("**" + getStrCNum() + "**" + "\n").getBytes()); - os.write(("C-num: " + _cNum + "\n").getBytes()); - os.write(("C-type: " + _cType + "\n").getBytes()); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof COPSObjHeader)) { - return false; - } - - final COPSObjHeader header = (COPSObjHeader) o; - - return _cNum == header._cNum && _cType == header._cType; - - } - - @Override - public int hashCode() { - int result = _cNum.hashCode(); - result = 31 * result + _cType.hashCode(); - return result; - } - - /** - * Method parse - * - * @param data a byte[] - * - */ - public final static COPSObjHeader parse(byte[] data) { - short len = 0; - len = 0; - len |= ((short) data[0]) << 8; - len |= ((short) data[1]) & 0xFF; - - int cNum = 0; - cNum |= data[2]; - - int cType = 0; - cType |= data[3]; - - final COPSObjHeader hdr = new COPSObjHeader(VAL_TO_CNUM.get(cNum), VAL_TO_CTYPE.get(cType)); - hdr.setDataLength(len); - return hdr; - } - - public enum CNum { - NA, - HANDLE, - CONTEXT, - ININTF, - OUTINTF, - REASON_CODE, - DEC, - LPDP_DEC, - ERROR, - CSI, - KA, - PEPID, - RPT, - PDP_REDIR, - LAST_PDP_ADDR, - ACCT_TIMER, - MSG_INTEGRITY, - } - - public enum CType { - NA, - DEF, - STATELESS, - REPL, - CSI, - NAMED - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Object Header + * + * @version COPSObjHeader.java, v 1.00 2003 + * + */ +public class COPSObjHeader { + + static Map VAL_TO_CNUM = new ConcurrentHashMap<>(); + static { + VAL_TO_CNUM.put(CNum.NA.ordinal(), CNum.NA); + VAL_TO_CNUM.put(CNum.HANDLE.ordinal(), CNum.HANDLE); + VAL_TO_CNUM.put(CNum.CONTEXT.ordinal(), CNum.CONTEXT); + VAL_TO_CNUM.put(CNum.ININTF.ordinal(), CNum.ININTF); + VAL_TO_CNUM.put(CNum.OUTINTF.ordinal(), CNum.OUTINTF); + VAL_TO_CNUM.put(CNum.REASON_CODE.ordinal(), CNum.REASON_CODE); + VAL_TO_CNUM.put(CNum.DEC.ordinal(), CNum.DEC); + VAL_TO_CNUM.put(CNum.LPDP_DEC.ordinal(), CNum.LPDP_DEC); + VAL_TO_CNUM.put(CNum.ERROR.ordinal(), CNum.ERROR); + VAL_TO_CNUM.put(CNum.CSI.ordinal(), CNum.CSI); + VAL_TO_CNUM.put(CNum.KA.ordinal(), CNum.KA); + VAL_TO_CNUM.put(CNum.PEPID.ordinal(), CNum.PEPID); + VAL_TO_CNUM.put(CNum.RPT.ordinal(), CNum.RPT); + VAL_TO_CNUM.put(CNum.PDP_REDIR.ordinal(), CNum.PDP_REDIR); + VAL_TO_CNUM.put(CNum.LAST_PDP_ADDR.ordinal(), CNum.LAST_PDP_ADDR); + VAL_TO_CNUM.put(CNum.ACCT_TIMER.ordinal(), CNum.ACCT_TIMER); + VAL_TO_CNUM.put(CNum.MSG_INTEGRITY.ordinal(), CNum.MSG_INTEGRITY); + } + + static Map VAL_TO_CTYPE = new ConcurrentHashMap<>(); + static { + VAL_TO_CTYPE.put(CType.NA.ordinal(), CType.NA); + VAL_TO_CTYPE.put(CType.DEF.ordinal(), CType.DEF); + VAL_TO_CTYPE.put(CType.STATELESS.ordinal(), CType.STATELESS); + VAL_TO_CTYPE.put(CType.REPL.ordinal(), CType.REPL); + VAL_TO_CTYPE.put(CType.CSI.ordinal(), CType.CSI); + VAL_TO_CTYPE.put(CType.NAMED.ordinal(), CType.NAMED); + } + + /** + * Denotes the type of COPSMsg + */ + private final CNum _cNum; + + /** + * Subtype or version of the information. + */ + private final CType _cType; + + /** + * Constructor + * @param cNum - the cNum value + * @param cType - the cType value + * @throws java.lang.IllegalArgumentException + */ + public COPSObjHeader(final CNum cNum, final CType cType) { + if (cNum == null || cType == null) throw new IllegalArgumentException("CNum and CType must not be null"); + _cNum = cNum; + _cType = cType; + } + + /** + * Get the data length in number of octets + * @return a short + */ + public short getHdrLength() { + return (short)4; + } + + /** + * Get the class information identifier cNum + * @return a byte + */ + + public CNum getCNum() { + return _cNum; + } + + /** + * Get the type per cNum + * @return a byte + */ + public CType getCType() { + return _cType; + } + + /** + * Get stringified CNum + * @return a String + */ + public String getStrCNum() { + switch (_cNum) { + case HANDLE: + return ("Client-handle"); + case CONTEXT: + return ("Context"); + case ININTF: + return ("In-Interface"); + case OUTINTF: + return ("Out-Interface"); + case REASON_CODE: + return ("Reason"); + case DEC: + return ("Decision"); + case LPDP_DEC: + return ("Local-Decision"); + case ERROR: + return ("Error"); + case CSI: + return ("Client-SI"); + case KA: + return ("KA-timer"); + case PEPID: + return ("PEP-id"); + case RPT: + return ("Report"); + case PDP_REDIR: + return ("Redirect PDP addr"); + case LAST_PDP_ADDR: + return ("Last PDP addr"); + case ACCT_TIMER: + return ("Account-Timer"); + case MSG_INTEGRITY: + return ("Message-Integrity"); + default: + return ("Unknown"); + } + } + + /** + * Writes data to a given network _socket + * @param socket a Socket + * @throws IOException + */ + public void writeData(final Socket socket, final int dataLength) throws IOException { + final int payloadSize = + getHdrLength() + dataLength; + final byte[] buf = new byte[4]; + buf[0] = (byte) (payloadSize >> 8); + buf[1] = (byte) payloadSize; + buf[2] = (byte)_cNum.ordinal(); + buf[3] = (byte)_cType.ordinal(); + + COPSUtil.writeData(socket, buf, 4); + } + + /** + * Write an object textual description in the output stream + * @param os an OutputStream + * @throws IOException + */ + public void dump(final OutputStream os) throws IOException { + os.write(("**" + getStrCNum() + "**" + "\n").getBytes()); + os.write(("C-num: " + _cNum + "\n").getBytes()); + os.write(("C-type: " + _cType + "\n").getBytes()); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSObjHeader)) { + return false; + } + + final COPSObjHeader header = (COPSObjHeader) o; + + return _cNum == header._cNum && _cType == header._cType; + + } + + @Override + public int hashCode() { + int result = _cNum.hashCode(); + result = 31 * result + _cType.hashCode(); + return result; + } + + public enum CNum { + NA, + HANDLE, + CONTEXT, + ININTF, + OUTINTF, + REASON_CODE, + DEC, + LPDP_DEC, + ERROR, + CSI, + KA, + PEPID, + RPT, + PDP_REDIR, + LAST_PDP_ADDR, + ACCT_TIMER, + MSG_INTEGRITY, + } + + public enum CType { + NA, + DEF, + STATELESS, + REPL, + CSI, + NAMED + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeaderData.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeaderData.java new file mode 100644 index 0000000..e4947d6 --- /dev/null +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjHeaderData.java @@ -0,0 +1,30 @@ +package org.umu.cops.stack; + +/** + * Class designed for simply containing the COPSHeader and the total message's byte count. + * + * No need to test as this class will be tested implicitly via other tests and this does not contain or need + * any domain specific logic + */ +public class COPSObjHeaderData { + + /** + * The actual header to be injected into the appropriate COPSMsg object + */ + final public COPSObjHeader header; + + /** + * The total number of bytes contained within the inbound message being parsed. + */ + final public int msgByteCount; + + /** + * Constructor + * @param hdr - the COPS message header + * @param numBytes - the total number of bytes contained within the message envelope + */ + public COPSObjHeaderData(final COPSObjHeader hdr, final int numBytes) { + this.header = hdr; + this.msgByteCount = numBytes; + } +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjectParser.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjectParser.java new file mode 100644 index 0000000..4684ee3 --- /dev/null +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSObjectParser.java @@ -0,0 +1,71 @@ +package org.umu.cops.stack; + +import java.util.Arrays; + +/** + * Static utilitarian methods for parsing COPS objects contained within COPS messages. + */ +public class COPSObjectParser { + + /** + * Parses the header information for a COPSObjBase object. + * @param data - the data to parse + * @return - the header + */ + public static COPSObjHeaderData parseObjHeader(final byte[] data) { + if (data == null || data.length < 4) + throw new IllegalArgumentException("Data cannot be null or fewer than 4 bytes"); + + // TODO - Determine what setting the _len value from the data buffer really means + int len = 0; + len |= ((short) data[0]) << 8; + len |= ((short) data[1]) & 0xFF; + + int cNum = 0; + cNum |= data[2]; + + int cType = 0; + cType |= data[3]; + + return new COPSObjHeaderData( + new COPSObjHeader(COPSObjHeader.VAL_TO_CNUM.get(cNum), COPSObjHeader.VAL_TO_CTYPE.get(cType)), len); + } + + /** + * Parses bytes to return a COPSInterface object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSInterface parseIpv4Interface(final COPSObjHeaderData objHdrData, final byte[] dataPtr, + final boolean isIn) { + if (isIn) return COPSIpv4InInterface.parse(objHdrData, dataPtr); + else return COPSIpv4OutInterface.parse(objHdrData, dataPtr); + } + + /** + * Parses bytes to return a COPSIpv6Interface object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSIpv6Interface parseIpv6Interface(final COPSObjHeaderData objHdrData, final byte[] dataPtr, + final boolean isIn) { + if (isIn) return COPSIpv6InInterface.parse(objHdrData, dataPtr); + else return COPSIpv6OutInterface.parse(objHdrData, dataPtr); + } + + /** + * Add padding in the data, if the data does not fall on 32-bit boundary + * @param len an int + * @return a COPSData + */ + public static COPSData getPadding(final int len) { + byte[] padBuf = new byte[len]; + Arrays.fill(padBuf, (byte) 0); + return new COPSData(padBuf, 0, len); + } + +} diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPdpAddress.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPdpAddress.java index f202364..53f9f93 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPdpAddress.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPdpAddress.java @@ -1,80 +1,157 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; - -/** - * COPS PDP Address - * - * @version COPSPdpAddress.java, v 1.00 2003 - * - */ -abstract public class COPSPdpAddress extends COPSObjBase { - - /** - * Method isPdpAddress - * - * @return a boolean - * - */ - public boolean isPdpAddress() { - return true; - }; - - /** - * Method isIpv4PdpAddress - * - * @return a boolean - * - */ - public boolean isIpv4PdpAddress() { - return false; - }; - - /** - * Method isIpv6PdpAddress - * - * @return a boolean - * - */ - public boolean isIpv6PdpAddress() { - return false; - }; - - /** - * Method isLastPdpAddress - * - * @return a boolean - * - */ - public boolean isLastPdpAddress() { - return false; - }; - - /** - * Method isPdpredirectAddress - * - * @return a boolean - * - */ - public boolean isPdpredirectAddress() { - return false; - }; - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - abstract public void dump(OutputStream os) throws IOException; -}; - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * Superclass for all PDP Address classes for which we appear to only have 2 concrete implementations and 4 + * subclasses meaning this class hierarchy is ripe for further refactoring. + */ +abstract public class COPSPdpAddress extends COPSObjBase { + + /** + * The address + */ + private COPSIpAddress _addr; + + /** + * The port number + */ + private final int _tcpPort; + + /** + * Currently the space holding this value is not in use. + */ + private final short _reserved; + + /** + * Constructor + * @param objHdr - the object's header info + * @param tcpPort - the port associated with an IP device + * @param reserved - not in use + */ + protected COPSPdpAddress(final COPSObjHeader objHdr, final COPSIpAddress addr, final int tcpPort, + final short reserved) { + super(objHdr); + if (addr == null) throw new IllegalArgumentException("Address must not be null"); + if (tcpPort < 1) throw new IllegalArgumentException("Invalid port number - " + tcpPort); + this._addr = addr; + this._tcpPort = tcpPort; + this._reserved = reserved; + } + + public int getTcpPort() { + return _tcpPort; + } + + public short getReserved() { + return _reserved; + } + + /** + * Creates the correct object of this type from a byte array. + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSPdpAddress parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) { + short reserved = 0; + int tcpPort = 0; + + switch (objHdrData.header.getCType()) { + case DEF: + final byte[] addr4 = new byte[4]; + System.arraycopy(dataPtr, 4, addr4, 0, 4); + reserved |= ((short) dataPtr[8]) << 8; + reserved |= ((short) dataPtr[9]) & 0xFF; + tcpPort |= ((short) dataPtr[10]) << 8; + tcpPort |= ((short) dataPtr[11]) & 0xFF; + + switch (objHdrData.header.getCNum()) { + case LAST_PDP_ADDR: + return new COPSIpv4LastPdpAddr(objHdrData.header, addr4, tcpPort, reserved); + case PDP_REDIR: + return new COPSIpv4PdpRedirectAddress(objHdrData.header, addr4, tcpPort, reserved); + default: + throw new IllegalArgumentException("Unsupported CNum - " + objHdrData.header.getCNum()); + } + case STATELESS: + final byte[] addr6 = new byte[16]; + System.arraycopy(dataPtr, 4, addr6, 0, 16); + reserved |= ((short) dataPtr[20]) << 8; + reserved |= ((short) dataPtr[21]) & 0xFF; + tcpPort |= ((short) dataPtr[22]) << 8; + tcpPort |= ((short) dataPtr[23]) & 0xFF; + switch (objHdrData.header.getCNum()) { + case LAST_PDP_ADDR: + return new COPSIpv6LastPdpAddr(objHdrData.header, addr6, tcpPort, reserved); + case PDP_REDIR: + return new COPSIpv6PdpRedirectAddress(objHdrData.header, addr6, tcpPort, reserved); + default: + throw new IllegalArgumentException("Unsupported CNum - " + objHdrData.header.getCNum()); + } + default: + throw new IllegalArgumentException("CType was not DEF(1) or STATELESS (2)"); + } + } + + @Override + public int getDataLength() { + return _addr.getDataLength() + 4; + } + + @Override + public void dumpBody(OutputStream os) throws IOException { + os.write(("Address: " + _addr.getIpName() + "\n").getBytes()); + os.write(("Port: " + _tcpPort + "\n").getBytes()); + } + + @Override + public void writeBody(final Socket socket) throws IOException { + _addr.writeData(socket); + + byte[] buf = new byte[4]; + buf[0] = (byte) (_reserved >> 8); + buf[1] = (byte) _reserved; + buf[2] = (byte) (_tcpPort >> 8); + buf[3] = (byte) _tcpPort ; + + COPSUtil.writeData(socket, buf, 4); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSPdpAddress)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSPdpAddress that = (COPSPdpAddress) o; + + return _reserved == that._reserved && _tcpPort == that._tcpPort && _addr.equals(that._addr); + + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _addr.hashCode(); + result = 31 * result + _tcpPort; + result = 31 * result + (int) _reserved; + return result; + } +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPepId.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPepId.java index 9f1df76..21866a2 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPepId.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSPepId.java @@ -1,120 +1,146 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS PEP Identification Object - * - * @version COPSPepId.java, v 1.00 2003 - * - */ -public class COPSPepId extends COPSObjBase { - - COPSObjHeader _objHdr; - COPSData _data; - COPSData _padding; - - public COPSPepId() { - _objHdr = new COPSObjHeader(CNum.PEPID, CType.DEF); - } - - protected COPSPepId(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - //Get the length of data following the obj header - short dLen = (short) (_objHdr.getDataLength() - 4); - COPSData d = new COPSData (dataPtr, 4, dLen); - setData(d); - } - - /** - * Method setData - * - * @param data a COPSData - * - */ - public void setData(COPSData data) { - _data = data; - if (_data.length() % 4 != 0) { - int padLen = 4 - _data.length() % 4; - _padding = getPadding(padLen); - } - _objHdr.setDataLength((short)_data.length()); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - int lpadding = 0; - if (_padding != null) lpadding = _padding.length(); - return ((short) (_objHdr.getDataLength() + lpadding)); - } - - /** - * Method getData - * - * @return a COPSData - * - */ - public COPSData getData() { - return _data; - }; - - /** - * Method isPepId - * - * @return a boolean - * - */ - public boolean isPepId() { - return true; - }; - - /** - * Write data to given netwrok socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - COPSUtil.writeData(id, _data.getData(), _data.length()); - if (_padding != null) { - COPSUtil.writeData(id, _padding.getData(), _padding.length()); - } - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("PEPID: " + _data.str() + "\n").getBytes()); - } -} - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS PEP Identification Object (RFC 2748) + * + * The PEP Identification Object is used to identify the PEP client to + * the remote PDP. It is required for Client-Open messages. + * + * C-Num = 11, C-Type = 1 + * + * Variable-length field. It is a NULL terminated ASCII string that is + * also zero padded to a 32-bit word boundary (so the object length is a + * multiple of 4 octets). The PEPID MUST contain an ASCII string that + * uniquely identifies the PEP within the policy domain in a manner that + * is persistent across PEP reboots. For example, it may be the PEP's + * statically assigned IP address or DNS name. This identifier may + * safely be used by a PDP as a handle for identifying the PEP in its + * policy rules. + */ +public class COPSPepId extends COPSObjBase { + + /** + * The payload data + */ + final COPSData _data; + + /** + * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes + */ + final COPSData _padding; + + /** + * Constructor generally used for sending messages + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSPepId(final COPSData data) { + this(new COPSObjHeader(CNum.PEPID, CType.DEF), data); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param data - the data + * @throws java.lang.IllegalArgumentException + */ + public COPSPepId(final COPSObjHeader hdr, final COPSData data) { + super(hdr); + + if (!hdr.getCNum().equals(CNum.PEPID)) + throw new IllegalArgumentException("CNum must be equal to " + CNum.PEPID); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("CType must be equal to " + CType.DEF); + if (data == null) throw new IllegalArgumentException("Data must not be null"); + + _data = data; + if ((_data.length() % 4) != 0) { + final int padLen = 4 - (_data.length() % 4); + _padding = COPSObjectParser.getPadding(padLen); + } else { + _padding = new COPSData(); + } + } + + @Override + protected int getDataLength() { + return _data.length() + _padding.length(); + } + + /** + * Method getData + * @return a COPSData + */ + public COPSData getData() { + return _data; + } + + @Override + protected void writeBody(final Socket socket) throws IOException { + COPSUtil.writeData(socket, _data.getData(), _data.length()); + if (_padding != null) { + COPSUtil.writeData(socket, _padding.getData(), _padding.length()); + } + } + + @Override + protected void dumpBody(final OutputStream os) throws IOException { + os.write(("PEPID: " + _data.str() + "\n").getBytes()); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (!(o instanceof COPSPepId)) { + return false; + } + if (!super.equals(o)) { + return false; + } + + final COPSPepId that = (COPSPepId) o; + + return _data.equals(that._data) && _padding.equals(that._padding) || + COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + _data.hashCode(); + result = 31 * result + _padding.hashCode(); + return result; + } + + /** + * Parses bytes to return a COPSPepId object + * @param objHdrData - the associated header + * @param dataPtr - the data to parse + * @return - the object + * @throws java.lang.IllegalArgumentException + */ + public static COPSPepId parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + short dLen = (short)(objHdrData.msgByteCount - 4); + return new COPSPepId(objHdrData.header, new COPSData (dataPtr, 4, dLen)); + } + +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReason.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReason.java index f8530e0..4b1d609 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReason.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReason.java @@ -1,171 +1,195 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Reason Object (RFC 2748 pag. 12) - * - * This object specifies the reason why the request state was deleted. - * It appears in the delete request (DRQ) message. The Reason Sub-code - * field is reserved for more detailed client-specific reason codes - * defined in the corresponding documents. - * - * C-Num = 5, C-Type = 1 - * - * 0 1 2 3 - * +--------------+--------------+--------------+--------------+ - * | Reason-Code | Reason Sub-code | - * +--------------+--------------+--------------+--------------+ - * - * Reason Code: - * 1 = Unspecified - * 2 = Management - * 3 = Preempted (Another request state takes precedence) - * 4 = Tear (Used to communicate a signaled state removal) - * 5 = Timeout (Local state has timed-out) - * 6 = Route Change (Change invalidates request state) - * 7 = Insufficient Resources (No local resource available) - * 8 = PDP's Directive (PDP decision caused the delete) - * 9 = Unsupported decision (PDP decision not supported) - * 10= Synchronize Handle Unknown - * 11= Transient Handle (stateless event) - * 12= Malformed Decision (could not recover) - * 13= Unknown COPS Object from PDP: - * Sub-code (octet 2) contains unknown object's C-Num - * and (octet 3) contains unknown object's C-Type. - * - * @version COPSReason.java, v 1.00 2003 - * - */ -public class COPSReason extends COPSPrObjBase { - - public final static String[] G_msgArray = { - "Unknown.", - "Unspecified.", - "Management.", - "Preempted (Another request state takes precedence).", - "Tear (Used to communicate a signaled state removal).", - "Timeout ( Local state has timed-out).", - "Route change (Change invalidates request state).", - "Insufficient Resources.", - "PDP's Directive.", - "Unsupported decision.", - "Synchronize handle unknown.", - "Transient handle.", - "Malformed decision.", - "Unknown COPS object from PDP.", - }; - - private COPSObjHeader _objHdr; - private short _reasonCode; - private short _reasonSubCode; - - /// - public COPSReason(short reasonCode, short subCode) { - _objHdr = new COPSObjHeader(CNum.REASON_CODE, CType.DEF); - _reasonCode = reasonCode; - _reasonSubCode = subCode; - _objHdr.setDataLength((short) 4); - } - - /** - Parse data and create COPSReason object - */ - protected COPSReason(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _reasonCode |= ((short) dataPtr[4]) << 8; - _reasonCode |= ((short) dataPtr[5]) & 0xFF; - _reasonSubCode |= ((short) dataPtr[6]) << 8; - _reasonSubCode |= ((short) dataPtr[7]) & 0xFF; - - _objHdr.setDataLength((short) 4); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - return (_objHdr.getDataLength()); - } - - /** - * Get Reason description - * - * @return a String - * - */ - public String getDescription() { - String reasonStr1; - String reasonStr2; - - ///Get the details from the error code - reasonStr1 = G_msgArray[_reasonCode]; - //TODO - defind reason sub-codes - reasonStr2 = ""; - return (reasonStr1 + ":" + reasonStr2); - } - - /** - * Always return true - * - * @return a boolean - * - */ - public boolean isReason() { - return true; - } - - /** - * Write object in network byte order to a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - - _objHdr.writeData(id); - - byte[] buf = new byte[4]; - - buf[0] = (byte) (_reasonCode >> 8); - buf[1] = (byte) _reasonCode; - buf[2] = (byte) (_reasonSubCode >> 8); - buf[3] = (byte) _reasonSubCode; - - - COPSUtil.writeData(id, buf, 4); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Reason Code: " + _reasonCode + "\n").getBytes()); - os.write(new String("Reason Sub Code: " + _reasonSubCode + "\n").getBytes()); - } -} - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Reason Object (RFC 2748 page. 12) + * + * This object specifies the reason why the request state was deleted. + * It appears in the delete request (DRQ) message. The Reason Sub-code + * field is reserved for more detailed client-specific reason codes + * defined in the corresponding documents. + * + * C-Num = 5, C-Type = 1 + * + * 0 1 2 3 + * +--------------+--------------+--------------+--------------+ + * | Reason-Code | Reason Sub-code | + * +--------------+--------------+--------------+--------------+ + * + * Reason Code: + * 1 = Unspecified + * 2 = Management + * 3 = Preempted (Another request state takes precedence) + * 4 = Tear (Used to communicate a signaled state removal) + * 5 = Timeout (Local state has timed-out) + * 6 = Route Change (Change invalidates request state) + * 7 = Insufficient Resources (No local resource available) + * 8 = PDP's Directive (PDP decision caused the delete) + * 9 = Unsupported decision (PDP decision not supported) + * 10= Synchronize Handle Unknown + * 11= Transient Handle (stateless event) + * 12= Malformed Decision (could not recover) + * 13= Unknown COPS Object from PDP: + * Sub-code (octet 2) contains unknown object's C-Num + * and (octet 3) contains unknown object's C-Type. + * + * @version COPSReason.java, v 1.00 2003 + * + */ +public class COPSReason extends COPSObjBase { + + private final static Map VAL_TO_REASON = new ConcurrentHashMap<>(); + static { + VAL_TO_REASON.put(ReasonCode.NA.ordinal(), ReasonCode.NA); + VAL_TO_REASON.put(ReasonCode.UNSPECIFIED.ordinal(), ReasonCode.UNSPECIFIED); + VAL_TO_REASON.put(ReasonCode.MANAGEMENT.ordinal(), ReasonCode.MANAGEMENT); + VAL_TO_REASON.put(ReasonCode.PREEMPTED.ordinal(), ReasonCode.PREEMPTED); + VAL_TO_REASON.put(ReasonCode.TEAR.ordinal(), ReasonCode.TEAR); + VAL_TO_REASON.put(ReasonCode.TIMEOUT.ordinal(), ReasonCode.TIMEOUT); + VAL_TO_REASON.put(ReasonCode.ROUTE_CHANGE.ordinal(), ReasonCode.ROUTE_CHANGE); + VAL_TO_REASON.put(ReasonCode.INSUFF_RESOURCES.ordinal(), ReasonCode.INSUFF_RESOURCES); + VAL_TO_REASON.put(ReasonCode.PDP_DIRECTIVE.ordinal(), ReasonCode.PDP_DIRECTIVE); + VAL_TO_REASON.put(ReasonCode.UNSUPPORT_DEC.ordinal(), ReasonCode.UNSUPPORT_DEC); + VAL_TO_REASON.put(ReasonCode.SYNC_HANDLE.ordinal(), ReasonCode.SYNC_HANDLE); + VAL_TO_REASON.put(ReasonCode.TRANS_HANDLE.ordinal(), ReasonCode.TRANS_HANDLE); + VAL_TO_REASON.put(ReasonCode.MALFORMED_DEC.ordinal(), ReasonCode.MALFORMED_DEC); + VAL_TO_REASON.put(ReasonCode.UNKNOWN_COPS_OBJ.ordinal(), ReasonCode.UNKNOWN_COPS_OBJ); + } + + private final static Map REASON_TO_STRING = new ConcurrentHashMap<>(); + static { + REASON_TO_STRING.put(ReasonCode.NA, "Unknown."); + REASON_TO_STRING.put(ReasonCode.UNSPECIFIED, "Unspecified."); + REASON_TO_STRING.put(ReasonCode.MANAGEMENT, "Management."); + REASON_TO_STRING.put(ReasonCode.PREEMPTED, "Preempted (Another request state takes precedence)."); + REASON_TO_STRING.put(ReasonCode.TEAR, "Tear (Used to communicate a signaled state removal)."); + REASON_TO_STRING.put(ReasonCode.TIMEOUT, "Timeout ( Local state has timed-out)."); + REASON_TO_STRING.put(ReasonCode.ROUTE_CHANGE, "Route change (Change invalidates request state)."); + REASON_TO_STRING.put(ReasonCode.INSUFF_RESOURCES, "Insufficient Resources."); + REASON_TO_STRING.put(ReasonCode.PDP_DIRECTIVE, "PDP's Directive."); + REASON_TO_STRING.put(ReasonCode.UNSUPPORT_DEC, "Unsupported decision."); + REASON_TO_STRING.put(ReasonCode.SYNC_HANDLE, "Synchronize handle unknown."); + REASON_TO_STRING.put(ReasonCode.TRANS_HANDLE, "Transient handle."); + REASON_TO_STRING.put(ReasonCode.MALFORMED_DEC, "Malformed decision."); + REASON_TO_STRING.put(ReasonCode.UNKNOWN_COPS_OBJ, "Unknown COPS object from PDP."); + } + + /** + * The reason + */ + private final ReasonCode _reasonCode; + + /** + * Reserved for more detailed client-specific reasons + */ + private final ReasonCode _reasonSubCode; + + /** + * Constructor generally used for sending messages + * @param reasonCode - the reason code + * @param subCode - more detailed reasons + * @throws java.lang.IllegalArgumentException + */ + public COPSReason(final ReasonCode reasonCode, final ReasonCode subCode) { + this(new COPSObjHeader(CNum.REASON_CODE, CType.DEF), reasonCode, subCode); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param reasonCode - the reason code + * @param subCode - the type of message + * @throws java.lang.IllegalArgumentException + */ + protected COPSReason(final COPSObjHeader hdr, final ReasonCode reasonCode, final ReasonCode subCode) { + super(hdr); + if (!hdr.getCNum().equals(CNum.REASON_CODE)) + throw new IllegalArgumentException("Must have a CNum value of " + CNum.REASON_CODE); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Must have a CType value of " + CType.DEF); + if (reasonCode == null || subCode == null) throw new IllegalArgumentException("Error codes must not be null"); + if (reasonCode.equals(ReasonCode.NA)) + throw new IllegalArgumentException("Error code must not be of type " + ReasonCode.NA); + + _reasonCode = reasonCode; + _reasonSubCode = subCode; + } + + public ReasonCode getReasonCode() { return _reasonCode; } + public ReasonCode getReasonSubCode() { return _reasonSubCode; } + + @Override + protected int getDataLength() { + return 4; + } + + /** + * Get Reason description + * @return a String + */ + public String getDescription() { + return (REASON_TO_STRING.get(_reasonCode) + ":"); + } + + @Override + protected void writeBody(final Socket id) throws IOException { + final byte[] buf = new byte[4]; + buf[0] = (byte) (_reasonCode.ordinal() >> 8); + buf[1] = (byte) _reasonCode.ordinal(); + buf[2] = (byte) (_reasonSubCode.ordinal() >> 8); + buf[3] = (byte) _reasonSubCode.ordinal(); + COPSUtil.writeData(id, buf, 4); + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("Reason Code: " + _reasonCode + "\n").getBytes()); + os.write(("Reason Sub Code: " + _reasonSubCode + "\n").getBytes()); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSReason parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + short reasonCode = 0; + reasonCode |= ((short) dataPtr[4]) << 8; + reasonCode |= ((short) dataPtr[5]) & 0xFF; + + short reasonSubCode = 0; + reasonSubCode |= ((short) dataPtr[6]) << 8; + reasonSubCode |= ((short) dataPtr[7]) & 0xFF; + + return new COPSReason(objHdrData.header, VAL_TO_REASON.get((int)reasonCode), + VAL_TO_REASON.get((int)reasonSubCode)); + } + + /** + * All of the supported reason codes + */ + public enum ReasonCode { + NA, UNSPECIFIED, MANAGEMENT, PREEMPTED, TEAR, TIMEOUT, ROUTE_CHANGE, INSUFF_RESOURCES, PDP_DIRECTIVE, + UNSUPPORT_DEC, SYNC_HANDLE, TRANS_HANDLE, MALFORMED_DEC, UNKNOWN_COPS_OBJ + } + +} + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportMsg.java index a474147..36f4413 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportMsg.java @@ -1,355 +1,353 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Vector; - -/** - * COPS Report Message (RFC 2748 pag. 25) - * - * The RPT message is used by the PEP to communicate to the PDP its - * success or failure in carrying out the PDP's decision, or to report - * an accounting related change in state. The Report-Type specifies the - * kind of report and the optional ClientSI can carry additional - * information per Client-Type. - * - * For every DEC message containing a configuration context that is - * received by a PEP, the PEP MUST generate a corresponding Report State - * message with the Solicited Message flag set describing its success or - * failure in applying the configuration decision. In addition, - * outsourcing decisions from the PDP MAY result in a corresponding - * solicited Report State from the PEP depending on the context and the - * type of client. RPT messages solicited by decisions for a given - * Client Handle MUST set the Solicited Message flag and MUST be sent in - * the same order as their corresponding Decision messages were - * received. There MUST never be more than one Report State message - * generated with the Solicited Message flag set per Decision. - * - * The Report State may also be used to provide periodic updates of - * client specific information for accounting and state monitoring - * purposes depending on the type of the client. In such cases the - * accounting report type should be specified utilizing the appropriate - * client specific information object. - * - * ::== - * - * - * [] - * [] - * - * @version COPSReportMsg.java, v 1.00 2003 - * - */ -public class COPSReportMsg extends COPSMsg { - /* COPSHeader coming from base class */ - private COPSHandle _clientHandle; - private COPSReportType _report; - private Vector _clientSI; - private COPSIntegrity _integrity; - - public COPSReportMsg() { - _clientHandle = null; - _report = null; - _integrity = null; - _clientSI = new Vector(20); - } - - /** - Parse data and create COPSReportMsg object - */ - protected COPSReportMsg (byte[] data) throws COPSException { - _clientHandle = null; - _report = null; - _integrity = null; - parse(data); - } - - /** - * Checks the sanity of COPS message and throw an - * COPSException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_clientHandle == null) || (_report == null)) - throw new COPSException("Bad message format"); - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT) - throw new COPSException ("Error Header (no COPS_OP_REQ)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Report object to the message - * - * @param report a COPSReportType - * - * @throws COPSException - * - */ - public void add (COPSReportType report) throws COPSException { - if (report == null) - throw new COPSException ("Null Handle"); - - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("No null Handle"); - - _report = report; - setMsgLength(); - } - - /** - * Add client handle to the message - * - * @param handle a COPSHandle - * - * @throws COPSException - * - */ - public void add (COPSHandle handle) throws COPSException { - if (handle == null) - throw new COPSException ("Null Handle"); - - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("No null Handle"); - - _clientHandle = handle; - setMsgLength(); - } - - /** - * Add one or more clientSI objects - * - * @param clientSI a COPSClientSI - * - * @throws COPSException - * - */ - public void add (COPSClientSI clientSI) throws COPSException { - if (clientSI == null) - throw new COPSException ("Null ClientSI"); - _clientSI.add(clientSI); - setMsgLength(); - } - - /** - * Add integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Get client Handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _clientHandle; - } - - /** - * Get report type - * - * @return a COPSReportType - * - */ - public COPSReportType getReport() { - return _report; - } - - /** - * Get clientSI - * - * @return a Vector - * - */ - public Vector getClientSI() { - return _clientSI; - } - - /** - * Returns true if it has Integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - } - - - /** - * Get Integrity. Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Writes data to given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - //checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_clientHandle != null) _clientHandle.writeData(id); - if (_report != null) _report.writeData(id); - - for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - clientSI.writeData(id); - } - - if (_integrity != null) _integrity.writeData(id); - } - - /** - * Parse data - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case HANDLE: - _clientHandle = new COPSHandle(buf); - _dataStart += _clientHandle.getDataLength(); - break; - case RPT: - _report = new COPSReportType(buf); - _dataStart += _report.getDataLength(); - break; - case CSI: - COPSClientSI csi = new COPSClientSI(buf); - _dataStart += csi.getDataLength(); - _clientSI.add(csi); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format, unknown object type"); - } - } - checkSanity(); - } - - /** - * Parse data - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT) - throw new COPSException ("Null Header"); - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - if (_clientHandle != null) len += _clientHandle.getDataLength(); - if (_report != null) len += _report.getDataLength(); - - for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - len += clientSI.getDataLength(); - } - - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_clientHandle != null) - _clientHandle.dump(os); - - if (_report != null) - _report.dump(os); - - for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - clientSI.dump(os); - } - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Vector; + +/** + * COPS Report Message (RFC 2748 pag. 25) + * + * The RPT message is used by the PEP to communicate to the PDP its + * success or failure in carrying out the PDP's decision, or to report + * an accounting related change in state. The Report-Type specifies the + * kind of report and the optional ClientSI can carry additional + * information per Client-Type. + * + * For every DEC message containing a configuration context that is + * received by a PEP, the PEP MUST generate a corresponding Report State + * message with the Solicited Message flag set describing its success or + * failure in applying the configuration decision. In addition, + * outsourcing decisions from the PDP MAY result in a corresponding + * solicited Report State from the PEP depending on the context and the + * type of client. RPT messages solicited by decisions for a given + * Client Handle MUST set the Solicited Message flag and MUST be sent in + * the same order as their corresponding Decision messages were + * received. There MUST never be more than one Report State message + * generated with the Solicited Message flag set per Decision. + * + * The Report State may also be used to provide periodic updates of + * client specific information for accounting and state monitoring + * purposes depending on the type of the client. In such cases the + * accounting report type should be specified utilizing the appropriate + * client specific information object. + * + * ::== + * + * + * [] + * [] + * + * @version COPSReportMsg.java, v 1.00 2003 + * + */ +public class COPSReportMsg extends COPSMsg { + /* COPSHeader coming from base class */ + private COPSHandle _clientHandle; + private COPSReportType _report; + private Vector _clientSI; + private COPSIntegrity _integrity; + + public COPSReportMsg() { + _clientHandle = null; + _report = null; + _integrity = null; + _clientSI = new Vector(20); + } + + /** + Parse data and create COPSReportMsg object + */ + protected COPSReportMsg (byte[] data) throws COPSException { + _clientHandle = null; + _report = null; + _integrity = null; + parse(data); + } + + /** + * Checks the sanity of COPS message and throw an + * COPSException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_clientHandle == null) || (_report == null)) + throw new COPSException("Bad message format"); + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT) + throw new COPSException ("Error Header (no COPS_OP_REQ)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Report object to the message + * + * @param report a COPSReportType + * + * @throws COPSException + * + */ + public void add (COPSReportType report) throws COPSException { + if (report == null) + throw new COPSException ("Null Handle"); + + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("No null Handle"); + + _report = report; + setMsgLength(); + } + + /** + * Add client handle to the message + * + * @param handle a COPSHandle + * + * @throws COPSException + * + */ + public void add (COPSHandle handle) throws COPSException { + if (handle == null) + throw new COPSException ("Null Handle"); + + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("No null Handle"); + + _clientHandle = handle; + setMsgLength(); + } + + /** + * Add one or more clientSI objects + * + * @param clientSI a COPSClientSI + * + * @throws COPSException + * + */ + public void add (COPSClientSI clientSI) throws COPSException { + if (clientSI == null) + throw new COPSException ("Null ClientSI"); + _clientSI.add(clientSI); + setMsgLength(); + } + + /** + * Add integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Get client Handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _clientHandle; + } + + /** + * Get report type + * + * @return a COPSReportType + * + */ + public COPSReportType getReport() { + return _report; + } + + /** + * Get clientSI + * + * @return a Vector + * + */ + public Vector getClientSI() { + return _clientSI; + } + + /** + * Returns true if it has Integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + } + + + /** + * Get Integrity. Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Writes data to given network socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + //checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_clientHandle != null) _clientHandle.writeData(id); + if (_report != null) _report.writeData(id); + + for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + clientSI.writeData(id); + } + + if (_integrity != null) _integrity.writeData(id); + } + + /** + * Parse data + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case HANDLE: + _clientHandle = COPSHandle.parse(objHdrData, buf); + _dataStart += _clientHandle.getDataLength(); + break; + case RPT: + _report = COPSReportType.parse(objHdrData, buf); + _dataStart += _report.getDataLength(); + break; + case CSI: + COPSClientSI csi = COPSClientSI.parse(objHdrData, buf); + _dataStart += csi.getDataLength(); + _clientSI.add(csi); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format, unknown object type"); + } + } + checkSanity(); + } + + /** + * Parse data + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT) + throw new COPSException ("Null Header"); + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + if (_clientHandle != null) len += _clientHandle.getDataLength(); + if (_report != null) len += _report.getDataLength(); + + for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + len += clientSI.getDataLength(); + } + + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_clientHandle != null) + _clientHandle.dump(os); + + if (_report != null) + _report.dump(os); + + for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + clientSI.dump(os); + } + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportType.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportType.java index 504d34b..fb5cdd7 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportType.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReportType.java @@ -1,163 +1,153 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import org.umu.cops.stack.COPSObjHeader.CNum; -import org.umu.cops.stack.COPSObjHeader.CType; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Report Type (RFC 2748 pag. 16 - * - * The Type of Report on the request state associated with a handle: - * - * C-Num = 12, C-Type = 1 - * - * 0 1 2 3 - * +--------------+--------------+--------------+--------------+ - * | Report-Type | ///////////// | - * +--------------+--------------+--------------+--------------+ - * - * Report-Type: - * 1 = Success : Decision was successful at the PEP - * 2 = Failure : Decision could not be completed by PEP - * 3 = Accounting: Accounting update for an installed state - * - * - * @version COPSReportType.java, v 1.00 2003 - * - */ -public class COPSReportType extends COPSPrObjBase { - - public final static String[] msgMap = { - "Unknown", - "Success", - "Failure", - "Accounting", - }; - - private COPSObjHeader _objHdr; - private short _rType; - private short _reserved; - - public final static short SUCCESS = 1; - public final static short FAILURE = 2; - public final static short ACCT = 3; - - public COPSReportType(short rType) { - _objHdr = new COPSObjHeader(CNum.RPT, CType.DEF); - _rType = rType; - _objHdr.setDataLength((short) 4); - } - - /** - Parse data and create COPSReportType object - */ - protected COPSReportType(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _rType |= ((short) dataPtr[4]) << 8; - _rType |= ((short) dataPtr[5]) & 0xFF; - _reserved |= ((short) dataPtr[6]) << 8; - _reserved |= ((short) dataPtr[7]) & 0xFF; - - _objHdr.setDataLength((short) 4); - } - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - /** - * If it is Success, return true - * - * @return a boolean - * - */ - public boolean isSuccess() { - return (_rType == SUCCESS ); - }; - - /** - * If it is Failure, return true - * - * @return a boolean - * - */ - public boolean isFailure() { - return (_rType == FAILURE); - }; - - /** - * If it is Accounting, return true - * - * @return a boolean - * - */ - public boolean isAccounting() { - return (_rType == ACCT); - }; - - /** - * Always return true - * - * @return a boolean - * - */ - public boolean isReport() { - return true; - }; - - /** - * Write data in network byte order on a given network socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - byte[] buf = new byte[4]; - - buf[0] = (byte) (_rType >> 8); - buf[1] = (byte) _rType; - buf[2] = (byte) (_reserved >> 8); - buf[3] = (byte) _reserved; - - COPSUtil.writeData(id, buf, 4); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Report: " + msgMap[_rType] + "\n").getBytes()); - } -} - - - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * COPS Report Type (RFC 2748 pg. 16) + * + * The Type of Report on the request state associated with a handle: + * + * C-Num = 12, C-Type = 1 + * + * 0 1 2 3 + * +--------------+--------------+--------------+--------------+ + * | Report-Type | ///////////// | + * +--------------+--------------+--------------+--------------+ + * + * Report-Type: + * 1 = Success : Decision was successful at the PEP + * 2 = Failure : Decision could not be completed by PEP + * 3 = Accounting: Accounting update for an installed state + * + * + * @version COPSReportType.java, v 1.00 2003 + * + */ +public class COPSReportType extends COPSObjBase { + + private final static Map VAL_TO_RPT_TYPE = new ConcurrentHashMap<>(); + static { + VAL_TO_RPT_TYPE.put(ReportType.NA.ordinal(), ReportType.NA); + VAL_TO_RPT_TYPE.put(ReportType.SUCCESS.ordinal(), ReportType.SUCCESS); + VAL_TO_RPT_TYPE.put(ReportType.FAILURE.ordinal(), ReportType.FAILURE); + VAL_TO_RPT_TYPE.put(ReportType.ACCOUNTING.ordinal(), ReportType.ACCOUNTING); + } + + private final static Map RPT_TYPE_TO_STRING = new ConcurrentHashMap<>(); + static { + RPT_TYPE_TO_STRING.put(ReportType.NA, "Unknown."); + RPT_TYPE_TO_STRING.put(ReportType.SUCCESS, "Success."); + RPT_TYPE_TO_STRING.put(ReportType.FAILURE, "Failure."); + RPT_TYPE_TO_STRING.put(ReportType.ACCOUNTING, "Accounting."); + } + + /** + * The type of report + */ + private final ReportType _rType; + + /** + * What is this attribute used for??? + */ + private final short _reserved; + + /** + * Constructor generally used for sending messages + * @param rType - the report type + * @throws java.lang.IllegalArgumentException + */ + public COPSReportType(final ReportType rType) { + this(new COPSObjHeader(CNum.RPT, CType.DEF), rType, (short)0); + } + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param hdr - the object header + * @param rType - the report type + * @param reserved - ??? + * @throws java.lang.IllegalArgumentException + */ + protected COPSReportType(final COPSObjHeader hdr, final ReportType rType, final short reserved) { + super(hdr); + if (!hdr.getCNum().equals(CNum.RPT)) + throw new IllegalArgumentException("Must have a CNum value of " + CNum.RPT); + if (!hdr.getCType().equals(CType.DEF)) + throw new IllegalArgumentException("Must have a CType value of " + CType.DEF); + if (rType == null) throw new IllegalArgumentException("Report type must not be null"); + if (rType.equals(ReportType.NA)) + throw new IllegalArgumentException("Report type must not be of type " + ReportType.NA); + + _rType = rType; + _reserved = reserved; + } + + public ReportType getReportType() { return _rType; } + + @Override + public int getDataLength() { + return 4; + } + + @Override + protected void writeBody(final Socket id) throws IOException { + final byte[] buf = new byte[4]; + + buf[0] = (byte) (_rType.ordinal() >> 8); + buf[1] = (byte) _rType.ordinal(); + buf[2] = (byte) (_reserved >> 8); + buf[3] = (byte) _reserved; + + COPSUtil.writeData(id, buf, 4); + } + + @Override + protected void dumpBody(final OutputStream os) throws IOException { + os.write(("Report: " + RPT_TYPE_TO_STRING.get(_rType) + "\n").getBytes()); + } + + /** + * Creates this object from a byte array + * @param objHdrData - the header + * @param dataPtr - the data to parse + * @return - a new Timer + * @throws java.lang.IllegalArgumentException + */ + public static COPSReportType parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) { + short rType = 0; + rType |= ((short) dataPtr[4]) << 8; + rType |= ((short) dataPtr[5]) & 0xFF; + + short reserved = 0; + reserved |= ((short) dataPtr[6]) << 8; + reserved |= ((short) dataPtr[7]) & 0xFF; + + return new COPSReportType(objHdrData.header, VAL_TO_RPT_TYPE.get((int)rType), reserved); + } + + /** + * The supported report types + */ + public enum ReportType { + NA, SUCCESS, FAILURE, ACCOUNTING + } + +} + + + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReqMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReqMsg.java index 6293aba..1ed1da1 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReqMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSReqMsg.java @@ -1,590 +1,574 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -/** - * COPS Request Message (RFC 2748 pag. 22) - * - * The PEP establishes a request state client handle for which the - * remote PDP may maintain state. The remote PDP then uses this handle - * to refer to the exchanged information and decisions communicated over - * the TCP connection to a particular PEP for a given client-type. - * - * Once a stateful handle is established for a new request, any - * subsequent modifications of the request can be made using the REQ - * message specifying the previously installed handle. The PEP is - * responsible for notifying the PDP whenever its local state changes so - * the PDP's state will be able to accurately mirror the PEP's state. - * - * The format of the Request message is as follows: - * - * ::= - * - * - * [] - * [] - * [] - * [] - * [] - * - * ::= | - * - * ::= | - * - * - * ::= [] - * - * [] - * [] - * [] - * [] - * - * The context object is used to determine the context within which all - * the other objects are to be interpreted. It also is used to determine - * the kind of decision to be returned from the policy server. This - * decision might be related to admission control, resource allocation, - * object forwarding and substitution, or configuration. - * - * The interface objects are used to determine the corresponding - * interface on which a signaling protocol message was received or is - * about to be sent. They are typically used if the client is - * participating along the path of a signaling protocol or if the client - * is requesting configuration data for a particular interface. - * - * ClientSI, the client specific information object, holds the client- - * type specific data for which a policy decision needs to be made. In - * the case of configuration, the Named ClientSI may include named - * information about the module, interface, or functionality to be - * configured. The ordering of multiple ClientSIs is not important. - * - * Finally, LPDPDecision object holds information regarding the local - * decision made by the LPDP. - * - * Malformed Request messages MUST result in the PDP specifying a - * Decision message with the appropriate error code. - * - * @version COPSReqMsg.java, v 1.00 2003 - * - */ -public class COPSReqMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSHandle _clientHandle; - private COPSContext _context; - private COPSInterface _inInterface; - private COPSInterface _outInterface; - private Vector _clientSIs; - private Hashtable _decisions; - private COPSIntegrity _integrity; - private COPSContext _lpdpContext; - - public COPSReqMsg() { - _clientHandle = null; - _context = null; - _inInterface = null; - _outInterface = null; - _clientSIs = new Vector(20); - _decisions = new Hashtable(); - _integrity = null; - _lpdpContext = null; - } - - /** - Parse data and create COPSReqMsg object - */ - protected COPSReqMsg(byte[] data) throws COPSException { - parse(data); - } - - /** - * Checks the sanity of COPS message and throw an - * COPSBadDataException when data is bad. - */ - public void checkSanity() throws COPSException { - if ((_hdr == null) || (_clientHandle == null) || (_context == null)) { - throw new COPSException("Bad message format"); - } - } - - /** - * Add an IN or OUT interface object - * - * @param inter a COPSInterface - * - * @throws COPSException - * - */ - public void add (COPSInterface inter) throws COPSException { - if (!(inter.isInInterface() || inter.isOutInterface())) - throw new COPSException ("No Interface"); - - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("Integrity should be the last one"); - - if (inter.isInInterface()) { - if (_inInterface != null) - throw new COPSException ("Object inInterface exits"); - - if (inter.isIpv4Address()) { - COPSIpv4InInterface inInter = (COPSIpv4InInterface) inter; - _inInterface = inInter; - } else { - COPSIpv6InInterface inInter = (COPSIpv6InInterface) inter; - _inInterface = inInter; - } - } else { - if (_outInterface != null) - throw new COPSException ("Object outInterface exits"); - - if (inter.isIpv4Address()) { - COPSIpv4OutInterface outInter = (COPSIpv4OutInterface) inter; - _outInterface = outInter; - } else { - COPSIpv6OutInterface outInter = (COPSIpv6OutInterface) inter; - _outInterface = outInter; - } - } - setMsgLength(); - } - - /** - * Add header to the message - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if (hdr.getOpCode() != COPSHeader.COPS_OP_REQ) - throw new COPSException ("Error Header (no COPS_OP_REQ)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add Context object to the message - * - * @param context a COPSContext - * - * @throws COPSException - * - */ - public void add (COPSContext context) throws COPSException { - if (context == null) - throw new COPSException ("Null Context"); - _context = context; - setMsgLength(); - } - - /** - * Add client handle to the message - * - * @param handle a COPSHandle - * - * @throws COPSException - * - */ - public void add (COPSHandle handle) throws COPSException { - if (handle == null) - throw new COPSException ("Null Handle"); - _clientHandle = handle; - setMsgLength(); - } - - /** - * Add one or more clientSI objects - * - * @param clientSI a COPSClientSI - * - * @throws COPSException - * - */ - public void add (COPSClientSI clientSI) throws COPSException { - if (clientSI == null) - throw new COPSException ("Null ClientSI"); - _clientSIs.add(clientSI); - setMsgLength(); - } - - /** - * Add one or more local decision object for a given decision context - * the context is optional, if null all decision object are tided to - * message context - * - * @param decision a COPSLPDPDecision - * @param context a COPSContext - * - * @throws COPSException - * - */ - public void addLocalDecision(COPSLPDPDecision decision, COPSContext context) throws COPSException { - if (!decision.isLocalDecision()) - throw new COPSException ("Local Decision"); - - Vector v = (Vector) _decisions.get(context); - if (decision.isFlagSet()) { - if (v.size() != 0) { - //Only one set of decision flags is allowed - //for each context - throw new COPSException ("Bad Message format, only one set of decision flags is allowed."); - } - } else { - if (v.size() == 0) { - //The flags decision must precede any other - //decision message, since the decision is not - //flags throw exception - throw new COPSException ("Bad Message format, flags decision must precede any other decision object."); - } - } - v.add(decision); - _decisions.put(context,v); - - setMsgLength(); - } - - /** - * Add integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_clientHandle != null) _clientHandle.writeData(id); - if (_context != null) _context.writeData(id); - - for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - clientSI.writeData(id); - } - - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - context.writeData(id); - - for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { - COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); - decision.writeData(id); - } - } - - if (_integrity != null) _integrity.writeData(id); - - } - - /** - * Return Header - * - * @return a COPSHeader - * - */ - public COPSHeader getHeader() { - return _hdr; - } - - /** - * Return client Handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _clientHandle; - } - - /** - * Return Context - * - * @return a COPSContext - * - */ - public COPSContext getContext() { - return _context; - } - - /** - * Returns true if it has In Interface - * - * @return a boolean - * - */ - public boolean hasInInterface() { - return (_inInterface == null); - } - - /** - * Should check hasInInterface() before calling - * - * @return a COPSInterface - * - */ - public COPSInterface getInInterface() { - return _inInterface; - } - - /** - * Returns true if it has Out interface - * - * @return a boolean - * - */ - public boolean hasOutInterface() { - return (_outInterface == null); - } - - /** - * Should check hasOutInterface() before calling - * - * @return a COPSInterface - * - */ - public COPSInterface getOutInterface() { - return _outInterface; - } - - /** - * Returns a vector if ClientSI objects - * - * @return a Vector - * - */ - public Vector getClientSI() { - return _clientSIs; - } - - /** - * Returns a HashTable of any local decisions - * - * @return a Hashtable - * - */ - public Hashtable getLpdpDecisions() { - return _decisions; - } - - /** - * Returns true if it has Integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity == null); - } - - /** - * Get Integrity. Should check hasIntegrity() becfore calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return _integrity; - } - - /** - * Parses the data and fills COPSReqMsg with its constituents - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case HANDLE: - _clientHandle = new COPSHandle(buf); - _dataStart += _clientHandle.getDataLength(); - break; - case CONTEXT: - if (_context == null) { - //Message context - _context = new COPSContext(buf); - _dataStart += _context.getDataLength(); - } else { - //lpdp context - _lpdpContext = new COPSContext(buf); - _dataStart += _lpdpContext.getDataLength(); - } - break; - case ININTF: - if (objHdr.getCType().ordinal() == 1) { - _inInterface = new COPSIpv4InInterface(buf); - } else { - _inInterface = new COPSIpv6InInterface(buf); - } - _dataStart += _inInterface.getDataLength(); - break; - case OUTINTF: - if (objHdr.getCType().ordinal() == 1) { - _outInterface = new COPSIpv4OutInterface(buf); - } else { - _outInterface = new COPSIpv6OutInterface(buf); - } - _dataStart += _outInterface.getDataLength(); - break; - case LPDP_DEC: - COPSLPDPDecision lpdp = new COPSLPDPDecision(buf); - _dataStart += lpdp.getDataLength(); - addLocalDecision(lpdp, _lpdpContext); - break; - case CSI: - COPSClientSI csi = new COPSClientSI (buf); - _dataStart += csi.getDataLength(); - _clientSIs.add(csi); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format, unknown object type"); - } - } - checkSanity(); - - } - - /** - * Parses the data and fills that follows the header hdr and fills COPSReqMsg - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - - if (_clientHandle != null) - len += _clientHandle.getDataLength(); - - if (_context != null) - len += _context.getDataLength(); - - for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - len += clientSI.getDataLength(); - } - - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - len += context.getDataLength(); - - for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { - COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); - len += decision.getDataLength(); - } - } - - if (_integrity != null) { - len += _integrity.getDataLength(); - } - - _hdr.setMsgLength((int) len); - - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_clientHandle != null) - _clientHandle.dump(os); - - if (_context != null) - _context.dump(os); - - for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { - COPSClientSI clientSI = (COPSClientSI) e.nextElement(); - clientSI.dump(os); - } - - //Display any local decisions - for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { - - COPSContext context = (COPSContext) e.nextElement(); - Vector v = (Vector) _decisions.get(context); - context.dump(os); - - for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { - COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); - decision.dump(os); - } - } - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Vector; + +/** + * COPS Request Message (RFC 2748 pag. 22) + * + * The PEP establishes a request state client handle for which the + * remote PDP may maintain state. The remote PDP then uses this handle + * to refer to the exchanged information and decisions communicated over + * the TCP connection to a particular PEP for a given client-type. + * + * Once a stateful handle is established for a new request, any + * subsequent modifications of the request can be made using the REQ + * message specifying the previously installed handle. The PEP is + * responsible for notifying the PDP whenever its local state changes so + * the PDP's state will be able to accurately mirror the PEP's state. + * + * The format of the Request message is as follows: + * + * ::= + * + * + * [] + * [] + * [] + * [] + * [] + * + * ::= | + * + * ::= | + * + * + * ::= [] + * + * [] + * [] + * [] + * [] + * + * The context object is used to determine the context within which all + * the other objects are to be interpreted. It also is used to determine + * the kind of decision to be returned from the policy server. This + * decision might be related to admission control, resource allocation, + * object forwarding and substitution, or configuration. + * + * The interface objects are used to determine the corresponding + * interface on which a signaling protocol message was received or is + * about to be sent. They are typically used if the client is + * participating along the path of a signaling protocol or if the client + * is requesting configuration data for a particular interface. + * + * ClientSI, the client specific information object, holds the client- + * type specific data for which a policy decision needs to be made. In + * the case of configuration, the Named ClientSI may include named + * information about the module, interface, or functionality to be + * configured. The ordering of multiple ClientSIs is not important. + * + * Finally, LPDPDecision object holds information regarding the local + * decision made by the LPDP. + * + * Malformed Request messages MUST result in the PDP specifying a + * Decision message with the appropriate error code. + * + * @version COPSReqMsg.java, v 1.00 2003 + * + */ +public class COPSReqMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSHandle _clientHandle; + private COPSContext _context; + private COPSInterface _inInterface; + private COPSInterface _outInterface; + private Vector _clientSIs; + private Hashtable _decisions; + private COPSIntegrity _integrity; + private COPSContext _lpdpContext; + + public COPSReqMsg() { + _clientHandle = null; + _context = null; + _inInterface = null; + _outInterface = null; + _clientSIs = new Vector(20); + _decisions = new Hashtable(); + _integrity = null; + _lpdpContext = null; + } + + /** + Parse data and create COPSReqMsg object + */ + protected COPSReqMsg(byte[] data) throws COPSException { + parse(data); + } + + /** + * Checks the sanity of COPS message and throw an + * COPSBadDataException when data is bad. + */ + public void checkSanity() throws COPSException { + if ((_hdr == null) || (_clientHandle == null) || (_context == null)) { + throw new COPSException("Bad message format"); + } + } + + /** + * Add an IN or OUT interface object + * + * @param inter a COPSInterface + * + * @throws COPSException + * + */ + public void add (COPSInterface inter) throws COPSException { + if (inter == null) + throw new COPSException ("No Interface"); + + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("Integrity should be the last one"); + + if (inter.isInInterface()) { + if (_inInterface != null) + throw new COPSException ("Object inInterface exits"); + _inInterface = inter; + } else { + if (_outInterface != null) + throw new COPSException("Object outInterface exits"); + _outInterface = inter; + } + setMsgLength(); + } + + /** + * Add header to the message + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if (hdr.getOpCode() != COPSHeader.COPS_OP_REQ) + throw new COPSException ("Error Header (no COPS_OP_REQ)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add Context object to the message + * + * @param context a COPSContext + * + * @throws COPSException + * + */ + public void add (COPSContext context) throws COPSException { + if (context == null) + throw new COPSException ("Null Context"); + _context = context; + setMsgLength(); + } + + /** + * Add client handle to the message + * + * @param handle a COPSHandle + * + * @throws COPSException + * + */ + public void add (COPSHandle handle) throws COPSException { + if (handle == null) + throw new COPSException ("Null Handle"); + _clientHandle = handle; + setMsgLength(); + } + + /** + * Add one or more clientSI objects + * + * @param clientSI a COPSClientSI + * + * @throws COPSException + * + */ + public void add (COPSClientSI clientSI) throws COPSException { + if (clientSI == null) + throw new COPSException ("Null ClientSI"); + _clientSIs.add(clientSI); + setMsgLength(); + } + + /** + * Add one or more local decision object for a given decision context + * the context is optional, if null all decision object are tided to + * message context + * + * @param decision a COPSLPDPDecision + * @param context a COPSContext + * + * @throws COPSException + * + */ + public void addLocalDecision(COPSLPDPDecision decision, COPSContext context) throws COPSException { + Vector v = (Vector) _decisions.get(context); + if (!decision.getFlag().equals(DecisionFlag.NA)) { + if (v.size() != 0) { + //Only one set of decision flags is allowed + //for each context + throw new COPSException ("Bad Message format, only one set of decision flags is allowed."); + } + } else { + if (v.size() == 0) { + //The flags decision must precede any other + //decision message, since the decision is not + //flags throw exception + throw new COPSException ("Bad Message format, flags decision must precede any other decision object."); + } + } + v.add(decision); + _decisions.put(context,v); + + setMsgLength(); + } + + /** + * Add integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * Writes data to given socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_clientHandle != null) _clientHandle.writeData(id); + if (_context != null) _context.writeData(id); + + for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + clientSI.writeData(id); + } + + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + context.writeData(id); + + for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { + COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); + decision.writeData(id); + } + } + + if (_integrity != null) _integrity.writeData(id); + + } + + /** + * Return Header + * + * @return a COPSHeader + * + */ + public COPSHeader getHeader() { + return _hdr; + } + + /** + * Return client Handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _clientHandle; + } + + /** + * Return Context + * + * @return a COPSContext + * + */ + public COPSContext getContext() { + return _context; + } + + /** + * Returns true if it has In Interface + * + * @return a boolean + * + */ + public boolean hasInInterface() { + return (_inInterface == null); + } + + /** + * Should check hasInInterface() before calling + * + * @return a COPSInterface + * + */ + public COPSInterface getInInterface() { + return _inInterface; + } + + /** + * Returns true if it has Out interface + * + * @return a boolean + * + */ + public boolean hasOutInterface() { + return (_outInterface == null); + } + + /** + * Should check hasOutInterface() before calling + * + * @return a COPSInterface + * + */ + public COPSInterface getOutInterface() { + return _outInterface; + } + + /** + * Returns a vector if ClientSI objects + * + * @return a Vector + * + */ + public Vector getClientSI() { + return _clientSIs; + } + + /** + * Returns a HashTable of any local decisions + * + * @return a Hashtable + * + */ + public Hashtable getLpdpDecisions() { + return _decisions; + } + + /** + * Returns true if it has Integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity == null); + } + + /** + * Get Integrity. Should check hasIntegrity() becfore calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return _integrity; + } + + /** + * Parses the data and fills COPSReqMsg with its constituents + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case HANDLE: + _clientHandle = COPSHandle.parse(objHdrData, buf); + _dataStart += _clientHandle.getDataLength(); + break; + case CONTEXT: + if (_context == null) { + //Message context + _context = COPSContext.parse(objHdrData, buf); + _dataStart += _context.getDataLength(); + } else { + //lpdp context + _lpdpContext = COPSContext.parse(objHdrData, buf); + _dataStart += _lpdpContext.getDataLength(); + } + break; + case ININTF: + if (objHdrData.header.getCType().equals(CType.DEF)) { + _inInterface = COPSObjectParser.parseIpv4Interface(objHdrData, buf, true); + } else { + _inInterface = COPSObjectParser.parseIpv6Interface(objHdrData, buf, true); + } + _dataStart += _inInterface.getDataLength(); + break; + case OUTINTF: + if (objHdrData.header.getCType().equals(CType.DEF)) { + _outInterface = COPSObjectParser.parseIpv4Interface(objHdrData, buf, false); + } else { + _outInterface = COPSObjectParser.parseIpv6Interface(objHdrData, buf, false); + } + _dataStart += _outInterface.getDataLength(); + break; + case LPDP_DEC: + COPSLPDPDecision lpdp = COPSLPDPDecision.parse(objHdrData, buf); + _dataStart += lpdp.getDataLength(); + addLocalDecision(lpdp, _lpdpContext); + break; + case CSI: + COPSClientSI csi = COPSClientSI.parse(objHdrData, buf); + _dataStart += csi.getDataLength(); + _clientSIs.add(csi); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format, unknown object type"); + } + } + checkSanity(); + + } + + /** + * Parses the data and fills that follows the header hdr and fills COPSReqMsg + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + + if (_clientHandle != null) + len += _clientHandle.getDataLength(); + + if (_context != null) + len += _context.getDataLength(); + + for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + len += clientSI.getDataLength(); + } + + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + len += context.getDataLength(); + + for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { + COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); + len += decision.getDataLength(); + } + } + + if (_integrity != null) { + len += _integrity.getDataLength(); + } + + _hdr.setMsgLength((int) len); + + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_clientHandle != null) + _clientHandle.dump(os); + + if (_context != null) + _context.dump(os); + + for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) { + COPSClientSI clientSI = (COPSClientSI) e.nextElement(); + clientSI.dump(os); + } + + //Display any local decisions + for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) { + + COPSContext context = (COPSContext) e.nextElement(); + Vector v = (Vector) _decisions.get(context); + context.dump(os); + + for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) { + COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement(); + decision.dump(os); + } + } + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSSyncStateMsg.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSSyncStateMsg.java index b9d352d..92e2e0f 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSSyncStateMsg.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSSyncStateMsg.java @@ -1,277 +1,275 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Sync State Message (RFC 2748 pag. 26 and pag. 29 - * - * The format of the Synchronize State Query message is as follows: - * - * ::= - * [] - * [] - * - * This message indicates that the remote PDP wishes the client (which - * appears in the common header) to re-send its state. If the optional - * Client Handle is present, only the state associated with this handle - * is synchronized. If the PEP does not recognize the requested handle, - * it MUST immediately send a DRQ message to the PDP for the handle that - * was specified in the SSQ message. If no handle is specified in the - * SSQ message, all the active client state MUST be synchronized with - * the PDP. - * - * The client performs state synchronization by re-issuing request - * queries of the specified client-type for the existing state in the - * PEP. When synchronization is complete, the PEP MUST issue a - * synchronize state complete message to the PDP. - * - * ::= - * [] - * [] - * - * The Client Handle object only needs to be included if the corresponding - * Synchronize State Message originally referenced a specific handle. - * - * @version COPSSyncStateMsg.java, v 1.00 2003 - * - */ -public class COPSSyncStateMsg extends COPSMsg { - - /* COPSHeader coming from base class */ - private COPSHandle _clientHandle; - private COPSIntegrity _integrity; - - public COPSSyncStateMsg() { - _clientHandle = null; - _integrity = null; - } - - /** - Parse data and create COPSSyncStateMsg object - */ - protected COPSSyncStateMsg(byte[] data) throws COPSException { - _clientHandle = null; - _integrity = null; - parse(data); - } - - /** - * Checks the sanity of COPS message and throw an - * COPSException when data is bad. - */ - public void checkSanity() throws COPSException { - if (_hdr == null) { - throw new COPSException("Bad message format"); - } - } - - /** - * Add message header - * - * @param hdr a COPSHeader - * - * @throws COPSException - * - */ - public void add (COPSHeader hdr) throws COPSException { - if (hdr == null) - throw new COPSException ("Null Header"); - if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) && - (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ)) - throw new COPSException ("Error Header (no COPS_OP_SSX)"); - _hdr = hdr; - setMsgLength(); - } - - /** - * Add client handle to the message - * - * @param handle a COPSHandle - * - * @throws COPSException - * - */ - public void add (COPSHandle handle) throws COPSException { - if (handle == null) - throw new COPSException ("Null Handle"); - - //Message integrity object should be the very last one - //If it is already added - if (_integrity != null) - throw new COPSException ("No null Handle"); - - _clientHandle = handle; - setMsgLength(); - } - - /** - * Add integrity object - * - * @param integrity a COPSIntegrity - * - * @throws COPSException - * - */ - public void add (COPSIntegrity integrity) throws COPSException { - if (integrity == null) - throw new COPSException ("Null Integrity"); - if (!integrity.isMessageIntegrity()) - throw new COPSException ("Error Integrity"); - _integrity = integrity; - setMsgLength(); - } - - /** - * If the optional Client Handle is present, only the state associated - * with this handle is synchronized. If no handle is specified in the - * SSQ message, all the active client state MUST be synchronized with - * the PDP. - * - * @return a boolean - * - */ - public boolean hasClientHandle() { - return (_clientHandle != null); - } - - /** - * Get client Handle - * - * @return a COPSHandle - * - */ - public COPSHandle getClientHandle() { - return _clientHandle; - } - - /** - * Returns true if it has integrity object - * - * @return a boolean - * - */ - public boolean hasIntegrity() { - return (_integrity != null); - } - - /** - * Get Integrity. Should check hasIntegrity() before calling - * - * @return a COPSIntegrity - * - */ - public COPSIntegrity getIntegrity() { - return (_integrity); - } - - /** - * Writes data to given socket - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - // checkSanity(); - if (_hdr != null) _hdr.writeData(id); - if (_clientHandle != null) _clientHandle.writeData(id); - if (_integrity != null) _integrity.writeData(id); - - } - - /** - * Parse data - * - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(byte[] data) throws COPSException { - super.parseHeader(data); - - while (_dataStart < _dataLength) { - byte[] buf = new byte[data.length - _dataStart]; - System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); - - COPSObjHeader objHdr = COPSObjHeader.parse(buf); - switch (objHdr.getCNum()) { - case HANDLE: - _clientHandle = new COPSHandle(buf); - _dataStart += _clientHandle.getDataLength(); - break; - case MSG_INTEGRITY: - _integrity = new COPSIntegrity(buf); - _dataStart += _integrity.getDataLength(); - break; - default: - throw new COPSException("Bad Message format, unknown object type"); - } - } - checkSanity(); - } - - /** - * Parse data - * - * @param hdr a COPSHeader - * @param data a byte[] - * - * @throws COPSException - * - */ - protected void parse(COPSHeader hdr, byte[] data) throws COPSException { - - if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) && - (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ)) - throw new COPSException ("Error Header (no COPS_OP_SSX)"); - - _hdr = hdr; - parse(data); - setMsgLength(); - } - - /** - * Set the message length, base on the set of objects it contains - * - * @throws COPSException - * - */ - protected void setMsgLength() throws COPSException { - short len = 0; - if (_clientHandle != null) len += _clientHandle.getDataLength(); - if (_integrity != null) len += _integrity.getDataLength(); - _hdr.setMsgLength(len); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _hdr.dump(os); - - if (_clientHandle != null) - _clientHandle.dump(os); - - if (_integrity != null) { - _integrity.dump(os); - } - } -} - - - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * COPS Sync State Message (RFC 2748 pag. 26 and pag. 29 + * + * The format of the Synchronize State Query message is as follows: + * + * ::= + * [] + * [] + * + * This message indicates that the remote PDP wishes the client (which + * appears in the common header) to re-send its state. If the optional + * Client Handle is present, only the state associated with this handle + * is synchronized. If the PEP does not recognize the requested handle, + * it MUST immediately send a DRQ message to the PDP for the handle that + * was specified in the SSQ message. If no handle is specified in the + * SSQ message, all the active client state MUST be synchronized with + * the PDP. + * + * The client performs state synchronization by re-issuing request + * queries of the specified client-type for the existing state in the + * PEP. When synchronization is complete, the PEP MUST issue a + * synchronize state complete message to the PDP. + * + * ::= + * [] + * [] + * + * The Client Handle object only needs to be included if the corresponding + * Synchronize State Message originally referenced a specific handle. + * + * @version COPSSyncStateMsg.java, v 1.00 2003 + * + */ +public class COPSSyncStateMsg extends COPSMsg { + + /* COPSHeader coming from base class */ + private COPSHandle _clientHandle; + private COPSIntegrity _integrity; + + public COPSSyncStateMsg() { + _clientHandle = null; + _integrity = null; + } + + /** + Parse data and create COPSSyncStateMsg object + */ + protected COPSSyncStateMsg(byte[] data) throws COPSException { + _clientHandle = null; + _integrity = null; + parse(data); + } + + /** + * Checks the sanity of COPS message and throw an + * COPSException when data is bad. + */ + public void checkSanity() throws COPSException { + if (_hdr == null) { + throw new COPSException("Bad message format"); + } + } + + /** + * Add message header + * + * @param hdr a COPSHeader + * + * @throws COPSException + * + */ + public void add (COPSHeader hdr) throws COPSException { + if (hdr == null) + throw new COPSException ("Null Header"); + if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) && + (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ)) + throw new COPSException ("Error Header (no COPS_OP_SSX)"); + _hdr = hdr; + setMsgLength(); + } + + /** + * Add client handle to the message + * + * @param handle a COPSHandle + * + * @throws COPSException + * + */ + public void add (COPSHandle handle) throws COPSException { + if (handle == null) + throw new COPSException ("Null Handle"); + + //Message integrity object should be the very last one + //If it is already added + if (_integrity != null) + throw new COPSException ("No null Handle"); + + _clientHandle = handle; + setMsgLength(); + } + + /** + * Add integrity object + * + * @param integrity a COPSIntegrity + * + * @throws COPSException + * + */ + public void add (COPSIntegrity integrity) throws COPSException { + if (integrity == null) + throw new COPSException ("Null Integrity"); + _integrity = integrity; + setMsgLength(); + } + + /** + * If the optional Client Handle is present, only the state associated + * with this handle is synchronized. If no handle is specified in the + * SSQ message, all the active client state MUST be synchronized with + * the PDP. + * + * @return a boolean + * + */ + public boolean hasClientHandle() { + return (_clientHandle != null); + } + + /** + * Get client Handle + * + * @return a COPSHandle + * + */ + public COPSHandle getClientHandle() { + return _clientHandle; + } + + /** + * Returns true if it has integrity object + * + * @return a boolean + * + */ + public boolean hasIntegrity() { + return (_integrity != null); + } + + /** + * Get Integrity. Should check hasIntegrity() before calling + * + * @return a COPSIntegrity + * + */ + public COPSIntegrity getIntegrity() { + return (_integrity); + } + + /** + * Writes data to given socket + * + * @param id a Socket + * + * @throws IOException + * + */ + public void writeData(Socket id) throws IOException { + // checkSanity(); + if (_hdr != null) _hdr.writeData(id); + if (_clientHandle != null) _clientHandle.writeData(id); + if (_integrity != null) _integrity.writeData(id); + + } + + /** + * Parse data + * + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(byte[] data) throws COPSException { + super.parseHeader(data); + + while (_dataStart < _dataLength) { + byte[] buf = new byte[data.length - _dataStart]; + System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart); + + final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf); + switch (objHdrData.header.getCNum()) { + case HANDLE: + _clientHandle = COPSHandle.parse(objHdrData, buf); + _dataStart += _clientHandle.getDataLength(); + break; + case MSG_INTEGRITY: + _integrity = COPSIntegrity.parse(objHdrData, buf); + _dataStart += _integrity.getDataLength(); + break; + default: + throw new COPSException("Bad Message format, unknown object type"); + } + } + checkSanity(); + } + + /** + * Parse data + * + * @param hdr a COPSHeader + * @param data a byte[] + * + * @throws COPSException + * + */ + protected void parse(COPSHeader hdr, byte[] data) throws COPSException { + + if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) && + (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ)) + throw new COPSException ("Error Header (no COPS_OP_SSX)"); + + _hdr = hdr; + parse(data); + setMsgLength(); + } + + /** + * Set the message length, base on the set of objects it contains + * + * @throws COPSException + * + */ + protected void setMsgLength() throws COPSException { + short len = 0; + if (_clientHandle != null) len += _clientHandle.getDataLength(); + if (_integrity != null) len += _integrity.getDataLength(); + _hdr.setMsgLength(len); + } + + /** + * Write an object textual description in the output stream + * + * @param os an OutputStream + * + * @throws IOException + * + */ + public void dump(OutputStream os) throws IOException { + _hdr.dump(os); + + if (_clientHandle != null) + _clientHandle.dump(os); + + if (_integrity != null) { + _integrity.dump(os); + } + } +} + + + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSTimer.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSTimer.java index e44e93a..db14492 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSTimer.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSTimer.java @@ -1,133 +1,69 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.Socket; - -/** - * COPS Timer Object - * - * @version COPSTimer.java, v 1.00 2003 - * - */ -public abstract class COPSTimer extends COPSObjBase { - - protected COPSObjHeader _objHdr; - private short _reserved; - private short _timerValue; - - /** - * Returns size in number of octects, including header - * - * @return a short - * - */ - public short getDataLength() { - //Add the size of the header also - return (_objHdr.getDataLength()); - } - - /** - * Method getTimerVal - * - * @return a short - * - */ - public short getTimerVal() { - return _timerValue; - }; - - /** - * Method isTimer - * - * @return a boolean - * - */ - public boolean isTimer() { - return true; - }; - - /** - * Method isKATimer - * - * @return a boolean - * - */ - public boolean isKATimer() { - return false; - }; - - /** - * Method isAcctTimer - * - * @return a boolean - * - */ - public boolean isAcctTimer() { - return false; - }; - - /** - * Write data to given socket in Network byte order - * - * @param id a Socket - * - * @throws IOException - * - */ - public void writeData(Socket id) throws IOException { - _objHdr.writeData(id); - - byte[] buf = new byte[4]; - - buf[0] = (byte) (_reserved >> 8); - buf[1] = (byte) _reserved; - buf[2] = (byte) (_timerValue >> 8); - buf[3] = (byte) _timerValue; - COPSUtil.writeData(id, buf, 4); - } - - protected COPSTimer(COPSObjHeader hdr, short timeVal) { - _objHdr = hdr; - //Time range is 1 - 65535 seconds - _timerValue = timeVal; - // _objHdr.setDataLength(sizeof(u_int32_t)); - _objHdr.setDataLength((short) 4); - } - - /** - * Receive data that is in netwrok byte order and fill in the obj. - */ - protected COPSTimer(byte[] dataPtr) { - _objHdr = COPSObjHeader.parse(dataPtr); - - _reserved |= ((short) dataPtr[4]) << 8; - _reserved |= ((short) dataPtr[5]) & 0xFF; - _timerValue |= ((short) dataPtr[6]) << 8; - _timerValue |= ((short) dataPtr[7]) & 0xFF; - - // _objHdr.setDataLength(sizeof(u_int32_t)); - _objHdr.setDataLength((short) 4); - } - - /** - * Write an object textual description in the output stream - * - * @param os an OutputStream - * - * @throws IOException - * - */ - public void dump(OutputStream os) throws IOException { - _objHdr.dump(os); - os.write(new String("Timer val: " + _timerValue + "\n").getBytes()); - } - -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +/** + * For extension by other COPS Timer Objects such as COPSAcctTimer & COPSKATimer + */ +public abstract class COPSTimer extends COPSObjBase { + + // TODO - determine what is the function of this member + private final short _reserved; + + /** + * The timer values + */ + private final short _timerValue; + + /** + * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the + * COPSObjHeader information is known + * @param header - the object header + * @param reserved - ??? + * @param timerVal - the timer value + */ + protected COPSTimer(final COPSObjHeader header, final short reserved, final short timerVal) { + super(header); + _reserved = reserved; + _timerValue = timerVal; + } + + /** + * Method getTimerVal + * @return a short + */ + public short getTimerVal() { + return _timerValue; + } + + @Override + public void writeBody(Socket socket) throws IOException { + byte[] buf = new byte[4]; + + buf[0] = (byte) (_reserved >> 8); + buf[1] = (byte) _reserved; + buf[2] = (byte) (_timerValue >> 8); + buf[3] = (byte) _timerValue; + COPSUtil.writeData(socket, buf, 4); + } + + @Override + protected int getDataLength() { + return 4; + } + + @Override + public void dumpBody(final OutputStream os) throws IOException { + os.write(("Timer val: " + _timerValue + "\n").getBytes()); + } + +} + diff --git a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSUtil.java b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSUtil.java index 072da7b..6edd432 100644 --- a/packetcable-driver/src/main/java/org/umu/cops/stack/COPSUtil.java +++ b/packetcable-driver/src/main/java/org/umu/cops/stack/COPSUtil.java @@ -1,73 +1,106 @@ -/* - * Copyright (c) 2003 University of Murcia. All rights reserved. - * -------------------------------------------------------------- - * For more information, please see . - */ - -package org.umu.cops.stack; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.Date; - -/** - * COPS Utils - * - * @version COPSUtil.java, v 2.00 2004 - * - */ -public class COPSUtil { - - /** - * Method writeData - * - * @param id a Socket - * @param data a byte[] - * @param len an int - * - * @throws IOException - * - */ - static void writeData(Socket id, byte[] data, int len) throws IOException { - OutputStream output; - output = id.getOutputStream(); - - output.write(data,0,len); - } - - /** - * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error - * bRead returns the bytes read - * - * @param connId a Socket - * @param dataRead a byte[] - * @param nchar an int - * - * @return an int - * - * @throws IOException - * - */ - static int readData(Socket connId, byte[] dataRead, int nchar) throws IOException { - InputStream input; - input = connId.getInputStream(); - - int nread = 0; - int startTime = (int) (new Date().getTime()); - do { - if (input.available() != 0) { - nread += input.read(dataRead,nread,nchar-nread); - startTime = (int) (new Date().getTime()); - } else { - int nowTime = (int) (new Date().getTime()); - if ((int)(nowTime - startTime) > 2000) - break; - } - } while (nread != nchar); - - return nread; - } -} - +/* + * Copyright (c) 2003 University of Murcia. All rights reserved. + * -------------------------------------------------------------- + * For more information, please see . + */ + +package org.umu.cops.stack; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Socket; +import java.util.Arrays; +import java.util.Date; + +/** + * Class to hold static utilitarian methods for streaming bytes over a Socket. + * + * @version COPSUtil.java, v 2.00 2004 + * + */ +public class COPSUtil { + + private final static Logger logger = LoggerFactory.getLogger(COPSUtil.class); + + /** + * Streams COPS data + * @param socket a Socket + * @param data a byte[] + * @param len an int + * @throws IOException + */ + public static void writeData(final Socket socket, final byte[] data, final int len) throws IOException { + logger.info("Writing COPS data"); + socket.getOutputStream().write(data, 0, len); + } + + /** + * Returns true if the data contained within data1 + padding1 is equivalent to data2 + padding2 + * @param data1 - the data from the first + * @param padding1 - the padding from the first + * @param data2 - the data from the second + * @param padding2 - the padding from the second + * @return - t/f + */ + public static boolean copsDataPaddingEquals(final COPSData data1, final COPSData padding1, + final COPSData data2, final COPSData padding2) { + final byte[] data1Bytes = data1.getData(); + final byte[] padding1Bytes = padding1.getData(); + + final byte[] data2Bytes = data2.getData(); + final byte[] padding2Bytes = padding2.getData(); + + if (data1Bytes.length + padding1Bytes.length != data2Bytes.length + padding2Bytes.length) + return false; + + final ByteArrayOutputStream thisStream = new ByteArrayOutputStream(); + final ByteArrayOutputStream thatStream = new ByteArrayOutputStream(); + try { + thisStream.write(data1Bytes); + thisStream.write(padding1Bytes); + thatStream.write(data2Bytes); + thatStream.write(padding2Bytes); + return Arrays.equals(thisStream.toByteArray(), thatStream.toByteArray()); + } catch (IOException e) { + return false; + } + } + + /** + * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error + * bRead returns the bytes read + * + * @param connId a Socket + * @param dataRead a byte[] + * @param nchar an int + * + * @return an int + * + * @throws IOException + * + */ + @Deprecated + static int readData(Socket connId, byte[] dataRead, int nchar) throws IOException { + InputStream input; + input = connId.getInputStream(); + + int nread = 0; + int startTime = (int) (new Date().getTime()); + do { + if (input.available() != 0) { + nread += input.read(dataRead,nread,nchar-nread); + startTime = (int) (new Date().getTime()); + } else { + int nowTime = (int) (new Date().getTime()); + if ((nowTime - startTime) > 2000) + break; + } + } while (nread != nchar); + + return nread; + } +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSAcctTimerTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSAcctTimerTest.java new file mode 100644 index 0000000..d7625ca --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSAcctTimerTest.java @@ -0,0 +1,84 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSAcctTimer class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSAcctTimerTest { + + private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF); + + @Test + public void testValidTimeAndDefaultHeader() { + final COPSAcctTimer timer = new COPSAcctTimer((short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(defaultHeader, timer.getHeader()); + } + + @Test + public void testValidTimeReservedAndDefaultHeader() { + final COPSAcctTimer timer = new COPSAcctTimer((short) 4, (short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(defaultHeader, timer.getHeader()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidCNum() { + new COPSAcctTimer(new COPSObjHeader(CNum.CONTEXT, CType.DEF), (short) 4, (short)10); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidCType() { + new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.REPL), (short) 4, (short)10); + } + + @Test + public void testValidCustomHeader() { + final COPSAcctTimer timer = new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), (short) 4, (short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), timer.getHeader()); + } + + @Test + public void testDumpDefaultHeader() throws Exception { + final COPSAcctTimer timer = new COPSAcctTimer((short) 4, (short)10); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + timer.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Account-Timer**", lines[0]); + Assert.assertEquals("C-num: ACCT_TIMER", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Timer val: 10", lines[3]); + } + + @Test + public void testDumpCustomHeader() throws Exception { + final COPSAcctTimer timer = new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), + (short) 4, (short)100); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + timer.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Account-Timer**", lines[0]); + Assert.assertEquals("C-num: ACCT_TIMER", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Timer val: 100", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSClientSITest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSClientSITest.java new file mode 100644 index 0000000..6f9e7cb --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSClientSITest.java @@ -0,0 +1,113 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSClientSI.CSIType; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSClientSI class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSClientSITest { + + @Test(expected = IllegalArgumentException.class) + public void invalidCSItype() { + new COPSClientSI(CSIType.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void nullData() { + new COPSClientSI(CSIType.SIGNALED, null); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSClientSI(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSClientSI(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), new COPSData()); + } + + @Test + public void csiSignaledEmptyData() { + final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData()); + Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType()); + Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum()); + Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal()); + Assert.assertEquals(new COPSData(), clientSI.getData()); + Assert.assertEquals(0, clientSI.getDataLength()); + } + + @Test + public void csiSignaledUnPaddedData() { + final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("1234")); + Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType()); + Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum()); + Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal()); + Assert.assertEquals(new COPSData("1234"), clientSI.getData()); + Assert.assertEquals(4, clientSI.getDataLength()); + } + + @Test + public void csiSignaledPaddedData() { + final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("12345")); + Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType()); + Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum()); + Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal()); + Assert.assertEquals(new COPSData("12345"), clientSI.getData()); + Assert.assertEquals(8, clientSI.getDataLength()); + } + + @Test + public void csiNamedPaddedData() { + final COPSClientSI clientSI = new COPSClientSI(CSIType.NAMED, new COPSData("12345")); + Assert.assertEquals(CSIType.NAMED, clientSI.getCsiType()); + Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum()); + Assert.assertEquals(CSIType.NAMED.ordinal(), clientSI.getHeader().getCType().ordinal()); + Assert.assertEquals(new COPSData("12345"), clientSI.getData()); + Assert.assertEquals(8, clientSI.getDataLength()); + } + + @Test + public void csiNamedDumpPadded() throws Exception { + final COPSClientSI clientSI = new COPSClientSI(CSIType.NAMED, new COPSData("12345")); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + clientSI.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Client-SI**", lines[0]); + Assert.assertEquals("C-num: CSI", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("CSI-type: NAMED", lines[3]); + Assert.assertEquals("client-SI: 12345", lines[4]); + } + + @Test + public void csiSignaledDumpUnpadded() throws Exception { + final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("1234")); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + clientSI.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Client-SI**", lines[0]); + Assert.assertEquals("C-num: CSI", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("CSI-type: SIGNALED", lines[3]); + Assert.assertEquals("client-SI: 1234", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSContextTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSContextTest.java new file mode 100644 index 0000000..0351b69 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSContextTest.java @@ -0,0 +1,111 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSContext.RType; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSContext class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSContextTest { + + @Test(expected = IllegalArgumentException.class) + public void invalidRType() { + new COPSContext(RType.NA, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullRType() { + new COPSContext(null, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSContext(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), RType.CONFIG, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSContext(new COPSObjHeader(CNum.CONTEXT, CType.NA), RType.CONFIG, (short)0); + } + + @Test + public void dumpConfig0() throws Exception { + final COPSContext context = new COPSContext(RType.CONFIG, (short)0); + Assert.assertEquals(4, context.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + context.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Context**", lines[0]); + Assert.assertEquals("C-num: CONTEXT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("context: Configuration,0", lines[3]); + } + + @Test + public void dumpInAdmin99() throws Exception { + final COPSContext context = new COPSContext(RType.IN_ADMIN, (short)99); + Assert.assertEquals(4, context.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + context.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Context**", lines[0]); + Assert.assertEquals("C-num: CONTEXT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("context: Incoming Message/Admission Control,99", lines[3]); + } + + @Test + public void dumpResAlloc25() throws Exception { + final COPSContext context = new COPSContext(RType.RES_ALLOC, (short)25); + Assert.assertEquals(4, context.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + context.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Context**", lines[0]); + Assert.assertEquals("C-num: CONTEXT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("context: Resource allocation,25", lines[3]); + } + + @Test + public void dumpOut15() throws Exception { + final COPSContext context = new COPSContext(RType.OUT, (short)15); + Assert.assertEquals(4, context.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + context.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Context**", lines[0]); + Assert.assertEquals("C-num: CONTEXT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("context: Outgoing message,15", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSDecisionTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSDecisionTest.java new file mode 100644 index 0000000..4a80f87 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSDecisionTest.java @@ -0,0 +1,361 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSDecision class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSDecisionTest { + + @Test(expected = IllegalArgumentException.class) + public void constructor1NullCommand() { + new COPSDecision(null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullCType() { + new COPSDecision(null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NaCType() { + new COPSDecision(CType.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullData() { + new COPSDecision(CType.DEF, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor3NullCommand() { + new COPSDecision(null, DecisionFlag.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor3NullDecisionFlag() { + new COPSDecision(Command.INSTALL, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor4NullCType() { + new COPSDecision(null, Command.INSTALL, DecisionFlag.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor4NaCType() { + new COPSDecision(CType.NA, Command.INSTALL, DecisionFlag.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor4NullCommand() { + new COPSDecision(CType.CSI, null, DecisionFlag.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor4NullFlags() { + new COPSDecision(CType.CSI, Command.INSTALL, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor5NullCType() { + final CType cType = null; + new COPSDecision(cType, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor5NaCType() { + new COPSDecision(CType.NA, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor5NullCommand() { + new COPSDecision(CType.CSI, null, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor5NullFlags() { + new COPSDecision(CType.CSI, Command.INSTALL, null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor5NullData() { + new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.NA, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor6NullHeader() { + final COPSObjHeader hdr = null; + new COPSDecision(hdr, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor6InvalidCNum() { + new COPSDecision(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), Command.INSTALL, DecisionFlag.NA, + new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor6NullCommand() { + new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), null, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor6NullDecison() { + new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), Command.INSTALL, null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor6NullData() { + new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), Command.INSTALL, DecisionFlag.NA, null); + } + + @Test + public void constructor1CommandInstall() throws Exception { + final COPSDecision decision = new COPSDecision(Command.INSTALL); + Assert.assertEquals(Command.INSTALL, decision.getCommand()); + Assert.assertEquals(4, decision.getDataLength()); + Assert.assertEquals(new COPSData(), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: INSTALL", lines[4]); + Assert.assertEquals("Command flags: NA", lines[5]); + } + + @Test + public void constructor1CommandRemove() throws Exception { + final COPSDecision decision = new COPSDecision(Command.REMOVE); + Assert.assertEquals(Command.REMOVE, decision.getCommand()); + Assert.assertEquals(4, decision.getDataLength()); + Assert.assertEquals(new COPSData(), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: REMOVE", lines[4]); + Assert.assertEquals("Command flags: NA", lines[5]); + } + + @Test + public void constructor2ValidCTypeEmptyData() throws Exception { + final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData()); + Assert.assertEquals(Command.NULL, decision.getCommand()); + Assert.assertEquals(4, decision.getDataLength()); + Assert.assertEquals(new COPSData(), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: NULL", lines[4]); + Assert.assertEquals("Command flags: NA", lines[5]); + } + + @Test + public void constructor2ValidCTypeDefUnpaddedData() throws Exception { + final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData("1234")); + Assert.assertEquals(Command.NULL, decision.getCommand()); + Assert.assertEquals(8, decision.getDataLength()); + Assert.assertEquals(new COPSData("1234"), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: NULL", lines[4]); + Assert.assertEquals("Command flags: NA", lines[5]); + } + + @Test + public void constructor2ValidCTypeDefPaddedData() throws Exception { + final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData("12345")); + Assert.assertEquals(Command.NULL, decision.getCommand()); + Assert.assertEquals(12, decision.getDataLength()); + Assert.assertEquals(new COPSData("12345"), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: NULL", lines[4]); + Assert.assertEquals("Command flags: NA", lines[5]); + } + + @Test + public void constructor2ValidCTypeNamedPaddedData() throws Exception { + final COPSDecision decision = new COPSDecision(CType.NAMED, new COPSData("12345")); + Assert.assertEquals(Command.NULL, decision.getCommand()); + Assert.assertEquals(12, decision.getDataLength()); + Assert.assertEquals(new COPSData("12345"), decision.getData()); + Assert.assertEquals(DecisionFlag.NA, decision.getFlag()); + Assert.assertEquals("Named decision data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: NAMED", lines[2]); + Assert.assertEquals("Decision (Named decision data)", lines[3]); + Assert.assertEquals("Data: 12345", lines[4]); + } + + @Test + public void constructor3Valid() throws Exception { + final COPSDecision decision = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR); + Assert.assertEquals(Command.INSTALL, decision.getCommand()); + Assert.assertEquals(4, decision.getDataLength()); + Assert.assertEquals(new COPSData(), decision.getData()); + Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag()); + Assert.assertEquals("Default", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Decision (Default)", lines[3]); + Assert.assertEquals("Command code: INSTALL", lines[4]); + Assert.assertEquals("Command flags: REQERROR", lines[5]); + } + + @Test + public void constructor4Valid() throws Exception { + final COPSDecision decision = new COPSDecision(CType.NAMED, Command.REMOVE, DecisionFlag.REQSTATE); + Assert.assertEquals(Command.REMOVE, decision.getCommand()); + Assert.assertEquals(4, decision.getDataLength()); + Assert.assertEquals(new COPSData(), decision.getData()); + Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag()); + Assert.assertEquals("Named decision data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: NAMED", lines[2]); + Assert.assertEquals("Decision (Named decision data)", lines[3]); + Assert.assertEquals("Data: ", lines[4]); + } + + @Test + public void constructor5Valid() throws Exception { + final COPSDecision decision = new COPSDecision(CType.CSI, Command.REMOVE, DecisionFlag.REQSTATE, + new COPSData("1234")); + Assert.assertEquals(Command.REMOVE, decision.getCommand()); + Assert.assertEquals(8, decision.getDataLength()); + Assert.assertEquals(new COPSData("1234"), decision.getData()); + Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag()); + Assert.assertEquals("Client specific decision data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: CSI", lines[2]); + Assert.assertEquals("Decision (Client specific decision data)", lines[3]); + Assert.assertEquals("Data: 1234", lines[4]); + } + + @Test + public void constructor6Valid() throws Exception { + final COPSDecision decision = new COPSDecision(new COPSObjHeader(CNum.DEC, CType.STATELESS), Command.INSTALL, + DecisionFlag.REQERROR, new COPSData("1234")); + Assert.assertEquals(Command.INSTALL, decision.getCommand()); + Assert.assertEquals(8, decision.getDataLength()); + Assert.assertEquals(new COPSData("1234"), decision.getData()); + Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag()); + Assert.assertEquals("Stateless data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Decision**", lines[0]); + Assert.assertEquals("C-num: DEC", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Decision (Stateless data)", lines[3]); + Assert.assertEquals("Data: 1234", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSErrorTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSErrorTest.java new file mode 100644 index 0000000..f7aafce --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSErrorTest.java @@ -0,0 +1,88 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSError.ErrorTypes; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSError class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSErrorTest { + + @Test(expected = IllegalArgumentException.class) + public void nullErrorCode() { + new COPSError(null, ErrorTypes.AUTH_FAILURE); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidErrorCode() { + new COPSError(ErrorTypes.NA, ErrorTypes.AUTH_FAILURE); + } + + @Test(expected = IllegalArgumentException.class) + public void nullErrorSubCode() { + new COPSError(ErrorTypes.AUTH_FAILURE, null); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSError(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ErrorTypes.AUTH_FAILURE, ErrorTypes.BAD_HANDLE); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSError(new COPSObjHeader(CNum.ERROR, CType.CSI), ErrorTypes.NA, ErrorTypes.BAD_HANDLE); + } + + @Test + public void valid1() throws Exception { + final COPSError error = new COPSError(ErrorTypes.BAD_HANDLE, ErrorTypes.NA); + Assert.assertEquals(ErrorTypes.BAD_HANDLE, error.getErrCode()); + Assert.assertEquals(ErrorTypes.NA, error.getErrSubCode()); + Assert.assertEquals(4, error.getDataLength()); + Assert.assertEquals("Bad handle.:", error.getDescription()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + error.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Error**", lines[0]); + Assert.assertEquals("C-num: ERROR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Error Code: BAD_HANDLE", lines[3]); + Assert.assertEquals("Error Sub Code: NA", lines[4]); + } + + @Test + public void valid2() throws Exception { + final COPSError error = new COPSError(ErrorTypes.AUTH_REQUIRED, ErrorTypes.FAIL_PROCESS); + Assert.assertEquals(ErrorTypes.AUTH_REQUIRED, error.getErrCode()); + Assert.assertEquals(ErrorTypes.FAIL_PROCESS, error.getErrSubCode()); + Assert.assertEquals(4, error.getDataLength()); + Assert.assertEquals("Authentication required.:", error.getDescription()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + error.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Error**", lines[0]); + Assert.assertEquals("C-num: ERROR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Error Code: AUTH_REQUIRED", lines[3]); + Assert.assertEquals("Error Sub Code: FAIL_PROCESS", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleFirstConstructorTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleFirstConstructorTest.java index c583081..e04b442 100644 --- a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleFirstConstructorTest.java +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleFirstConstructorTest.java @@ -20,9 +20,8 @@ public class COPSHandleFirstConstructorTest { public void constructWithDefaultId() { final COPSData id = new COPSData(); final COPSHandle handle = new COPSHandle(id); - Assert.assertEquals(4, handle.getDataLength()); + Assert.assertEquals(0, handle.getDataLength()); Assert.assertTrue(id.equals(handle.getId())); - validateSuperMethods(handle); final COPSHandle eqHash = new COPSHandle(id); Assert.assertTrue(handle.equals(eqHash)); @@ -31,33 +30,16 @@ public class COPSHandleFirstConstructorTest { @Test public void constructWithData() { - final COPSData id = new COPSData("12345678"); + final COPSData id = new COPSData("12345"); final COPSHandle handle = new COPSHandle(id); // TODO - need to determine if 12 is indeed correct given the value "123456778" - Assert.assertEquals(12, handle.getDataLength()); + Assert.assertEquals(8, handle.getDataLength()); Assert.assertTrue(id.equals(handle.getId())); - validateSuperMethods(handle); final COPSHandle eqHash = new COPSHandle(id); Assert.assertTrue(handle.equals(eqHash)); Assert.assertEquals(handle.hashCode(), eqHash.hashCode()); } - private void validateSuperMethods(final COPSHandle handle) { - Assert.assertTrue(handle.isClientHandle()); - Assert.assertFalse(handle.isMessageIntegrity()); - Assert.assertFalse(handle.isClientSI()); - Assert.assertFalse(handle.isContext()); - Assert.assertFalse(handle.isCOPSHeader()); - Assert.assertFalse(handle.isDecision()); - Assert.assertFalse(handle.isError()); - Assert.assertFalse(handle.isInterface()); - Assert.assertFalse(handle.isLocalDecision()); - Assert.assertFalse(handle.isPdpAddress()); - Assert.assertFalse(handle.isPepId()); - Assert.assertFalse(handle.isReason()); - Assert.assertFalse(handle.isReport()); - Assert.assertFalse(handle.isTimer()); - } } diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleSecondConstructorTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleSecondConstructorTest.java deleted file mode 100644 index c863f15..0000000 --- a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleSecondConstructorTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.umu.cops.stack; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for the second constructor of the COPSHandle class. - * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSHandle had been - * released and my assumptions may be incorrect. - */ -public class COPSHandleSecondConstructorTest { - - @Test(expected = IllegalArgumentException.class) - public void nullBytes() { - final byte[] bytes = null; - new COPSHandle(bytes); - } - - @Test(expected = IllegalArgumentException.class) - public void emptyBytes() { - new COPSHandle(new byte[]{}); - } - - @Test(expected = IllegalArgumentException.class) - public void oneByte() { - new COPSHandle(new byte[]{(byte)1}); - } - -// @Test - // TODO - Determine what values this byte array should contain??? As written, an exception is thrown in COPSData - // TODO - when attempting to set the _len attribute. - public void fourBytes() { - final byte[] bytes = new byte[]{(byte)1, (byte)2, (byte)3, (byte)4, (byte)5}; - final COPSHandle handle = new COPSHandle(bytes); - Assert.assertEquals(4, handle.getDataLength()); - Assert.fail("Implement me"); - } - - // TODO - implement more tests once we can determine how exactly to properly instantiate a COPSHandle object - -} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleTest.java new file mode 100644 index 0000000..6c2a5f3 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSHandleTest.java @@ -0,0 +1,141 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSHandle class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSHandle had been + * released and my assumptions may be incorrect. + */ +public class COPSHandleTest { + + private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.HANDLE, CType.DEF); + + @Test (expected = IllegalArgumentException.class) + public void constructWithNullId() { + final COPSData id = null; + new COPSHandle(id); + } + + @Test + public void constructWithDefaultId() { + final COPSData id = new COPSData(); + final COPSHandle handle = new COPSHandle(id); + + Assert.assertEquals(defaultHeader, handle.getHeader()); + Assert.assertEquals(0, handle.getDataLength()); + Assert.assertTrue(id.equals(handle.getId())); + + final COPSHandle eqHash = new COPSHandle(id); + Assert.assertTrue(handle.equals(eqHash)); + Assert.assertEquals(handle.hashCode(), eqHash.hashCode()); + } + + @Test + public void constructWithDataNoPadding() { + final COPSData id = new COPSData("12345678"); + final COPSHandle handle = new COPSHandle(id); + + Assert.assertEquals(defaultHeader, handle.getHeader()); + Assert.assertEquals(8, handle.getDataLength()); + Assert.assertTrue(id.equals(handle.getId())); + + final COPSHandle eqHash = new COPSHandle(id); + Assert.assertTrue(handle.equals(eqHash)); + Assert.assertEquals(handle.hashCode(), eqHash.hashCode()); + } + + @Test + public void constructWithDataWithPadding() { + final COPSData id = new COPSData("123456789"); + final COPSHandle handle = new COPSHandle(id); + + Assert.assertEquals(defaultHeader, handle.getHeader()); + Assert.assertEquals(12, handle.getDataLength()); + Assert.assertTrue(id.equals(handle.getId())); + + final COPSHandle eqHash = new COPSHandle(id); + Assert.assertTrue(handle.equals(eqHash)); + Assert.assertEquals(handle.hashCode(), eqHash.hashCode()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructWithNullHeader() { + new COPSHandle(null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructWithHeaderInvalidCNum() { + new COPSHandle(new COPSObjHeader(CNum.KA, CType.DEF), new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructWithHeaderInvalidCType() { + new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.REPL), new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructWithNullData() { + new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.DEF), null); + } + + @Test + public void constructWithHeaderValidCTypeAndDump() throws Exception { + final COPSHandle handle = new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.DEF), new COPSData()); + Assert.assertEquals(new COPSObjHeader(CNum.HANDLE, CType.DEF), handle.getHeader()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + handle.dump(os); + final String out = new String(os.toByteArray()); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Client-handle**", lines[0]); + Assert.assertEquals("C-num: HANDLE", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("client-handle: ", lines[3]); + System.out.println(out); + os.close(); + } + + @Test + public void dumpNoPadding() throws Exception { + final COPSHandle handle = new COPSHandle(new COPSData("12345678")); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + handle.dump(os); + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Client-handle**", lines[0]); + Assert.assertEquals("C-num: HANDLE", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("client-handle: 12345678", lines[3]); + os.close(); + } + + @Test + public void dumpWithPadding() throws Exception { + final COPSData id = new COPSData("123456789"); + final COPSHandle handle = new COPSHandle(id); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + handle.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Client-handle**", lines[0]); + Assert.assertEquals("C-num: HANDLE", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("client-handle: 123456789", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIntegrityTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIntegrityTest.java new file mode 100644 index 0000000..b24c433 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIntegrityTest.java @@ -0,0 +1,107 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSError class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIntegrityTest { + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSIntegrity(new COPSObjHeader(CNum.NA, CType.DEF), 0, 0, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.NA), 0, 0, new COPSData()); + } + + @Test + public void defaultConstructor() throws Exception { + final COPSIntegrity integrity = new COPSIntegrity(); + Assert.assertEquals(0, integrity.getKeyId()); + Assert.assertEquals(0, integrity.getSeqNum()); + Assert.assertEquals(new COPSData(), integrity.getKeyDigest()); + Assert.assertEquals(8, integrity.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + integrity.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Message-Integrity**", lines[0]); + Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Key Id: 0", lines[3]); + Assert.assertEquals("Sequence: 0", lines[4]); + Assert.assertEquals("Key digest: ", lines[5]); + } + + @Test + public void nullData() { + final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 1, 2, null); + Assert.assertEquals(1, integrity.getKeyId()); + Assert.assertEquals(2, integrity.getSeqNum()); + Assert.assertEquals(new COPSData(), integrity.getKeyDigest()); + } + + @Test + public void protectedConstructorNoPadding() throws Exception { + final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 5, 6, + new COPSData("1234")); + Assert.assertEquals(5, integrity.getKeyId()); + Assert.assertEquals(6, integrity.getSeqNum()); + Assert.assertEquals(new COPSData("1234"), integrity.getKeyDigest()); + Assert.assertEquals(12, integrity.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + integrity.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Message-Integrity**", lines[0]); + Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Key Id: 5", lines[3]); + Assert.assertEquals("Sequence: 6", lines[4]); + Assert.assertEquals("Key digest: 1234", lines[5]); + } + + @Test + public void protectedConstructorWithPadding() throws Exception { + final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 5, 6, + new COPSData("12345")); + Assert.assertEquals(5, integrity.getKeyId()); + Assert.assertEquals(6, integrity.getSeqNum()); + Assert.assertEquals(new COPSData("12345"), integrity.getKeyDigest()); + Assert.assertEquals(16, integrity.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + integrity.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Message-Integrity**", lines[0]); + Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Key Id: 5", lines[3]); + Assert.assertEquals("Sequence: 6", lines[4]); + Assert.assertEquals("Key digest: 12345", lines[5]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4AddressTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4AddressTest.java new file mode 100644 index 0000000..75f8333 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4AddressTest.java @@ -0,0 +1,36 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Tests for the COPSIpv4Address class. + */ +public class COPSIpv4AddressTest { + + @Test(expected = UnknownHostException.class) + public void badHost() throws Exception { + new COPSIpv4Address("foo"); + } + + @Test + public void localhost() throws Exception { + final COPSIpv4Address address = new COPSIpv4Address("localhost"); + Assert.assertEquals(4, address.getDataLength()); + Assert.assertArrayEquals(InetAddress.getByName("localhost").getAddress(), address.getAddressBytes()); + Assert.assertEquals("localhost", address.getIpName()); + } + + @Test + public void addrBytes() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + final COPSIpv4Address address = new COPSIpv4Address(addr); + Assert.assertEquals(4, address.getDataLength()); + Assert.assertArrayEquals(addr, address.getAddressBytes()); + Assert.assertEquals("localhost", address.getIpName()); + } + +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4InInterfaceTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4InInterfaceTest.java new file mode 100644 index 0000000..19c86f5 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4InInterfaceTest.java @@ -0,0 +1,66 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSIpv4InInterface class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv4InInterfaceTest { + + @Test(expected = IllegalArgumentException.class) + public void nullAddress() { + new COPSIpv4InInterface(null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullHeader() throws Exception { + new COPSIpv4InInterface(null, new COPSIpv4Address("localhost"), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddressWithHeader() { + new COPSIpv4InInterface(new COPSObjHeader(CNum.ININTF, CType.DEF), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSIpv4InInterface(new COPSObjHeader(CNum.HANDLE, CType.DEF), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSIpv4InInterface(new COPSObjHeader(CNum.ININTF, CType.STATELESS), null, 0); + } + + @Test + public void valid() throws Exception { + final COPSIpv4Address address = new COPSIpv4Address("localhost"); + final COPSIpv4InInterface intf = new COPSIpv4InInterface(address, 5); + Assert.assertEquals(new COPSObjHeader(CNum.ININTF, CType.DEF), intf.getHeader()); + Assert.assertEquals(8, intf.getDataLength()); + Assert.assertEquals(address, intf._addr); + Assert.assertEquals(5, intf._ifindex); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + intf.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**In-Interface**", lines[0]); + Assert.assertEquals("C-num: ININTF", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Address: localhost", lines[3]); + Assert.assertEquals("ifindex: 5", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4LastPdpAddrTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4LastPdpAddrTest.java new file mode 100644 index 0000000..c45ab10 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4LastPdpAddrTest.java @@ -0,0 +1,112 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Tests for the first constructor of the COPSIpv4LastPdpAddr class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv4LastPdpAddrTest { + + @Test(expected = IllegalArgumentException.class) + public void nullHost() throws Exception { + new COPSIpv4LastPdpAddr(null, 1234, (short)0); + } + + @Test(expected = UnknownHostException.class) + public void invalidHost() throws Exception { + new COPSIpv4LastPdpAddr("foo", 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidPort() throws Exception { + new COPSIpv4LastPdpAddr("localhost", 0, (short)0); + } + + @Test + public void validConstructor1() throws Exception { + final COPSIpv4LastPdpAddr lastAddr = new COPSIpv4LastPdpAddr("localhost", 1234, (short)0); + Assert.assertEquals(8, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Last PDP addr**", lines[0]); + Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Ipv4LastPdpAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + @Test(expected = IllegalArgumentException.class) + public void nullObjHeader() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4LastPdpAddr(null, addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddr() throws Exception { + new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), null, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void zeroPort() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), addr, 0, (short)0); + } + + @Test + public void validConstructor2() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + final COPSIpv4LastPdpAddr lastAddr = new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), + addr, 1234, (short)0); + Assert.assertEquals(8, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Last PDP addr**", lines[0]); + Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Ipv4LastPdpAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4OutInterfaceTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4OutInterfaceTest.java new file mode 100644 index 0000000..dd56ecc --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4OutInterfaceTest.java @@ -0,0 +1,66 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSIpv4OutInterfaceTest class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv4OutInterfaceTest { + + @Test(expected = IllegalArgumentException.class) + public void nullAddress() { + new COPSIpv4OutInterface(null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullHeader() throws Exception { + new COPSIpv4OutInterface(null, new COPSIpv4Address("localhost"), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddressWithHeader() { + new COPSIpv4OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.DEF), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSIpv4OutInterface(new COPSObjHeader(CNum.HANDLE, CType.DEF), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSIpv4OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), null, 0); + } + + @Test + public void valid() throws Exception { + final COPSIpv4Address address = new COPSIpv4Address("localhost"); + final COPSIpv4OutInterface intf = new COPSIpv4OutInterface(address, 5); + Assert.assertEquals(new COPSObjHeader(CNum.OUTINTF, CType.DEF), intf.getHeader()); + Assert.assertEquals(8, intf.getDataLength()); + Assert.assertEquals(address, intf._addr); + Assert.assertEquals(5, intf._ifindex); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + intf.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Out-Interface**", lines[0]); + Assert.assertEquals("C-num: OUTINTF", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Address: localhost", lines[3]); + Assert.assertEquals("ifindex: 5", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddressTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddressTest.java new file mode 100644 index 0000000..30f6e11 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv4PdpRedirectAddressTest.java @@ -0,0 +1,112 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Tests for the first constructor of the COPSIpv4PdpRedirectAddress class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv4PdpRedirectAddressTest { + + @Test(expected = IllegalArgumentException.class) + public void nullHost() throws Exception { + new COPSIpv4PdpRedirectAddress(null, 1234, (short)0); + } + + @Test(expected = UnknownHostException.class) + public void invalidHost() throws Exception { + new COPSIpv4PdpRedirectAddress("foo", 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidPort() throws Exception { + new COPSIpv4PdpRedirectAddress("localhost", 0, (short)0); + } + + @Test + public void validConstructor1() throws Exception { + final COPSIpv4PdpRedirectAddress lastAddr = new COPSIpv4PdpRedirectAddress("localhost", 1234, (short)0); + Assert.assertEquals(8, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Redirect PDP addr**", lines[0]); + Assert.assertEquals("C-num: PDP_REDIR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Ipv4PdpRedirectAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + @Test(expected = IllegalArgumentException.class) + public void nullObjHeader() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4PdpRedirectAddress(null, addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddr() throws Exception { + new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), null, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void zeroPort() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), addr, 0, (short)0); + } + + @Test + public void validConstructor2() throws Exception { + final byte[] addr = InetAddress.getByName("localhost").getAddress(); + final COPSIpv4PdpRedirectAddress lastAddr = new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), + addr, 1234, (short)0); + Assert.assertEquals(8, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Redirect PDP addr**", lines[0]); + Assert.assertEquals("C-num: PDP_REDIR", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Ipv4PdpRedirectAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6AddressTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6AddressTest.java new file mode 100644 index 0000000..7c8fefa --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6AddressTest.java @@ -0,0 +1,47 @@ +package org.umu.cops.stack; + +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 for the COPSIpv6Address class. + */ +public class COPSIpv6AddressTest { + + @Test(expected = UnknownHostException.class) + public void badHost() throws Exception { + new COPSIpv6Address("foo"); + } + + @Test + public void localhost() throws Exception { + final COPSIpv6Address address = new COPSIpv6Address("localhost"); + Assert.assertEquals(16, address.getDataLength()); + Assert.assertArrayEquals(getLocalhostIpv6Address(), address.getAddressBytes()); + Assert.assertEquals("localhost", address.getIpName()); + } + + @Test + public void addrBytes() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + final COPSIpv6Address address = new COPSIpv6Address(addr); + Assert.assertEquals(16, address.getDataLength()); + Assert.assertArrayEquals(addr, address.getAddressBytes()); + Assert.assertEquals("localhost", address.getIpName()); + } + + private byte[] getLocalhostIpv6Address() throws UnknownHostException { + final InetAddress[] addrs = Inet4Address.getAllByName("localhost"); + for (final InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + return addr.getAddress(); + } + } + throw new UnknownHostException("InetAddress could not be found"); + } +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6InInterfaceTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6InInterfaceTest.java new file mode 100644 index 0000000..afa9c85 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6InInterfaceTest.java @@ -0,0 +1,66 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSIpv6InInterface class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv6InInterfaceTest { + + @Test(expected = IllegalArgumentException.class) + public void nullAddress() { + new COPSIpv6InInterface(null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullHeader() throws Exception { + new COPSIpv6InInterface(null, new COPSIpv6Address("localhost"), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddressWithHeader() { + new COPSIpv6InInterface(new COPSObjHeader(CNum.ININTF, CType.STATELESS), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSIpv6InInterface(new COPSObjHeader(CNum.HANDLE, CType.STATELESS), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSIpv6InInterface(new COPSObjHeader(CNum.ININTF, CType.DEF), null, 0); + } + + @Test + public void valid() throws Exception { + final COPSIpv6Address address = new COPSIpv6Address("localhost"); + final COPSIpv6InInterface intf = new COPSIpv6InInterface(address, 5); + Assert.assertEquals(new COPSObjHeader(CNum.ININTF, CType.STATELESS), intf.getHeader()); + Assert.assertEquals(20, intf.getDataLength()); + Assert.assertEquals(address, intf._addr); + Assert.assertEquals(5, intf._ifindex); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + intf.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**In-Interface**", lines[0]); + Assert.assertEquals("C-num: ININTF", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Address: localhost", lines[3]); + Assert.assertEquals("ifindex: 5", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6LastPdpAddrTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6LastPdpAddrTest.java new file mode 100644 index 0000000..494635e --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6LastPdpAddrTest.java @@ -0,0 +1,130 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Tests for the first constructor of the COPSIpv6PdpRedirectAddress class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv6LastPdpAddrTest { + + @Test(expected = IllegalArgumentException.class) + public void nullHost() throws Exception { + new COPSIpv6LastPdpAddr(null, 1234, (short)0); + } + + @Test(expected = UnknownHostException.class) + public void invalidHost() throws Exception { + new COPSIpv6LastPdpAddr("foo", 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidPort() throws Exception { + new COPSIpv6LastPdpAddr("localhost", 0, (short)0); + } + + @Test + public void validConstructor1() throws Exception { + final COPSIpv6LastPdpAddr lastAddr = new COPSIpv6LastPdpAddr("localhost", 1234, (short)0); + Assert.assertEquals(20, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Last PDP addr**", lines[0]); + Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Ipv6LastPdpAddr", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + @Test(expected = IllegalArgumentException.class) + public void nullObjHeader() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6LastPdpAddr(null, addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.ACCT_TIMER, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddr() throws Exception { + new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), null, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void ipv4Addr() throws Exception { + final byte[] addr = new byte[] { 127, 0, 0, 1}; + new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void zeroPort() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 0, (short)0); + } + + @Test + public void validConstructor2() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + final COPSIpv6LastPdpAddr lastAddr = new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, + CType.STATELESS), addr, 1234, (short)0); + Assert.assertEquals(20, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Last PDP addr**", lines[0]); + Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Ipv6LastPdpAddr", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests + + private byte[] getLocalhostIpv6Address() throws UnknownHostException { + final InetAddress[] addrs = Inet4Address.getAllByName("localhost"); + for (final InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + return addr.getAddress(); + } + } + throw new UnknownHostException("InetAddress could not be found"); + } +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6OutInterfaceTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6OutInterfaceTest.java new file mode 100644 index 0000000..e6181cf --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6OutInterfaceTest.java @@ -0,0 +1,66 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSIpv6OutInterfaceTest class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv6OutInterfaceTest { + + @Test(expected = IllegalArgumentException.class) + public void nullAddress() { + new COPSIpv6OutInterface(null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullHeader() throws Exception { + new COPSIpv6OutInterface(null, new COPSIpv6Address("localhost"), 0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddressWithHeader() { + new COPSIpv6OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSIpv6OutInterface(new COPSObjHeader(CNum.HANDLE, CType.STATELESS), null, 0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSIpv6OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.DEF), null, 0); + } + + @Test + public void valid() throws Exception { + final COPSIpv6Address address = new COPSIpv6Address("localhost"); + final COPSIpv6OutInterface intf = new COPSIpv6OutInterface(address, 5); + Assert.assertEquals(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), intf.getHeader()); + Assert.assertEquals(20, intf.getDataLength()); + Assert.assertEquals(address, intf._addr); + Assert.assertEquals(5, intf._ifindex); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + intf.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Out-Interface**", lines[0]); + Assert.assertEquals("C-num: OUTINTF", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Address: localhost", lines[3]); + Assert.assertEquals("ifindex: 5", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddressTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddressTest.java new file mode 100644 index 0000000..e6c8a42 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSIpv6PdpRedirectAddressTest.java @@ -0,0 +1,130 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * Tests for the first constructor of the COPSIpv6PdpRedirectAddress class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSIpv6PdpRedirectAddressTest { + + @Test(expected = IllegalArgumentException.class) + public void nullHost() throws Exception { + new COPSIpv6PdpRedirectAddress(null, 1234, (short)0); + } + + @Test(expected = UnknownHostException.class) + public void invalidHost() throws Exception { + new COPSIpv6PdpRedirectAddress("foo", 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidPort() throws Exception { + new COPSIpv6PdpRedirectAddress("localhost", 0, (short)0); + } + + @Test + public void validConstructor1() throws Exception { + final COPSIpv6PdpRedirectAddress lastAddr = new COPSIpv6PdpRedirectAddress("localhost", 1234, (short)0); + Assert.assertEquals(20, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Redirect PDP addr**", lines[0]); + Assert.assertEquals("C-num: PDP_REDIR", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Ipv6PdpRedirectAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + @Test(expected = IllegalArgumentException.class) + public void nullObjHeader() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6PdpRedirectAddress(null, addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.ACCT_TIMER, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void nullAddr() throws Exception { + new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), null, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void ipv4Addr() throws Exception { + final byte[] addr = new byte[] { 127, 0, 0, 1}; + new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 1234, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void zeroPort() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 0, (short)0); + } + + @Test + public void validConstructor2() throws Exception { + final byte[] addr = getLocalhostIpv6Address(); + final COPSIpv6PdpRedirectAddress lastAddr = new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, + CType.STATELESS), addr, 1234, (short)0); + Assert.assertEquals(20, lastAddr.getDataLength()); + Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), lastAddr.getHeader()); + Assert.assertEquals(1234, lastAddr.getTcpPort()); + Assert.assertEquals(0, lastAddr.getReserved()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + lastAddr.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(6, lines.length); + Assert.assertEquals("**Redirect PDP addr**", lines[0]); + Assert.assertEquals("C-num: PDP_REDIR", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Ipv6PdpRedirectAddress", lines[3]); + Assert.assertEquals("Address: localhost", lines[4]); + Assert.assertEquals("Port: 1234", lines[5]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests + + private byte[] getLocalhostIpv6Address() throws UnknownHostException { + final InetAddress[] addrs = Inet4Address.getAllByName("localhost"); + for (final InetAddress addr : addrs) { + if (addr instanceof Inet6Address) { + return addr.getAddress(); + } + } + throw new UnknownHostException("InetAddress could not be found"); + } +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSKATimerTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSKATimerTest.java new file mode 100644 index 0000000..9d896ab --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSKATimerTest.java @@ -0,0 +1,84 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSKATimer class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSKATimer had been + * released and my assumptions may be incorrect. + */ +public class COPSKATimerTest { + + private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.KA, CType.DEF); + + @Test + public void testValidTimeAndDefaultHeader() { + final COPSKATimer timer = new COPSKATimer((short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(defaultHeader, timer.getHeader()); + } + + @Test + public void testValidTimeReservedAndDefaultHeader() { + final COPSKATimer timer = new COPSKATimer((short) 4, (short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(defaultHeader, timer.getHeader()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidCNum() { + new COPSKATimer(new COPSObjHeader(CNum.CONTEXT, CType.DEF), (short) 4, (short)10); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidCType() { + new COPSKATimer(new COPSObjHeader(CNum.KA, CType.REPL), (short) 4, (short)10); + } + + @Test + public void testValidCustomHeader() { + final COPSKATimer timer = new COPSKATimer(new COPSObjHeader(CNum.KA, CType.DEF), (short) 4, (short)10); + Assert.assertEquals((short)10, timer.getTimerVal()); + Assert.assertEquals(new COPSObjHeader(CNum.KA, CType.DEF), timer.getHeader()); + } + + @Test + public void testDumpDefaultHeader() throws Exception { + final COPSKATimer timer = new COPSKATimer((short) 4, (short)10); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + timer.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**KA-timer**", lines[0]); + Assert.assertEquals("C-num: KA", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Timer val: 10", lines[3]); + } + + @Test + public void testDumpCustomHeader() throws Exception { + final COPSKATimer timer = new COPSKATimer(new COPSObjHeader(CNum.KA, CType.DEF), + (short) 4, (short)100); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + timer.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**KA-timer**", lines[0]); + Assert.assertEquals("C-num: KA", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Timer val: 100", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSLPDPDecisionTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSLPDPDecisionTest.java new file mode 100644 index 0000000..3590702 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSLPDPDecisionTest.java @@ -0,0 +1,121 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSDecision.Command; +import org.umu.cops.stack.COPSDecision.DecisionFlag; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSLPDPDecision class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSLPDPDecisionTest { + + @Test(expected = IllegalArgumentException.class) + public void constructor1NullCType() { + final CType cType = null; + new COPSLPDPDecision(cType, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor1NaCType() { + new COPSLPDPDecision(CType.NA, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor1NullCommand() { + new COPSLPDPDecision(CType.CSI, null, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor1NullFlags() { + new COPSLPDPDecision(CType.CSI, Command.INSTALL, null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor1NullData() { + new COPSLPDPDecision(CType.CSI, Command.INSTALL, DecisionFlag.NA, null); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullHeader() { + final COPSObjHeader hdr = null; + new COPSLPDPDecision(hdr, Command.INSTALL, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2InvalidCNum() { + new COPSLPDPDecision(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), Command.INSTALL, DecisionFlag.NA, + new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullCommand() { + new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), null, DecisionFlag.NA, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullDecison() { + new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), Command.INSTALL, null, new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void constructor2NullData() { + new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), Command.INSTALL, DecisionFlag.NA, null); + } + + @Test + public void constructor1Valid() throws Exception { + final COPSLPDPDecision decision = new COPSLPDPDecision(CType.CSI, Command.REMOVE, DecisionFlag.REQSTATE, + new COPSData("1234")); + Assert.assertEquals(Command.REMOVE, decision.getCommand()); + Assert.assertEquals(8, decision.getDataLength()); + Assert.assertEquals(new COPSData("1234"), decision.getData()); + Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag()); + Assert.assertEquals("Client specific decision data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Local-Decision**", lines[0]); + Assert.assertEquals("C-num: LPDP_DEC", lines[1]); + Assert.assertEquals("C-type: CSI", lines[2]); + Assert.assertEquals("Decision (Client specific decision data)", lines[3]); + Assert.assertEquals("Data: 1234", lines[4]); + } + + @Test + public void constructor2Valid() throws Exception { + final COPSLPDPDecision decision = new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.STATELESS), Command.INSTALL, + DecisionFlag.REQERROR, new COPSData("1234")); + Assert.assertEquals(Command.INSTALL, decision.getCommand()); + Assert.assertEquals(8, decision.getDataLength()); + Assert.assertEquals(new COPSData("1234"), decision.getData()); + Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag()); + Assert.assertEquals("Stateless data", decision.getTypeStr()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + decision.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Local-Decision**", lines[0]); + Assert.assertEquals("C-num: LPDP_DEC", lines[1]); + Assert.assertEquals("C-type: STATELESS", lines[2]); + Assert.assertEquals("Decision (Stateless data)", lines[3]); + Assert.assertEquals("Data: 1234", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSPepIdTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSPepIdTest.java new file mode 100644 index 0000000..b3aa875 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSPepIdTest.java @@ -0,0 +1,94 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSPepId class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSPepIdTest { + + + @Test(expected = IllegalArgumentException.class) + public void nullData() { + new COPSPepId(null); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSPepId(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), new COPSData()); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSPepId(new COPSObjHeader(CNum.PEPID, CType.CSI), new COPSData()); + } + + @Test + public void emptyData() throws Exception { + final COPSPepId pepId = new COPSPepId(new COPSData()); + Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum()); + Assert.assertEquals(new COPSData(), pepId.getData()); + Assert.assertEquals(0, pepId.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + pepId.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**PEP-id**", lines[0]); + Assert.assertEquals("C-num: PEPID", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("PEPID: ", lines[3]); + } + + @Test + public void unpaddedData() throws Exception { + final COPSPepId pepId = new COPSPepId(new COPSData("1234")); + Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum()); + Assert.assertEquals(new COPSData("1234"), pepId.getData()); + Assert.assertEquals(4, pepId.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + pepId.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**PEP-id**", lines[0]); + Assert.assertEquals("C-num: PEPID", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("PEPID: 1234", lines[3]); + } + + @Test + public void paddedData() throws Exception { + final COPSPepId pepId = new COPSPepId(new COPSData("12345")); + Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum()); + Assert.assertEquals(new COPSData("12345"), pepId.getData()); + Assert.assertEquals(8, pepId.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + pepId.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**PEP-id**", lines[0]); + Assert.assertEquals("C-num: PEPID", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("PEPID: 12345", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReasonTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReasonTest.java new file mode 100644 index 0000000..dd90344 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReasonTest.java @@ -0,0 +1,88 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSReason.ReasonCode; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSReason class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSReasonTest { + + @Test(expected = IllegalArgumentException.class) + public void nullReasonCode() { + new COPSReason(null, ReasonCode.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidReasonCode() { + new COPSReason(ReasonCode.NA, ReasonCode.MALFORMED_DEC); + } + + @Test(expected = IllegalArgumentException.class) + public void nullSubCode() { + new COPSReason(ReasonCode.MANAGEMENT, null); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSReason(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ReasonCode.ROUTE_CHANGE, ReasonCode.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSReason(new COPSObjHeader(CNum.REASON_CODE, CType.CSI), ReasonCode.PREEMPTED, ReasonCode.SYNC_HANDLE); + } + + @Test + public void valid1() throws Exception { + final COPSReason reason = new COPSReason(ReasonCode.TRANS_HANDLE, ReasonCode.NA); + Assert.assertEquals(ReasonCode.TRANS_HANDLE, reason.getReasonCode()); + Assert.assertEquals(ReasonCode.NA, reason.getReasonSubCode()); + Assert.assertEquals(4, reason.getDataLength()); + Assert.assertEquals("Transient handle.:", reason.getDescription()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reason.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Reason**", lines[0]); + Assert.assertEquals("C-num: REASON_CODE", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Reason Code: TRANS_HANDLE", lines[3]); + Assert.assertEquals("Reason Sub Code: NA", lines[4]); + } + + @Test + public void valid2() throws Exception { + final COPSReason reason = new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.TEAR); + Assert.assertEquals(ReasonCode.INSUFF_RESOURCES, reason.getReasonCode()); + Assert.assertEquals(ReasonCode.TEAR, reason.getReasonSubCode()); + Assert.assertEquals(4, reason.getDataLength()); + Assert.assertEquals("Insufficient Resources.:", reason.getDescription()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reason.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(5, lines.length); + Assert.assertEquals("**Reason**", lines[0]); + Assert.assertEquals("C-num: REASON_CODE", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Reason Code: INSUFF_RESOURCES", lines[3]); + Assert.assertEquals("Reason Sub Code: TEAR", lines[4]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} diff --git a/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReportTypeTest.java b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReportTypeTest.java new file mode 100644 index 0000000..ab89ce0 --- /dev/null +++ b/packetcable-driver/src/test/java/org/umu/cops/stack/COPSReportTypeTest.java @@ -0,0 +1,96 @@ +package org.umu.cops.stack; + +import org.junit.Assert; +import org.junit.Test; +import org.umu.cops.stack.COPSObjHeader.CNum; +import org.umu.cops.stack.COPSObjHeader.CType; +import org.umu.cops.stack.COPSReportType.ReportType; + +import java.io.ByteArrayOutputStream; + +/** + * Tests for the first constructor of the COPSReportType class. + * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been + * released and my assumptions may be incorrect. + */ +public class COPSReportTypeTest { + + @Test(expected = IllegalArgumentException.class) + public void nullReportType() { + new COPSReportType(null); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidReportType() { + new COPSReportType(ReportType.NA); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCNum() { + new COPSReportType(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ReportType.ACCOUNTING, (short)0); + } + + @Test(expected = IllegalArgumentException.class) + public void invalidCType() { + new COPSReportType(new COPSObjHeader(CNum.RPT, CType.CSI), ReportType.FAILURE, (short)0); + } + + @Test + public void validSuccessRpt() throws Exception { + final COPSReportType reason = new COPSReportType(ReportType.SUCCESS); + Assert.assertEquals(ReportType.SUCCESS, reason.getReportType()); + Assert.assertEquals(4, reason.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reason.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Report**", lines[0]); + Assert.assertEquals("C-num: RPT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Report: Success.", lines[3]); + } + + @Test + public void validFailureRpt() throws Exception { + final COPSReportType reason = new COPSReportType(ReportType.FAILURE); + Assert.assertEquals(ReportType.FAILURE, reason.getReportType()); + Assert.assertEquals(4, reason.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reason.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Report**", lines[0]); + Assert.assertEquals("C-num: RPT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Report: Failure.", lines[3]); + } + + @Test + public void validAccountingRpt() throws Exception { + final COPSReportType reason = new COPSReportType(ReportType.ACCOUNTING); + Assert.assertEquals(ReportType.ACCOUNTING, reason.getReportType()); + Assert.assertEquals(4, reason.getDataLength()); + + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reason.dump(os); + + final String out = new String(os.toByteArray()); + System.out.println(out); + final String[] lines = out.split("\n"); + Assert.assertEquals(4, lines.length); + Assert.assertEquals("**Report**", lines[0]); + Assert.assertEquals("C-num: RPT", lines[1]); + Assert.assertEquals("C-type: DEF", lines[2]); + Assert.assertEquals("Report: Accounting.", lines[3]); + } + + // The writeData() method will be tested implicitly via any of the COPSMsg tests +} -- 2.36.6