<classifier>features</classifier>
<type>xml</type>
</dependency>
- <dependency>
- <groupId>org.opendaylight.openflowplugin</groupId>
- <artifactId>features-openflowplugin</artifactId>
- <version>0.0.3-SNAPSHOT</version>
- <classifier>features</classifier>
- <type>xml</type>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>features-flow</artifactId>
<artifactId>packetcable-model</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.packetcable</groupId>
+ <artifactId>packetcable-driver</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!--
- Necessary TODO: Put dependencies for configfiles directly referenced
+ Put dependencies for configfiles directly referenced
in your features.xml file. For every <configfile> reference in your
features.xml file, you need a corresponding dependency here.
<feature version='${project.version}'>odl-packetcable-consumer</feature>
<feature version='${project.version}'>odl-packetcable-provider</feature>
<feature version='${project.version}'>odl-packetcable-model</feature>
+ <feature version='${project.version}'>odl-packetcable-driver</feature>
</feature>
<!--
Define your features. It is useful to list then in order of dependency. So if A depends on B, list A first.
<feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-packetcable-model</feature>
<feature version='${project.version}'>odl-packetcable-provider</feature>
- <bundle>mvn:org.opendaylight.controller.packetcable/packetcable-consumer/${project.version}</bundle>
+ <feature version='${project.version}'>odl-packetcable-driver</feature>
</feature>
<!--- * Basic MD-SAL Model feature -->
<feature name='odl-packetcable-model' version='${project.version}' description='OpenDaylight :: packetcable :: Model'>
<feature version='0.6.2-SNAPSHOT'>odl-yangtools-binding</feature>
<feature version='0.6.2-SNAPSHOT'>odl-yangtools-models</feature>
- <!--feature version='0.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature-->
-<feature version='${project.version}'>odl-flow-model</feature>
+ <feature version='${project.version}'>odl-flow-model</feature>
<bundle>mvn:org.opendaylight.controller.packetcable/packetcable-model/${project.version}</bundle>
</feature>
<feature name='odl-packetcable-provider' version='${project.version}' description='OpenDaylight :: packetcable :: Provider'>
<feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
<bundle>mvn:org.opendaylight.controller.packetcable/packetcable-provider/${project.version}</bundle>
- <!--feature version='0.0.3-SNAPSHOT'>odl-openflowplugin-flow-services</feature-->
-<feature version='${project.version}'>odl-flow-model</feature>
+ <bundle>mvn:org.opendaylight.controller.packetcable/packetcable-driver/${project.version}</bundle>
+ <feature version='${project.version}'>odl-flow-model</feature>
<feature version='${project.version}'>odl-packetcable-model</feature>
+ <feature version='${project.version}'>odl-packetcable-driver</feature>
</feature>
+ <!--- * * -->
+ <feature name='odl-packetcable-driver' version='${project.version}' description='OpenDaylight :: packetcable :: Driver'>
+ <feature version='1.1-SNAPSHOT'>odl-mdsal-broker</feature>
+ </feature>
+
</features>
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>packetcable-driver</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
</dependency>
--- /dev/null
+package org.opendaylight.controller.config.yang.config.pcmm_service.impl;
+
+import org.opendaylight.controller.org.pcmm.api.PcmmService;
+import org.opendaylight.controller.org.pcmm.impl.PcmmServiceImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.PacketcableServiceService;
+import org.opendaylight.yangtools.concepts.Registration;
+
+public class PcmmServiceModule
+ extends
+ org.opendaylight.controller.config.yang.config.pcmm_service.impl.AbstractPcmmServiceModule {
+ public PcmmServiceModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public PcmmServiceModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.pcmm_service.impl.PcmmServiceModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ PacketcableServiceService packetcableServiceService = getRpcRegistryDependency().getRpcService(PacketcableServiceService.class);
+ final PcmmService pcmmService = new PcmmServiceImpl(packetcableServiceService);
+ final Registration pcmmListenerReg = getNotificationServiceDependency().registerNotificationListener(pcmmService);
+ final PcmmServiceRuntimeRegistration runtimeReg = getRootRuntimeBeanRegistratorWrapper().register(pcmmService);
+ return new AutoCloseablePcmmService(packetcableServiceService, pcmmListenerReg, runtimeReg);
+ }
+
+ class AutoCloseablePcmmService extends PcmmServiceImpl implements
+ AutoCloseable {
+
+ private PcmmServiceRuntimeRegistration runtimeReg;
+ private Registration pcmmListenerReg;
+
+ public AutoCloseablePcmmService(PacketcableServiceService packetcableServiceService, Registration pcmmListenerReg, PcmmServiceRuntimeRegistration runtimeReg) {
+ super(packetcableServiceService);
+ this.runtimeReg = runtimeReg;
+ this.pcmmListenerReg = pcmmListenerReg;
+ }
+
+ @Override
+ public void close() throws Exception {
+ pcmmListenerReg.close();
+ runtimeReg.close();
+ }
+
+ }
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: pcmm-service-impl yang module local name: pcmm-service-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon Aug 11 19:34:09 CEST 2014
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.pcmm_service.impl;
+public class PcmmServiceModuleFactory extends org.opendaylight.controller.config.yang.config.pcmm_service.impl.AbstractPcmmServiceModuleFactory {
+
+}
--- /dev/null
+package org.opendaylight.controller.org.pcmm.api;
+
+import org.opendaylight.controller.config.yang.config.pcmm_service.impl.PcmmServiceRuntimeMXBean;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.PacketcableServiceListener;
+
+public interface PcmmService extends PcmmServiceRuntimeMXBean,
+ PacketcableServiceListener {
+
+}
--- /dev/null
+package org.opendaylight.controller.org.pcmm.impl;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+
+import org.opendaylight.controller.org.pcmm.api.PcmmService;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.node.cmts.rev140120.CmtsReference;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.CmtsUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.packetcable.service.rev140120.PacketcableServiceService;
+import org.pcmm.rcd.IPCMMPolicyServer;
+import org.pcmm.rcd.IPCMMPolicyServer.IPSCMTSClient;
+import org.pcmm.rcd.impl.PCMMPolicyServer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class PcmmServiceImpl implements PcmmService {
+
+ private static final Logger log = LoggerFactory.getLogger(PcmmServiceImpl.class);
+ private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+ private PacketcableServiceService packetcableServiceService;
+ private List<IpAddress> cmtsList;
+ private Map<CmtsReference, IPSCMTSClient> cmtsClients;
+ private IPCMMPolicyServer policyServer;
+
+ public PcmmServiceImpl(PacketcableServiceService packetcableServiceService) {
+ this.packetcableServiceService = packetcableServiceService;
+ policyServer = new PCMMPolicyServer();
+ cmtsClients = Maps.newConcurrentMap();
+ cmtsList = Lists.newArrayList();
+ }
+
+ @Override
+ public void onCmtsAdded(CmtsAdded notification) {
+ String ipv4 = notification.getId().getIpv4Address().getValue();
+ IPSCMTSClient client = policyServer.requestCMTSConnection(ipv4);
+ if (client.isConnected()) {
+ cmtsClients.put(notification.getCmtsRef(), client);
+ cmtsList.add(notification.getId());
+ }
+ }
+
+ @Override
+ public void onCmtsRemoved(CmtsRemoved notification) {
+ if (cmtsList.contains(notification.getId()))
+ cmtsList.remove(notification.getId());
+ if (cmtsClients.containsKey(notification.getCmtsRef())) {
+ IPSCMTSClient client = cmtsClients.remove(notification.getCmtsRef());
+ client.disconnect();
+ }
+ }
+
+ @Override
+ public void onCmtsUpdated(CmtsUpdated notification) {
+ // TODO
+ }
+
+ @Override
+ public Boolean sendGateDelete() {
+ // TODO change me
+ boolean ret = true;
+ for (Iterator<IPSCMTSClient> iter = cmtsClients.values().iterator(); iter.hasNext();)
+ ret &= cmtsClients.get(0).gateDelete();
+ return ret;
+ }
+
+ @Override
+ public Boolean sendGateSynchronize() {
+ boolean ret = true;
+ for (Iterator<IPSCMTSClient> iter = cmtsClients.values().iterator(); iter.hasNext();)
+ ret &= cmtsClients.get(0).gateSynchronize();
+ return ret;
+ }
+
+ @Override
+ public Boolean sendGateInfo() {
+ boolean ret = true;
+ for (Iterator<IPSCMTSClient> iter = cmtsClients.values().iterator(); iter.hasNext();)
+ ret &= cmtsClients.get(0).gateInfo();
+ return ret;
+ }
+
+ @Override
+ public Boolean sendGateSet() {
+ boolean ret = true;
+ for (Iterator<IPSCMTSClient> iter = cmtsClients.values().iterator(); iter.hasNext();)
+ ret &= cmtsClients.get(0).gateSet();
+ return ret;
+ }
+}
--- /dev/null
+module pcmm-service-impl {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:pcmm-service:impl";
+ prefix "pcmm-service-impl";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+ description
+ "This module contains the base YANG definitions for
+ pcmm-service impl implementation.";
+
+ revision "2014-08-10" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of pcmm service interface identity.
+ identity pcmm-service {
+ base "config:service-type";
+ config:java-class "org.opendaylight.controller.org.pcmm.api.PcmmService";
+ }
+
+ // This is the definition of pcmm service implementation module identity.
+ identity pcmm-service-impl {
+ base config:module-type;
+ config:provided-service pcmm-service;
+ config:java-name-prefix PcmmService;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case pcmm-service-impl {
+ when "/config:modules/config:module/config:type = 'pcmm-service-impl'";
+
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-rpc-registry;
+ }
+ }
+ }
+
+ container notification-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-notification-service;
+ }
+ }
+ }
+ }
+ }
+
+ augment "/config:modules/config:module/config:state" {
+ case pcmm-service-impl {
+ when "/config:modules/config:module/config:type = 'pcmm-service-impl'";
+
+ rpcx:rpc-context-instance "send-gate-set-rpc";
+ rpcx:rpc-context-instance "send-gate-delete-rpc";
+ rpcx:rpc-context-instance "send-gate-info-rpc";
+ rpcx:rpc-context-instance "send-gate-synchronize-rpc";
+
+ }
+ }
+
+ identity send-gate-set-rpc;
+
+ rpc send-gate-set {
+ description
+ "Shortcut JMX call to send a gate-set message for testing.";
+
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance send-gate-set-rpc;
+ }
+ }
+ }
+
+ output {
+ leaf result {
+ type boolean;
+ }
+ }
+ }
+
+ identity send-gate-delete-rpc;
+
+ rpc send-gate-delete {
+ description
+ "Shortcut JMX call to send a gate-delete message for testing.";
+
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance send-gate-delete-rpc;
+ }
+ }
+ }
+
+ output {
+ leaf result {
+ type boolean;
+ }
+ }
+ }
+
+ identity send-gate-synchronize-rpc;
+
+ rpc send-gate-synchronize {
+ description
+ "Shortcut JMX call to send a gate-Synchronize message for testing.";
+
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance send-gate-synchronize-rpc;
+ }
+ }
+ }
+
+ output {
+ leaf result {
+ type boolean;
+ }
+ }
+ }
+
+ identity send-gate-info-rpc;
+
+ rpc send-gate-info {
+ description
+ "Shortcut JMX call to send a gate-info message for testing.";
+
+ input {
+ uses rpcx:rpc-context-ref {
+ refine context-instance {
+ rpcx:rpc-context-instance send-gate-info-rpc;
+ }
+ }
+ }
+
+ output {
+ leaf result {
+ type boolean;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+# define compiler and compiler flag variables
+
+JFLAGS = -g
+JC = javac
+JUNIT=/usr/share/junit/junit.jar
+JCOPS=src/main/java/jcops.jar
+PCMM=src/main/java/pcmm.jar
+CLASSPATH = -classpath .:$(PCMM):$(JCOPS):$(JUNIT)
+JFLAGS = -encoding UTF-8 $(CLASSPATH)
+JAR_PKG = Test.jar
+
+
+#
+# Clear any default targets for building .class files from .java files; we
+# will provide our own target entry to do this in this makefile.
+# make has a set of default targets for different suffixes (like .c.o)
+# Currently, clearing the default for .java.class is not necessary since
+# make does not have a definition for this target, but later versions of
+# make may, so it doesn't hurt to make sure that we clear any default
+# definitions for these
+#
+
+.SUFFIXES: .java .class
+
+
+#
+# Here is our target entry for creating .class files from .java files
+# This is a target entry that uses the suffix rule syntax:
+# DSTS:
+# rule
+# 'TS' is the suffix of the target file, 'DS' is the suffix of the dependency
+# file, and 'rule' is the rule for building a target
+# '$*' is a built-in macro that gets the basename of the current target
+# Remember that there must be a < tab > before the command line ('rule')
+#
+
+.java.class:
+ $(JC) $(JFLAGS) $*.java
+
+
+#
+# CLASSES is a macro consisting of 4 words (one for each java source file)
+#
+
+SOURCES = \
+ Main.java \
+ Test.java
+
+
+CLASSES = $(SOURCES:%.java=%.class)
+
+#
+# the default make target entry
+#
+
+default: classes
+
+
+#
+# This target entry uses Suffix Replacement within a macro:
+# $(name:string1=string2)
+# In the words in the macro named 'name' replace 'string1' with 'string2'
+# Below we are replacing the suffix .java of all words in the macro CLASSES
+# with the .class suffix
+#
+
+classes: $(SOURCES:.java=.class)
+
+jar:
+ jar cve $(JAR_PKG) $(CLASSES)
+
+tar:
+ tar czpf $(TARBALL) $(SOURCES) Makefile
+
+
+#
+# RM is a predefined macro in make (RM = rm -f)
+#
+
+clean:
+ $(RM) *.class
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.controller.packetcable</groupId>
+ <artifactId>packetcable-plugin</artifactId>
+ <version>1.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>packetcable-driver</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>
+ A lightweight implementation of PCMM COPS PDP client
+ </description>
+
+ <url></url>
+ <inceptionYear>2013</inceptionYear>
+
+ <licenses>
+ <license>
+ </license>
+ </licenses>
+
+ <mailingLists>
+ <mailingList>
+ </mailingList>
+ </mailingLists>
+
+ <developers>
+ <developer>
+ </developer>
+ </developers>
+
+ <contributors>
+ <contributor>
+ </contributor>
+ </contributors>
+
+ <scm>
+ <connection></connection>
+ <developerConnection></developerConnection>
+ <url></url>
+ </scm>
+
+ <issueManagement>
+ <system></system>
+ <url></url>
+ </issueManagement>
+
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
+ <salGeneratorPath>src/main/yang-gen-sal</salGeneratorPath>
+ <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+ <nexus.repository.snapshot>opendaylight.snapshot</nexus.repository.snapshot>
+ <nexus.repository.release>opendaylight.release</nexus.repository.release>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ <version>1.0.9</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <version>1.0.9</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>13.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.sip</groupId>
+ <artifactId>jain-sip-ri</artifactId>
+ <version>1.2.158</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-primitives</groupId>
+ <artifactId>commons-primitives</artifactId>
+ <version>20041207.202534</version>
+ </dependency>
+ </dependencies>
+
+ <modules></modules>
+
+ <build>
+ <directory>${project.basedir}/target</directory>
+ <outputDirectory>${project.build.directory}/classes</outputDirectory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
+ <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
+ <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
+ <resources>
+ <resource>
+ <directory>${project.basedir}/src/main/resources</directory>
+ </resource>
+ </resources>
+ <testResources>
+ <testResource>
+ <directory>${project.basedir}/src/test/resources</directory>
+ </testResource>
+ </testResources>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.0</version>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+package org.pcmm;
+
+public interface PCMMConstants {
+
+ // Port used by the PCMM
+ public static final String PCMM_PORT = "pcmm.port";
+ // Pool size, determining the number of connections that could be
+ // established with CMTSs
+ public static final String PS_POOL_SIZE = "pcmm.ps.pool.size";
+ // Default keep-alive timer value (secs)
+ public static final String KA_TIMER = "pcmm.keep.alive.timer";
+ // Default accounting timer value (secs)
+ public static final String ACC_TIMER = "pcmm.accounting.timer";
+ // default ip mask
+ public static final String DEFAULT_MASK = "pcmm.default.mask";
+ // default timeout
+ public static final String DEFAULT_TIEMOUT = "pcmm.default.timeout";
+
+}
\ No newline at end of file
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import org.umu.cops.common.COPS_def;
+
+public class PCMMDef extends COPS_def {
+
+ public static final short C_PCMM = (short) 0x800A;
+
+ /**
+ * Get a representative string for an COPS Client Type.
+ *
+ * @param cType
+ * COPS Client Type
+ * @return A representative <tt>String</tt>
+ *
+ */
+ public String strClientType(short cType) {
+ switch (cType) {
+ case C_PCMM:
+ return ("C_PCMM");
+ default:
+ return super.strClientType(cType);
+ }
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+public class PCMMGlobalConfig {
+ // System
+ public static int Debug = 0;
+ public static int LogLevel = 0;
+ public static int DefaultBestEffortTrafficRate = 2500000;
+ // Service Flow Attributes Defaults
+ public static int DefaultBestEffortClassPriority = 69;
+ public static int DefaultUnsolicatedGrantSize = 1000;
+ public static int DefaultUnsolicatedGrantsPerInterval = 3;
+ public static int DefaultUnsolicatedGrantInterval = 8000;
+ // Gate Specification Defaults
+ public static int DSCPToSMark = 0;
+ public static int Priority = 0;
+ public static int PreEmption = 0;
+ public static int GateFlags = 0;
+ public static int GateTOSField = 0;
+ public static int GateTOSMask = 0;
+ public static int GateClass = 0;
+ // Authorization life timer
+ public static short GateT1 = 200;
+ // Authorization renew timer
+ public static short GateT2 = 300;
+ // Reservation life timer
+ public static short GateT3 = 0;
+ // Reservation renew timer
+ public static short GateT4 = 0;
+
+ // XXX - A new home for some of these @ org.pcmm.gates.impl.BestEffortService
+ public static int UGSTransmissionPolicy = 0x037F;
+ public static int BETransmissionPolicy = 0x0;
+ public static int BETrafficPriority = 0x0;
+ public static byte EClassifierPriority = 0x45;
+
+ // Temporary Configure Items For Demo or Lacking Design
+ public static int DefaultLowBestEffortTrafficRate = 500000;
+ public static int DefaultVideoSourcePort = 8081;
+ public static int DefaultAlternateSourcePort = 1369;
+ // public static String DefaultCMTS = "127.0.0.1"
+
+/* Demo Kit Layout
+ public static String DefaultCMTS = "10.32.4.3";
+ public static String SubscriberID = "10.32.104.2";
+ public static String dstIP = "10.32.4.208";
+ public static String srcIP = "10.32.154.2";
+*/
+
+/* LAB Bench Layout */
+ public static String DefaultCMTS = "10.32.15.3";
+ public static String SubscriberID = "10.32.115.143";
+ public static String dstIP = "10.32.0.234";
+ public static String srcIP = "10.32.215.111";
+
+ public static String DefautRadius = "192.168.50.2";
+ public static short srcPort = 8081;
+ public static short dstPort = 0;
+ public static int GateID1 = 0;
+ public static int GateID2 = 0;
+ public static void setGateID1(int n) {
+ GateID1 = n;
+ }
+ public static int getGateID1() {
+ return GateID1;
+ }
+ public static void setGateID2(int n) {
+ GateID2 = n;
+ }
+ public static int getGateID2() {
+ return GateID2;
+ }
+}
+
+/*
+ *
+ * // if(Constants.DEBUG.isEnabled()) { } public enum Constants { DEBUG(true),
+ * PRINT_VARS(false);
+ *
+ * private boolean enabled;
+ *
+ * private Constants(boolean enabled) { this.enabled = enabled; }
+ *
+ * public boolean isEnabled() { return enabled; } }
+ */
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.umu.cops.common.COPSDebug;
+import org.umu.cops.ospep.COPSPepException;
+import org.umu.cops.prpdp.COPSPdpAgent;
+import org.umu.cops.prpdp.COPSPdpException;
+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.COPSError;
+import org.umu.cops.stack.COPSException;
+import org.umu.cops.stack.COPSHandle;
+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.COPSReqMsg;
+import org.umu.cops.stack.COPSTransceiver;
+// import org.umu.cops.prpdp.COPSPdpDataProcess;
+import org.pcmm.objects.MMVersionInfo;
+
+
+/**
+ * Core PDP agent for provisioning
+ */
+public class PCMMPdpAgent extends COPSPdpAgent {
+ /** Well-known port for PCMM */
+ public static final int WELL_KNOWN_PDP_PORT = 3918;
+
+ private COPSPepId _pepId;
+ private String _pepIdString;
+ /**
+ * PEP host name
+ */
+ private String psHost;
+
+ /**
+ * PEP port
+ */
+ private int psPort;
+
+ private Socket socket;
+
+ /**
+ * Policy data processing object
+ */
+ private PCMMPdpDataProcess _process;
+ private MMVersionInfo _mminfo;
+ private COPSHandle _handle;
+ private short _transactionID;
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param clientType
+ * COPS Client-type
+ * @param process
+ * Object to perform policy data processing
+ */
+ public PCMMPdpAgent(short clientType, PCMMPdpDataProcess process) {
+ this(clientType, null, WELL_KNOWN_PDP_PORT, process);
+ }
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param clientType
+ * COPS Client-type
+ * @param psHost
+ * Host to connect to
+ * @param psPort
+ * Port to connect to
+ * @param process
+ * Object to perform policy data processing
+ */
+ public PCMMPdpAgent(short clientType, String psHost, int psPort, PCMMPdpDataProcess process) {
+ super(psPort, clientType, null);
+ this._process = process;
+ this.psHost = psHost;
+ }
+
+ /**
+ * XXX -tek- This is the retooled connect. Not sure if the while forever
+ * loop is needed. Socket accept --> handleClientOpenMsg --> pdpConn.run()
+ *
+ * Below is new Thread(pdpConn).start(); Does that do it?
+ *
+ */
+ /**
+ * Connects to a PDP
+ *
+ * @param psHost
+ * CMTS host name
+ * @param psPort
+ * CMTS port
+ * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt>
+ * otherwise
+ * @throws java.net.UnknownHostException
+ * @throws java.io.IOException
+ * @throws COPSException
+ * @throws COPSPepException
+ */
+ public boolean connect(String psHost, int psPort)
+ throws UnknownHostException, IOException, COPSException,
+ COPSPdpException {
+
+ this.psHost = psHost;
+ this.psPort = psPort;
+ // Create Socket and send OPN
+ InetAddress addr = InetAddress.getByName(psHost);
+ try {
+ socket = new Socket(addr, psPort);
+ } catch (IOException e) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
+ return (false);
+ }
+ COPSDebug.err(getClass().getName(), "PDP Socket Opened");
+ // Loop through for Incoming messages
+
+ // server infinite loop
+ // while(true)
+ {
+
+ // We're waiting for an message
+ try {
+ COPSDebug.err(getClass().getName(),
+ "PDP COPSTransceiver.receiveMsg ");
+ COPSMsg msg = COPSTransceiver.receiveMsg(socket);
+ if (msg.getHeader().isAClientOpen()) {
+ COPSDebug.err(getClass().getName(),
+ "PDP msg.getHeader().isAClientOpen");
+ handleClientOpenMsg(socket, msg);
+ } else {
+ // COPSDebug.err(getClass().getName(),
+ // COPSDebug.ERROR_NOEXPECTEDMSG);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ }
+ ;
+ }
+ } catch (Exception e) { // COPSException, IOException
+ // COPSDebug.err(getClass().getName(),
+ // COPSDebug.ERROR_EXCEPTION,
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")",
+ // e);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ }
+ ;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Handles a COPS client-open message
+ *
+ * @param conn
+ * Socket to the PEP
+ * @param msg
+ * <tt>COPSMsg</tt> 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() != getClientType()) {
+ // 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) {
+ }
+
+ 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) {
+ }
+
+ throw new COPSException("Mandatory COPS object missing (PEPId)");
+ }
+ setPepId(pepId);
+ // Support
+ if ((cMsg.getClientSI() != null) ) {
+ _mminfo = new MMVersionInfo(cMsg
+ .getClientSI().getData().getData());
+ System.out.println("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);
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
+ closeMsg.add(cHdr);
+ closeMsg.add(err);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ }
+
+ throw new COPSException("Unsupported objects (PdpAddress, Integrity)");
+ }
+ /*
+ */
+
+ // Connection accepted
+ COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg
+ .getHeader().getClientType());
+ COPSKATimer katimer = new COPSKATimer(getKaTimer());
+ COPSAcctTimer acctTimer = new COPSAcctTimer(getAcctTimer());
+ COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
+ acceptMsg.add(ahdr);
+ acceptMsg.add(katimer);
+ if (getAcctTimer() != 0)
+ acceptMsg.add(acctTimer);
+ acceptMsg.writeData(conn);
+ // XXX - handleRequestMsg
+ try {
+ COPSDebug.err(getClass().getName(), "PDP COPSTransceiver.receiveMsg ");
+ COPSMsg rmsg = COPSTransceiver.receiveMsg(socket);
+ // Client-Close
+ if (rmsg.getHeader().isAClientClose()) {
+ System.out.println(((COPSClientCloseMsg) rmsg)
+ .getError().getDescription());
+ // 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);
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
+ closeMsg.add(cHdr);
+ closeMsg.add(err);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ }
+ throw new COPSException("CMTS requetsed Client-Close");
+ } else {
+ // Request
+ if (rmsg.getHeader().isARequest()) {
+ COPSReqMsg rMsg = (COPSReqMsg) rmsg;
+ _handle = rMsg.getClientHandle();
+ } else
+ throw new COPSException("Can't understand request");
+
+ }
+ } catch (Exception e) { // COPSException, IOException
+ throw new COPSException("Error COPSTransceiver.receiveMsg");
+ }
+
+ COPSDebug.err(getClass().getName(), "PDPCOPSConnection");
+ PCMMPdpConnection pdpConn = new PCMMPdpConnection(pepId, conn, _process);
+ pdpConn.setKaTimer(getKaTimer());
+ if (getAcctTimer() != 0)
+ pdpConn.setAccTimer(getAcctTimer());
+
+ // XXX - handleRequestMsg
+ // XXX - check handle is valid
+ PCMMPdpReqStateMan man = new PCMMPdpReqStateMan(getClientType(), _handle.getId().str());
+ pdpConn.getReqStateMans().put(_handle.getId().str(),man);
+ man.setDataProcess(_process);
+ try {
+ man.initRequestState(conn);
+ } catch (COPSPdpException unae) {
+ }
+ // XXX - End handleRequestMsg
+
+ COPSDebug.err(getClass().getName(), "PDP Thread(pdpConn).start");
+ new Thread(pdpConn).start();
+ getConnectionMap().put(pepId.getData().str(), pdpConn);
+ }
+
+ /**
+ * @return the _psHost
+ */
+ public String getPsHost() {
+ return psHost;
+ }
+
+ /**
+ * @param _psHost
+ * the _psHost to set
+ */
+ public void setPsHost(String _psHost) {
+ this.psHost = _psHost;
+ }
+
+ /**
+ * @return the _psPort
+ */
+ public int getPsPort() {
+ return psPort;
+ }
+
+ /**
+ * @param _psPort
+ * the _psPort to set
+ */
+ public void setPsPort(int _psPort) {
+ this.psPort = _psPort;
+ }
+
+ /**
+ * @return the socket
+ */
+ public Socket getSocket() {
+ return socket;
+ }
+
+ /**
+ * @param socket
+ * the socket to set
+ */
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ }
+
+ /**
+ * @return the _process
+ */
+ public PCMMPdpDataProcess getProcess() {
+ return _process;
+ }
+
+ /**
+ * @param _process
+ * the _process to set
+ */
+ public void setProcess(PCMMPdpDataProcess _process) {
+ this._process = _process;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the PepId
+ * @return <tt>COPSPepId</tt>
+ */
+ public COPSPepId getPepId() {
+ return _pepId;
+ }
+
+ public String getPepIdString() {
+ return _pepIdString;
+ }
+
+ /**
+ * Sets the PepId
+ * @param <tt>COPSPepId</tt>
+ */
+ public void setPepId(COPSPepId pepId) {
+ _pepId = pepId;
+ _pepIdString = pepId.getData().str();
+ }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMClient#isConnected()
+ */
+ public boolean isConnected() {
+ return socket != null && socket.isConnected();
+ }
+
+
+}
--- /dev/null
+/*\r
+ @header@\r
+ */\r
+\r
+package org.pcmm;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.prpdp.COPSPdpException;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKAMsg;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * Class for managing an provisioning connection at the PDP side.\r
+ */\r
+public class PCMMPdpConnection implements Runnable {\r
+\r
+ /**\r
+ Socket connected to PEP\r
+ */\r
+ private Socket _sock;\r
+\r
+ /**\r
+ PEP identifier\r
+ */\r
+ private COPSPepId _pepId;\r
+\r
+ /**\r
+ Time of the latest keep-alive sent\r
+ */\r
+ private Date _lastKa;\r
+\r
+ /**\r
+ Opcode of the latest message sent\r
+ */\r
+ private byte _lastmessage;\r
+\r
+ /**\r
+ * Time of the latest keep-alive received\r
+ */\r
+ protected Date _lastRecKa;\r
+\r
+ /**\r
+ Maps a Client Handle to a Handler\r
+ */\r
+ protected Hashtable _managerMap;\r
+ // map < String(COPSHandle), COPSPdpHandler> HandlerMap;\r
+\r
+ /**\r
+ * PDP policy data processor class\r
+ */\r
+ protected PCMMPdpDataProcess _process;\r
+\r
+ /**\r
+ Accounting timer value (secs)\r
+ */\r
+ protected short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer value (secs)\r
+ */\r
+ protected short _kaTimer;\r
+\r
+ /**\r
+ COPS error returned by PEP\r
+ */\r
+ protected COPSError _error;\r
+\r
+ /**\r
+ * Creates a new PDP connection\r
+ *\r
+ * @param pepId PEP-ID of the connected PEP\r
+ * @param sock Socket connected to PEP\r
+ * @param process Object for processing policy data\r
+ */\r
+ public PCMMPdpConnection(COPSPepId pepId, Socket sock, PCMMPdpDataProcess process) {\r
+ _sock = sock;\r
+ _pepId = pepId;\r
+\r
+ _lastKa = new Date();\r
+ _lastmessage = COPSHeader.COPS_OP_OPN;\r
+ _managerMap = new Hashtable(20);\r
+\r
+ _kaTimer = 120;\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Gets the time of that latest keep-alive sent\r
+ * @return Time of that latest keep-alive sent\r
+ */\r
+ public Date getLastKAlive() {\r
+ return _lastKa;\r
+ }\r
+\r
+ /**\r
+ * Sets the keep-alive timer value\r
+ * @param kaTimer Keep-alive timer value (secs)\r
+ */\r
+ public void setKaTimer(short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the keep-alive timer value\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer() {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets the accounting timer value\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAccTimer(short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the accounting timer value\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer() {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the latest COPS message\r
+ * @return Code of the latest message sent\r
+ */\r
+ public byte getLastMessage() {\r
+ return _lastmessage;\r
+ }\r
+\r
+ /**\r
+ * Gets active handles\r
+ * @return An <tt>Enumeration</tt> holding all active handles\r
+ */\r
+ public Enumeration getHandles() {\r
+ return _managerMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets the handle map\r
+ * @return A <tt>Hashtable</tt> holding the handle map\r
+ */\r
+ public Hashtable getReqStateMans() {\r
+ return _managerMap;\r
+ }\r
+\r
+ /**\r
+ * Gets the PEP-ID\r
+ * @return The ID of the PEP, as a <tt>String</tt>\r
+ */\r
+ public String getPepId() {\r
+ return _pepId.getData().str();\r
+ }\r
+\r
+ /**\r
+ * Checks whether the socket to the PEP is closed or not\r
+ * @return <tt>true</tt> if closed, <tt>false</tt> otherwise\r
+ */\r
+ public boolean isClosed() {\r
+ return _sock.isClosed();\r
+ }\r
+\r
+ /**\r
+ * Closes the socket to the PEP\r
+ * @throws IOException\r
+ */\r
+ protected void close()\r
+ throws IOException {\r
+ _sock.close();\r
+ }\r
+\r
+ /**\r
+ * Gets the socket to the PEP\r
+ * @return Socket connected to the PEP\r
+ */\r
+ public Socket getSocket() {\r
+ return _sock;\r
+ }\r
+\r
+ /**\r
+ * Main loop\r
+ */\r
+ public void run () {\r
+ Date _lastSendKa = new Date();\r
+ _lastRecKa = new Date();\r
+ try {\r
+ while (!_sock.isClosed()) {\r
+ if (_sock.getInputStream().available() != 0) {\r
+ _lastmessage = processMessage(_sock);\r
+ _lastRecKa = new Date();\r
+ }\r
+\r
+ // Keep Alive\r
+ if (_kaTimer > 0) {\r
+ // Timeout at PDP\r
+ int _startTime = (int) (_lastRecKa.getTime());\r
+ int cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > _kaTimer*1000) {\r
+ _sock.close();\r
+ // Notify all Request State Managers\r
+ notifyNoKAAllReqStateMan();\r
+ }\r
+\r
+ // Send to PEP\r
+ _startTime = (int) (_lastSendKa.getTime());\r
+ cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > ((_kaTimer*3/4)*1000)) {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
+ COPSKAMsg msg = new COPSKAMsg();\r
+\r
+ msg.add(hdr);\r
+\r
+ COPSTransceiver.sendMsg(msg, _sock);\r
+ _lastSendKa = new Date();\r
+ }\r
+ }\r
+\r
+ try {\r
+ Thread.sleep(500);\r
+ } catch (Exception e) {};\r
+\r
+ }\r
+ } catch (Exception e) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ }\r
+\r
+ // connection closed by server\r
+ // COPSDebug.out(getClass().getName(),"Connection closed by client");\r
+ try {\r
+ _sock.close();\r
+ } catch (IOException e) {};\r
+\r
+ // Notify all Request State Managers\r
+ try {\r
+ notifyCloseAllReqStateMan();\r
+ } catch (COPSPdpException e) {};\r
+ }\r
+\r
+ /**\r
+ * Gets a COPS message from the socket and processes it\r
+ * @param conn Socket connected to the PEP\r
+ * @return Type of COPS message\r
+ */\r
+ private byte processMessage(Socket conn)\r
+ throws COPSPdpException, COPSException, IOException {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
+\r
+ if (msg.getHeader().isAClientClose()) {\r
+ handleClientCloseMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_CC;\r
+ } else if (msg.getHeader().isAKeepAlive()) {\r
+ handleKeepAliveMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_KA;\r
+ } else if (msg.getHeader().isARequest()) {\r
+ handleRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_REQ;\r
+ } else if (msg.getHeader().isAReport()) {\r
+ handleReportMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_RPT;\r
+ } else if (msg.getHeader().isADeleteReq()) {\r
+ handleDeleteRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_DRQ;\r
+ } else if (msg.getHeader().isASyncComplete()) {\r
+ handleSyncComplete(conn, msg);\r
+ return COPSHeader.COPS_OP_SSC;\r
+ } else {\r
+ throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handle Client Close Message, close the passed connection\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ */\r
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
+ _error = cMsg.getError();\r
+\r
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
+\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ conn.close();\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Gets the occurred COPS Error\r
+ * @return <tt>COPSError</tt> object\r
+ */\r
+ protected COPSError getError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Handle Keep Alive Message\r
+ *\r
+ * <Keep-Alive> ::= <Common Header>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
+ COPSKAMsg cMsg = (COPSKAMsg) msg;\r
+\r
+ COPSKAMsg kaMsg = (COPSKAMsg) msg;\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ kaMsg.writeData(conn);\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Handle Delete Request Message\r
+ *\r
+ * <Delete Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Reason>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;\r
+ // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ // Delete clientHandler\r
+ if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {\r
+ // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +\r
+ // cMsg.getClientHandle().getId().getData());\r
+ }\r
+\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processDeleteRequestState(cMsg);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Handle Request Message\r
+ *\r
+ * <Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleRequestMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ COPSReqMsg reqMsg = (COPSReqMsg) msg;\r
+ COPSContext cntxt = reqMsg.getContext();\r
+ COPSHeader header = reqMsg.getHeader();\r
+ //short reqType = cntxt.getRequestType();\r
+ short cType = header.getClientType();\r
+\r
+ // Support\r
+ if (reqMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ PCMMPdpReqStateMan man;\r
+ man = (PCMMPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+\r
+ man = new PCMMPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());\r
+ _managerMap.put(reqMsg.getClientHandle().getId().str(),man);\r
+ man.setDataProcess(_process);\r
+ man.initRequestState(_sock);\r
+\r
+ // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +\r
+ // header.getClientType() + " msgType=" +\r
+ // cntxt.getMessageType() + ", connId=" + conn.toString());\r
+ }\r
+\r
+ man.processRequest(reqMsg);\r
+ }\r
+\r
+ /**\r
+ * Handle Report Message\r
+ *\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleReportMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSReportMsg repMsg = (COPSReportMsg) msg;\r
+ // COPSHandle handle = repMsg.getClientHandle();\r
+ // COPSHeader header = repMsg.getHeader();\r
+\r
+ // Support\r
+ if (repMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processReport(repMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method handleSyncComplete\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleSyncComplete(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
+ // COPSHandle handle = cMsg.getClientHandle();\r
+ // COPSHeader header = cMsg.getHeader();\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processSyncComplete(cMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Requests a COPS sync from the PEP\r
+ * @throws COPSException\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncAllRequestState()\r
+ throws COPSException, COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.syncRequestState();\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyCloseAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processClosedConnection(_error);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyNoKAAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processNoKAConnection();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import java.util.Hashtable;
+
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.impl.PCMMGateReq;
+// import org.umu.cops.prpdp.COPSPdpDataProcess;
+import org.umu.cops.stack.COPSError;
+
+
+public class PCMMPdpDataProcess { // extends COPSPdpDataProcess
+ private Hashtable installPolicy;
+ private Hashtable removePolicy;
+
+ public PCMMPdpDataProcess() {
+ }
+
+ /**
+ * PDPAgent gets the policies to delete from PEP
+ *
+ * @param man
+ * @return
+ */
+ public Hashtable getRemovePolicy(PCMMPdpReqStateMan man) {
+ return removePolicy;
+ }
+
+ /**
+ * PDPAgent gets the policies to be installed in PEP
+ *
+ * @param man
+ * @return
+ */
+ public Hashtable getInstallPolicy(PCMMPdpReqStateMan man) {
+ return installPolicy;
+ }
+
+ /**
+ * PEP configuration items for sending inside the request
+ *
+ * @param man
+ * @param reqSIs
+ */
+ public void setClientData(PCMMPdpReqStateMan man, Hashtable reqSIs) {
+
+ System.out.println(getClass().getName() + ": " + "Request Info");
+ /*
+ for (Enumeration e = reqSIs.keys() ; e.hasMoreElements() ;) {
+ String strprid = (String) e.nextElement();
+ String strepd = (String) reqSIs.get(strprid);
+
+ // Check PRID-EPD
+ // ....
+ System.out.println(getClass().getName() + ": " + "PRID: " + strprid);
+ System.out.println(getClass().getName() + ": " + "EPD: " + strepd);
+ }
+
+ // Create policies to be deleted
+ // ....
+
+ // Create policies to be installed
+ String prid = new String("<XPath>");
+ String epd = new String("<?xml this is an XML policy>");
+ installPolicy.put(prid, epd);
+ */
+ }
+
+ /**
+ * Fail report received
+ *
+ * @param man
+ * @param reportSIs
+ */
+ public void failReport(PCMMPdpReqStateMan man, PCMMGateReq gateMsg) {
+
+ System.out.println(getClass().getName()+ ": " + "Fail Report notified.");
+ System.out.println(getClass().getName()+ ": " + gateMsg.getError().toString());
+
+ /*
+
+ System.out.println(getClass().getName() + ": " + "Report Info");
+ for (Enumeration e = reportSIs.keys() ; e.hasMoreElements() ;) {
+ String strprid = (String) e.nextElement();
+ String strepd = (String) reportSIs.get(strprid);
+
+ // Check PRID-EPD
+ // ....
+ System.out.println(getClass().getName()+ ": " + "PRID: " + strprid);
+ System.out.println(getClass().getName()+ ": " + "EPD: " + strepd);
+ }
+ */
+ }
+
+ /**
+ * Positive report received
+ *
+ * @param man
+ * @param reportSIs
+ */
+ public void successReport(PCMMPdpReqStateMan man, PCMMGateReq gateMsg) {
+ System.out.println(getClass().getName()+ ": " + "Success Report notified.");
+
+ if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {
+ System.out.println(getClass().getName()+ ": GateDeleteAck ");
+ System.out.println(getClass().getName()+ ": 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 ) {
+ System.out.println(getClass().getName()+ ": GateSetAck ");
+ System.out.println(getClass().getName()+ ": GateID = " + gateMsg.getGateID().getGateID());
+ if (0 == PCMMGlobalConfig.getGateID1())
+ PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());
+ if (0 == PCMMGlobalConfig.getGateID2())
+ PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());
+ }
+
+ /*
+ System.out.println(getClass().getName()+ ": " + "Report Info");
+ for (Enumeration e = reportSIs.keys() ; e.hasMoreElements() ;) {
+ String strprid = (String) e.nextElement();
+ String strepd = (String) reportSIs.get(strprid);
+
+ // Check PRID-EPD
+ // ....
+ System.out.println(getClass().getName()+ ": " + "PRID: " + strprid);
+ System.out.println(getClass().getName()+ ": " + "EPD: " + strepd);
+ }
+ */
+
+ }
+
+ /**
+ * Accounting report received
+ *
+ * @param man
+ * @param reportSIs
+ */
+ public void acctReport(PCMMPdpReqStateMan man, PCMMGateReq gateMsg) {
+ System.out.println(getClass().getName()+ ": " + "Acct Report notified.");
+
+ /*
+ System.out.println(getClass().getName()+ ": " + "Report Info");
+ for (Enumeration e = reportSIs.keys() ; e.hasMoreElements() ;) {
+ String strprid = (String) e.nextElement();
+ String strepd = (String) reportSIs.get(strprid);
+
+ // Check PRID-EPD
+ // ....
+ System.out.println(getClass().getName()+ ": " + "PRID: " + strprid);
+ System.out.println(getClass().getName()+ ": " + "EPD: " + strepd);
+ }
+ */
+ }
+
+ /**
+ * Notifies that an Accounting report is missing
+ *
+ * @param man
+ */
+ public void notifyNoAcctReport(PCMMPdpReqStateMan man) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * Notifies that a KeepAlive message is missing
+ *
+ * @param man
+ */
+ public void notifyNoKAliveReceived(PCMMPdpReqStateMan man) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * PEP closed the connection
+ *
+ * @param man
+ * @param error
+ */
+ public void notifyClosedConnection(PCMMPdpReqStateMan man, COPSError error) {
+ System.out.println(getClass().getName() + ": " + "Connection was closed by PEP");
+ }
+
+ /**
+ * Delete request state received
+ *
+ * @param man
+ */
+ public void notifyDeleteRequestState(PCMMPdpReqStateMan man) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ /**
+ * Closes request state
+ *
+ * @param man
+ */
+ public void closeRequestState(PCMMPdpReqStateMan man) {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.pcmm.gates.IAMID;
+import org.pcmm.gates.IClassifier;
+import org.pcmm.gates.IExtendedClassifier;
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IGateSpec;
+import org.pcmm.gates.IGateSpec.DSCPTOS;
+import org.pcmm.gates.IGateSpec.Direction;
+import org.pcmm.gates.IPCMMGate;
+import org.pcmm.gates.ISubscriberID;
+import org.pcmm.gates.ITrafficProfile;
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.impl.AMID;
+import org.pcmm.gates.impl.BestEffortService;
+import org.pcmm.gates.impl.Classifier;
+import org.pcmm.gates.impl.ExtendedClassifier;
+import org.pcmm.gates.impl.GateID;
+import org.pcmm.gates.impl.GateSpec;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.pcmm.gates.impl.SubscriberID;
+import org.pcmm.gates.impl.TransactionID;
+import org.umu.cops.prpdp.COPSPdpException;
+import org.umu.cops.stack.COPSClientSI;
+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.COPSException;
+import org.umu.cops.stack.COPSHandle;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSObjHeader;
+//temp
+import org.umu.cops.stack.COPSReportMsg;
+import org.umu.cops.stack.COPSSyncStateMsg;
+import org.umu.cops.stack.COPSTransceiver;
+//pcmm
+/*
+ * Example of an UNSOLICITED decision
+ *
+ * <Gate Control Command> = <COPS Common Header> <Client Handle> <Context> <Decision Flags> <ClientSI Data>
+ *
+ * <ClientSI Data> = <Gate-Set> | <Gate-Info> | <Gate-Delete> |
+ * <PDP-Config> | <Synch-Request> | <Msg-Receipt>
+ * <Gate-Set> = <Decision Header> <TransactionID> <AMID> <SubscriberID> [<GateID>] <GateSpec>
+ * <Traffic Profile> <classifier> [<classifier...>] [<Event Generation Info>]
+ * [<Volume-Based Usage Limit>] [<Time-Based Usage Limit>][<Opaque Data>] [<UserID>]
+ */
+
+/**
+ * COPS message transceiver class for provisioning connections at the PDP side.
+ */
+public class PCMMPdpMsgSender {
+
+ /**
+ * 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;
+
+ /**
+ *
+ */
+ protected short _transactionID;
+ protected short _classifierID;
+ // XXX - this does not need to be here
+ protected int _gateID;
+
+ /**
+ * Creates a PCMMPdpMsgSender
+ *
+ * @param clientType
+ * COPS client-type
+ * @param clientHandle
+ * Client handle
+ * @param sock
+ * Socket to the PEP
+ */
+ public PCMMPdpMsgSender(short clientType, COPSHandle clientHandle,
+ Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+
+ _transactionID = 0;
+ _classifierID = 0;
+ _sock = sock;
+ }
+
+ public PCMMPdpMsgSender(short clientType, short tID,
+ COPSHandle clientHandle, Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+ _transactionID = tID;
+ _classifierID = 0;
+ _sock = sock;
+ }
+
+ /**
+ * Gets the client handle
+ *
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ *
+ * @return Client-type value
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Gets the transaction-id
+ *
+ * @return transaction-id value
+ */
+ public short getTransactionID() {
+ return _transactionID;
+ }
+
+
+ /**
+ * Sends a PCMM GateSet COPS Decision message
+ *
+ * @param
+ * @throws COPSPdpException
+ */
+ public void sendGateSet(IPCMMGate gate)
+ throws COPSPdpException {
+ // 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
+ COPSHandle handle = new COPSHandle();
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
+ ITransactionID trID = new TransactionID();
+
+ handle.setId(getClientHandle().getId());
+
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateSet);
+ _transactionID = (short) (_transactionID == 0 ? (short) (Math.random() * hashCode())
+ : _transactionID);
+ trID.setTransactionIdentifier(_transactionID);
+
+ gate.setTransactionID(trID);
+
+
+ // new pcmm specific clientsi
+ COPSClientSI clientSD = new COPSClientSI(COPSObjHeader.COPS_DEC, (byte) 4);
+ byte[] data = gate.getData();
+ clientSD.setData(new COPSData(data, 0, data.length));
+ try {
+ decisionMsg.add(hdr);
+ decisionMsg.add(handle);
+ // Decisions (no flags supplied)
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ COPSDecision install = new COPSDecision();
+ install.setCmdCode(COPSDecision.DEC_INSTALL);
+ install.setFlags(COPSDecision.F_REQERROR);
+ decisionMsg.addDecision(install, cntxt);
+ decisionMsg.add(clientSD); // setting up the gate
+ /*
+ try {
+ decisionMsg.dump(System.out);
+ } catch (IOException unae) {
+ System.out.println("Error dumping " + unae.getMessage());
+ }
+ */
+
+ } catch (COPSException e) {
+ System.out.println("Error making Msg" + e.getMessage());
+ }
+
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ System.out.println("Failed to send the decision, reason: "
+ + e.getMessage());
+ }
+
+ }
+
+ /**
+ * Sends a PCMM GateSet COPS Decision message
+ *
+ * @param
+ * @throws COPSPdpException
+ */
+ public void sendGateSetDemo(int num)
+ throws COPSPdpException {
+
+ // 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
+ COPSHandle handle = new COPSHandle();
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
+
+ IPCMMGate gate = new PCMMGateReq();
+ ITransactionID trID = new TransactionID();
+
+ IAMID amid = new AMID();
+ ISubscriberID subscriberID = new SubscriberID();
+ IGateSpec gateSpec = new GateSpec();
+ IClassifier classifier = new Classifier();
+ IExtendedClassifier eclassifier = new ExtendedClassifier();
+ int TrafficRate = 0;
+
+ if (num == 1)
+ TrafficRate = PCMMGlobalConfig.DefaultBestEffortTrafficRate;
+ else
+ TrafficRate = PCMMGlobalConfig.DefaultLowBestEffortTrafficRate;
+
+ ITrafficProfile trafficProfile = new BestEffortService(
+ (byte) 7); //BestEffortService.DEFAULT_ENVELOP);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ TrafficRate);
+ // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ TrafficRate);
+ // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ TrafficRate);
+ // PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+
+
+ // new pcmm specific clientsi
+ COPSClientSI clientSD = new COPSClientSI(COPSObjHeader.COPS_DEC, (byte) 4);
+
+ handle.setId(getClientHandle().getId());
+
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateSet);
+ _transactionID = (short) (_transactionID == 0 ? (short) (Math.random() * hashCode())
+ : _transactionID);
+ trID.setTransactionIdentifier(_transactionID);
+
+ amid.setApplicationType((short) 1);
+ amid.setApplicationMgrTag((short) 1);
+ gateSpec.setDirection(Direction.UPSTREAM);
+ gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
+ gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
+ gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
+ gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
+ gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
+
+ // XXX - if the version major is less than 4 we need to use Classifier
+ if (true) {
+ //eclassifier.setProtocol(IClassifier.Protocol.NONE);
+ eclassifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress
+ .getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress
+ .getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress
+ .getByName(PCMMGlobalConfig.dstIP);
+ InetAddress mask = InetAddress.getByName("0.0.0.0");
+ subscriberID.setSourceIPAddress(subIP);
+ eclassifier.setSourceIPAddress(srcIP);
+ eclassifier.setDestinationIPAddress(dstIP);
+ eclassifier.setIPDestinationMask(mask);
+ eclassifier.setIPSourceMask(mask);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ eclassifier.setSourcePortStart(PCMMGlobalConfig.srcPort);
+ eclassifier.setSourcePortEnd(PCMMGlobalConfig.srcPort);
+ eclassifier.setDestinationPortStart(PCMMGlobalConfig.dstPort);
+ eclassifier.setDestinationPortEnd(PCMMGlobalConfig.dstPort);
+ eclassifier.setActivationState((byte) 0x01);
+ // check if we have a stored value of classifierID else we just
+ // create
+ // one
+ // eclassifier.setClassifierID((short) 0x01);
+ eclassifier.setClassifierID((short) (_classifierID == 0 ? Math
+ .random() * hashCode() : _classifierID));
+ // XXX - testie
+ // eclassifier.setClassifierID((short) 1);
+
+ eclassifier.setAction((byte) 0x00);
+ // XXX - temp default until Gate Modify is hacked in
+ // eclassifier.setPriority(PCMMGlobalConfig.EClassifierPriority);
+ eclassifier.setPriority((byte) 65);
+
+ } else {
+ classifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress
+ .getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress
+ .getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress
+ .getByName(PCMMGlobalConfig.dstIP);
+ subscriberID.setSourceIPAddress(subIP);
+ classifier.setSourceIPAddress(srcIP);
+ classifier.setDestinationIPAddress(dstIP);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ classifier.setSourcePort(PCMMGlobalConfig.srcPort);
+ classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
+ }
+
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateSpec(gateSpec);
+ gate.setTrafficProfile(trafficProfile);
+ gate.setClassifier(eclassifier);
+
+ byte[] data = gate.getData();
+
+ // new pcmm specific clientsi
+ clientSD.setData(new COPSData(data, 0, data.length));
+ try {
+ decisionMsg.add(hdr);
+ decisionMsg.add(handle);
+ // Decisions (no flags supplied)
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ COPSDecision install = new COPSDecision();
+ install.setCmdCode(COPSDecision.DEC_INSTALL);
+ install.setFlags(COPSDecision.F_REQERROR);
+ decisionMsg.addDecision(install, cntxt);
+ decisionMsg.add(clientSD); // setting up the gate
+ /*
+ try {
+ decisionMsg.dump(System.out);
+ } catch (IOException unae) {
+ System.out.println("Error dumping " + unae.getMessage());
+ }
+ */
+
+ } catch (COPSException e) {
+ System.out.println("Error making Msg" + e.getMessage());
+ }
+
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ System.out.println("Failed to send the decision, reason: "
+ + e.getMessage());
+ }
+
+ }
+ /**
+ * Sends a PCMM GateSet COPS Decision message
+ *
+ * @param
+ * @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());
+
+ // Client Handle with the same clientHandle as the request
+ COPSHandle handle = new COPSHandle();
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
+
+ IPCMMGate gate = new PCMMGateReq();
+ ITransactionID trID = new TransactionID();
+
+ IAMID amid = new AMID();
+ ISubscriberID subscriberID = new SubscriberID();
+ IGateSpec gateSpec = new GateSpec();
+ IClassifier classifier = new Classifier();
+ IExtendedClassifier eclassifier = new ExtendedClassifier();
+
+ // XXX check if other values should be provided
+ //
+ ITrafficProfile trafficProfile = new BestEffortService(
+ (byte) 7); //BestEffortService.DEFAULT_ENVELOP);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getReservedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop()
+ .setMaximumSustainedTrafficRate(
+ PCMMGlobalConfig.DefaultLowBestEffortTrafficRate );
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+
+
+ // new pcmm specific clientsi
+ COPSClientSI clientSD = new COPSClientSI(COPSObjHeader.COPS_DEC,
+ (byte) 4);
+
+ handle.setId(getClientHandle().getId());
+
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateSet);
+ _transactionID = (short) (_transactionID == 0 ? (short) (Math.random() * hashCode())
+ : _transactionID);
+ trID.setTransactionIdentifier(_transactionID);
+
+ amid.setApplicationType((short) 1);
+ amid.setApplicationMgrTag((short) 1);
+ gateSpec.setDirection(Direction.UPSTREAM);
+ gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
+ gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
+ gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
+ gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
+ gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
+
+ // XXX - if the version major is less than 4 we need to use Classifier
+ if (true) {
+ //eclassifier.setProtocol(IClassifier.Protocol.NONE);
+ eclassifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress
+ .getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress
+ .getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress
+ .getByName(PCMMGlobalConfig.dstIP);
+ InetAddress mask = InetAddress.getByName("0.0.0.0");
+ subscriberID.setSourceIPAddress(subIP);
+ eclassifier.setSourceIPAddress(srcIP);
+ eclassifier.setDestinationIPAddress(dstIP);
+ eclassifier.setIPDestinationMask(mask);
+ eclassifier.setIPSourceMask(mask);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ eclassifier.setSourcePortStart(PCMMGlobalConfig.srcPort);
+ eclassifier.setSourcePortEnd(PCMMGlobalConfig.srcPort);
+ eclassifier.setDestinationPortStart(PCMMGlobalConfig.dstPort);
+ eclassifier.setDestinationPortEnd(PCMMGlobalConfig.dstPort);
+ eclassifier.setActivationState((byte) 0x01);
+ // check if we have a stored value of classifierID else we just
+ // create
+ // one
+ // eclassifier.setClassifierID((short) 0x01);
+ eclassifier.setClassifierID((short) (_classifierID == 0 ? Math
+ .random() * hashCode() : _classifierID));
+ // XXX - testie
+ // eclassifier.setClassifierID((short) 1);
+
+ eclassifier.setAction((byte) 0x00);
+ // XXX - temp default until Gate Modify is hacked in
+ // eclassifier.setPriority(PCMMGlobalConfig.EClassifierPriority);
+ eclassifier.setPriority((byte) 65);
+
+ } else {
+ classifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress
+ .getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress
+ .getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress
+ .getByName(PCMMGlobalConfig.dstIP);
+ subscriberID.setSourceIPAddress(subIP);
+ classifier.setSourceIPAddress(srcIP);
+ classifier.setDestinationIPAddress(dstIP);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ classifier.setSourcePort(PCMMGlobalConfig.srcPort);
+ classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
+ }
+
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateSpec(gateSpec);
+ gate.setTrafficProfile(trafficProfile);
+ gate.setClassifier(eclassifier);
+
+ byte[] data = gate.getData();
+
+ // new pcmm specific clientsi
+ clientSD.setData(new COPSData(data, 0, data.length));
+ try {
+ decisionMsg.add(hdr);
+ decisionMsg.add(handle);
+ // Decisions (no flags supplied)
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ COPSDecision install = new COPSDecision();
+ install.setCmdCode(COPSDecision.DEC_INSTALL);
+ install.setFlags(COPSDecision.F_REQERROR);
+ decisionMsg.addDecision(install, cntxt);
+ decisionMsg.add(clientSD); // setting up the gate
+ /*
+ try {
+ decisionMsg.dump(System.out);
+ } catch (IOException unae) {
+ System.out.println("Error dumping " + unae.getMessage());
+ }
+ */
+
+ } catch (COPSException e) {
+ System.out.println("Error making Msg" + e.getMessage());
+ }
+
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ System.out.println("Failed to send the decision, reason: "
+ + e.getMessage());
+ }
+
+ }
+
+
+ public boolean handleGateReport(Socket socket) throws COPSPdpException {
+ try {
+ // waits for the gate-set-ack or error
+ COPSMsg responseMsg = COPSTransceiver.receiveMsg(socket);
+ if (responseMsg.getHeader().isAReport()) {
+ System.out.println("processing received report from CMTS");
+ COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI().size() == 0) {
+ return false;
+ }
+ COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI()
+ .elementAt(0);
+ IPCMMGate responseGate = new PCMMGateReq(clientSI.getData()
+ .getData());
+ if (responseGate.getTransactionID() != null
+ && responseGate.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
+ System.out.println("the CMTS has sent a Gate-Set-Ack response");
+ // here CMTS responded that he acknowledged the Gate-Set
+ // TODO do further check of Gate-Set-Ack GateID etc...
+ _gateID = responseGate.getGateID().getGateID();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ } catch (Exception e) { // COPSException, IOException
+ throw new COPSPdpException("Error COPSTransceiver.receiveMsg");
+ }
+ }
+
+
+ /**
+ * Sends a PCMM GateSet COPS Decision message
+ *
+ * @param
+ * @throws COPSPdpException
+ */
+ public void sendGateSet() throws COPSPdpException {
+ // 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
+ COPSHandle handle = new COPSHandle();
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
+
+ IPCMMGate gate = new PCMMGateReq();
+ ITransactionID trID = new TransactionID();
+
+ IAMID amid = new AMID();
+ ISubscriberID subscriberID = new SubscriberID();
+ IGateSpec gateSpec = new GateSpec();
+ IClassifier classifier = new Classifier();
+ // XXX check if other values should be provided
+ ITrafficProfile trafficProfile = new BestEffortService(
+ BestEffortService.DEFAULT_ENVELOP);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setMaximumTrafficBurst(
+ BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop()
+ .setRequestTransmissionPolicy(
+ PCMMGlobalConfig.BETransmissionPolicy);
+
+ // new pcmm specific clientsi
+ COPSClientSI clientSD = new COPSClientSI(COPSObjHeader.COPS_DEC,
+ (byte) 4);
+
+ handle.setId(getClientHandle().getId());
+ // byte[] content = "1234".getBytes();
+
+ // handle.setId(new COPSData(content, 0, content.length));
+
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateSet);
+ _transactionID = (short) (_transactionID == 0 ? (short) (Math.random() * hashCode())
+ : _transactionID);
+ trID.setTransactionIdentifier(_transactionID);
+
+ amid.setApplicationType((short) 1);
+ amid.setApplicationMgrTag((short) 1);
+ gateSpec.setDirection(Direction.UPSTREAM);
+ gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
+ gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
+ gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
+ gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
+ gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
+
+ /*
+ * ((DOCSISServiceClassNameTrafficProfile) trafficProfile)
+ * .setServiceClassName("S_up");
+ */
+
+ classifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress.getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress.getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress.getByName(PCMMGlobalConfig.dstIP);
+ subscriberID.setSourceIPAddress(subIP);
+ classifier.setSourceIPAddress(srcIP);
+ classifier.setDestinationIPAddress(dstIP);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ classifier.setSourcePort(PCMMGlobalConfig.srcPort);
+ classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
+
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateSpec(gateSpec);
+ gate.setTrafficProfile(trafficProfile);
+ gate.setClassifier(classifier);
+
+ byte[] data = gate.getData();
+
+ // new pcmm specific clientsi
+ clientSD.setData(new COPSData(data, 0, data.length));
+
+ try {
+ decisionMsg.add(hdr);
+ decisionMsg.add(handle);
+ // Decisions (no flags supplied)
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ COPSDecision install = new COPSDecision();
+ install.setCmdCode(COPSDecision.DEC_INSTALL);
+ install.setFlags(COPSDecision.F_REQERROR);
+ decisionMsg.addDecision(install, cntxt);
+ decisionMsg.add(clientSD); // setting up the gate
+ /*
+ try {
+ decisionMsg.dump(System.out);
+ } catch (IOException unae) {
+ System.out.println("Error dumping " + unae.getMessage());
+ }
+ */
+
+ } catch (COPSException e) {
+ System.out.println("Error making Msg" + e.getMessage());
+ }
+
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ System.out.println("Failed to send the decision, reason: "
+ + e.getMessage());
+ }
+
+ }
+
+ /**
+ * Sends a message asking that the request state be deleted
+ *
+ * @throws COPSPdpException
+ */
+ public void sendGateDelete(int gID) throws COPSPdpException {
+ /*
+ * Example of an UNSOLICITED decision <Gate Control Command> = <COPS
+ * Common Header> <Client Handle> <Context> <Decision Flags> <ClientSI
+ * Data> <ClientSI Data> = <Gate-Set> | <Gate-Info> | <Gate-Delete> |
+ * <PDP-Config> | <Synch-Request> | <Msg-Receipt> <Gate-Delete> =
+ * <Decision Header> <TransactionID> <AMID> <SubscriberID> <GateID>
+ */
+ // 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
+ COPSHandle handle = new COPSHandle();
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
+
+ IPCMMGate gate = new PCMMGateReq();
+ ITransactionID trID = new TransactionID();
+
+ IAMID amid = new AMID();
+ ISubscriberID subscriberID = new SubscriberID();
+ IGateSpec gateSpec = new GateSpec();
+ IGateID gateID = new GateID();
+
+ // new pcmm specific clientsi
+ COPSClientSI clientSD = new COPSClientSI(COPSObjHeader.COPS_DEC, (byte) 4);
+
+ handle.setId(getClientHandle().getId());
+
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateDelete);
+ _transactionID = (short) (_transactionID == 0 ? (short) (Math.random() * hashCode())
+ : _transactionID);
+ trID.setTransactionIdentifier(_transactionID);
+
+ amid.setApplicationType((short) 1);
+ amid.setApplicationMgrTag((short) 1);
+ gateID.setGateID(gID);
+
+ try {
+ InetAddress subIP = InetAddress.getByName(PCMMGlobalConfig.SubscriberID);
+ subscriberID.setSourceIPAddress(subIP);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateID(gateID);
+
+ // XXX - GateID
+ byte[] data = gate.getData();
+
+ // new pcmm specific clientsi
+ clientSD.setData(new COPSData(data, 0, data.length));
+
+ try {
+ decisionMsg.add(hdr);
+ decisionMsg.add(handle);
+ // Decisions (no flags supplied)
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ COPSDecision install = new COPSDecision();
+ install.setCmdCode(COPSDecision.DEC_INSTALL);
+ install.setFlags(COPSDecision.F_REQERROR);
+ decisionMsg.addDecision(install, cntxt);
+ decisionMsg.add(clientSD); // setting up the gate
+ /*
+ try {
+ decisionMsg.dump(System.out);
+ } catch (IOException unae) {
+ System.out.println("Error dumping " + unae.getMessage());
+ }
+ */
+
+ } catch (COPSException e) {
+ System.out.println("Error making Msg" + e.getMessage());
+ }
+
+ // ** Send the GateDelete Decision
+ // **
+ try {
+ decisionMsg.writeData(_sock);
+ // decisionMsg.writeData(socket_id);
+ } catch (IOException e) {
+ System.out.println("Failed to send the decision, reason: "
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a request asking that a new request state be created
+ *
+ * @throws COPSPdpException
+ */
+ public void sendOpenNewRequestState() throws COPSPdpException {
+ /*
+ * <Decision Message> ::= <Common Header: Flag UNSOLICITED> <Client
+ * Handle> *(<Decision>) [<Integrity>] <Decision> ::= <Context>
+ * <Decision: Flags> <Decision: Flags> ::= 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
+ COPSHandle clienthandle = new COPSHandle();
+ clienthandle.setId(_handle.getId());
+
+ // Decisions
+ // <Context>
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
+ // <Decision: Flags>
+ 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 sendGateInfo() throws COPSPdpException {
+ /*
+ * <Gate-Info> ::= <Common Header> [<Client Handle>] [<Integrity>]
+ */
+
+ // 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
+ COPSHandle clienthandle = new COPSHandle();
+ clienthandle.setId(_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 GateInfo request, reason: "
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a message asking for a COPS sync operation
+ *
+ * @throws COPSPdpException
+ */
+ public void sendSyncRequest() throws COPSPdpException {
+ /*
+ * <Synchronize State Request> ::= <Common Header> [<Client Handle>]
+ * [<Integrity>]
+ */
+
+ // 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
+ COPSHandle clienthandle = new COPSHandle();
+ clienthandle.setId(_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());
+ }
+ }
+ // XXX - Temp
+ public void sendSyncRequestState() throws COPSPdpException {
+ }
+ // XXX - Temp
+ public void sendDeleteRequestState() throws COPSPdpException {
+ }
+}
--- /dev/null
+/**\r
+ @header@\r
+ */\r
+\r
+package org.pcmm;\r
+\r
+/*\r
+import java.io.*;\r
+import java.util.UUID.*;\r
+*/\r
+import java.net.Socket;\r
+import java.util.Arrays;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.pcmm.gates.ITransactionID;\r
+import org.pcmm.gates.impl.PCMMGateReq;\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.prpdp.COPSPdpException;\r
+import org.umu.cops.stack.COPSClientSI;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSPrObjBase;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReportType;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+/*\r
+import org.pcmm.base.IPCMMBaseObject;\r
+import org.pcmm.gates.IAMID;\r
+import org.pcmm.gates.IGateID;\r
+import org.pcmm.gates.ISubscriberID;\r
+import org.pcmm.gates.IPCError;\r
+import org.pcmm.gates.impl.AMID;\r
+import org.pcmm.gates.impl.GateID;\r
+import org.pcmm.gates.impl.SubscriberID;\r
+import org.pcmm.gates.impl.TransactionID;\r
+import org.pcmm.gates.impl.PCError;\r
+*/\r
+\r
+\r
+\r
+\r
+/**\r
+ * State manager class for provisioning requests, at the PDP side.\r
+ */\r
+public class PCMMPdpReqStateMan {\r
+\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request received\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions sent\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report received\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request State finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New Request State solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete Request State solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC request sent\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * SYNC completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * Keep-alive timeout\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * Accounting timeout\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Object for performing policy data processing\r
+ */\r
+ protected PCMMPdpDataProcess _process;\r
+\r
+ /**\r
+ * Current state of the request being managed\r
+ */\r
+ protected short _status;\r
+\r
+ /** COPS message transceiver used to send COPS messages */\r
+ protected PCMMPdpMsgSender _sender;\r
+\r
+ /**\r
+ * Creates a request state manager\r
+ * @param clientType Client-type\r
+ * @param clientHandle Client handle\r
+ */\r
+ public PCMMPdpReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+\r
+ _status = ST_CREATE;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the status of the request\r
+ * @return Request state value\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Gets the policy data processing object\r
+ * @return Policy data processing object\r
+ */\r
+ public PCMMPdpDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Sets the policy data processing object\r
+ * @param process Policy data processing object\r
+ */\r
+ public void setDataProcess(PCMMPdpDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Called when COPS sync is completed\r
+ * @param repMsg COPS sync message\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
+ throws COPSPdpException {\r
+\r
+ _status = ST_SYNCALL;\r
+\r
+ // maybe we should notifySyncComplete ...\r
+ }\r
+\r
+ /**\r
+ * Initializes a new request state over a socket\r
+ * @param sock Socket to the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void initRequestState(Socket sock)\r
+ throws COPSPdpException {\r
+ // Inits an object for sending COPS messages to the PEP\r
+ _sender = new PCMMPdpMsgSender(_clientType, _handle, sock);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ * Processes a COPS request\r
+ * @param msg COPS request received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processRequest(COPSReqMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ COPSHeader hdrmsg = msg.getHeader();\r
+ COPSHandle handlemsg = msg.getClientHandle();\r
+ COPSContext contextmsg = msg.getContext();\r
+\r
+ //** Analyze the request\r
+ //**\r
+\r
+ /* <Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
+ *\r
+ * Very important, this is actually being treated like this:\r
+ * <Named ClientSI> ::= <PRID> | <EPD>\r
+ *\r
+\r
+ // Named ClientSI\r
+ Vector clientSIs = msg.getClientSI();\r
+ Hashtable reqSIs = new Hashtable(40);\r
+ String strobjprid = new String();\r
+ for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
+ switch (obj.getSNum())\r
+ {\r
+ case COPSPrObjBase.PR_PRID:\r
+ strobjprid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ reqSIs.put(strobjprid, obj.getData().str());\r
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ //** Here we must retrieve a decision depending on\r
+ //** the supplied ClientSIs\r
+ // reqSIs is a hashtable with the prid and epds\r
+\r
+ // ................\r
+ //\r
+ Hashtable removeDecs = new Hashtable();\r
+ Hashtable installDecs = new Hashtable();\r
+ _process.setClientData(this, reqSIs);\r
+\r
+ removeDecs = _process.getRemovePolicy(this);\r
+ installDecs = _process.getInstallPolicy(this);\r
+\r
+ //** We create the SOLICITED decision\r
+ //**\r
+ _sender.sendDecision(removeDecs, installDecs);\r
+ _status = ST_DECS;\r
+ */\r
+ }\r
+\r
+ /**\r
+ * Processes a report\r
+ * @param msg Report message from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processReport(COPSReportMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ //** Analyze the report\r
+ //**\r
+\r
+ /*\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
+ * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
+ *\r
+ * Important, <Named ClientSI> is not parsed\r
+ */\r
+\r
+ // COPSHeader hdrmsg = msg.getHeader();\r
+ // COPSHandle handlemsg = msg.getClientHandle();\r
+\r
+ // WriteBinaryDump("COPSReportMessage", msg.getData().getData());\r
+ // Report Type\r
+ COPSReportType rtypemsg = msg.getReport();\r
+\r
+ // Named ClientSI\r
+ Vector clientSIs = msg.getClientSI();\r
+ COPSClientSI myclientSI = (COPSClientSI) msg.getClientSI().elementAt(0);\r
+ byte[] data = Arrays.copyOfRange(myclientSI.getData().getData(), 0, myclientSI.getData().getData().length );\r
+\r
+ // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);\r
+ System.out.println("PCMMGateReq Parse Gate Message");\r
+ PCMMGateReq gateMsg = new PCMMGateReq(data);\r
+\r
+ Hashtable repSIs = new Hashtable(40);\r
+ String strobjprid = new String();\r
+ for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ System.out.println("COPSPrObjBase.PR_PRID");\r
+ strobjprid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ System.out.println("COPSPrObjBase.PR_EPD");\r
+ repSIs.put(strobjprid, obj.getData().str());\r
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
+ break;\r
+ default:\r
+ COPSDebug.err(getClass().getName(),"Object s-num: " + obj.getSNum() + "stype " + obj.getSType());\r
+ COPSDebug.err(getClass().getName(),"PRID: " + strobjprid);\r
+ COPSDebug.err(getClass().getName(),"EPD: " + obj.getData().str());\r
+ break;\r
+ }\r
+ }\r
+\r
+ System.out.println("rtypemsg process");\r
+ //** Here we must act in accordance with\r
+ //** the report received\r
+ if (rtypemsg.isSuccess()) {\r
+ System.out.println("rtypemsg success");\r
+ _status = ST_REPORT;\r
+ if (_process != null)\r
+ _process.successReport(this, gateMsg);\r
+ else\r
+{\r
+ if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {\r
+ System.out.println(getClass().getName()+ ": GateDeleteAck ");\r
+ System.out.println(getClass().getName()+ ": GateID = " + gateMsg.getGateID().getGateID());\r
+ if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())\r
+ PCMMGlobalConfig.setGateID1(0);\r
+ if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2())\r
+ PCMMGlobalConfig.setGateID2(0);\r
+\r
+ }\r
+ if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) {\r
+ System.out.println(getClass().getName()+ ": GateSetAck ");\r
+ System.out.println(getClass().getName()+ ": GateID = " + gateMsg.getGateID().getGateID());\r
+ if (0 == PCMMGlobalConfig.getGateID1())\r
+ PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());\r
+ if (0 == PCMMGlobalConfig.getGateID2())\r
+ PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());\r
+ }\r
+\r
+}\r
+ } else if (rtypemsg.isFailure()) {\r
+ System.out.println("rtypemsg failure");\r
+ _status = ST_REPORT;\r
+ if (_process != null)\r
+ _process.failReport(this, gateMsg);\r
+else\r
+{\r
+ System.out.println(getClass().getName()+ ": " + gateMsg.getError().toString());\r
+}\r
+\r
+ } else if (rtypemsg.isAccounting()) {\r
+ System.out.println("rtypemsg account");\r
+ _status = ST_ACCT;\r
+ if (_process != null)\r
+ _process.acctReport(this, gateMsg);\r
+ }\r
+ System.out.println("Out processReport");\r
+ }\r
+\r
+ /**\r
+ * Called when connection is closed\r
+ * @param error Reason\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processClosedConnection(COPSError error)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ /**\r
+ * Called when no keep-alive is received\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processNoKAConnection()\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ /**\r
+ * Deletes the request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void finalizeRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendDeleteRequestState();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Asks for a COPS sync\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendSyncRequestState();\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ /**\r
+ * Opens a new request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void openNewRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendOpenNewRequestState();\r
+ _status = ST_NEW;\r
+ }\r
+\r
+ /**\r
+ * Processes a COPS delete message\r
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+}\r
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.umu.cops.common.COPSDebug;
+import org.umu.cops.prpep.COPSPepAgent;
+import org.umu.cops.prpep.COPSPepConnection;
+import org.umu.cops.prpep.COPSPepException;
+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 PCMMPepAgent extends COPSPepAgent implements Runnable {
+
+ /** Well-known port for COPS */
+ public static final int WELL_KNOWN_CMTS_PORT = 3918;
+
+ /**
+ * PDP host IP
+ */
+ private ServerSocket serverSocket;
+
+ /**
+ * PDP host port
+ */
+ private int serverPort;
+
+ /**
+ * COPS error returned by PDP
+ */
+ private COPSError error;
+
+ /**
+ * Creates a PEP agent
+ *
+ * @param pepID
+ * PEP-ID
+ * @param clientType
+ * Client-type
+ */
+ public PCMMPepAgent(String pepID, short clientType) {
+ super(pepID, clientType);
+ serverPort = WELL_KNOWN_CMTS_PORT;
+ }
+
+ /**
+ * Creates a PEP agent with a PEP-ID equal to "noname"
+ *
+ * @param clientType
+ * Client-type
+ */
+ public PCMMPepAgent(short clientType) {
+ super(clientType);
+ serverPort = WELL_KNOWN_CMTS_PORT;
+ }
+
+ /**
+ * Runs the PEP process XXX - not sure of the exception throwing
+ */
+ public void run() {
+ try {
+
+ COPSDebug.err(getClass().getName(), "Create Server Socket on Port "
+ + serverPort);
+
+ 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.err(getClass().getName(), "New connection accepted "
+ + socket.getInetAddress() + ":" + socket.getPort());
+
+ processConnection(socket);
+ /**
+ * XXX - processConnection handles the open request from PEP And
+ * a thread is created for conn = new
+ * COPSPepConnection(_clientType, socket); the main processing
+ * loop for PEP
+ */
+
+ }
+ } catch (IOException e) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
+ } catch (COPSException e) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
+ } catch (COPSPepException e) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
+ }
+ }
+
+ /**
+ * Establish connection to PDP's IP address
+ *
+ * <Client-Open> ::= <Common Header> <PEPID> [<ClientSI>] [<LastPDPAddr>]
+ * [<Integrity>]
+ *
+ * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]
+ *
+ * <Client-Accept> ::= <Common Header> <KA Timer> [<ACCT Timer>]
+ * [<Integrity>]
+ *
+ * Not send [<Integrity>]
+ *
+ * <Client-Close> ::= <Common Header> <Error> [<PDPRedirAddr>] [<Integrity>]
+ *
+ * Not send [<PDPRedirAddr>], [<Integrity>]
+ *
+ * @throws UnknownHostException
+ * @throws IOException
+ * @throws COPSException
+ * @throws COPSPepException
+ *
+ */
+ private COPSPepConnection processConnection(Socket socket)
+ throws UnknownHostException, IOException, COPSException,
+ COPSPepException {
+ // Build OPN
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, getClientType());
+
+ COPSPepId pepId = new COPSPepId();
+ COPSData d = new COPSData(getPepID());
+ 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);
+ */
+ COPSDebug.err(getClass().getName(), "Send COPSClientOpenMsg to PDP");
+ msg.writeData(socket);
+
+ // Receive the response
+ COPSDebug.err(getClass().getName(), "Receive the resposne from PDP");
+ COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
+
+ if (recvmsg.getHeader().isAClientAccept()) {
+ COPSDebug.err(getClass().getName(), "isAClientAccept from PDP");
+ 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(getClientType(),
+ socket);
+ conn.setKaTimer(_kaTimeVal);
+ conn.setAcctTimer(_acctTimer);
+ COPSDebug.err(getClass().getName(), "Thread(conn).start");
+ new Thread(conn).start();
+
+ return conn;
+ } else if (recvmsg.getHeader().isAClientClose()) {
+ COPSDebug.err(getClass().getName(), "isAClientClose from PDP");
+ 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());
+ }
+ }
+
+ /**
+ * Gets the COPS error returned by the PDP
+ *
+ * @return <tt>COPSError</tt> returned by PDP
+ */
+ public COPSError getConnectionError() {
+ return error;
+ }
+
+ public void setConnectionError(COPSError _error) {
+ this.error = _error;
+ }
+
+ /**
+ * @return the serverSocket
+ */
+ public ServerSocket getServerSocket() {
+ return serverSocket;
+ }
+
+ /**
+ * @param serverSocket
+ * the serverSocket to set
+ */
+ public void setServerSocket(ServerSocket serverSocket) {
+ this.serverSocket = serverSocket;
+ }
+
+ /**
+ * @return the serverPort
+ */
+ public int getServerPort() {
+ return serverPort;
+ }
+
+ /**
+ * @param serverPort
+ * the serverPort to set
+ */
+ public void setServerPort(int serverPort) {
+ this.serverPort = serverPort;
+ }
+
+}
--- /dev/null
+package org.pcmm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Loads the PCMM Properties file.
+ *
+ */
+public class PCMMProperties implements PCMMConstants {
+
+ private static Properties properties;
+ private static Logger logger = LoggerFactory.getLogger(PCMMProperties.class);
+
+ static {
+ try {
+ InputStream in = PCMMProperties.class.getClassLoader().getResourceAsStream("pcmm.properties");
+ properties = new Properties();
+ properties.load(in);
+ in.close();
+ } catch (IOException ie) {
+ logger.error(ie.getMessage());
+ }
+ }
+
+ protected static String get(String key) {
+ return properties.getProperty(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> T get(String key, Class<T> type, Object _default) {
+ String prop = get(key);
+ if (prop != null && !prop.isEmpty()) {
+ if (Boolean.class.isAssignableFrom(type))
+ return (T) Boolean.valueOf(prop);
+ else if (Integer.class.isAssignableFrom(type))
+ return (T) Integer.valueOf(prop);
+ else if (Short.class.isAssignableFrom(type))
+ return (T) Short.valueOf(prop);
+ if (Float.class.isAssignableFrom(type))
+ return (T) Float.valueOf(prop);
+ if (Long.class.isAssignableFrom(type))
+ return (T) Long.valueOf(prop);
+ if (Double.class.isAssignableFrom(type))
+ return (T) Double.valueOf(prop);
+ else if (String.class.isAssignableFrom(type))
+ return (T) prop;
+ }
+ return (T) _default;
+ }
+
+ public static <T> T get(String key, Class<T> type) {
+ return get(key, type, null);
+ }
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.base;
+
+/**
+ * Adapter interface
+ *
+ */
+public interface IAdapter<Type> {
+
+ Object adapt(Object object, Class<?> clazz);
+
+ Type adapt(Object object);
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.base;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import org.umu.cops.stack.COPSData;
+
+/**
+ * Base interface for all PCMM objects, it define the {@code S-Type},
+ * {@code S-Num} and the data length
+ *
+ */
+public interface IPCMMBaseObject {
+
+ /**
+ * sets the S-Type
+ *
+ * @param stype
+ */
+ void setSType(byte stype);
+
+ /**
+ *
+ * @return S-Type
+ */
+ byte getSType();
+
+ /**
+ * sets the S-Num
+ *
+ * @param snum
+ * S-Num
+ */
+ void setSNum(byte snum);
+
+ /**
+ * gets the S-Num
+ *
+ * @return S-Num
+ */
+ byte getSNum();
+
+ /**
+ * sets the length;
+ *
+ * @param len
+ */
+ void setLength(short len);
+
+ /**
+ * gets the length;
+ *
+ * @return length
+ */
+ short getLength();
+
+ /**
+ * sets the COPS data
+ *
+ * @param data
+ * COPS data
+ */
+ void setData(COPSData data);
+
+ /**
+ * gets the COPS data
+ *
+ * @return COPS data
+ */
+ COPSData getData();
+
+ void writeData(Socket id) throws IOException;
+
+ byte[] getAsBinaryArray();
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.base.impl;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Arrays;
+
+import org.pcmm.base.IPCMMBaseObject;
+import org.umu.cops.stack.COPSData;
+
+/**
+ *
+ * Implementation of the base class {@link IPCMMBaseObject}
+ *
+ */
+public class PCMMBaseObject /* extends COPSPrObjBase */implements
+ IPCMMBaseObject {
+
+ private byte sType;
+ private byte sNum;
+ private short len;
+ private COPSData copsData;
+ private COPSData pad;
+ protected final short offset = (short) 4;
+
+ public PCMMBaseObject(byte[] data) {
+ parse(data);
+ }
+
+ public PCMMBaseObject(short len, byte sType, byte sNum) {
+ this.len = (len);
+ this.sType = (sType);
+ this.sNum = (sNum);
+ byte[] array = new byte[len - offset];
+ Arrays.fill(array, (byte) 0);
+ setData(new COPSData(array, 0, array.length));
+ }
+
+ protected COPSData getPadding(int len) {
+ byte[] padBuf = new byte[len];
+ Arrays.fill(padBuf, (byte) 0);
+ COPSData d = new COPSData(padBuf, 0, len);
+ return d;
+ }
+
+ /**
+ * Add head padding to the specified byte array filled with zeros
+ *
+ * @param off
+ * offset
+ * @param array
+ * input array
+ * @return byte array
+ */
+ protected byte[] headPadding(int off, byte[] array) {
+ byte[] returnArray = new byte[array.length + off];
+ Arrays.fill(returnArray, (byte) 0);
+ System.arraycopy(array, 0, returnArray, off, array.length);
+ return returnArray;
+ }
+
+ protected void parse(byte[] data) {
+ if (data == null || data.length == 0)
+ throw new IllegalArgumentException("data could not be null");
+ len = 0;
+ len |= ((short) data[0]) << 8;
+ len |= ((short) data[1]) & 0xFF;
+ sNum = data[2];
+ sType = data[3];
+ copsData = new COPSData(data, offset, data.length - offset);
+ }
+
+ protected void setShort(short value, short startPos) {
+ byte[] data = getData().getData();
+ data[startPos] = (byte) (value >> 8);
+ data[startPos + 1] = (byte) value;
+ setData(new COPSData(data, 0, data.length));
+ }
+
+ protected short getShort(short startPos) {
+ byte[] data = getData().getData();
+ short retVal = 0;
+ retVal |= ((short) data[startPos]) << 8;
+ retVal |= ((short) data[startPos + 1]) & 0xFF;
+ return retVal;
+ }
+
+ protected void setInt(int value, short startPos) {
+ byte[] data = getData().getData();
+ data[startPos] = (byte) (value >> 24);
+ data[startPos + 1] = (byte) (value >> 16);
+ data[startPos + 2] = (byte) (value >> 8);
+ data[startPos + 3] = (byte) value;
+ setData(new COPSData(data, 0, data.length));
+ }
+
+ protected int getInt(short startPos) {
+ byte[] data = getData().getData();
+ int retVal = 0;
+ retVal |= ((short) data[startPos]) << 24;
+ retVal |= ((short) data[startPos + 1]) << 16;
+ retVal |= ((short) data[startPos + 2]) << 8;
+ retVal |= ((short) data[startPos + 3]) & 0xFF;
+ return retVal;
+ }
+
+ protected void setBytes(byte[] value, short startPos) {
+ byte[] data = getData().getData();
+ for (byte b : value)
+ data[startPos++] = b;
+ setData(new COPSData(data, 0, data.length));
+ }
+
+ protected byte[] getBytes(short startPos, short size) {
+ return Arrays.copyOfRange(getData().getData(), startPos, startPos
+ + size);
+ }
+
+ protected void setByte(byte value, short startPos) {
+ setBytes(new byte[] { value }, startPos);
+ }
+
+ protected byte getByte(short startPos) {
+ return getBytes(startPos, (short) 1)[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#setSType(byte)
+ */
+ @Override
+ public void setSType(byte stype) {
+ this.sType = stype;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#getSType()
+ */
+ @Override
+ public byte getSType() {
+ return sType;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#setSNum(byte)
+ */
+ @Override
+ public void setSNum(byte snum) {
+ this.sNum = snum;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#getSNum()
+ */
+ @Override
+ public byte getSNum() {
+ return sNum;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#setLength(short)
+ */
+ @Override
+ public void setLength(short len) {
+ this.len = len;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#getLength()
+ */
+ @Override
+ public short getLength() {
+ return (short) (len + (pad != null ? pad.length() : 0));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#setData(org.umu.cops.stack.COPSData)
+ */
+ @Override
+ public void setData(COPSData data) {
+ this.copsData = data;
+ if (data.length() % offset != 0) {
+ int padLen = offset - (data.length() % offset);
+ pad = getPadding(padLen);
+ }
+ len = (short) (data.length() + offset);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#getData()
+ */
+ @Override
+ public COPSData getData() {
+ return copsData;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#writeData(java.net.Socket)
+ */
+ public void writeData(Socket id) throws IOException {
+ byte[] data = getAsBinaryArray();
+ id.getOutputStream().write(data, 0, data.length);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.base.IPCMMBaseObject#getAsBinaryArray()
+ */
+ @Override
+ public byte[] getAsBinaryArray() {
+ byte[] array = new byte[getLength()];
+ array[0] = (byte) (len >> 8);
+ array[1] = (byte) len;
+ array[2] = sNum;
+ array[3] = sType;
+ System.arraycopy(getData().getData(), 0, array, offset, getData()
+ .length());
+ if (pad != null)
+ System.arraycopy(pad.getData(), 0, array, offset
+ + getData().length(), pad.length());
+ return array;
+ }
+}
--- /dev/null
+package org.pcmm.concurrent;
+
+import java.util.concurrent.Callable;
+/**
+ *
+ */
+public interface IWorker extends Runnable {
+
+ /**
+ * defines the task to be performed by this worker
+ *
+ * @param c
+ */
+ void task(Callable<?> c);
+
+ /**
+ * defines wait time before start working on the task
+ *
+ * @param t
+ */
+ void shouldWait(int t);
+
+ /**
+ * ends the current working task.
+ */
+ void done();
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.concurrent;
+
+import org.pcmm.base.IAdapter;
+
+/**
+ *
+ */
+public interface IWorkerPool extends IAdapter<IWorker> {
+ // handles 32 workers
+ static int DEFAULT_MAX_WORKERS = 32;
+
+ /**
+ * schedules a worker for beginning its task after t milliseconds.
+ *
+ * @param worker
+ * : the worker
+ * @param t
+ * : time to wait
+ * @return the id of the worker (PID) to be used for killing the worker if
+ * needed
+ */
+ int schedule(IWorker worker, int t);
+
+ /**
+ * schedules a worker for immediate execution.
+ *
+ * @param worker
+ * : the worker
+ * @return the id of the worker (PID) to be used for killing the worker if
+ * needed
+ */
+ int schedule(IWorker worker);
+
+ /**
+ * kills the worker with the specified pid
+ *
+ * @param pid
+ */
+ void sendKillSignal(int pid);
+
+ /**
+ * sends a terminate signal for all active workers and recycles the pool.
+ */
+ void killAll();
+
+ /**
+ * cleans up the pool from finished tasks
+ */
+ void recycle();
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.concurrent.impl;
+
+import java.util.concurrent.Callable;
+
+import org.pcmm.concurrent.IWorker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ */
+public class Worker implements IWorker {
+
+ private int waitTimer;
+
+ private Callable<?> task;
+ private Logger logger = LoggerFactory.getLogger(IWorker.class);
+
+ public Worker() {
+
+ }
+
+ public Worker(Callable<?> task) {
+ this.task = task;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+ try {
+ if (waitTimer > 0)
+ Thread.sleep(waitTimer);
+ task.call();
+ } catch (Throwable e) {
+ logger.error(e.getMessage());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorker#task(java.util.concurrent.Callable)
+ */
+ @Override
+ public void task(Callable<?> c) {
+ logger.debug("Task added " + c);
+ this.task = c;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorker#shouldWait(int)
+ */
+ @Override
+ public void shouldWait(int t) {
+ logger.debug("Worker will start after :" + t + " ms");
+ waitTimer = t;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorker#done()
+ */
+ @Override
+ public void done() {
+ logger.debug("worker finished tasks");
+
+ }
+
+}
--- /dev/null
+package org.pcmm.concurrent.impl;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.pcmm.concurrent.IWorker;
+import org.pcmm.concurrent.IWorkerPool;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Pool to manage PCMM workers
+ */
+public class WorkerPool implements IWorkerPool {
+
+ /**
+ *
+ */
+ private Map<Integer, WeakReference<IWorker>> workersMap;
+
+ private Logger logger = LoggerFactory.getLogger(IWorkerPool.class);
+ private ExecutorService executor;
+
+ public WorkerPool() {
+ this(DEFAULT_MAX_WORKERS);
+ }
+
+ public WorkerPool(int size) {
+ logger.info("Pool size :" + size);
+ workersMap = new HashMap<Integer, WeakReference<IWorker>>();
+ executor = Executors.newFixedThreadPool(size);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorkerPool#schedule(org.pcmm.threading.IWorker,
+ * int)
+ */
+ @Override
+ public int schedule(IWorker worker, int t) {
+ if (worker == null)
+ return -1;
+ logger.debug("woker[" + worker + "] added, starts in " + t + " ms");
+ WeakReference<IWorker> workerRef = new WeakReference<IWorker>(worker);
+ int ref = workerRef.hashCode();
+ workersMap.put(ref, workerRef);
+ worker.shouldWait(t);
+ executor.execute(worker);
+ return ref;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.concurrent.IWorkerPool#schedule(org.pcmm.concurrent.IWorker)
+ */
+ @Override
+ public int schedule(IWorker worker) {
+ return schedule(worker, 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.concurrent.IWorkerPool#sendKillSignal(int)
+ */
+ @Override
+ public void sendKillSignal(int pid) {
+ if (workersMap.size() > 0) {
+ WeakReference<IWorker> weakRef = workersMap.get(pid);
+ if (weakRef != null) {
+ IWorker ref = weakRef.get();
+ if (ref != null)
+ ref.done();
+ if (!weakRef.isEnqueued()) {
+ weakRef.clear();
+ weakRef.enqueue();
+ }
+ }
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorkerPool#killAll()
+ */
+ @Override
+ public void killAll() {
+ for (WeakReference<IWorker> weakRef : workersMap.values()) {
+ IWorker ref = weakRef.get();
+ if (ref != null)
+ ref.done();
+ if (!weakRef.isEnqueued()) {
+ weakRef.clear();
+ weakRef.enqueue();
+ }
+ }
+ recycle();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.threading.IWorkerPool#recycle()
+ */
+ @Override
+ public void recycle() {
+ for (Iterator<Integer> pids = workersMap.keySet().iterator(); pids.hasNext();) {
+ WeakReference<IWorker> weakRef = workersMap.get(pids.next());
+ IWorker ref = weakRef.get();
+ if (ref == null) {
+ if (!weakRef.isEnqueued()) {
+ weakRef.clear();
+ weakRef.enqueue();
+ }
+ workersMap.remove(weakRef);
+ }
+ }
+
+ }
+
+ @Override
+ public Object adapt(Object object, Class<?> clazz) {
+ if (clazz.isAssignableFrom(object.getClass()))
+ return object;
+ return null;
+ }
+
+ @Override
+ public IWorker adapt(Object object) {
+ IWorker worker = (IWorker) adapt(object, IWorker.class);
+ if (worker == null) {
+ if (object instanceof Callable)
+ worker = new Worker((Callable<?>) object);
+ else if (object instanceof Runnable) {
+ final Runnable runner = (Runnable) object;
+ worker = new Worker(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ ((Runnable) runner).run();
+ return null;
+ }
+ });
+ }
+ }
+ return worker;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ * <p>
+ * The AMID consists of two fields: the Application Manager Tag and Application
+ * Type. Each Application Manager is pre-provisioned with an Application Manager
+ * Tag that is unique within the universe of a single service provider. The
+ * Application Manager may also be pre-provisioned with a set of Application
+ * Type values that can be used to identify the particular application that a
+ * gate is associated with. The Application Manager includes the AMID in all
+ * messages that it issues to the Policy Server. The Policy Server transparently
+ * passes this information to the CMTS via Gate Control messages. The CMTS MUST
+ * return the AMID associated with the Gate to the Policy Server. The Policy
+ * Server uses this information to associate Gate messages with a particular
+ * Application Manager and Application Type.
+ * </p>
+ * <p>
+ * The Application Manager Tag MUST be a globally unique value assigned to the
+ * Application Manager by the service provider. The Application Manager MUST use
+ * the assigned Application Manager Tag in all its interactions with Policy
+ * Servers. Note that since the Application Manager may be operated by a third
+ * party, and a single Application Manager could interact with multiple service
+ * provider operators, a single physical Application Manager may be provisioned
+ * with multiple Application Manager Tags, and multiple Application Type sets
+ * (one for each configured Application Manager Tag).
+ * </p>
+ *
+ *
+ */
+public interface IAMID extends IPCMMBaseObject {
+
+ static final short LENGTH = 8;
+ static final byte SNUM = 2;
+ static final byte STYPE = 1;
+
+ void setApplicationType(short type);
+
+ short getApplicationType();
+
+ void setApplicationMgrTag(short type);
+
+ short getApplicationMgrTag();
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import java.net.InetAddress;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ *
+ *
+ *
+ */
+public interface IClassifier extends IPCMMBaseObject {
+
+ static final short LENGTH = 24;
+ static final byte SNUM = 6;
+ static final byte STYPE = 1;
+
+ static enum Protocol {
+ /*ICMP((short) 1), IGMP((short) 2), */
+ NONE((short)0), TCP((short) 6), UDP((short) 17);
+
+ Protocol(short v) {
+ this.value = v;
+ }
+
+ public static Protocol valueOf(short v) {
+ switch (v) {
+ case 0:
+ return NONE;
+ /*
+ case 1:
+ return ICMP;
+ case 2:
+ return IGMP;
+ */
+ case 6:
+ return TCP;
+ default:
+ return UDP;
+ }
+ }
+ private short value;
+
+ public short getValue() {
+ return value;
+ }
+ }
+
+ /**
+ * IP Destination Address or IPv6 Destination Address is the termination
+ * point for the IP flow
+ *
+ * @return destination IP address.
+ */
+ InetAddress getDestinationIPAddress();
+
+ void setDestinationIPAddress(InetAddress address);
+
+ short getDestinationPort();
+
+ void setDestinationPort(short p);
+
+ /**
+ * Source IP, IP Source Address, or IPv6 Source Address (in the case of
+ * Extended Classifier or IPv6 Classifier) is the IP address (as seen at the
+ * CMTS) of the originator of the IP flow.
+ *
+ * @return source IP address.
+ */
+ InetAddress getSourceIPAddress();
+
+ void setSourceIPAddress(InetAddress a);
+
+ short getSourcePort();
+
+ void setSourcePort(short p);
+
+ /**
+ * Protocol field, in a legacy Classifier or Extended Classifier, identifies
+ * the type of protocol (e.g., IP, ICMP, etc.). The Next Header Type field
+ * serves a similar function in the IPv6 Classifier.
+ *
+ * @return the protocol.
+ */
+ Protocol getProtocol();
+
+ /**
+ * @see <a
+ * href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.txt">protocols</a>
+ * @param p
+ */
+ void setProtocol(Protocol p);
+
+ /**
+ * Priority may be used to distinguish between multiple classifiers that
+ * match a particular packet. This is typically set to a default value since
+ * classifiers are generally intended to be unique.
+ *
+ * @return priority.
+ */
+ byte getPriority();
+
+ /**
+ * sets the priority;
+ *
+ * @param p
+ * priority
+ */
+ void setPriority(byte p);
+
+ byte getDSCPTOS();
+
+ void setDSCPTOS(byte v);
+
+ byte getDSCPTOSMask();
+
+ void setDSCPTOSMask(byte v);
+
+ // DSCP/TOS Field
+ // ï‚·
+ // DSCP/TOS Mask
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import java.net.InetAddress;
+
+public interface IExtendedClassifier extends IClassifier {
+
+ static final short LENGTH = 40;
+ static final byte SNUM = 6;
+ static final byte STYPE = 2;
+
+ void setIPSourceMask(InetAddress a);
+
+ void setIPDestinationMask(InetAddress m);
+
+ void setSourcePortStart(short p);
+
+ void setSourcePortEnd(short p);
+
+ void setDestinationPortStart(short p);
+
+ void setDestinationPortEnd(short p);
+
+ void setClassifierID(short p);
+
+ /**
+ * <pre>
+ * 0x00 Inactive
+ * 0x01 Active
+ * </pre>
+ *
+ * @param s
+ */
+ void setActivationState(byte s);
+
+ /**
+ * <pre>
+ * 0x00 Add classifier
+ * 0x01 Replace classifier
+ * 0x02 Delete classifier
+ * 0x03 No change
+ * </pre>
+ *
+ * @param a
+ */
+ void setAction(byte a);
+
+ InetAddress getIPSourceMask();
+
+ InetAddress getIPDestinationMask();
+
+ short getSourcePortStart();
+
+ short getSourcePortEnd();
+
+ short getDestinationPortStart();
+
+ short getDestinationPortEnd();
+
+ short getClassifierID();
+
+ byte getActivationState();
+
+ byte getAction();
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ *
+ */
+public interface IGateID extends IPCMMBaseObject {
+ static final short LENGTH = 8;
+ static final byte SNUM = 4;
+ static final byte STYPE = 1;
+
+ void setGateID(int gateID);
+
+ int getGateID();
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ * <p>
+ * The GateSpec describes some high-level attributes of the Gate, and contains
+ * information regarding the treatment of other objects specified in the Gate
+ * message.
+ * </p>
+ *
+ *
+ *
+ *
+ */
+public interface IGateSpec extends IPCMMBaseObject {
+
+ static final byte SNUM = 5;
+ static final byte STYPE = 1;
+ static final short LENGTH = 16;
+
+ /**
+ * <p>
+ * Direction indicates whether the Gate is for an upstream or downstream
+ * flow. Depending on this direction, the CMTS MUST reserve and activate the
+ * DOCSIS flows accordingly. For Multicast Gates the CMTS needs to only
+ * support flows or gates in the downstream direction.
+ * </p>
+ *
+ *
+ */
+ public enum Direction {
+
+ UPSTREAM((byte) 1), DOWNSTREAM((byte) 0);
+
+ private Direction(byte value) {
+ this.value = value;
+ }
+
+ public byte getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ switch (value) {
+ case 1:
+ return "Upstream";
+ default:
+ return "Downstream";
+ }
+ }
+
+ private byte value;
+
+ public static Direction valueOf(byte v) {
+ switch (v) {
+ case 0:
+ return Direction.DOWNSTREAM;
+ case 1:
+ return Direction.UPSTREAM;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
+
+ };
+
+ /**
+ *
+ */
+ public enum DSCPTOS {
+
+ ENABLE((byte) 1), OVERRIDE((byte) 0);
+
+ private DSCPTOS(byte value) {
+ this.value = value;
+ }
+
+ public byte getValue() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ switch (value) {
+ case 1:
+ return "Enable";
+ default:
+ return "Override";
+ }
+ }
+
+ public static DSCPTOS valueOf(byte v) {
+ switch (v) {
+ case 0:
+ return DSCPTOS.OVERRIDE;
+ case 1:
+ return DSCPTOS.ENABLE;
+ default:
+ throw new IllegalArgumentException("not supported value");
+ }
+ }
+
+ private byte value;
+
+ };
+
+ /**
+ * <p>
+ * provides a way for the Application Manager and the Policy Server to group
+ * Gates into different classes with different authorization
+ * characteristics. For example, one could use the SessionClassID to
+ * represent some prioritization or preemption scheme that would allow
+ * either the Policy Server or the CMTS to preempt a pre-authorized Gate in
+ * favor of allowing a new Gate with a higher priority to be authorized.
+ * </p>
+ *
+ * @return session class ID;
+ */
+ ISessionClassID getSessionClassID();
+
+ /**
+ * <p>
+ * sets the session class ID;
+ * </p>
+ * <p>
+ * SessionClassID is a 1-byte unsigned integer value which identifies the
+ * proper admission control policy or parameters to be applied for this
+ * Gate. The SessionClassID is a bit field, defined as follows: Bit 0-2:
+ * Priority, a number from 0 to 7, where 0 is low priority and 7 is high.
+ * Bit 3: Preemption, set to enable preemption of bandwidth allocated to
+ * lower priority sessions if necessary (if supported). Bit 4-7:
+ * Configurable, default to 0
+ * </p>
+ */
+ void setSessionClassID(ISessionClassID id);
+
+ /**
+ *
+ * @return direction.
+ */
+ Direction getDirection();
+
+ /**
+ * sets the direction
+ *
+ * @param direction
+ * Direction
+ */
+ void setDirection(Direction direction);
+
+ /**
+ * Authorized Timer limits the amount of time the authorization must remain
+ * valid before it is reserved
+ *
+ * @return time in ms;
+ */
+ short getTimerT1();
+
+ /**
+ * sets the authorized timer
+ *
+ * @param authTimer
+ * : authorized timer
+ */
+ void setTimerT1(short authTimer);
+
+ /**
+ * Reserved Timer limits the amount of time the reservation must remain
+ * valid before the resources are committed
+ *
+ * @return time in ms;
+ */
+ short getTimerT2();
+
+ /**
+ * sets the reserved timer.
+ *
+ * @param timer
+ */
+ void setTimerT2(short timer);
+
+ /**
+ * Committed Timer limits the amount of time a committed service flow may
+ * remain idle.
+ *
+ * @return time in ms;
+ */
+ short getTimerT3();
+
+ /**
+ * sets the committed timer.
+ *
+ * @param t
+ * timer
+ */
+ void setTimerT3(short t);
+
+ /**
+ * Committed Recovery Timer limits the amount of time that a committed
+ * service flow can remain without a subsequent refresh message from the
+ * PS/AM once the PS/AM has been notified of inactivity
+ *
+ * @return time in ms;
+ */
+ short getTimerT4();
+
+ /**
+ * sets the Committed Recovery Timer.
+ *
+ * @param t
+ * timer
+ */
+ void setTimerT4(short t);
+
+ /**
+ *
+ * @param dscpTos
+ */
+ void setDSCP_TOSOverwrite(DSCPTOS dscpTos);
+
+ /**
+ *
+ * @return DSCP/TOS
+ */
+ DSCPTOS getDSCP_TOSOverwrite();
+
+ /**
+ *
+ * @return
+ */
+ byte getDSCP_TOSMask();
+
+ /**
+ *
+ * @param dscp_tos_mask
+ */
+ void setDSCP_TOSMask(byte dscp_tos_mask);
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+public interface IIPv6Classifier extends IExtendedClassifier {
+ static final short LENGTH = 64;
+ static final byte SNUM = 6;
+ static final byte STYPE = 3;
+
+ // Tc-low
+ // Tc-high
+ // Tc-mask
+ // Flow Label
+ // Next Header Type
+ // Source Prefix Length
+ // Destination Prefix Length
+ // IPv6 Source Address
+ // IPv6 Destination Address
+ // Source Port Start
+ // Source Port End
+ // Destination Port Start
+ // Destination Port End
+ // ClassifierID
+ // Priority
+ // Activation State
+ // Action
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ *
+ */
+public interface IPCMMError extends IPCMMBaseObject {
+ static final short LENGTH = 8;
+ static final byte SNUM = 14;
+ static final byte STYPE = 1;
+ final String[] errors = { "Insufficient Resources", "Unknown GateID",
+ "Missing Required Object", "Invalid Object",
+ "Volume Based Usage Limit Exceeded",
+ "Time Based Usage Limit Exceeded", "Session Class Limit Exceeded",
+ "Undefined Service Class Name", "Incompatible Envelope",
+ "Invalid SubscriberID", "Unauthorized AMID",
+ "Number of Classifiers Not Supported", "Policy Exception",
+ "Invalid Field Value in Object", "Transport Error",
+ "Unknown Gate Command", "DOCSIS 1.0 CM",
+ "Number of SIDs exceeded in CM", "Number of SIDs exceeded in CMTS",
+ "Unauthorized PSID", "No State for PDP", "Unsupported Synch Type",
+ "State Data Incomplete", "Upstream Drop Unsupported",
+ "Multicast Gate Error", "Multicast Volume Limit Unsupported",
+ "Uncommitted Multicast Not Supported",
+ "Multicast Gate Modification Not Supported",
+ "Upstream Multicast Not Supported",
+ "Multicast GateSpec incompatibility", "Multicast QoS Error",
+ "Multicast Downstream Resequencing mismatch",
+ "Other, Unspecified Error" };
+
+ static enum Description {
+ ERROR_01((short) 1, errors[0]), ERROR_02((short) 2, errors[1]), ERROR_06(
+ (short) 6, errors[2]), ERROR_07((short) 7, errors[3]), ERROR_08(
+ (short) 8, errors[4]), ERROR_09((short) 9, errors[5]), ERROR_10(
+ (short) 10, errors[6]), ERROR_11((short) 11, errors[7]), ERROR_12(
+ (short) 12, errors[8]), ERROR_13((short) 13, errors[9]), ERROR_14(
+ (short) 14, errors[10]), ERROR_15((short) 15, errors[11]), ERROR_16(
+ (short) 16, errors[12]), ERROR_17((short) 17, errors[13]), ERROR_18(
+ (short) 18, errors[14]), ERROR_19((short) 19, errors[15]), ERROR_20(
+ (short) 20, errors[16]), ERROR_21((short) 21, errors[17]), ERROR_22(
+ (short) 22, errors[18]), ERROR_23((short) 23, errors[19]), ERROR_24(
+ (short) 24, errors[20]), ERROR_25((short) 25, errors[21]), ERROR_26(
+ (short) 26, errors[22]), ERROR_27((short) 27, errors[23]), ERROR_28(
+ (short) 28, errors[24]), ERROR_29((short) 29, errors[25]), ERROR_30(
+ (short) 30, errors[26]), ERROR_31((short) 31, errors[27]), ERROR_32(
+ (short) 32, errors[28]), ERROR_33((short) 33, errors[29]), ERROR_34(
+ (short) 34, errors[30]), ERROR_35((short) 35, errors[31]), ERROR_127(
+ (short) 127, errors[28]);
+
+ private final short code;
+ private final String description;
+
+ private Description(short code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public short getCode() {
+ return code;
+ }
+
+ public static String valueOf(short errCode) {
+ switch (errCode) {
+ case 1:
+ case 2:
+ return errors[errCode - 1];
+ case 127:
+ return errors[32];
+ default:
+ if (errCode > 35 || errCode < 1)
+ throw new IllegalArgumentException("unrecongnized error code : " + errCode);
+ return errors[errCode - 4];
+ }
+ }
+ }
+
+ void setErrorCode(short ErrorCode);
+
+ short getErrorCode();
+
+ void setErrorSubcode(short ErrorSubcode);
+
+ short getErrorSubcode();
+
+ String getDescription();
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+
+/**
+ * <p>
+ * A PacketCable Multimedia Gate is a logical representation of a policy
+ * decision that has been installed on the CMTS. A Gate is used to control
+ * access by a single IP flow to enhanced QoS Services provided by a DOCSIS
+ * cable network. Gates are unidirectional; a single Gate controls access to a
+ * flow in either the upstream or the downstream direction, but not both. For a
+ * bi-directional IP session, two Gates are required, one for upstream and one
+ * for downstream, each identified by a unique GateID. It is important to
+ * recognize that this is a fundamental difference from PacketCable 1.x, in
+ * which a single GateID may reference both an upstream and a downstream Gate.
+ * </p>
+ * <p>
+ * In PacketCable Multimedia, each Gate has a separate GateID. The Gate defines
+ * </p>
+ * <p>
+ *
+ * </p>
+ *
+ *
+ */
+public interface IPCMMGate {
+
+
+ /**
+ *
+ * @return whether this gate is multicast or unicast.
+ */
+ boolean isMulticast();
+
+ /**
+ * GateID is the handle for the Gate.
+ *
+ */
+ void setGateID(IGateID gateid);
+
+ /**
+ * AMID is the handle that identifies the Application Manager and
+ * Application Type
+ *
+ */
+ void setAMID(IAMID iamid);
+
+ /**
+ * SubscriberID uniquely identifies the Client for which the policy is being
+ * set.
+ *
+ */
+ void setSubscriberID(ISubscriberID subscriberID);
+
+ /**
+ * (i.e., QoS limits, timers, etc.).
+ *
+ */
+ void setGateSpec(IGateSpec gateSpec);
+
+ /**
+ * Classifier describes the IP flow(s) that will be mapped to the DOCSIS
+ * Service Flow.
+ *
+ */
+ void setClassifier(IClassifier classifier);
+
+ /**
+ * Traffic Profile describes the QoS attributes of the Service Flow used to
+ * support the IP flow.
+ */
+ void setTrafficProfile(ITrafficProfile profile);
+
+ void setTransactionID(ITransactionID transactionID);
+
+ void setError(IPCMMError error);
+
+ ITransactionID getTransactionID();
+
+ /**
+ * GateID is the handle for the Gate.
+ *
+ * @return gateID
+ */
+ IGateID getGateID();
+
+ /**
+ * AMID is the handle that identifies the Application Manager and
+ * Application Type
+ *
+ * @return AMID handle.
+ */
+ IAMID getAMID();
+
+ /**
+ * SubscriberID uniquely identifies the Client for which the policy is being
+ * set.
+ *
+ * @return unique subscriber ID.
+ */
+ ISubscriberID getSubscriberID();
+
+ /**
+ * (i.e., QoS limits, timers, etc.).
+ *
+ * @return gateSpec object.
+ */
+ IGateSpec getGateSpec();
+
+ /**
+ * Classifier describes the IP flow(s) that will be mapped to the DOCSIS
+ * Service Flow.
+ *
+ * @return Classifier object.
+ */
+ IClassifier getClassifier();
+
+ /**
+ * Traffic Profile describes the QoS attributes of the Service Flow used to
+ * support the IP flow.
+ */
+ ITrafficProfile getTrafficProfile();
+
+ /**
+ * The PacketCable Error object contains information on the type of error that has occurred.
+ */
+ IPCMMError getError();
+
+
+ /**
+ *
+ * @return cops data
+ */
+ byte[] getData();
+ // Event Generation Info (optional)
+ // Time-Based Usage Limit (optional)
+ // Volume-Based Usage Limit (optional)
+ // Opaque Data (optional)
+ // UserID (optional)
+ // SharedResourceID (optional)
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates;
+
+/**
+ *
+ */
+public interface ISessionClassID {
+
+ /**
+ * gets the priority bits
+ *
+ * @return O-7 priority value
+ */
+ byte getPriority();
+
+ /**
+ * sets the priority value (0-7)
+ *
+ * @param value
+ * priority
+ */
+ void setPriority(byte value);
+
+ /**
+ * gets the preemption value;
+ *
+ * @return peemption
+ */
+ byte getPreemption();
+
+ /**
+ * * sets the preemption
+ *
+ * @param value
+ * preemption
+ */
+ void setPreemption(byte value);
+
+ /**
+ * compress the priority and preemption to a single byte value;
+ *
+ * @return SessionClassID as byte
+ */
+ byte toSingleByte();
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import java.net.InetAddress;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ * <p>
+ * The SubscriberID, consisting of the IPv4 or IPv6 address of either the CM or
+ * client CPE device (either directly connected to the CM or on a routable
+ * network behind the CM), identifies the user requesting the service. In
+ * complex network environments this address may be used to route Gate Control
+ * messages between a number of Policy Servers and to determine which CMTS is
+ * providing service to a particular endpoint. In addition to the IPv4 or IPv6
+ * address, a subscriber may also be identified via a FQDN or some opaque data
+ * (object defined below) relevant to the service in question.
+ * </p>
+ * <p>
+ * For a Multicast Gates the CMTS uses the SubscriberID to decide where the
+ * Multicast replication needs to be created. The CMTS treats the SubscriberID
+ * as the source IP address of a JoinMulticastSession [1]. If the SubscriberID
+ * is on an IP subnet that is not directly connected to the CMTS, the CMTS MAY
+ * reject the Gate as having an invalid SubscriberID see 6.4.2.14 PacketCable
+ * Error.
+ * </p>
+ *
+ *
+ */
+
+public interface ISubscriberID extends IPCMMBaseObject {
+ static final short LENGTH = 8;
+ static final byte SNUM = 3;
+ static final byte STYPE = 1;
+
+ /**
+ * source IP address for the PCMM gate.
+ *
+ * @return IP v4 or v6 ip address.
+ */
+ InetAddress getSourceIPAddress();
+
+ void setSourceIPAddress(InetAddress address);
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+public interface ITrafficProfile extends IPCMMBaseObject {
+
+ static final byte SNUM = 7;
+
+ /**
+ * 0x001, 0x011 and 0x111 (Authorized, Reserved, and Committed) are allowed
+ *
+ * @param en
+ */
+ void setEnvelop(byte en);
+
+ byte getEnvelop();
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates;
+
+import org.pcmm.base.IPCMMBaseObject;
+
+/**
+ */
+public interface ITransactionID extends IPCMMBaseObject {
+
+ static final byte SNUM = 1;
+ static final byte STYPE = 1;
+ static final short LENGTH = 8;
+
+ static final short GateSet = 4;
+ static final short GateSetAck = 5;
+ static final short GateSetErr = 6;
+ static final short GateInfo = 7;
+ static final short GateInfoAck = 8;
+ static final short GateInfoErr = 9;
+ static final short GateDelete = 10;
+ static final short GateDeleteAck = 11;
+ static final short GateDeleteErr = 12;
+ static final short GateReportState = 15;
+ static final short GateCmdErr = 16;
+ static final short PDPConfig = 17;
+ static final short PDPConfigAck = 18;
+ static final short PDPConfigErr = 19;
+ static final short SynchRequest = 20;
+ static final short SynchReport = 21;
+ static final short SynchComplete = 22;
+ static final short MsgReceipt = 23;
+
+ void setTransactionIdentifier(short id);
+
+ short getTransactionIdentifier();
+
+ void setGateCommandType(short type);
+
+ short getGateCommandType();
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IAMID;
+
+/**
+ *
+ */
+public class AMID extends PCMMBaseObject implements IAMID {
+
+ /**
+ *
+ */
+ public AMID() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public AMID(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public AMID(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IAMID#setApplicationType(short)
+ */
+ @Override
+ public void setApplicationType(short type) {
+ setShort(type, (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IAMID#getApplicationType()
+ */
+ @Override
+ public short getApplicationType() {
+ return getShort((short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IAMID#setApplicationMgrTag(short)
+ */
+ @Override
+ public void setApplicationMgrTag(short type) {
+ setShort(type, (short) 2);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IAMID#getApplicationMgrTag()
+ */
+ @Override
+ public short getApplicationMgrTag() {
+ return getShort((short) 2);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import java.util.Arrays;
+
+// import org.junit.Assert;
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.ITrafficProfile;
+import org.umu.cops.stack.COPSData;
+
+/**
+ *
+ */
+public class BestEffortService extends PCMMBaseObject implements
+ ITrafficProfile {
+ public static final byte STYPE = 3;
+ // XXX -> 60=0x3C, 112 = 0x70, 164=0xA4
+ // Length = 44=0x2C, 80=0x50 or 116=0x74
+ public static final short LENGTH = 44;
+
+ public static final byte DEFAULT_TRAFFIC_PRIORITY = 0;
+ // Authorized
+ public static final byte DEFAULT_ENVELOP = 0x7;
+
+ public static final int DEFAULT_MAX_TRAFFIC_BURST = 3044;
+
+ private BEEnvelop authorizedEnvelop;
+
+ private BEEnvelop reservedEnvelop;
+
+ private BEEnvelop committedEnvelop;
+
+ /**
+ *
+ * @param e
+ * envelop
+ */
+ public BestEffortService(byte e) {
+ super((short) (e == 1 ? LENGTH : (e == 7 ? 116 : 80)), STYPE, SNUM);
+ setEnvelop(e);
+ authorizedEnvelop = new BEEnvelop();
+ if (e > 1) {
+ reservedEnvelop = new BEEnvelop();
+ if (e == 7)
+ committedEnvelop = new BEEnvelop();
+ }
+ }
+
+ public BestEffortService(byte[] bytes) {
+ super(bytes);
+ byte e = getEnvelop();
+ authorizedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, 8, LENGTH)));
+ if (e > 1) {
+ reservedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, LENGTH, 80)));
+ if (e == 7)
+ committedEnvelop = new BEEnvelop(headPadding(offset, Arrays.copyOfRange(bytes, 80, 116)));
+ }
+ }
+
+ @Override
+ public void setEnvelop(byte e) {
+ setLength((short) (e == 1 ? LENGTH : (e == 7 ? 116 : 80)));
+ // reset cops data to fit the new length
+ byte[] array = new byte[getLength() - offset];
+ Arrays.fill(array, (byte) 0);
+ setData(new COPSData(array, 0, array.length));
+ setByte(e, (short) 0);
+ }
+
+ @Override
+ public byte getEnvelop() {
+ return getByte((short) 0);
+ }
+
+ public BEEnvelop getAuthorizedEnvelop() {
+ return authorizedEnvelop;
+ }
+
+ public BEEnvelop getReservedEnvelop() {
+ return reservedEnvelop;
+ }
+
+ public BEEnvelop getCommittedEnvelop() {
+ return committedEnvelop;
+ }
+
+ @Override
+ public byte[] getAsBinaryArray() {
+ byte[] returnBuffer = super.getAsBinaryArray();
+
+ {// fill buffer with the Authorized Envelop
+ byte[] authEnv = Arrays.copyOfRange(getAuthorizedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
+ // offset + 4 since the Envelop data begin from byte nb 8
+ System.arraycopy(authEnv, 0, returnBuffer, offset + 4, authEnv.length);
+ }
+ if (getReservedEnvelop() != null) {
+ byte[] reservedEnv = Arrays.copyOfRange(getReservedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
+ System.arraycopy(reservedEnv, 0, returnBuffer, LENGTH, reservedEnv.length);
+ }
+ if (getCommittedEnvelop() != null) {
+ byte[] commitEnv = Arrays.copyOfRange(getCommittedEnvelop().getAsBinaryArray(), offset, BEEnvelop.LENGHT);
+ System.arraycopy(commitEnv, 0, returnBuffer, LENGTH + 36, commitEnv.length);
+ }
+ return returnBuffer;
+ }
+
+ /**
+ *
+ *
+ */
+ public static class BEEnvelop extends PCMMBaseObject {
+ // basically we need 36 bytes but since PCMMBasedObject needs 4 bytes
+ // more we allocate 40 bytes and then subtract them when setting BE
+ // data.
+ private final static short LENGHT = 40;
+
+ protected BEEnvelop() {
+ super(LENGHT, (byte) 0, (byte) 0);
+ setTrafficPriority(DEFAULT_TRAFFIC_PRIORITY);
+ }
+
+ protected BEEnvelop(byte[] buffer) {
+ super(buffer);
+ }
+
+ public void setTrafficPriority(byte p) {
+ setByte(p, (short) 0);
+ }
+
+ public byte getTrafficPriority() {
+ return getByte((short) 0);
+ }
+
+ //
+ public void setRequestTransmissionPolicy(int p) {
+ setInt(p, (short) 4);
+ }
+
+ public int getRequestTransmissionPolicy() {
+ return getInt((short) 4);
+ }
+
+ public int getMaximumSustainedTrafficRate() {
+ return getInt((short) 8);
+ }
+
+ public void setMaximumSustainedTrafficRate(int p) {
+ setInt(p, (short) 8);
+ }
+
+ public int getMaximumTrafficBurst() {
+ return getInt((short) 12);
+ }
+
+ public void setMaximumTrafficBurst(int p) {
+ setInt(p, (short) 12);
+ }
+
+ public int getMinimumReservedTrafficRate() {
+ return getInt((short) 16);
+ }
+
+ public void setMinimumReservedTrafficRate(int p) {
+ setInt(p, (short) 16);
+ }
+
+ public short getAssumedMinimumReservedTrafficRatePacketSize() {
+ return getShort((short) 20);
+ }
+
+ public void setAssumedMinimumReservedTrafficRatePacketSize(short p) {
+ setShort(p, (short) 20);
+ }
+
+ public short getMaximumConcatenatedBurst() {
+ return getShort((short) 22);
+ }
+
+ public void setMaximumConcatenatedBurst(short p) {
+ setShort(p, (short) 22);
+ }
+
+ public int getRequiredAttributeMask() {
+ return getInt((short) 24);
+ }
+
+ public void setRequiredAttributeMask(int p) {
+ setInt(p, (short) 24);
+ }
+
+ public int getForbiddenAttributeMask() {
+ return getInt((short) 28);
+ }
+
+ public void setForbiddenAttributeMask(int p) {
+ setInt(p, (short) 28);
+ }
+
+ public int getAttributeAggregationRuleMask() {
+ return getInt((short) 32);
+ }
+
+ public void setAttributeAggregationRuleMask(int p) {
+ setInt(p, (short) 32);
+ }
+
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IClassifier;
+
+/**
+ *
+ */
+public class Classifier extends PCMMBaseObject implements IClassifier {
+
+ /**
+ *
+ */
+ public Classifier() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public Classifier(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public Classifier(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getDestinationIPAddress()
+ */
+ @Override
+ public InetAddress getDestinationIPAddress() {
+ try {
+ return Inet4Address.getByAddress(getBytes((short) 8, (short) 4));
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IClassifier#setDestinationIPAddress(java.net.InetAddress)
+ */
+ @Override
+ public void setDestinationIPAddress(InetAddress address) {
+ setBytes(address.getAddress(), (short) 8);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getDestinationPort()
+ */
+ @Override
+ public short getDestinationPort() {
+ return getShort((short) 14);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setDestinationPort(short)
+ */
+ @Override
+ public void setDestinationPort(short p) {
+ setShort(p, (short) 14);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getSourceIPAddress()
+ */
+ @Override
+ public InetAddress getSourceIPAddress() {
+ try {
+ return Inet4Address.getByAddress(getBytes((short) 4, (short) 4));
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setSourceIPAddress(java.net.InetAddress)
+ */
+ @Override
+ public void setSourceIPAddress(InetAddress a) {
+ setBytes(a.getAddress(), (short) 4);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getSourcePort()
+ */
+ @Override
+ public short getSourcePort() {
+ return getShort((short) 12);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setSourcePort(short)
+ */
+ @Override
+ public void setSourcePort(short p) {
+ setShort(p, (short) 12);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getProtocol()
+ */
+ @Override
+ public Protocol getProtocol() {
+ return Protocol.valueOf(getShort((short) 0));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setProtocol(short)
+ */
+ @Override
+ public void setProtocol(Protocol p) {
+ setShort(p.getValue(), (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getPriority()
+ */
+ @Override
+ public byte getPriority() {
+ return getBytes((short) 16, (short) 1)[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setPriority(byte)
+ */
+ @Override
+ public void setPriority(byte p) {
+ setBytes(new byte[] { p }, (short) 16);
+ }
+
+ @Override
+ public byte getDSCPTOS() {
+ return getBytes((short) 2, (short) 1)[0];
+ }
+
+ @Override
+ public void setDSCPTOS(byte v) {
+ setBytes(new byte[] { v }, (short) 2);
+
+ }
+
+ @Override
+ public byte getDSCPTOSMask() {
+ return getBytes((short) 3, (short) 1)[0];
+ }
+
+ @Override
+ public void setDSCPTOSMask(byte v) {
+ setBytes(new byte[] { v }, (short) 3);
+
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.ITrafficProfile;
+
+/**
+ *
+ */
+public class DOCSISServiceClassNameTrafficProfile extends PCMMBaseObject
+ implements ITrafficProfile {
+
+ public static final byte STYPE = 2;
+ public static final short LENGTH = 12;
+
+ /**
+ *
+ */
+ public DOCSISServiceClassNameTrafficProfile() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public DOCSISServiceClassNameTrafficProfile(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public DOCSISServiceClassNameTrafficProfile(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ setEnvelop((byte) 0x7);
+ }
+
+ /**
+ * @return the serviceClassName
+ */
+ public String getServiceClassName() {
+ return new String(getBytes((short) 4, (short) 4));
+ }
+
+ /**
+ * @param serviceClassName
+ * the serviceClassName to set
+ */
+ public void setServiceClassName(String serviceClassName) {
+ setBytes(serviceClassName.getBytes(), (short) 4);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITrafficProfile#getEnvelop()
+ */
+ @Override
+ public byte getEnvelop() {
+ return getBytes((short) 0, (short) 1)[0];
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITrafficProfile#setEnvelop(byte)
+ */
+ @Override
+ public void setEnvelop(byte en) {
+ setBytes(new byte[] { en }, (short) 0);
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IExtendedClassifier;
+
+/**
+ *
+ */
+public class ExtendedClassifier extends PCMMBaseObject implements
+ IExtendedClassifier {
+
+ public ExtendedClassifier() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public ExtendedClassifier(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public ExtendedClassifier(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getDestinationIPAddress()
+ */
+ @Override
+ public InetAddress getDestinationIPAddress() {
+ try {
+ return InetAddress.getByAddress(getBytes((short) 12, (short) 4));
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IClassifier#setDestinationIPAddress(java.net.InetAddress)
+ */
+ @Override
+ public void setDestinationIPAddress(InetAddress address) {
+ setBytes(address.getAddress(), (short) 12);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getDestinationPort()
+ */
+ @Override
+ public short getDestinationPort() {
+ return getShort((short) 24);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setDestinationPort(short)
+ */
+ @Override
+ public void setDestinationPort(short p) {
+ setShort(p, (short) 24);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getSourceIPAddress()
+ */
+ @Override
+ public InetAddress getSourceIPAddress() {
+ try {
+ return InetAddress.getByAddress(getBytes((short) 4, (short) 4));
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setSourceIPAddress(java.net.InetAddress)
+ */
+ @Override
+ public void setSourceIPAddress(InetAddress a) {
+ setBytes(a.getAddress(), (short) 4);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getSourcePort()
+ */
+ @Override
+ public short getSourcePort() {
+ return getShort((short) 20);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setSourcePort(short)
+ */
+ @Override
+ public void setSourcePort(short p) {
+ setShort(p, (short) 20);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getProtocol()
+ */
+ @Override
+ public Protocol getProtocol() {
+ return Protocol.valueOf(getShort((short) 0));
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setProtocol(short)
+ */
+ @Override
+ public void setProtocol(Protocol p) {
+ setShort(p.getValue(), (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#getPriority()
+ */
+ @Override
+ public byte getPriority() {
+ return getByte((short) 30);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IClassifier#setPriority(byte)
+ */
+ @Override
+ public void setPriority(byte p) {
+ setByte(p, (short) 30);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getIPSourceMask()
+ */
+ @Override
+ public InetAddress getIPSourceMask() {
+ try {
+ return InetAddress.getByAddress(getBytes((short) 8, (short) 4));
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IExtendedClassifier#setIPSourceMask(java.net.InetAddress)
+ */
+ @Override
+ public void setIPSourceMask(InetAddress a) {
+ setBytes(a.getAddress(), (short) 8);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getIPDestinationMask()
+ */
+ @Override
+ public InetAddress getIPDestinationMask() {
+ try {
+ return InetAddress.getByAddress(getBytes((short) 16, (short) 4));
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IExtendedClassifier#setIPDestinationMask(java.net.InetAddress
+ * )
+ */
+ @Override
+ public void setIPDestinationMask(InetAddress m) {
+ setBytes(m.getAddress(), (short) 16);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getSourcePortStart()
+ */
+ @Override
+ public short getSourcePortStart() {
+ return getShort((short) 20);
+ }
+
+ @Override
+ public void setSourcePortStart(short p) {
+ setShort(p, (short) 20);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getSourcePortEnd()
+ */
+ @Override
+ public short getSourcePortEnd() {
+ return getShort((short) 22);
+ }
+
+ @Override
+ public void setSourcePortEnd(short p) {
+ setShort(p, (short) 22);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getDestinationPortStart()
+ */
+ @Override
+ public short getDestinationPortStart() {
+ return getShort((short) 24);
+ }
+
+ @Override
+ public void setDestinationPortStart(short p) {
+ setShort(p, (short) 24);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getDestinationPortEnd()
+ */
+ @Override
+ public short getDestinationPortEnd() {
+ return getShort((short) 26);
+ }
+
+ @Override
+ public void setDestinationPortEnd(short p) {
+ setShort(p, (short) 26);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getClassifierID()
+ */
+ @Override
+ public short getClassifierID() {
+ return getShort((short) 28);
+ }
+
+ @Override
+ public void setClassifierID(short p) {
+ setShort(p, (short) 28);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getActivationState()
+ */
+ @Override
+ public byte getActivationState() {
+ return getByte((short) 31);
+ }
+
+ @Override
+ public void setActivationState(byte s) {
+ setByte(s, (short) 31);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IExtendedClassifier#getAction()
+ */
+ @Override
+ public byte getAction() {
+ return getByte((short) 32);
+ }
+
+ @Override
+ public void setAction(byte a) {
+ setByte(a, (short) 32);
+ }
+
+ @Override
+ public byte getDSCPTOS() {
+ return getByte((short) 2);
+ }
+
+ @Override
+ public void setDSCPTOS(byte v) {
+ setByte(v, (short) 2);
+ }
+
+ @Override
+ public byte getDSCPTOSMask() {
+ return getByte((short) 3);
+ }
+
+ @Override
+ public void setDSCPTOSMask(byte v) {
+ setByte(v, (short) 3);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IGateID;
+
+/**
+ *
+ */
+public class GateID extends PCMMBaseObject implements IGateID {
+
+ /**
+ *
+ */
+ public GateID() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public GateID(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public GateID(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IGateID#setGateID(int)
+ */
+ @Override
+ public void setGateID(int gateID) {
+ setInt(gateID, (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IGateID#getGateID()
+ */
+ @Override
+ public int getGateID() {
+ return getInt((short) 0);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IGateSpec;
+import org.pcmm.gates.ISessionClassID;
+
+/**
+ *
+ */
+public class GateSpec extends PCMMBaseObject implements IGateSpec {
+
+ public GateSpec() {
+ super(LENGTH, STYPE, SNUM);
+ }
+
+ public GateSpec(byte[] data) {
+ super(data);
+ }
+
+ @Override
+ public ISessionClassID getSessionClassID() {
+ return new SessionClassID(getByte((short) 3));
+ }
+
+ @Override
+ public void setSessionClassID(ISessionClassID id) {
+ setByte(id.toSingleByte(), (short) 3);
+ }
+
+ @Override
+ public Direction getDirection() {
+ return Direction.valueOf(getByte((short) 0));
+ }
+
+ @Override
+ public void setDirection(Direction direction) {
+ setByte(direction.getValue(), (short) 0);
+ }
+
+ @Override
+ public short getTimerT1() {
+ return getShort((short) 4);
+ }
+
+ @Override
+ public void setTimerT1(short authTimer) {
+ setShort(authTimer, (short) 4);
+ }
+
+ @Override
+ public short getTimerT2() {
+ return getShort((short) 6);
+ }
+
+ @Override
+ public void setTimerT2(short timer) {
+ setShort(timer, (short) 6);
+
+ }
+
+ @Override
+ public short getTimerT3() {
+ return getShort((short) 8);
+ }
+
+ @Override
+ public void setTimerT3(short t) {
+ setShort(t, (short) 8);
+
+ }
+
+ @Override
+ public short getTimerT4() {
+ return getShort((short) 10);
+ }
+
+ @Override
+ public void setTimerT4(short t) {
+ setShort(t, (short) 10);
+ }
+
+ @Override
+ public void setDSCP_TOSOverwrite(DSCPTOS dscpTos) {
+ setByte(dscpTos.getValue(), (short) 1);
+ }
+
+ @Override
+ public DSCPTOS getDSCP_TOSOverwrite() {
+ return DSCPTOS.valueOf(getByte((short) 1));
+ }
+
+ @Override
+ public byte getDSCP_TOSMask() {
+ return getByte((short) 2);
+ }
+
+ @Override
+ public void setDSCP_TOSMask(byte dscp_tos_mask) {
+ setByte(dscp_tos_mask, (short) 2);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.IPCMMError;
+
+/**
+ *
+ */
+public class PCMMError extends PCMMBaseObject implements IPCMMError {
+ /**
+ *
+ */
+ public PCMMError() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ public PCMMError(short errorCode, short subErrCode) {
+ this();
+ setErrorCode(errorCode);
+ setErrorSubcode(subErrCode);
+ }
+
+ /**
+ * @param data
+ */
+ public PCMMError(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public PCMMError(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCError#setErrorCode(int)
+ */
+ @Override
+ public void setErrorCode(short errorCode) {
+ setShort(errorCode, (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCError#getErrorCode()
+ */
+ @Override
+ public short getErrorCode() {
+ return getShort((short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCError#setErrorSubcode(int)
+ */
+ @Override
+ public void setErrorSubcode(short errorSubcode) {
+ setShort(errorSubcode, (short) 2);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCError#getErrorCode()
+ */
+ @Override
+ public short getErrorSubcode() {
+ return getShort((short) 2);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCError#getDescription()
+ */
+ @Override
+ public String getDescription() {
+ String hex = Integer.toHexString(getErrorSubcode() & 0xFFFF);
+ return "Error Code: " + getErrorCode() + " Error Subcode : " + hex
+ + " " + Description.valueOf(getErrorCode());
+ }
+
+ @Override
+ public String toString() {
+ return getDescription();
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import java.util.Arrays;
+
+import org.pcmm.base.IPCMMBaseObject;
+import org.pcmm.gates.IAMID;
+import org.pcmm.gates.IClassifier;
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IGateSpec;
+import org.pcmm.gates.IPCMMError;
+import org.pcmm.gates.IPCMMGate;
+import org.pcmm.gates.ISubscriberID;
+import org.pcmm.gates.ITrafficProfile;
+import org.pcmm.gates.ITransactionID;
+
+/**
+ * <p>
+ * <Gate-set>=<Decision Header><TransactionID><AMID> <SubscriberID> [<GateI>]
+ * <GateSpec> <Traffic Profile> <classifier>
+ * </p>
+ */
+public class PCMMGateReq implements IPCMMGate {
+
+ private boolean multicast;
+ private IGateID gateID;
+ private IAMID iamid;
+ private IPCMMError error;
+ private ISubscriberID subscriberID;
+ private ITransactionID transactionID;
+ private IGateSpec gateSpec;
+ private ITrafficProfile trafficProfile;
+ private IClassifier classifier;
+
+ public PCMMGateReq() {
+ }
+
+ public PCMMGateReq(byte[] data) {
+ short len, offset;
+ byte sNum, sType;
+ len = offset = 0;
+ sNum = sType = (byte) 0;
+ while (offset + 5 < data.length) {
+ len = 0;
+ len |= ((short) data[offset]) << 8;
+ len |= ((short) data[offset + 1]) & 0xFF;
+ sNum = data[offset + 2];
+ sType = data[offset + 3];
+ byte[] dataBuffer = Arrays.copyOfRange(data, offset, offset + len);
+ switch (sNum) {
+ case IGateID.SNUM:
+ setGateID(new GateID(dataBuffer));
+ break;
+ case IAMID.SNUM:
+ setAMID(new AMID(dataBuffer));
+ break;
+ case ISubscriberID.SNUM:
+ setSubscriberID(new SubscriberID(dataBuffer));
+ break;
+ case ITransactionID.SNUM:
+ setTransactionID(new TransactionID(dataBuffer));
+ break;
+ case IGateSpec.SNUM:
+ setGateSpec(new GateSpec(dataBuffer));
+ break;
+ case ITrafficProfile.SNUM:
+ setTrafficProfile(new BestEffortService(dataBuffer));
+ break;
+ case IClassifier.SNUM:
+ setClassifier(new Classifier(dataBuffer));
+ break;
+ case IPCMMError.SNUM:
+ error = new PCMMError(dataBuffer);
+ break;
+ default:
+ System.out.println("unhandled Object skept : S-NUM=" + sNum
+ + " S-TYPE=" + sType + " LEN=" + len);
+ }
+ offset += len;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#isMulticast()
+ */
+ @Override
+ public boolean isMulticast() {
+ // TODO Auto-generated method stub
+ return multicast;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#setGateID(short)
+ */
+ @Override
+ public void setGateID(IGateID gateid) {
+ this.gateID = gateid;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#setAMID(org.pcmm.gates.IAMID)
+ */
+ @Override
+ public void setAMID(IAMID iamid) {
+ this.iamid = iamid;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IPCMMGate#getSubscriberID(org.pcmm.gates.ISubscriberID)
+ */
+ @Override
+ public void setSubscriberID(ISubscriberID subscriberID) {
+ this.subscriberID = subscriberID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getGateSpec(org.pcmm.gates.IGateSpec)
+ */
+ @Override
+ public void setGateSpec(IGateSpec gateSpec) {
+ this.gateSpec = gateSpec;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getClassifier(org.pcmm.gates.IClassifier)
+ */
+ @Override
+ public void setClassifier(IClassifier classifier) {
+ this.classifier = classifier;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.IPCMMGate#getTrafficProfile(org.pcmm.gates.ITrafficProfile
+ * )
+ */
+ @Override
+ public void setTrafficProfile(ITrafficProfile profile) {
+ this.trafficProfile = profile;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getGateID()
+ */
+ @Override
+ public IGateID getGateID() {
+ return gateID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getAMID()
+ */
+ @Override
+ public IAMID getAMID() {
+ return iamid;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getSubscriberID()
+ */
+ @Override
+ public ISubscriberID getSubscriberID() {
+ return subscriberID;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getGateSpec()
+ */
+ @Override
+ public IGateSpec getGateSpec() {
+ return gateSpec;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getClassifier()
+ */
+ @Override
+ public IClassifier getClassifier() {
+ return classifier;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.IPCMMGate#getTrafficProfile()
+ */
+ @Override
+ public ITrafficProfile getTrafficProfile() {
+ return trafficProfile;
+ }
+
+ @Override
+ public void setTransactionID(ITransactionID transactionID) {
+ this.transactionID = transactionID;
+ }
+
+ @Override
+ public ITransactionID getTransactionID() {
+ return transactionID;
+ }
+
+ public IPCMMError getError() {
+ return error;
+ }
+
+ public void setError(IPCMMError error) {
+ this.error = error;
+ }
+
+ @Override
+ public byte[] getData() {
+ byte[] array = new byte[0];
+ if (getTransactionID() != null) {
+ array = fill(array, getTransactionID());
+ }
+ if (getGateID() != null) {
+ array = fill(array, getGateID());
+ }
+ if (getAMID() != null) {
+ array = fill(array, getAMID());
+
+ }
+ if (getSubscriberID() != null) {
+ array = fill(array, getSubscriberID());
+ }
+ if (getGateSpec() != null) {
+ array = fill(array, getGateSpec());
+ }
+ if (getTrafficProfile() != null) {
+ array = fill(array, getTrafficProfile());
+ }
+ if (getClassifier() != null) {
+ array = fill(array, getClassifier());
+ }
+ return array;
+ }
+
+ private byte[] fill(byte[] array, IPCMMBaseObject obj) {
+ byte[] a = obj.getAsBinaryArray();
+ int offset = array.length;
+ array = Arrays.copyOf(array, offset + a.length);
+ System.arraycopy(a, 0, array, offset, a.length);
+ return array;
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.gates.ISessionClassID;
+
+/**
+ *
+ */
+public class SessionClassID implements ISessionClassID {
+
+ private byte priority;
+ private byte preemption;
+
+ // TODO check this;
+ private byte session;
+
+ public SessionClassID() {
+ this((byte) 0);
+ }
+
+ public SessionClassID(byte value) {
+ session = value;
+ priority = 0;
+ preemption = 0;
+ priority |= value >> 2;
+ preemption |= value >> 3;
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISessionClassID#getPriority()
+ */
+ @Override
+ public byte getPriority() {
+ return priority;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISessionClassID#setPriority(byte)
+ */
+ @Override
+ public void setPriority(byte value) {
+ this.priority = value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISessionClassID#getPreemption()
+ */
+ @Override
+ public byte getPreemption() {
+ return preemption;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISessionClassID#setPreemption(byte)
+ */
+ @Override
+ public void setPreemption(byte value) {
+ this.preemption = value;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISessionClassID#toSingleByte()
+ */
+ @Override
+ public byte toSingleByte() {
+ // byte ret = 0;
+ // ret |= (priority << 2);
+ // ret |= (preemption & 0xf);
+ // return ret;
+ return session;
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.ISubscriberID;
+
+/**
+ *
+ */
+public class SubscriberID extends PCMMBaseObject implements ISubscriberID {
+
+ /**
+ *
+ */
+ public SubscriberID() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public SubscriberID(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public SubscriberID(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ISubscriberID#getSourceIPAddress()
+ */
+ @Override
+ public InetAddress getSourceIPAddress() {
+ try {
+ return Inet4Address.getByAddress(getBytes((short) 0, (short) 4));
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.gates.ISubscriberID#setSourceIPAddress(java.net.InetAddress)
+ */
+ @Override
+ public void setSourceIPAddress(InetAddress address) {
+ setBytes(address.getAddress(), (short) 0);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.gates.impl;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+import org.pcmm.gates.ITransactionID;
+
+/**
+ *
+ */
+public class TransactionID extends PCMMBaseObject implements ITransactionID {
+
+ /**
+ *
+ */
+ public TransactionID() {
+ this(LENGTH, STYPE, SNUM);
+ }
+
+ /**
+ * @param data
+ */
+ public TransactionID(byte[] data) {
+ super(data);
+ }
+
+ /**
+ * @param len
+ * @param sType
+ * @param sNum
+ */
+ public TransactionID(short len, byte sType, byte sNum) {
+ super(len, sType, sNum);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITransactionID#setTransactionIdentifier(short)
+ */
+ @Override
+ public void setTransactionIdentifier(short id) {
+ setShort(id, (short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITransactionID#getTransactionIdentifier()
+ */
+ @Override
+ public short getTransactionIdentifier() {
+ return getShort((short) 0);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITransactionID#setGateCommandType(short)
+ */
+ @Override
+ public void setGateCommandType(short type) {
+ setShort(type, (short) 2);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.gates.ITransactionID#getGateCommandType()
+ */
+ @Override
+ public short getGateCommandType() {
+ return getShort((short) 2);
+ }
+
+}
--- /dev/null
+/**
+ *
+ */
+/**
+ *
+ */
+package org.pcmm.gates.impl;
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.messages;
+
+/**
+ * This defines the messages exchanged between client and server.
+ *
+ *
+ * <pre>
+ * 1 = Request (REQ)
+ * 2 = Decision (DEC)
+ * 3 = Report State (RPT)
+ * 4 = Delete Request State (DRQ)
+ * 5 = Synchronize State Req (SSQ)
+ * 6 = Client-Open (OPN)
+ * 7 = Client-Accept (CAT)
+ * 8 = Client-Close (CC)
+ * 9 = Keep-Alive (KA)
+ * 10= Synchronize Complete (SSC)
+ * </pre>
+ *
+ */
+public interface IMessage {
+
+ public static enum MessageProperties {
+ CLIENT_TYPE("Client-Type"), PEP_ID("Pep-ID"), KA_TIMER("KA-Timer"), ACCEPT_TIMER(
+ "Accept-Timer"), ERR_MESSAGE("Error-Message"), ERR_MESSAGE_SUB_CODE(
+ "Error-Message-Code"), MM_MAJOR_VERSION_INFO(
+ "MM-Major-Version-info"), MM_MINOR_VERSION_INFO(
+ "MM-Minor-Version-info"), R_TYPE("R-Type"), M_TYPE("M-Type"), CLIENT_HANDLE(
+ "Client-Handle"), GATE_CONTROL("Gate-Control"), DECISION_CMD_CODE(
+ "Decision-Type"), DECISION_FLAG("Decision-Flag");
+
+ private MessageProperties(String valueString) {
+ this.value = valueString;
+ }
+
+ private String value;
+
+ public String getValue() {
+ return value;
+ }
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.messages;
+
+import java.util.Properties;
+
+import org.umu.cops.stack.COPSMsg;
+
+/**
+ *
+ * Factory used to create {@code COPSMsg} based on message type input and a list
+ * of properties.
+ *
+ */
+public interface IMessageFactory {
+
+ /**
+ * creates a new message with the specified message type.
+ *
+ * @param messageType
+ * message type
+ * @return new message.
+ */
+ COPSMsg create(byte messageType);
+
+ /**
+ * creates a new message with the specified message type and content
+ *
+ * @param messageType
+ * message type
+ * @param properties
+ * message content.
+ * @return new message.
+ */
+ COPSMsg create(byte messageType, Properties properties);
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.messages.impl;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.umu.cops.stack.COPSClientSI;
+import org.umu.cops.stack.COPSContext;
+import org.umu.cops.stack.COPSDecision;
+import org.umu.cops.stack.COPSError;
+import org.umu.cops.stack.COPSException;
+import org.umu.cops.stack.COPSHandle;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSIntegrity;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSObjHeader;
+
+/**
+ * COPS Decision Message
+ *
+ *
+ */
+
+public class COPSDecisionMsgEX extends COPSMsg {
+
+ /* COPSHeader coming from base class */
+ private COPSHandle _clientHandle;
+ private COPSError _error;
+ private Hashtable _decisions;
+ private COPSIntegrity _integrity;
+ private COPSContext _decContext;
+ private COPSClientSI clientSI;
+
+ // /
+ public COPSDecisionMsgEX() {
+ _clientHandle = null;
+ _error = null;
+ _decisions = new Hashtable(20);
+ _integrity = null;
+ _decContext = null;
+ clientSI = 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 COPSDecisionMsgEX(byte[] data) throws COPSException {
+ _decisions = new Hashtable(20);
+ _clientHandle = null;
+ _error = null;
+ _integrity = null;
+ _decContext = null;
+ clientSI = 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 = new COPSObjHeader(buf) {
+ };
+ switch (objHdr.getCNum()) {
+ case COPSObjHeader.COPS_HANDLE: {
+ _clientHandle = new COPSHandle(buf) {
+ };
+ _dataStart += _clientHandle.getDataLength();
+ }
+ break;
+ case COPSObjHeader.COPS_CONTEXT: {
+ // dec context
+ _decContext = new COPSContext(buf) {
+ };
+ _dataStart += _decContext.getDataLength();
+ }
+ break;
+ case COPSObjHeader.COPS_ERROR: {
+ _error = new COPSError(buf) {
+ };
+ _dataStart += _error.getDataLength();
+ }
+ break;
+ case COPSObjHeader.COPS_DEC: {
+ COPSDecision decs = new COPSDecision(buf) {
+ };
+ _dataStart += decs.getDataLength();
+ addDecision(decs, _decContext);
+ }
+ break;
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {
+ _integrity = new COPSIntegrity(buf);
+ _dataStart += _integrity.getDataLength();
+ }
+ break;
+ case COPSObjHeader.COPS_CSI: {
+ clientSI = new COPSClientSI(buf) {
+ };
+ _dataStart += clientSI.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 a client specific informations
+ *
+ * @param clientSI
+ * a COPSClientSI
+ *
+ * @throws COPSException
+ *
+ */
+ public void add(COPSClientSI clientSI) throws COPSException {
+ if (clientSI == null)
+ throw new COPSException("Null ClientSI");
+ this.clientSI = 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 (clientSI != null)
+ clientSI.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;
+ }
+
+ public COPSClientSI getClientSI() {
+ return clientSI;
+ }
+
+ /**
+ * 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 (clientSI != null)
+ len += clientSI.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 (clientSI != null)
+ clientSI.dump(os);
+ if (_integrity != null) {
+ _integrity.dump(os);
+ }
+ }
+}
--- /dev/null
+/**
+ * @header@
+ */
+package org.pcmm.messages.impl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Properties;
+
+import org.pcmm.messages.IMessage.MessageProperties;
+import org.pcmm.messages.IMessageFactory;
+import org.pcmm.objects.MMVersionInfo;
+import org.pcmm.rcd.ICMTS;
+import org.pcmm.rcd.IPCMMClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.COPSClientSI;
+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.COPSHandle;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSKAMsg;
+import org.umu.cops.stack.COPSKATimer;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSObjHeader;
+import org.umu.cops.stack.COPSPepId;
+import org.umu.cops.stack.COPSReqMsg;
+
+/**
+ *
+ *
+ */
+public class MessageFactory implements IMessageFactory {
+
+ /** 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;
+
+ private Logger logger = LoggerFactory.getLogger(getClass().getName());
+
+ private static MessageFactory instance;
+
+ private MessageFactory() {
+ }
+
+ public static MessageFactory getInstance() {
+ if (instance == null)
+ instance = new MessageFactory();
+ return instance;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.messages.IMessageFactory#create(pcmm.messages.MessageType)
+ */
+ public COPSMsg create(byte messageType) {
+ return create(messageType, new Properties());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.messages.IMessageFactory#create(org.pcmm.messages.IMessage.
+ * MessageType, java.util.Properties)
+ */
+ public COPSMsg create(byte messageType, Properties properties) {
+ // return new PCMMMessage(messageType, content);
+ switch (messageType) {
+ case COPSHeader.COPS_OP_OPN:
+ return createOPNMessage(properties);
+ case COPSHeader.COPS_OP_REQ:
+ return createREQMessage(properties);
+ case COPSHeader.COPS_OP_CAT:
+ return createCATMessage(properties);
+ case COPSHeader.COPS_OP_CC:
+ return createCCMessage(properties);
+ case COPSHeader.COPS_OP_DEC:
+ return createDECMessage(properties);
+ case COPSHeader.COPS_OP_DRQ:
+ break;
+ case COPSHeader.COPS_OP_KA:
+ return createKAMessage(properties);
+ case COPSHeader.COPS_OP_RPT:
+ break;
+ case COPSHeader.COPS_OP_SSC:
+ break;
+ case COPSHeader.COPS_OP_SSQ:
+ break;
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param prop
+ * @return
+ */
+ protected COPSMsg createDECMessage(Properties prop) {
+ COPSDecisionMsg msg = new COPSDecisionMsg();
+ // ===common part between all gate control messages
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, IPCMMClient.CLIENT_TYPE);
+ // handle
+ COPSHandle handle = new COPSHandle();
+ // context
+ COPSContext context = new COPSContext(COPSContext.CONFIG, (short) 0);
+ // decision
+ COPSDecision decision = new COPSDecision();
+ if (prop.get(MessageProperties.DECISION_CMD_CODE) != null)
+ decision.setCmdCode((byte) prop.get(MessageProperties.DECISION_CMD_CODE));
+ if (prop.get(MessageProperties.DECISION_FLAG) != null)
+ decision.setFlags((short) prop.get(MessageProperties.DECISION_FLAG));
+ COPSClientSI si = new COPSClientSI(COPSObjHeader.COPS_DEC, (byte) 4);
+ if (prop.get(MessageProperties.GATE_CONTROL) != null)
+ si.setData((COPSData) prop.get(MessageProperties.GATE_CONTROL));
+ try {
+ msg.add(hdr);
+ if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
+ handle.setId(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
+ msg.add(handle);
+ msg.addDecision(decision, context);
+ msg.add(si);
+ // try {
+ // msg.dump(System.out);
+ // } catch (IOException unae) {
+ // }
+
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ }
+
+ return msg;
+ }
+
+ /**
+ * creates a Client-Open message.
+ *
+ * @param prop
+ * properties
+ * @return COPS message
+ */
+ protected COPSMsg createOPNMessage(Properties prop) {
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, IPCMMClient.CLIENT_TYPE);
+ COPSPepId pepId = new COPSPepId();
+ // version infor object
+ short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO;
+ short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO;
+ if (prop.get(MessageProperties.MM_MAJOR_VERSION_INFO) != null)
+ majorVersion = (Short) prop.get(MessageProperties.MM_MAJOR_VERSION_INFO);
+ if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null)
+ minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO);
+ // Mandatory MM version.
+ COPSClientSI clientSI = new COPSClientSI((byte) 1);
+ byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray();
+ clientSI.setData(new COPSData(versionInfo, 0, versionInfo.length));
+ COPSClientOpenMsg msg = new COPSClientOpenMsg();
+ try {
+ COPSData d = null;
+ if (prop.get(MessageProperties.PEP_ID) != null)
+ d = new COPSData((String) prop.get(MessageProperties.PEP_ID));
+ else
+ d = new COPSData(InetAddress.getLocalHost().getHostName());
+ pepId.setData(d);
+ msg.add(hdr);
+ msg.add(pepId);
+ msg.add(clientSI);
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ } catch (UnknownHostException e) {
+ logger.error(e.getMessage());
+ }
+ return msg;
+ }
+
+ /**
+ * creates a Client-Accept message.
+ *
+ * @param prop
+ * properties
+ * @return COPS message
+ */
+ protected COPSMsg createCATMessage(Properties prop) {
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_CAT, IPCMMClient.CLIENT_TYPE);
+ COPSKATimer katimer = null;
+ COPSAcctTimer acctTimer = null;
+ if (prop.get(MessageProperties.KA_TIMER) != null)
+ katimer = new COPSKATimer((short) prop.get(MessageProperties.KA_TIMER));
+ else
+ katimer = new COPSKATimer((short) KA_TIMER_VALUE);
+ if (prop.get(MessageProperties.ACCEPT_TIMER) != null)
+ acctTimer = new COPSAcctTimer((short) prop.get(MessageProperties.ACCEPT_TIMER));
+ else
+ acctTimer = new COPSAcctTimer(ACCT_TIMER_VALUE);
+ COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
+ try {
+ acceptMsg.add(hdr);
+ acceptMsg.add(katimer);
+ if (acctTimer.getTimerVal() != 0)
+ acceptMsg.add(acctTimer);
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ }
+ return acceptMsg;
+ }
+
+ /**
+ * creates a Client-Close message.
+ *
+ * @param prop
+ * properties
+ * @return COPS message
+ */
+ protected COPSMsg createCCMessage(Properties prop) {
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, IPCMMClient.CLIENT_TYPE);
+ COPSError err = null;
+ if (prop.get(MessageProperties.ERR_MESSAGE) != null) {
+ short code = (short) 0;
+ short error = (short) prop.get(MessageProperties.ERR_MESSAGE);
+ if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null)
+ code = (short) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
+ err = new COPSError(error, code);
+ } else
+ err = new COPSError(COPSError.COPS_ERR_UNKNOWN, (short) 0);
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
+ try {
+ closeMsg.add(cHdr);
+ closeMsg.add(err);
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ }
+ return closeMsg;
+ }
+
+ /**
+ * creates a Request message
+ *
+ * @param prop
+ * properties
+ * @return Request message
+ */
+ protected COPSMsg createREQMessage(Properties prop) {
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_REQ, IPCMMClient.CLIENT_TYPE);
+ COPSReqMsg req = new COPSReqMsg();
+ short rType = ICMTS.DEFAULT_R_TYPE;
+ short mType = ICMTS.DEFAULT_M_TYPE;
+ if (prop.get(MessageProperties.R_TYPE) != null)
+ rType = (Short) prop.get(MessageProperties.R_TYPE);
+ if (prop.get(MessageProperties.M_TYPE) != null)
+ mType = (Short) prop.get(MessageProperties.M_TYPE);
+ COPSContext copsContext = new COPSContext(rType, mType);
+ COPSHandle copsHandle = new COPSHandle();
+ if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
+ copsHandle.setId(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
+ else
+ // just a random handle
+ copsHandle.setId(new COPSData("" + Math.random() * 82730));
+ try {
+ req.add(cHdr);
+ req.add(copsContext);
+ req.add(copsHandle);
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ }
+ return req;
+ }
+
+ /**
+ * creates a Keep-Alive message.
+ *
+ * @param prop
+ * properties
+ * @return COPS message
+ */
+ protected COPSMsg createKAMessage(Properties prop) {
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_KA, (short) 0);
+ COPSKAMsg kaMsg = new COPSKAMsg();
+ COPSKATimer timer = null;
+ if (prop.get(MessageProperties.KA_TIMER) != null)
+ timer = new COPSKATimer((Short) prop.get(MessageProperties.KA_TIMER));
+ else
+ timer = new COPSKATimer();
+ try {
+ kaMsg.add(cHdr);
+ } catch (COPSException e) {
+ logger.error(e.getMessage());
+ }
+ return kaMsg;
+ }
+}
--- /dev/null
+/**
+ * Package defining the messages exchanged between PCMM client and server.
+ */
+/**
+ *
+ */
+package org.pcmm.messages;
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.nio;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.nio.ByteBuffer;
+import java.util.Date;
+
+import org.pcmm.PCMMProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.COPSException;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSMsgParser;
+
+/**
+ * this class provides a set of utilities to efficiently read/write data from a
+ * stream, it could parameterized with a reading timeout or -1 for blocking
+ * until get a message
+ *
+ */
+public class PCMMChannel {
+
+ private Logger logger = LoggerFactory.getLogger(getClass().getName());
+ private ByteBuffer dataBuffer;
+ private Socket socket;
+ private int timeout;
+ public static final int DEFAULT_BYTE_BUFFER_SIZE = 2048;
+ public static final int DEFAULT_READ_TIMEOUT = -1;
+
+ public PCMMChannel(Socket socket) {
+ this(socket, PCMMProperties.get(PCMMProperties.DEFAULT_TIEMOUT,
+ Integer.class, DEFAULT_READ_TIMEOUT));
+ }
+
+ public PCMMChannel(Socket socket, int timeout) {
+ this.socket = socket;
+ dataBuffer = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE);
+ logger.info("Allocated byte buffer with size = "
+ + DEFAULT_BYTE_BUFFER_SIZE);
+ this.timeout = timeout;
+ logger.info("Set read/write timeout to : " + timeout);
+
+ }
+
+ public int readData(byte[] dataRead, int nchar) throws IOException {
+ InputStream input;
+ input = getSocket().getInputStream();
+ int nread = 0;
+ int startTime = (int) (new Date().getTime());
+ do {
+ if (timeout == -1 || 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) > timeout)
+ break;
+ }
+ } while (nread != nchar);
+ return nread;
+ }
+
+ /**
+ * Method sendMsg
+ *
+ * @param msg
+ * a COPSMsg
+ *
+ * @throws IOException
+ * @throws COPSException
+ *
+ */
+ public void sendMsg(COPSMsg msg) throws IOException, COPSException {
+ logger.debug("sendMsg({})==>{}", getSocket(), msg);
+ msg.checkSanity();
+ msg.writeData(getSocket());
+ }
+
+ /**
+ * Method receiveMessage
+ *
+ * @return a COPSMsg
+ *
+ * @throws IOException
+ * @throws COPSException
+ *
+ */
+ public COPSMsg receiveMessage() throws IOException, COPSException {
+ int nread = 0;
+ byte[] hBuf = new byte[8];
+
+ logger.debug("receiveMessage({})", getSocket());
+
+ nread = readData(hBuf, 8);
+
+ if (nread == 0) {
+ throw new COPSException("Error reading connection");
+ }
+
+ if (nread != 8) {
+ throw new COPSException("Bad COPS message");
+ }
+
+ COPSHeader hdr = new COPSHeader(hBuf);
+ int dataLen = hdr.getMsgLength() - hdr.getHdrLength();
+ logger.debug("COPS Msg length :[" + dataLen + "]\n");
+ byte[] buf = new byte[dataLen + 1];
+ nread = 0;
+
+ nread = readData(buf, dataLen);
+ buf[dataLen] = (byte) '\0';
+ logger.debug("Data read length:[" + nread + "]\n");
+
+ if (nread != dataLen) {
+ throw new COPSException("Bad COPS message");
+ }
+ COPSMsgParser prser = new COPSMsgParser();
+ COPSMsg msg = prser.parse(hdr, buf);
+ return msg;
+ }
+
+ /**
+ * @return the dataBuffer
+ */
+ public ByteBuffer getDataBuffer() {
+ return dataBuffer;
+ }
+
+ /**
+ * @param dataBuffer
+ * the dataBuffer to set
+ */
+ public void setDataBuffer(ByteBuffer dataBuffer) {
+ this.dataBuffer = dataBuffer;
+ }
+
+ /**
+ * @return the socket
+ */
+ public Socket getSocket() {
+ return socket;
+ }
+
+ /**
+ * @param socket
+ * the socket to set
+ */
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ }
+
+ /**
+ * @return the timeout
+ */
+ public int getTimeout() {
+ return timeout;
+ }
+
+ /**
+ * @param timeout
+ * the timeout to set
+ */
+ public void setTimeout(int timeout) {
+ this.timeout = timeout;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+
+/**
+ *
+ * PCMM MM version info Object
+ *
+ */
+public class MMVersionInfo extends PCMMBaseObject {
+
+ private short majorVersionNB;
+ private short minorVersionNB;
+ public static final short DEFAULT_MAJOR_VERSION_INFO = (short) 5;
+ public static final short DEFAULT_MINOR_VERSION_INFO = (short) 0;
+
+ public MMVersionInfo() {
+ this(DEFAULT_MAJOR_VERSION_INFO, DEFAULT_MINOR_VERSION_INFO);
+ }
+
+ public MMVersionInfo(short majorVersionNB, short minorVersionNB) {
+ super((short) 8, (byte) 1, (byte) 16);
+ setShort(this.majorVersionNB = majorVersionNB, (short) 0);
+ setShort(this.minorVersionNB = minorVersionNB, (short) 2);
+ }
+
+ /**
+ * Parse data and create COPSHandle object
+ */
+ public MMVersionInfo(byte[] dataPtr) {
+ super(dataPtr);
+ majorVersionNB = getShort((short) 0);
+ minorVersionNB = getShort((short) 2);
+ }
+
+ /**
+ * @return the majorVersionNB
+ */
+ public short getMajorVersionNB() {
+ return majorVersionNB;
+ }
+
+ /**
+ * @param majorVersionNB
+ * the majorVersionNB to set
+ */
+ public void setMajorVersionNB(short majorVersionNB) {
+ this.majorVersionNB = majorVersionNB;
+ }
+
+ /**
+ * @return the minorVersionNB
+ */
+ public short getMinorVersionNB() {
+ return minorVersionNB;
+ }
+
+ /**
+ * @param minorVersionNB
+ * the minorVersionNB to set
+ */
+ public void setMinorVersionNB(short minorVersionNB) {
+ this.minorVersionNB = minorVersionNB;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+/**
+ * this class holds and maps flow ID to PCMM gate ID and Transaction ID
+ *
+ */
+public class PCMMIDHolder extends PCMMResource {
+
+ /**
+ * flow id.
+ */
+ private int flowID;
+ /**
+ * gate id.
+ */
+ private int gateID;
+ /**
+ * transaction id.
+ */
+ private short transactionID;
+
+ public PCMMIDHolder(int flowID, int gateID, short transactionID) {
+ this.flowID = flowID;
+ this.gateID = gateID;
+ this.transactionID = transactionID;
+
+ }
+
+ public PCMMIDHolder() {
+
+ }
+
+ public int getFlowID() {
+ return flowID;
+ }
+
+ public void setFlowID(int flowID) {
+ this.flowID = flowID;
+ }
+
+ public int getGateID() {
+ return gateID;
+ }
+
+ public void setGateID(int gateID) {
+ this.gateID = gateID;
+ }
+
+ public short getTransactionID() {
+ return transactionID;
+ }
+
+ public void setTransactionID(short transactionID) {
+ this.transactionID = transactionID;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+/**
+ *
+ * This class is a holder for PCMM objects. This class is intended to be
+ * sub-classed
+
+ *
+ */
+public class PCMMResource {
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This stores and handles the PCMM resources.
+ *
+ */
+public class PCMMResourceSet {
+
+ private Map<Object, PCMMResourcesMapper<?, ?>> mapper;
+
+ private static PCMMResourceSet instance;
+
+ private PCMMResourceSet() {
+ mapper = new HashMap<Object, PCMMResourcesMapper<?, ?>>();
+ }
+
+ public static PCMMResourceSet getInstance() {
+ if (instance == null)
+ instance = new PCMMResourceSet();
+ return instance;
+ }
+
+ /**
+ * adds a new mapping
+ *
+ * @param key
+ * to be used for identifying mapped structure
+ * @return resource mapper
+ */
+ @SuppressWarnings("unchecked")
+ public <M, T extends PCMMResource> PCMMResourcesMapper<M, T> getMappedResources(
+ Object key) {
+ return (PCMMResourcesMapper<M, T>) mapper.get(key);
+ }
+
+ public <M, T extends PCMMResource> void mapResources(Object key,
+ PCMMResourcesMapper<M, T> resources) {
+ mapper.put(key, resources);
+ }
+
+ public void removeMapping(Object key) {
+ mapper.remove(key);
+ }
+
+ public void removeAllMappings() {
+ mapper.clear();
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+/**
+ *
+ * Resources mapper used to associate a key to a set of values
+ */
+public class PCMMResourcesMapper<M, T extends PCMMResource> {
+
+ private M key;
+
+ private T value;
+
+ public PCMMResourcesMapper() {
+ }
+
+ public PCMMResourcesMapper(M key, T value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public M getKey() {
+ return key;
+ }
+
+ public void setKey(M key) {
+ this.key = key;
+ }
+
+ public T getValue() {
+ return value;
+ }
+
+ public void setValue(T value) {
+ this.value = value;
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.objects;
+
+import org.pcmm.base.impl.PCMMBaseObject;
+
+/**
+ *
+ * PCMM SyncOptions object
+ *
+ */
+public class SyncOptions extends PCMMBaseObject {
+
+ private byte synchType;
+
+ private byte reportType;
+
+ public static final byte STANDARD_REPORT_DATA = (byte) 0;
+ public static final byte COMPLETE_GATE_DATA = (byte) 1;
+ public static final byte FULL_SYNCHRONIZATION = (byte) 0;
+ public static final byte INCREMENTAL_SYNCHRONIZATION = (byte) 1;
+
+ public SyncOptions() {
+ this(STANDARD_REPORT_DATA, FULL_SYNCHRONIZATION);
+ }
+
+ public SyncOptions(byte reportType, byte synchType) {
+ super((short) 8, (byte) 1, (byte) 18);
+ setByte(this.reportType = reportType, (short) 4);
+ setByte(this.synchType = synchType, (short) 6);
+ }
+
+ /**
+ * Parse data and create COPSHandle object
+ */
+ public SyncOptions(byte[] dataPtr) {
+ super(dataPtr);
+ reportType = getByte((short) 4);
+ synchType = getByte((short) 6);
+ }
+
+ /**
+ * @return the synchType
+ */
+ public byte getSynchType() {
+ return synchType;
+ }
+
+ /**
+ * @param synchType
+ * the synchType to set
+ */
+ public void setSynchType(byte synchType) {
+ this.synchType = synchType;
+ }
+
+ /**
+ * @return the reportType
+ */
+ public byte getReportType() {
+ return reportType;
+ }
+
+ /**
+ * @param reportType
+ * the reportType to set
+ */
+ public void setReportType(byte reportType) {
+ this.reportType = reportType;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.rcd;
+
+/**
+ * <p>
+ * In describing the role of the CMTS network element, it is important to
+ * consider the relation among DOCSIS, PacketCable 1.x and PacketCable
+ * Multimedia functionality. While each of these suites of specifications
+ * addresses a specific set of functional requirements, each has also been
+ * defined in such a way that corresponding implementations may be constructed
+ * in a modular manner; either PacketCable 1.x or PacketCable Multimedia Gate
+ * Control may be layered on top of a DOCSIS 1.1 or greater CMTS foundation,
+ * with the option of adding additional, complementary functionality as business
+ * indicates. Further, it should be emphasized that it is a significant asset of
+ * the PacketCable architecture that both telephony and Multimedia variants
+ * employ considerable architectural similarity, leading to potential reuse in
+ * the underlying Gate management models.
+ * </p>
+ * <p>
+ * The PacketCable Multimedia CMTS is a generalized version of the PacketCable
+ * 1.x CMTS that has been defined in order to deliver telephony services in
+ * PacketCable 1.x networks. The CMTS is responsible for fulfilling requests for
+ * QoS that are received from one or more Policy Servers. It performs this
+ * function by installing Gates, which are similar to the Gates defined in [14];
+ * Gates allow the subscriber's cable modem to request network resources from
+ * the CMTS through the creation of dynamic DOCSIS flows with guaranteed levels
+ * of QoS. The CMTS also sends Event Messages detailing actual usage of QoS
+ * resources to the Record Keeping Server.
+ * </p>
+ * <p>
+ * The CMTS acts as a server (PS should send OPN message to CMTS to initiate
+ * communication), and acts as a client for the rest of the exchange process.
+ * </p>
+ *
+ *
+ */
+public interface ICMTS extends IPCMMServer {
+
+ // generates a GateID and assigns it to the IPCMMGate.
+
+ static final short DEFAULT_R_TYPE = (short) 0x08;
+ static final short DEFAULT_M_TYPE = (short) 0;
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.rcd;
+
+import java.net.InetAddress;
+
+import org.umu.cops.stack.COPSMsg;
+
+/**
+ * <p>
+ * This is a Client Type 1, which represents existing "legacy" endpoints (e.g.,
+ * PC applications, gaming consoles) that lack specific QoS awareness or
+ * signaling capabilities. This client has no awareness of DOCSIS, CableHome, or
+ * PacketCable messaging, and hence no related requirements can be placed upon
+ * it. Client Type 1 communicates with an Application Manager to request
+ * service, and does not (cannot) request QoS resources directly from the MSO
+ * access network.
+ * </p>
+ *
+ *
+ */
+public interface IPCMMClient {
+
+ /**
+ * PCMM client-type
+ */
+ static final short CLIENT_TYPE = (short) 0x800A;
+
+ /**
+ * sends a message to the server.
+ *
+ * @param requestMessage
+ * request message.
+ */
+ void sendRequest(COPSMsg requestMessage);
+
+ /**
+ * Reads message from server
+ *
+ * @return COPS message
+ */
+ COPSMsg readMessage();
+
+ /**
+ * tries to connect to the server.
+ *
+ * @param address
+ * server address
+ * @param port
+ * server port
+ * @return connection state
+ */
+ boolean tryConnect(String address, int port);
+
+ /**
+ * tries to connect to the server.
+ *
+ * @param address
+ * server address
+ * @param port
+ * server port
+ * @return connection state
+ */
+ boolean tryConnect(InetAddress address, int port);
+
+ /**
+ * disconnects from server.
+ *
+ * @return disconnection status.
+ */
+ boolean disconnect();
+
+ /**
+ *
+ * @return whether the client is connected to the server of not.
+ */
+ boolean isConnected();
+
+ /**
+ * gets the client handle
+ *
+ * @return client handle
+ */
+ String getClientHandle();
+
+ /**
+ *
+ * sets the client handle
+ *
+ * @param handle
+ * cleint hanlde
+ */
+ void setClientHandle(String handle);
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.rcd;
+
+import java.net.InetAddress;
+
+import org.pcmm.objects.MMVersionInfo;
+import org.pcmm.state.IStateful;
+
+/**
+ * <i>PKT-SP-MM-I05-091029 PacketCableTM Specification</i>
+ * <p>
+ * As discussed in RFC 2753 [11], the policy management framework underlying
+ * PacketCable Multimedia is based on the work of the IETF's Resource Allocation
+ * Protocol (RAP) working group. Since the Policy Server is situated between the
+ * Application Manager and the CMTS, it simultaneously plays a dual role as a
+ * "proxy" for AM-initiated session requests and as a "sentry" for defining and
+ * enforcing Resource Control Domain policy. As described in [11] and in keeping
+ * with the PacketCable 1.x DQoS model, the Policy Server serves as Policy
+ * Decision Point (PDP) in relation to the CMTS in that the Policy Server
+ * implements MSO-defined authorization and resource-management procedures.
+ * Conversely, the Policy Server assumes the role of Policy Enforcement Point
+ * (PEP) in relation to the Application Manager as it proxies Gate Control
+ * messages to and from the CMTS element. To revisit the interaction scenario,
+ * the Application Manager issues policy requests to the Policy Server. The
+ * Policy Server acting as a "sentry" for these requests, and applies a set of
+ * policy rules that have been pre-provisioned by the MSO. Upon passing the
+ * checks, the Policy Server then acts as a "proxy" with respect to the
+ * Application Manager and the CMTS, forwarding the policy request and returning
+ * any associated response. Each policy request transaction must be processed
+ * individually. Policy decisions may be based on a number of factors, such as:
+ * <ul>
+ * <li>Parameters associated with the request and the status of available
+ * resources</li>
+ * <li>Identity of the particular client and associated profile information</li>
+ * <li>Application parameters</li>
+ * <li>Security considerations</li>
+ * <li>Time-of-day</li>
+ * </ul>
+ * The primary functions of the Policy Server include:
+ * <ul>
+ * <li>A policy decision request mechanism, invoked by Application Managers</li>
+ * <li>A policy decision request 'policing' mechanism, enforcing installed
+ * Policy Rules</li>
+ * <li>A policy decision delivery mechanism, used to install policy decisions on
+ * the CMTS</li>
+ * <li>A mechanism to allow for the proxying of QoS management messages to the
+ * CMTS on behalf of the Application Manager</li>
+ * <li>An event recording interface to a Record Keeping Server that is used to
+ * log policy requests, which may in turn be correlated with network resource
+ * usage records</li>·
+ * </ul>
+ * Since the Policy Server functions as a proxy between the AM and CMTS elements
+ * (with complementary client and server interfaces) some MSOs may elect to
+ * deploy multiple layers of Policy Servers and to delegate certain policy
+ * decisions among these servers in order to satisfy requirements associated
+ * with scalability and fault-tolerance.
+ * </p>
+ * <p>
+ * <i>Stateful & Stateless Policy Servers</i> There are two basic classes of
+ * Policy Servers – Stateful and Stateless. A Stateless Policy Server is a
+ * slight misnomer since it does maintain enough state to map Application
+ * Manager requests to the proper CMTS and maintain COPS session state, while a
+ * pure Stateless Policy Server maintains no state on any of the media sessions.
+ * Stateful Policy Servers come in several varieties – some participate in
+ * admission control and thus monitor the QoS attributes of active media
+ * sessions, some leave QoS and admission control to the CMTS but monitor
+ * time-based or volume-based service requests from the Application Manager, and
+ * some Policy Servers are somewhere between these extremes. The reason there is
+ * a variety of Policy Server types is that there is a variety of environments
+ * that operators are trying to support. For example, some operators may wish to
+ * support PacketCable Multimedia over the same CMTSs that they use for
+ * PacketCable telephony, and they may want a single CMS/Policy Server that has
+ * a more global view of the network resources being used. On the other hand,
+ * some operators may wish to run a PacketCable Multimedia- only environment, or
+ * they may utilize simpler CMTS-driven mechanisms for partitioning PacketCable
+ * Multimedia and telephony resources. These simpler configurations have more
+ * modest requirements on the amount of state that a Policy Server maintains.
+ * Policy Server state requirements can also be driven by the level of trust
+ * between the Policy Server and Application Manager; a Stateful Policy Server
+ * can more readily police Application Manager session control behavior than can
+ * a Stateless Policy Server. So a Stateful Policy Server may be more
+ * appropriate for operators supporting third party Application Managers. Other
+ * operators may rely on economics to enforce their trust relationships with
+ * Application Managers, or they may control the Application Managers
+ * themselves. In such cases a Stateless Policy Server may be more appropriate.
+ * Since it is impossible to categorize all the various components of media
+ * session and network QoS state that a Policy Server is maintaining, the
+ * protocol is designed to be independent of this complexity. A Stateful Policy
+ * Server gleans PacketCable Multimedia media session information from the
+ * Application Manager requests it proxies; any other information it requires is
+ * gathered via mechanisms that are outside the scope of this specification. The
+ * CMTS and the Application Manager make no distinction as to the type of Policy
+ * Server to which they are connected, and the protocol is designed in such a
+ * manner that the type of Policy Server is transparent to the end point. The
+ * type of Policy Server is only of importance to the operator. Since some types
+ * of Policy Servers attempt to assist with admission control and may have a
+ * larger view of the network and its resources, additional state
+ * synchronization issues may arise in design in a network which contains more
+ * than one of these types of Policy Servers. It is the responsibility of the
+ * operator to ensure that the efforts of these Policy Servers are not
+ * undermined by a network that includes other autonomous Policy Servers.
+ * </p>
+ * <p>
+ * <i>Modification of Requests and Responses by Policy Servers</i> Although
+ * nominally a part of the Resource Control Domain, the Policy Server can be an
+ * intermediary between the Service and the Resource Control Domains, in
+ * addition to its normal role of implementing MSO-defined authorization and
+ * resource management procedures. In either of these capacities it may modify
+ * the incoming request before forwarding it to the CMTS. In acting as an
+ * intermediary between the SCD and RCD, the Policy Server may translate fields
+ * from formats or scales used in the SCD into formats or scales used in the
+ * RCD. For example, the Policy Server may modify the "priority" of a request
+ * coming from an Application Manager (especially important to do for an AM
+ * outside of the MSO network) so that this priority field uses a consistent
+ * scale throughout the operator's RCD. In its capacity as an intermediary, the
+ * Policy Server may use bidirectional translation – in other words, it should
+ * translate requests from the AM to the CMTS and "untranslate" the responses
+ * from the CMTS to the AM. This capability can be supported by stateful policy
+ * servers by remembering the original request, and it can be supported by
+ * stateless Policy Servers if the translation function is invertible.
+ * Modification of certain objects, specifically the Classifier and Traffic
+ * Profile objects, may cause operational problems in the originating AM. As
+ * such, these objects MUST NOT be modified by the policy server. Aside from
+ * these exceptions, all other objects may be policed and modified at the PS's
+ * discretion based on provisioned policy rules.
+ * </p>
+ *
+ */
+public interface IPCMMPolicyServer extends IPCMMServer, IStateful {
+
+ /**
+ * establishes COPS connection with the CMTS
+ *
+ * @param host
+ * : remote host name or ip address
+ * @return connected socket.
+ */
+ IPSCMTSClient requestCMTSConnection(String host);
+
+ /**
+ * establishes COPS connection with the CMTS
+ *
+ * @param host
+ * : remote ip address‚
+ * @return connected socket.
+ */
+ IPSCMTSClient requestCMTSConnection(InetAddress host);
+
+ /**
+ * <p>
+ * In the PacketCable model, the CMTS (PEP) is the one that listens on the
+ * assigned port 3918, and it is the Policy Server that MUST initiate the
+ * TCP connection to the CMTS, thus we implement the IPCMMClient interface.
+ * </p>
+ */
+ public static interface IPSCMTSClient extends IPCMMClient {
+
+ /**
+ *
+ * @return Classifier Id.
+ */
+ short getClassifierId();
+
+ /**
+ *
+ * @return the transaction Id.
+ */
+ short getTransactionId();
+
+ /**
+ * Gate id transmitted by the CMTS to the PS.
+ *
+ * @return the Gate Id.
+ */
+ int getGateId();
+
+ /**
+ * initiates a Gate-Set with the CMTS
+ *
+ * @return
+ */
+ boolean gateSet();
+
+ /**
+ * initiates a Gate-Info with the CMTS
+ *
+ * @return
+ */
+ boolean gateInfo();
+
+ /**
+ * initiates a Gate-Delete with the CMTS
+ *
+ * @return
+ */
+ boolean gateDelete();
+
+ /**
+ * sends synch request
+ *
+ * @return
+ */
+ boolean gateSynchronize();
+
+ /**
+ * Sets the value of the multi-media version info.
+ *
+ * @param MM
+ * version info
+ */
+ void setVersionInfo(MMVersionInfo vInfo);
+
+ /**
+ *
+ * @return MM version info
+ */
+ MMVersionInfo getVersionInfo();
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.rcd;
+
+import org.pcmm.concurrent.IWorker;
+import org.pcmm.state.IStateful;
+
+/**
+ * <p>
+ * As discussed in RFC 2753 [11], the policy management framework underlying
+ * PacketCable Multimedia is based on the work of the IETF's Resource Allocation
+ * Protocol (RAP) working group. Since the Policy Server is situated between the
+ * Application Manager and the CMTS, it simultaneously plays a dual role as a
+ * "proxy" for AM-initiated session requests and as a "sentry" for defining and
+ * enforcing Resource Control Domain policy.
+ * </p>
+ * <p>
+ * As described in [11] and in keeping with the PacketCable 1.x DQoS model, the
+ * Policy Server serves as Policy Decision Point (PDP) in relation to the CMTS
+ * resource-management procedures. Conversely, the Policy Server assumes the
+ * role of Policy Enforcement Point (PEP) in relation to the Application Manager
+ * as it proxies Gate Control messages to and from the CMTS element.
+ * </p>
+ * <p>
+ * To revisit the interaction scenario, the Application Manager issues policy
+ * requests to the Policy Server. The Policy Server acting as a "sentry" for
+ * these requests, and applies a set of policy rules that have been
+ * pre-provisioned by the MSO. Upon passing the checks, the Policy Server then
+ * acts as a "proxy" with respect to the Application Manager and the CMTS,
+ * forwarding the policy request and returning any associated response. Each
+ * policy request transaction must be processed individually.
+ * </p>
+ * <p>
+ * Policy decisions may be based on a number of factors, such as:
+ * <ul>
+ * <li>Parameters associated with the request and the status of available
+ * resources</li>
+ * <li>Identity of the particular client and associated profile information</li>
+ * <li>Application parameters</li>
+ * <li>Security considerations</li>
+ * <li>Time-of-day</li>
+ * </ul>
+ * The primary functions of the Policy Server include:
+ * <ul>
+ * <li>A policy decision request mechanism, invoked by Application Managers</li>
+ * <li>A policy decision request 'policing' mechanism, enforcing installed
+ * Policy Rules</li>
+ * <li>A policy decision delivery mechanism, used to install policy decisions on
+ * the CMTS</li>
+ * <li>A mechanism to allow for the proxying of QoS management messages to the
+ * CMTS on behalf of the Application Manager</li>
+ * <li>An event recording interface to a Record Keeping Server that is used to
+ * log policy requests, which may in turn be correlated with network resource
+ * usage records</li>
+ * </ul>
+ * <p>
+ * Since the Policy Server functions as a proxy between the AM and CMTS elements
+ * (with complementary client and server interfaces) some MSOs may elect to
+ * deploy multiple layers of Policy Servers and to delegate certain policy
+ * decisions among these servers in order to satisfy requirements associated
+ * with scalability and fault-tolerance.
+ * </p>
+ * </p>
+ *
+ *
+ */
+public interface IPCMMServer extends IStateful {
+
+ /**
+ *
+ */
+ void startServer();
+
+ /**
+ *
+ */
+ void stopServer();
+
+ /**
+ * When a client connects to the server, a handler is needed to manage the
+ * exchange of the messages between this client and the server.
+ *
+ *
+ */
+ public static interface IPCMMClientHandler extends IWorker, IPCMMClient {
+
+ }
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.rcd.impl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import org.pcmm.nio.PCMMChannel;
+// import org.junit.Assert;
+import org.pcmm.objects.MMVersionInfo;
+import org.pcmm.rcd.IPCMMClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.COPSMsg;
+
+/**
+ *
+ * default implementation for {@link IPCMMClient}
+ *
+ *
+ */
+public class AbstractPCMMClient implements IPCMMClient {
+
+ protected Logger logger = LoggerFactory.getLogger(AbstractPCMMClient.class);
+ /**
+ * socket used to communicated with server.
+ */
+ private Socket socket;
+
+ private String clientHanlde;
+
+ private MMVersionInfo versionInfo;
+
+ private PCMMChannel channel;
+
+ public AbstractPCMMClient() {
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMClient#sendRequest(pcmm.messages.IMessage)
+ */
+ public void sendRequest(COPSMsg requestMessage) {
+ try {
+ channel.sendMsg(requestMessage);
+ } catch (Exception e) {
+ logger.error(e.getMessage(), getSocket());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMClient#readMessage()
+ */
+ public COPSMsg readMessage() {
+ try {
+ COPSMsg recvdMsg = channel.receiveMessage();
+ // logger.debug("received message : " + recvdMsg.getHeader());
+ return recvdMsg;
+ } catch (Exception e) {
+ logger.error(e.getMessage(), getSocket());
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMClient#tryConnect(java.lang.String, int)
+ */
+ public boolean tryConnect(String address, int port) {
+ try {
+ InetAddress addr = InetAddress.getByName(address);
+ tryConnect(addr, port);
+ } catch (UnknownHostException e) {
+ logger.error(e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMClient#tryConnect(java.net.InetAddress, int)
+ */
+ public boolean tryConnect(InetAddress address, int port) {
+ try {
+ setSocket(new Socket(address, port));
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMClient#disconnect()
+ */
+ public boolean disconnect() {
+ if (isConnected()) {
+ try {
+ socket.close();
+ channel = null;
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @return the socket
+ */
+ public Socket getSocket() {
+ return socket;
+ }
+
+ public PCMMChannel getChannel() {
+ return channel;
+ }
+
+ /**
+ * @param socket
+ * the socket to set
+ */
+ public void setSocket(Socket socket) {
+ this.socket = socket;
+ if (this.socket != null
+ && (this.channel == null || !this.channel.getSocket().equals(
+ this.socket)))
+ channel = new PCMMChannel(this.socket);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMClient#isConnected()
+ */
+ public boolean isConnected() {
+ return socket != null && socket.isConnected();
+ }
+
+ /**
+ * @return the versionInfo
+ */
+ public MMVersionInfo getVersionInfo() {
+ return versionInfo;
+ }
+
+ /**
+ * @param versionInfo
+ * the versionInfo to set
+ */
+ public void setVersionInfo(MMVersionInfo versionInfo) {
+ this.versionInfo = versionInfo;
+ }
+
+ @Override
+ public String getClientHandle() {
+ return clientHanlde;
+ }
+
+ @Override
+ public void setClientHandle(String handle) {
+ this.clientHanlde = handle;
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.rcd.impl;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.Executors;
+
+import org.pcmm.PCMMConstants;
+import org.pcmm.PCMMProperties;
+import org.pcmm.concurrent.IWorkerPool;
+import org.pcmm.concurrent.impl.WorkerPool;
+// import org.junit.Assert;
+import org.pcmm.messages.impl.MessageFactory;
+import org.pcmm.rcd.IPCMMServer;
+import org.pcmm.state.IState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSMsg;
+
+/*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMServer
+ */
+public abstract class AbstractPCMMServer implements IPCMMServer {
+ protected Logger logger;
+ /*
+ * A ServerSocket to accept messages ( OPN requests)
+ */
+ private ServerSocket serverSocket;
+
+ private Socket stopSocket;
+
+ private volatile boolean keepAlive;
+ /*
+ *
+ */
+ private int port;
+
+ IWorkerPool pool;
+
+ protected AbstractPCMMServer() {
+ this(PCMMProperties.get(PCMMConstants.PCMM_PORT, Integer.class));
+ }
+
+ protected AbstractPCMMServer(int port) {
+ // XXX - Assert.assertTrue(port >= 0 && port <= 65535);
+ this.port = port;
+ keepAlive = true;
+ logger = LoggerFactory.getLogger(getClass().getName());
+ int poolSize = PCMMProperties.get(PCMMConstants.PS_POOL_SIZE, Integer.class);
+ pool = new WorkerPool(poolSize);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMServer#startServer()
+ */
+ public void startServer() {
+ if (serverSocket != null)
+ return;
+ try {
+ serverSocket = new ServerSocket(port);
+ logger.info("Server started and listening on port :" + port);
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ }
+ // execute this in a single thread executor
+ Executors.newSingleThreadExecutor().execute(new Runnable() {
+ public void run() {
+ while (keepAlive) {
+ try {
+ Socket socket = serverSocket.accept();
+ logger.info("Accepted a new connection from :" + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
+ if (keepAlive) {
+ pool.schedule(getPCMMClientHandler(socket));
+ logger.info("Handler attached tp : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
+ } else {
+ logger.info("connection to be closed : " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort());
+ socket.close();
+ }
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ try {
+ if (stopSocket != null && stopSocket.isConnected()) {
+ logger.info("Cleaning up");
+ stopSocket.close();
+ }
+ if (serverSocket != null && serverSocket.isBound()) {
+ logger.info("Server about to stop");
+ serverSocket.close();
+ logger.info("Server stopped");
+ }
+ } catch (IOException e) {
+ logger.error(e.getMessage());
+ }
+ }
+ });
+ }
+
+ /**
+ * This client is used to handle requests from within the Application
+ * Manager
+ *
+ * @param socket
+ * @return client handler
+ */
+ protected abstract IPCMMClientHandler getPCMMClientHandler(Socket socket);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMServer#stopServer()
+ */
+ public void stopServer() {
+ // set to stop
+ keepAlive = false;
+ try {
+ if (serverSocket != null) {
+ stopSocket = new Socket(serverSocket.getInetAddress(), serverSocket.getLocalPort());
+ logger.info("STOP socket created and attached");
+ }
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.state.IStateful#recordState()
+ */
+ public void recordState() {
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.state.IStateful#getRecoredState()
+ */
+ public IState getRecoredState() {
+ return null;
+ }
+
+ /**
+ * @return the serverSocket
+ */
+ public ServerSocket getServerSocket() {
+ return serverSocket;
+ }
+
+ /**
+ * @param serverSocket
+ * the serverSocket to set
+ */
+ public void setServerSocket(ServerSocket serverSocket) {
+ this.serverSocket = serverSocket;
+ }
+
+ /**
+ * @return the port
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * @param port
+ * the port to set
+ */
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see pcmm.rcd.IPCMMServer.IPCMMClientHandler
+ */
+ public abstract class AbstractPCMMClientHandler extends AbstractPCMMClient
+ implements IPCMMClientHandler {
+
+ protected boolean sendCCMessage = false;
+
+ public AbstractPCMMClientHandler(Socket socket) {
+ super();
+ setSocket(socket);
+ }
+
+ @Override
+ public boolean disconnect() {
+ // XXX send CC message
+ sendCCMessage = true;
+ /*
+ * is this really needed ?
+ */
+ // if (getSocket() != null)
+ // handlersPool.remove(getSocket());
+ COPSMsg message = MessageFactory.getInstance().create(COPSHeader.COPS_OP_CC);
+ sendRequest(message);
+ return super.disconnect();
+ }
+
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+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;
+import org.pcmm.messages.impl.MessageFactory;
+import org.pcmm.rcd.ICMTS;
+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;
+
+/**
+ *
+ */
+public class CMTS extends AbstractPCMMServer implements ICMTS {
+
+ public CMTS() {
+ super();
+ }
+
+ @Override
+ protected IPCMMClientHandler getPCMMClientHandler(final Socket socket) {
+
+ return new AbstractPCMMClientHandler(socket) {
+
+ private String handle;
+
+ public void run() {
+ try {
+ // send OPN message
+ // set the major version info and minor version info to
+ // default (5,0)
+ logger.info("Send OPN message to the PS");
+ sendRequest(MessageFactory.getInstance().create(COPSHeader.COPS_OP_OPN, new Properties()));
+ // wait for CAT
+ COPSMsg recvMsg = readMessage();
+
+ if (recvMsg.getHeader().isAClientClose()) {
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvMsg;
+ logger.info("PS requested Client-Close" + cMsg.getError().getDescription());
+ // send a CC message and close the socket
+ disconnect();
+ return;
+ }
+ if (recvMsg.getHeader().isAClientAccept()) {
+ logger.info("received Client-Accept from PS");
+ 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();
+
+ logger.info("Send a REQ message to the PS");
+ {
+ Properties prop = new Properties();
+ COPSMsg reqMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_REQ, prop);
+ handle = ((COPSReqMsg) reqMsg).getClientHandle().getId().str();
+ sendRequest(reqMsg);
+ }
+ // Create the connection manager
+ PCMMCmtsConnection conn = new PCMMCmtsConnection(CLIENT_TYPE, socket);
+ // pcmm specific handler
+ // conn.addReqStateMgr(handle, new
+ // PCMMPSReqStateMan(CLIENT_TYPE, handle));
+ conn.addRequestState(handle, new CmtsDataProcessor());
+ conn.setKaTimer(kaTimeVal);
+ conn.setAcctTimer(acctTimer);
+ logger.info(getClass().getName() + " Thread(conn).start");
+ new Thread(conn).start();
+ } else {
+ // messages of other types are not expected
+ throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
+ }
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ }
+ }
+
+ @Override
+ public void task(Callable<?> c) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void shouldWait(int t) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void done() {
+ // TODO Auto-generated method stub
+
+ }
+
+ };
+ }
+
+ /* public */class PCMMCmtsConnection extends COPSPepConnection {
+
+ public PCMMCmtsConnection(short clientType, Socket sock) {
+ super(clientType, sock);
+ }
+
+ public COPSPepReqStateMan addRequestState(String clientHandle, COPSPepDataProcess process)
+ throws COPSException, COPSPepException {
+ return super.addRequestState(clientHandle, process);
+ }
+
+ // public void addReqStateMgr(String hanlde, COPSPepReqStateMan r) {
+ // // map < String(COPSHandle), COPSPepReqStateMan>;
+ // getReqStateMans().put(hanlde, r);
+ // }
+ }
+
+ @SuppressWarnings("rawtypes")
+ class PCMMPSReqStateMan extends COPSPepReqStateMan {
+
+ public PCMMPSReqStateMan(short clientType, String clientHandle) {
+ super(clientType, clientHandle);
+ _process = new CmtsDataProcessor();
+
+ }
+
+ @Override
+ protected void processDecision(COPSDecisionMsg dMsg)
+ throws COPSPepException {
+
+ // COPSHandle handle = dMsg.getClientHandle();
+ Hashtable decisions = dMsg.getDecisions();
+
+ Hashtable<String, String> removeDecs = new Hashtable<String, String>(10);
+ Hashtable<String, String> installDecs = new Hashtable<String, String>(10);
+ Hashtable<String, String> errorDecs = new Hashtable<String, String>(10);
+ 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()) {
+ // TODO when there is install request only the PR_PRID
+ // is git but the ClientSI object containing the PR_EPD
+ // is null??? this is why the tests fail and so I set
+ // the assertion to NOT true....
+ 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;
+ }
+ }
+ }
+ }
+ if (_process != null) {
+ // ** 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;
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ class CmtsDataProcessor extends COPSPepDataProcess {
+
+ private Hashtable<String, String> removeDecs;
+ private Hashtable<String, String> installDecs;
+ private Hashtable<String, String> errorDecs;
+ private COPSPepReqStateMan stateManager;
+
+ public CmtsDataProcessor() {
+ setRemoveDecs(new Hashtable<String, String>(10));
+ setInstallDecs(new Hashtable<String, String>(10));
+ setErrorDecs(new Hashtable<String, String>(10));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setDecisions(COPSPepReqStateMan man, Hashtable removeDecs, Hashtable installDecs, Hashtable errorDecs) {
+ setRemoveDecs(removeDecs);
+ setInstallDecs(installDecs);
+ setErrorDecs(errorDecs);
+ setStateManager(man);
+ }
+
+ @Override
+ public boolean isFailReport(COPSPepReqStateMan man) {
+ return (errorDecs != null && errorDecs.size() > 0);
+ }
+
+ @Override
+ public Hashtable getReportData(COPSPepReqStateMan man) {
+ if (isFailReport(man)) {
+ return errorDecs;
+ } else {
+ ITransactionID transactionID = null;
+ String key = null;
+ Hashtable<String, String> siDataHashTable = new Hashtable<String, String>();
+ if (installDecs.size() > 0) {
+ String data = "";
+ for (String k : installDecs.keySet()) {
+ data = installDecs.get(k);
+ break;
+ }
+ transactionID = new PCMMGateReq(new COPSData(data).getData()).getTransactionID();
+ IPCMMGate responseGate = new PCMMGateReq();
+ responseGate.setTransactionID(transactionID);
+ siDataHashTable.put(key, new String(responseGate.getData()));
+ }
+ return siDataHashTable;
+ }
+ }
+
+ @Override
+ public Hashtable getClientData(COPSPepReqStateMan man) {
+ // TODO Auto-generated method stub
+ return new Hashtable<String, String>();
+ }
+
+ @Override
+ public Hashtable getAcctData(COPSPepReqStateMan man) {
+ // TODO Auto-generated method stub
+ return new Hashtable<String, String>();
+ }
+
+ @Override
+ public void notifyClosedConnection(COPSPepReqStateMan man, COPSError error) {
+
+ }
+
+ @Override
+ public void notifyNoKAliveReceived(COPSPepReqStateMan man) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void closeRequestState(COPSPepReqStateMan man) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void newRequestState(COPSPepReqStateMan man) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Hashtable<String, String> getRemoveDecs() {
+ return removeDecs;
+ }
+
+ public void setRemoveDecs(Hashtable<String, String> removeDecs) {
+ this.removeDecs = removeDecs;
+ }
+
+ public Hashtable<String, String> getInstallDecs() {
+ return installDecs;
+ }
+
+ public void setInstallDecs(Hashtable<String, String> installDecs) {
+ this.installDecs = installDecs;
+ }
+
+ public Hashtable<String, String> getErrorDecs() {
+ return errorDecs;
+ }
+
+ public void setErrorDecs(Hashtable<String, String> errorDecs) {
+ this.errorDecs = errorDecs;
+ }
+
+ public COPSPepReqStateMan getStateManager() {
+ return stateManager;
+ }
+
+ public void setStateManager(COPSPepReqStateMan stateManager) {
+ this.stateManager = stateManager;
+ }
+ }
+}
--- /dev/null
+/**
+ * @header@
+ */
+package org.pcmm.rcd.impl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Properties;
+
+import org.pcmm.PCMMConstants;
+import org.pcmm.PCMMGlobalConfig;
+import org.pcmm.PCMMProperties;
+import org.pcmm.gates.IAMID;
+import org.pcmm.gates.IClassifier;
+import org.pcmm.gates.IExtendedClassifier;
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IGateSpec;
+import org.pcmm.gates.IGateSpec.DSCPTOS;
+import org.pcmm.gates.IGateSpec.Direction;
+import org.pcmm.gates.IPCMMError;
+import org.pcmm.gates.IPCMMGate;
+import org.pcmm.gates.ISubscriberID;
+import org.pcmm.gates.ITrafficProfile;
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.impl.AMID;
+import org.pcmm.gates.impl.BestEffortService;
+import org.pcmm.gates.impl.Classifier;
+import org.pcmm.gates.impl.ExtendedClassifier;
+import org.pcmm.gates.impl.GateID;
+import org.pcmm.gates.impl.GateSpec;
+import org.pcmm.gates.impl.PCMMError;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.pcmm.gates.impl.SubscriberID;
+import org.pcmm.gates.impl.TransactionID;
+import org.pcmm.messages.IMessage.MessageProperties;
+import org.pcmm.messages.impl.MessageFactory;
+import org.pcmm.objects.MMVersionInfo;
+import org.pcmm.rcd.IPCMMPolicyServer;
+import org.pcmm.utils.PCMMException;
+import org.umu.cops.prpdp.COPSPdpConnection;
+import org.umu.cops.prpdp.COPSPdpDataProcess;
+import org.umu.cops.stack.COPSClientAcceptMsg;
+import org.umu.cops.stack.COPSClientCloseMsg;
+import org.umu.cops.stack.COPSClientOpenMsg;
+import org.umu.cops.stack.COPSClientSI;
+import org.umu.cops.stack.COPSData;
+import org.umu.cops.stack.COPSDecision;
+import org.umu.cops.stack.COPSError;
+import org.umu.cops.stack.COPSException;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSReportMsg;
+import org.umu.cops.stack.COPSReqMsg;
+
+/**
+ *
+ * PCMM policy server
+ *
+ */
+public class PCMMPolicyServer extends AbstractPCMMServer implements
+ IPCMMPolicyServer {
+ /**
+ * since PCMMPolicyServer can connect to multiple CMTS (PEP) we need to
+ * manage each connection in a separate thread.
+ */
+
+ public PCMMPolicyServer() {
+ super();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.rcd.IPCMMPolicyServer#requestCMTSConnection(java.lang.String)
+ */
+ public IPSCMTSClient requestCMTSConnection(String host) {
+ try {
+ InetAddress address = InetAddress.getByName(host);
+ return requestCMTSConnection(address);
+ } catch (UnknownHostException e) {
+ logger.error(e.getMessage());
+ }
+ return null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.pcmm.rcd.IPCMMPolicyServer#requestCMTSConnection(java.net.InetAddress
+ * )
+ */
+ public IPSCMTSClient requestCMTSConnection(InetAddress host) {
+ IPSCMTSClient client = new PSCMTSClient();
+ try {
+ if (client.tryConnect(host, PCMMProperties.get(PCMMConstants.PCMM_PORT, Integer.class))) {
+ boolean endNegotiation = false;
+ while (!endNegotiation) {
+ logger.debug("waiting for OPN message from CMTS");
+ COPSMsg opnMessage = client.readMessage();
+ // Client-Close
+ if (opnMessage.getHeader().isAClientClose()) {
+ COPSError error = ((COPSClientCloseMsg) opnMessage).getError();
+ logger.debug("CMTS requetsed Client-Close");
+ throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode()));
+ } else // Client-Open
+ if (opnMessage.getHeader().isAClientOpen()) {
+ logger.debug("OPN message received from CMTS");
+ COPSClientOpenMsg opn = (COPSClientOpenMsg) opnMessage;
+ if (opn.getClientSI() == null)
+ throw new COPSException("CMTS shoud have sent MM version info in Client-Open message");
+ else {
+ // set the version info
+ MMVersionInfo vInfo = new MMVersionInfo(opn.getClientSI().getData().getData());
+ client.setVersionInfo(vInfo);
+ logger.debug("CMTS sent MMVersion info : major:" + vInfo.getMajorVersionNB() + " minor:" + vInfo.getMinorVersionNB()); //
+ if (client.getVersionInfo().getMajorVersionNB() == client.getVersionInfo().getMinorVersionNB()) {
+ // send a CC since CMTS has exhausted all
+ // protocol selection attempts
+ throw new COPSException("CMTS exhausted all protocol selection attempts");
+ }
+ }
+ // send CAT response
+ Properties prop = new Properties();
+ logger.debug("send CAT to the CMTS ");
+ COPSMsg catMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_CAT, prop);
+ client.sendRequest(catMsg);
+ // wait for REQ msg
+ COPSMsg reqMsg = client.readMessage();
+ // Client-Close
+ if (reqMsg.getHeader().isAClientClose()) {
+ COPSError error = ((COPSClientCloseMsg) opnMessage).getError();
+ logger.debug("CMTS requetsed Client-Close");
+ throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode()));
+ } else // Request
+ if (reqMsg.getHeader().isARequest()) {
+ logger.debug("Received REQ message form CMTS");
+ // end connection attempts
+ COPSReqMsg req = (COPSReqMsg) reqMsg;
+ // set the client handle to be used later by the
+ // gate-set
+ client.setClientHandle(req.getClientHandle().getId().str());
+ COPSPdpDataProcess processor = null;
+ COPSPdpConnection copsPdpConnection = new COPSPdpConnection(opn.getPepId(), ((AbstractPCMMClient) client).getSocket(), processor);
+ copsPdpConnection.setKaTimer(((COPSClientAcceptMsg) catMsg).getKATimer().getTimerVal());
+ pool.schedule(pool.adapt(copsPdpConnection));
+ endNegotiation = true;
+ } else
+ throw new COPSException("Can't understand request");
+ } else {
+ throw new COPSException("Can't understand request");
+ }
+ }
+ }
+ // else raise exception.
+ } catch (Exception e) {
+ logger.error(e.getMessage());
+ // no need to keep connection.
+ client.disconnect();
+ return null;
+ }
+ return client;
+ }
+
+ @Override
+ protected IPCMMClientHandler getPCMMClientHandler(Socket socket) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ *
+ * @see {@link IPSCMTSClient}
+ */
+ /* public */static class PSCMTSClient extends AbstractPCMMClient implements
+ IPSCMTSClient {
+ /**
+ * Transaction id is
+ */
+ private short transactionID;
+ private short classifierID;
+ private int gateID;
+
+ public PSCMTSClient() {
+ super();
+ logger.info("Client " + getClass() + hashCode() + " crated and started");
+ }
+
+ public PSCMTSClient(Socket socket) {
+ setSocket(socket);
+ }
+
+ public boolean gateSet() {
+ logger.debug("Sending Gate-Set message");
+ if (!isConnected())
+ throw new IllegalArgumentException("Not connected");
+ // XXX check if other values should be provided
+ //
+ ITrafficProfile trafficProfile = buildTrafficProfile();
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+ ITransactionID trID = new TransactionID();
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateSet);
+ transactionID = (short) (transactionID == 0 ? (short) (Math.random() * hashCode()) : transactionID);
+ trID.setTransactionIdentifier(transactionID);
+ // AMID
+ IAMID amid = getAMID();
+ // GATE SPEC
+ IGateSpec gateSpec = getGateSpec();
+ ISubscriberID subscriberID = new SubscriberID();
+ // Classifier if MM version <4, Extended Classifier else
+ IClassifier eclassifier = getClassifier(subscriberID);
+
+ IPCMMGate gate = new PCMMGateReq();
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateSpec(gateSpec);
+ gate.setTrafficProfile(trafficProfile);
+ gate.setClassifier(eclassifier);
+ byte[] data = gate.getData();
+
+ // 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.GATE_CONTROL, new COPSData(data, 0, data.length));
+ COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop);
+ // ** Send the GateSet Decision
+ // **
+ sendRequest(decisionMsg);
+ // TODO check on this ?
+ // waits for the gate-set-ack or error
+ COPSMsg responseMsg = readMessage();
+ if (responseMsg.getHeader().isAReport()) {
+ logger.info("processing received report from CMTS");
+ COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI().size() == 0) {
+ logger.debug("CMTS responded with an empty SI");
+ return false;
+ }
+ COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
+ IPCMMError error = ((PCMMGateReq) responseGate).getError();
+ if (error != null) {
+ logger.error(error.toString());
+ return false;
+ }
+ logger.info("the CMTS has sent TransactionID :"+responseGate.getTransactionID());
+ if (responseGate.getTransactionID() != null && responseGate.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
+ logger.info("the CMTS has sent a Gate-Set-Ack response");
+ // here CMTS responded that he acknowledged the Gate-Set
+ // TODO do further check of Gate-Set-Ack GateID etc...
+ gateID = responseGate.getGateID().getGateID();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMPolicyServer#gateDelete()
+ */
+ @Override
+ public boolean gateDelete() {
+ if (!isConnected()) {
+ logger.error("Not connected");
+ return false;
+ }
+ ITransactionID trID = new TransactionID();
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateDelete);
+ trID.setTransactionIdentifier(transactionID);
+ // AMID
+ IAMID amid = getAMID();
+ // GATE SPEC
+ ISubscriberID subscriberID = new SubscriberID();
+ try {
+ subscriberID.setSourceIPAddress(InetAddress.getLocalHost());
+ } catch (UnknownHostException e1) {
+ logger.error(e1.getMessage());
+ }
+
+ IGateID gateIdObj = new GateID();
+ gateIdObj.setGateID(gateID);
+
+ IPCMMGate gate = new PCMMGateReq();
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateID(gateIdObj);
+
+ // 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);
+ 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);
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(getSocket());
+ } catch (IOException e) {
+ logger.error("Failed to send the decision, reason: " + e.getMessage());
+ return false;
+ }
+ // waits for the gate-delete-ack or error
+ COPSMsg responseMsg = readMessage();
+ if (responseMsg.getHeader().isAReport()) {
+ logger.info("processing received report from CMTS");
+ COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI().size() == 0) {
+ return false;
+ }
+ COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
+ IPCMMError error = ((PCMMGateReq) responseGate).getError();
+ if (error != null) {
+ logger.error(error.toString());
+ return false;
+ }
+ // here CMTS responded that he acknowledged the Gate-delete
+ // message
+ ITransactionID responseTransactionID = responseGate.getTransactionID();
+ if (responseTransactionID != null && responseTransactionID.getGateCommandType() == ITransactionID.GateDeleteAck) {
+ // TODO check : Is this test needed ??
+ if (responseGate.getGateID().getGateID() == gateID && responseTransactionID.getTransactionIdentifier() == transactionID) {
+ logger.info("the CMTS has sent a Gate-Delete-Ack response");
+ return true;
+ }
+ }
+
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMPolicyServer#gateInfo()
+ */
+ @Override
+ public boolean gateInfo() {
+ if (!isConnected()) {
+ logger.error("Not connected");
+ return false;
+ }
+ ITransactionID trID = new TransactionID();
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.GateInfo);
+ trID.setTransactionIdentifier(transactionID);
+ // AMID
+ IAMID amid = getAMID();
+ // GATE SPEC
+ ISubscriberID subscriberID = new SubscriberID();
+ try {
+ subscriberID.setSourceIPAddress(InetAddress.getLocalHost());
+ } catch (UnknownHostException e1) {
+ logger.error(e1.getMessage());
+ }
+ IGateID gateIdObj = new GateID();
+ gateIdObj.setGateID(gateID);
+
+ IPCMMGate gate = new PCMMGateReq();
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateID(gateIdObj);
+
+ // 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);
+ 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);
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(getSocket());
+ } catch (IOException e) {
+ logger.error("Failed to send the decision, reason: " + e.getMessage());
+ return false;
+ }
+ // waits for the gate-Info-ack or error
+ COPSMsg responseMsg = readMessage();
+ if (responseMsg.getHeader().isAReport()) {
+ logger.info("processing received report from CMTS");
+ COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI().size() == 0) {
+ return false;
+ }
+ COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
+ IPCMMError error = ((PCMMGateReq) responseGate).getError();
+ ITransactionID responseTransactionID = responseGate.getTransactionID();
+ if (error != null) {
+ logger.debug(responseTransactionID != null ? responseTransactionID.toString() : "returned Transaction ID is null");
+ logger.error(error.toString());
+ return false;
+ }
+ // here CMTS responded that he acknowledged the Gate-Info
+ // message
+ /*
+ * <Gate-Info-Ack> = <ClientSI Header> <TransactionID> <AMID>
+ * <SubscriberID> <GateID> [<Event Generation Info>] <Gate-Spec>
+ * <classifier> <classifier...>] <Traffic Profile> <Gate Time
+ * Info> <Gate Usage Info> [<Volume-Based Usage Limit>] [<PSID>]
+ * [<Msg-Receipt-Key>] [<UserID>] [<Time-Based Usage Limit>]
+ * [<Opaque Data>] <GateState> [<SharedResourceID>]
+ */
+ if (responseTransactionID != null && responseTransactionID.getGateCommandType() == ITransactionID.GateInfoAck) {
+ // TODO need to implement missing data wrapper
+ logger.info("TransactionID : " + responseTransactionID.toString());
+ logger.info("AMID :" + String.valueOf(responseGate.getAMID()));
+ logger.info("SubscriberID :" + String.valueOf(responseGate.getSubscriberID()));
+ logger.info("Traffic Profile :" + String.valueOf(responseGate.getTrafficProfile()));
+ logger.info("Gate Time Info :");
+ logger.info("Gate Usage Info :");
+ logger.info("GateState :");
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.pcmm.rcd.IPCMMPolicyServer#synchronize()
+ */
+ @Override
+ public boolean gateSynchronize() {
+ if (!isConnected()) {
+ logger.error("Not connected");
+ return false;
+ }
+ ITransactionID trID = new TransactionID();
+ // set transaction ID to gate set
+ trID.setGateCommandType(ITransactionID.SynchRequest);
+ trID.setTransactionIdentifier(transactionID);
+ // AMID
+ IAMID amid = getAMID();
+ // GATE SPEC
+ ISubscriberID subscriberID = new SubscriberID();
+ try {
+ subscriberID.setSourceIPAddress(InetAddress.getLocalHost());
+ } catch (UnknownHostException e1) {
+ logger.error(e1.getMessage());
+ }
+ IGateID gateIdObj = new GateID();
+ gateIdObj.setGateID(gateID);
+
+ IPCMMGate gate = new PCMMGateReq();
+ gate.setTransactionID(trID);
+ gate.setAMID(amid);
+ gate.setSubscriberID(subscriberID);
+ gate.setGateID(gateIdObj);
+
+ // 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);
+ 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);
+ // ** Send the GateSet Decision
+ // **
+ try {
+ decisionMsg.writeData(getSocket());
+ } catch (IOException e) {
+ logger.error("Failed to send the decision, reason: " + e.getMessage());
+ return false;
+ }
+ // waits for the gate-Info-ack or error
+ COPSMsg responseMsg = readMessage();
+ if (responseMsg.getHeader().isAReport()) {
+ logger.info("processing received report from CMTS");
+ COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI().size() == 0) {
+ return false;
+ }
+ COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
+ IPCMMError error = ((PCMMGateReq) responseGate).getError();
+ ITransactionID responseTransactionID = responseGate.getTransactionID();
+ if (error != null) {
+ logger.debug(responseTransactionID != null ? responseTransactionID.toString() : "returned Transaction ID is null");
+ logger.error(error.toString());
+ return false;
+ }
+ // here CMTS responded that he acknowledged the Gate-Info
+ // message
+ /*
+ * <Gate-Info-Ack> = <ClientSI Header> <TransactionID> <AMID>
+ * <SubscriberID> <GateID> [<Event Generation Info>] <Gate-Spec>
+ * <classifier> <classifier...>] <Traffic Profile> <Gate Time
+ * Info> <Gate Usage Info> [<Volume-Based Usage Limit>] [<PSID>]
+ * [<Msg-Receipt-Key>] [<UserID>] [<Time-Based Usage Limit>]
+ * [<Opaque Data>] <GateState> [<SharedResourceID>]
+ */
+ if (responseTransactionID != null && responseTransactionID.getGateCommandType() == ITransactionID.SynchReport) {
+ // TODO need to implement missing data wrapper
+ logger.info("TransactionID : " + responseTransactionID.toString());
+ logger.info("AMID :" + String.valueOf(responseGate.getAMID()));
+ logger.info("SubscriberID :" + String.valueOf(responseGate.getSubscriberID()));
+ logger.info("Traffic Profile :" + String.valueOf(responseGate.getTrafficProfile()));
+ logger.info("Gate Time Info :");
+ logger.info("Gate Usage Info :");
+ logger.info("GateState :");
+ return true;
+ }
+
+ }
+ return false;
+ }
+
+ private IAMID getAMID() {
+ IAMID amid = new AMID();
+ amid.setApplicationType((short) 1);
+ amid.setApplicationMgrTag((short) 1);
+ return amid;
+ }
+
+ private IClassifier getClassifier(ISubscriberID subscriberID) {
+ IClassifier classifier = null;
+ // if the version major is less than 4 we need to use Classifier
+ if (getVersionInfo().getMajorVersionNB() >= 4) {
+ classifier = new ExtendedClassifier();
+ // eclassifier.setProtocol(IClassifier.Protocol.NONE);
+ classifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress.getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress.getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress.getByName(PCMMGlobalConfig.dstIP);
+ InetAddress mask = InetAddress.getByName(PCMMProperties.get(PCMMConstants.DEFAULT_MASK, String.class));
+ subscriberID.setSourceIPAddress(subIP);
+ classifier.setSourceIPAddress(srcIP);
+ classifier.setDestinationIPAddress(dstIP);
+ ((IExtendedClassifier) classifier).setIPDestinationMask(mask);
+ ((IExtendedClassifier) classifier).setIPSourceMask(mask);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ ((IExtendedClassifier) classifier).setSourcePortStart(PCMMGlobalConfig.srcPort);
+ ((IExtendedClassifier) classifier).setSourcePortEnd(PCMMGlobalConfig.srcPort);
+ ((IExtendedClassifier) classifier).setDestinationPortStart(PCMMGlobalConfig.dstPort);
+ ((IExtendedClassifier) classifier).setDestinationPortEnd(PCMMGlobalConfig.dstPort);
+ ((IExtendedClassifier) classifier).setActivationState((byte) 0x01);
+ /*
+ * check if we have a stored value of classifierID else we just
+ * create one eclassifier.setClassifierID((short) 0x01);
+ */
+ ((IExtendedClassifier) classifier).setClassifierID((short) (classifierID == 0 ? Math.random() * hashCode() : classifierID));
+ // XXX - testie
+ // eclassifier.setClassifierID((short) 1);
+ ((IExtendedClassifier) classifier).setAction((byte) 0x00);
+ // XXX - temp default until Gate Modify is hacked in
+ // eclassifier.setPriority(PCMMGlobalConfig.EClassifierPriority);
+ classifier.setPriority((byte) 65);
+
+ } else {
+ classifier = new Classifier();
+ classifier.setProtocol(IClassifier.Protocol.TCP);
+ try {
+ InetAddress subIP = InetAddress.getByName(PCMMGlobalConfig.SubscriberID);
+ InetAddress srcIP = InetAddress.getByName(PCMMGlobalConfig.srcIP);
+ InetAddress dstIP = InetAddress.getByName(PCMMGlobalConfig.dstIP);
+ subscriberID.setSourceIPAddress(subIP);
+ classifier.setSourceIPAddress(srcIP);
+ classifier.setDestinationIPAddress(dstIP);
+ } catch (UnknownHostException unae) {
+ System.out.println("Error getByName" + unae.getMessage());
+ }
+ classifier.setSourcePort(PCMMGlobalConfig.srcPort);
+ classifier.setDestinationPort(PCMMGlobalConfig.dstPort);
+ }
+ return classifier;
+ }
+
+ /**
+ *
+ * @return GateSpec object
+ */
+ private IGateSpec getGateSpec() {
+ IGateSpec gateSpec = new GateSpec();
+ gateSpec.setDirection(Direction.UPSTREAM);
+ gateSpec.setDSCP_TOSOverwrite(DSCPTOS.OVERRIDE);
+ gateSpec.setTimerT1(PCMMGlobalConfig.GateT1);
+ gateSpec.setTimerT2(PCMMGlobalConfig.GateT2);
+ gateSpec.setTimerT3(PCMMGlobalConfig.GateT3);
+ gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
+ return gateSpec;
+ }
+
+ /**
+ * creates a traffic profile with 3 envelops (Authorized, Reserved and
+ * Committed).
+ *
+ * @return Traffic profile
+ */
+ private ITrafficProfile buildTrafficProfile() {
+ ITrafficProfile trafficProfile = new BestEffortService(BestEffortService.DEFAULT_ENVELOP);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop().setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop().setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop().setRequestTransmissionPolicy(PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getAuthorizedEnvelop().setMaximumSustainedTrafficRate(PCMMGlobalConfig.DefaultLowBestEffortTrafficRate);
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+ ((BestEffortService) trafficProfile).getReservedEnvelop().setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getReservedEnvelop().setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getReservedEnvelop().setRequestTransmissionPolicy(PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getReservedEnvelop().setMaximumSustainedTrafficRate(PCMMGlobalConfig.DefaultLowBestEffortTrafficRate);
+ // PCMMGlobalConfig.DefaultBestEffortTrafficRate);
+
+ ((BestEffortService) trafficProfile).getCommittedEnvelop().setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop().setMaximumTrafficBurst(BestEffortService.DEFAULT_MAX_TRAFFIC_BURST);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop().setRequestTransmissionPolicy(PCMMGlobalConfig.BETransmissionPolicy);
+ ((BestEffortService) trafficProfile).getCommittedEnvelop().setMaximumSustainedTrafficRate(PCMMGlobalConfig.DefaultLowBestEffortTrafficRate);
+ return trafficProfile;
+ }
+
+ @Override
+ public short getClassifierId() {
+ return classifierID;
+ }
+
+ @Override
+ public short getTransactionId() {
+ return transactionID;
+ }
+
+ @Override
+ public int getGateId() {
+ return gateID;
+ }
+ }
+
+}
--- /dev/null
+
+/**
+ * <p>
+ * The Resource Control Domain (RCD) may be defined as a logical grouping of elements that provide connectivity and network resource level policy management along the packet forwarding paths to and from an end host.
+ * The RCD consists of CMTS and Policy Server entities whose responsibilities include management of resources along the packet forwarding paths.
+ * </p>
+ *
+ *
+ */
+package org.pcmm.rcd;
+
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.scd;
+
+/**
+ * <p>
+ * The Application Server is a network entity that interfaces with the
+ * Application Manager that requests PacketCable Multimedia services on behalf
+ * of clients. The AS may reside on the MSO's network or it may reside outside
+ * of this domain and interact with the MSO network via a particular trust
+ * relationship. Similarly, the AS may be under direct control of the operator
+ * or it may be controlled by a third-party. Any given AS may communicate with
+ * one or more Application Managers.
+ * </p>
+ * <p>
+ * The AS will communicate with a client via a signaling protocol that is
+ * outside the scope of this specification. Using this unspecified protocol, the
+ * Domain policies. For client requests that pass these checks, the AS
+ * determines the particular QoS parameters necessary to deliver the service to
+ * the client, based upon its knowledge of the requested service. It then sends
+ * a request for these resources to the appropriate Application Manager, which
+ * may deny the request based upon additional Service Control Domain policies or
+ * may pass the request on to the Policy Server.
+ * </p>
+ *
+ *
+ */
+public interface IApplicationServer {
+
+ /**
+ * sets the Application Server's id
+ *
+ * @param id
+ * : the id of the AS
+ */
+ void setASId(String id);
+
+ /**
+ * gets the AS id
+ *
+ * @return AS id
+ */
+ String getASId();
+
+}
--- /dev/null
+/**
+ *
+ */
+/**
+ *
+ */
+package org.pcmm.scd.impl;
--- /dev/null
+/**
+ * <p>
+ * The Service Control Domain (SCD) is defined as a logical grouping of elements that offer applications and content to service subscribers.
+ * The Application Manager resides in the SCD. Note that there may be one or more SCDs related to a single RCD. Conversely, each RCD may interact with one or more SCDs.
+ * </p>
+ *
+ *
+ */
+package org.pcmm.scd;
+
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.state;
+
+/**
+ *
+ */
+public interface IPCMMRecordKeepingServer {
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.state;
+
+/**
+ * <p>
+ * Object serving as a state holder, each stateful server should keep record of
+ * clients' state
+ * </p>
+ *
+ *
+ *
+ */
+public interface IState {
+
+}
--- /dev/null
+/**
+ @header@
+ */
+
+
+package org.pcmm.state;
+
+/**
+ * <p>
+ * Each stateful server should implement this interface, to be able to save and
+ * retrieve clients' state
+ * </p>
+ *
+ *
+ *
+ */
+public interface IStateful {
+
+ /**
+ * records the collected client state
+ */
+ void recordState();
+
+ /**
+ *
+ * @return recorded state.
+ */
+ IState getRecoredState();
+
+}
--- /dev/null
+/**
+ */
+package org.pcmm.state;
+
--- /dev/null
+/**
+ @header@
+ */
+
+package org.pcmm.utils;
+
+import org.pcmm.gates.IPCMMError;
+
+/**
+ * Defines the Exception that could be thrown by the API.
+ *
+ */
+public class PCMMException extends Exception {
+
+ public PCMMException(IPCMMError error) {
+ this(error.getDescription(), error.getErrorCode());
+ }
+
+ public PCMMException(String message, int code) {
+ super("error code [" + code + "]" + message);
+ }
+
+}
--- /dev/null
+/**
+ @header@
+ */
+package org.pcmm.utils;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class PCMMUtils {
+
+ public static void WriteBinaryDump(String rootFileName, byte[] buffer) {
+ // Make this Unique
+ String fileName = "/tmp/" + rootFileName + "-" + java.util.UUID.randomUUID() + ".bin";
+ try {
+
+ System.out.println("Open fileName " + fileName);
+ FileOutputStream outputStream = new FileOutputStream(fileName);
+
+ // write() writes as many bytes from the buffer
+ // as the length of the buffer. You can also
+ // use
+ // write(buffer, offset, length)
+ // if you want to write a specific number of
+ // bytes, or only part of the buffer.
+ outputStream.write(buffer);
+
+ // Always close files.
+ outputStream.close();
+
+ System.out.println("Wrote " + buffer.length + " bytes");
+ } catch (IOException ex) {
+ System.out.println("Error writing file '" + fileName + "'");
+ // Or we could just do this:
+ // ex.printStackTrace();
+ }
+ }
+
+ public static byte[] ReadBinaryDump(String fileName) {
+ // The name of the file to open.
+ // String fileName = "COPSReportMessage.txt";
+ try {
+ FileInputStream inputStream = new FileInputStream(fileName);
+ // Use this for reading the data.
+ byte[] buffer = new byte[inputStream.available()];
+ // read fills buffer with data and returns
+ // the number of bytes read (which of course
+ // may be less than the buffer size, but
+ // it will never be more).
+ int total = inputStream.read(buffer);
+
+ // Always close files.
+ inputStream.close();
+
+ System.out.println("Read " + total + " bytes");
+ return buffer;
+ } catch (FileNotFoundException ex) {
+ System.out.println("Unable to open file '" + fileName + "'");
+ } catch (IOException ex) {
+ System.out.println("Error reading file '" + fileName + "'");
+ // Or we could just do this:
+ // ex.printStackTrace();
+ }
+ return null;
+ }
+}
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+package org.umu.cops.common;\r
+\r
+import java.io.PrintStream;\r
+\r
+/**\r
+ * Class to print debug and error messages.\r
+ *\r
+ * @version COPSDebug.java, v 3.00 2004\r
+ *\r
+ */\r
+public class COPSDebug {\r
+\r
+ static public final String ERROR_NOEXPECTEDMSG = "Message not expected";\r
+ static public final String ERROR_EXCEPTION = "Exception not expected";\r
+ static public final String ERROR_SOCKET = "Error socket";\r
+ static public final String ERROR_NOSUPPORTED = "Object not supported";\r
+\r
+ static public PrintStream _err = System.err;\r
+\r
+ /** Prints an error message.\r
+ *\r
+ * @param cname Name of class that generated the error\r
+ * @param str Error message\r
+ *\r
+ */\r
+ public static void err (String cname, String str) {\r
+ if (_err != null)\r
+ _err.println(cname + ":" + str);\r
+ }\r
+\r
+ /** Prints an error message.\r
+ *\r
+ * @param cname Name of class that generated the error\r
+ * @param str Error message\r
+ * @param e Exception\r
+ *\r
+ */\r
+ public static void err (String cname, String str, Exception e) {\r
+ if (_err != null) {\r
+ _err.println(cname + ":" + str);\r
+ _err.println(" -Reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /** Prints an error message.\r
+ *\r
+ * @param cname Name of class that generated the error\r
+ * @param str Error message\r
+ * @param extra Information\r
+ * @param e Exception\r
+ *\r
+ */\r
+ public static void err (String cname, String str, String extra, Exception e) {\r
+ if (_err != null) {\r
+ _err.println(cname + ":" + str);\r
+ _err.println(" -Info: " + extra);\r
+ _err.println(" -Reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /** Prints an error message.\r
+ *\r
+ * @param cname Name of class that generated the error\r
+ * @param str Error message\r
+ * @param extra Information\r
+ *\r
+ */\r
+ public static void err (String cname, String str, String extra) {\r
+ if (_err != null) {\r
+ _err.println(cname + ":" + str);\r
+ _err.println(" -Info: " + extra);\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+package org.umu.cops.common;\r
+\r
+/**\r
+ * Class containing keywords supported by the client types.\r
+ *\r
+ * @version COPS_def.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPS_def {\r
+\r
+ /** COPS Client Type for RSVP\r
+ */\r
+ public final static short C_RSVP = 1;\r
+\r
+ /** COPS Client Type for SIP\r
+ */\r
+ public final static short C_SIP = 100;\r
+\r
+ /** COPS Client Type for IPSec\r
+ */\r
+ public final static short C_IPSEC = (short) 0x8001;\r
+\r
+ /** Maximum COPS Client Type\r
+ */\r
+ public final static short C_MAX = (short) 0xFFFF;\r
+\r
+ /** Get a representative string for an COPS Client Type.\r
+ *\r
+ * @param cType COPS Client Type\r
+ * @return A representative <tt>String</tt>\r
+ *\r
+ */\r
+ public String strClientType(short cType) {\r
+ switch (cType) {\r
+ case C_RSVP:\r
+ return ("C_RSVP");\r
+ case C_SIP:\r
+ return ("C_SIP");\r
+ case C_IPSEC:\r
+ return ("C_IPSEC");\r
+ default:\r
+ return "Unknown";\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.ospdp;\r
+\r
+/**\r
+ * COPS PEP Exception\r
+ *\r
+ * @version COPSPepException.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPdpException extends Exception {\r
+\r
+ private int rc;\r
+ final static int GENERAL_ERROR = 0x00000001;\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message.\r
+ * @param msg Exception message\r
+ */\r
+ public COPSPdpException(String msg) {\r
+ super(msg);\r
+ rc=0;\r
+ }\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message and return code.\r
+ * @param msg Exception message\r
+ * @param retCode Return code\r
+ */\r
+ public COPSPdpException(String msg, int retCode) {\r
+ super(msg);\r
+ rc = retCode;\r
+ }\r
+\r
+ /**\r
+ * Gets the return code of the exception\r
+ * @return Exception's return code\r
+ */\r
+ public int returnCode() {\r
+ return rc;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospdp;\r
+\r
+import java.io.IOException;\r
+import java.net.ServerSocket;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSAcctTimer;\r
+import org.umu.cops.stack.COPSClientAcceptMsg;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSClientOpenMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKATimer;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * Core PDP agent for outsourcing.\r
+ */\r
+public class COPSPdpOSAgent extends Thread {\r
+ /** Well-known port for COPS */\r
+ public static final int WELL_KNOWN_PDP_PORT = 3288;\r
+ /** Default keep-alive timer value (secs) */\r
+ public static final short KA_TIMER_VALUE = 30;\r
+ /** Default accounting timer value (secs) */\r
+ public static final short ACCT_TIMER_VALUE = 0;\r
+\r
+ /**\r
+ PDP host IP\r
+ */\r
+ private ServerSocket _serverSocket;\r
+\r
+ /**\r
+ PDP host port\r
+ */\r
+ private int _serverPort;\r
+\r
+ /**\r
+ Client-type of connecting PEP\r
+ */\r
+ private short _clientType;\r
+\r
+ /**\r
+ Accounting timer (secs)\r
+ */\r
+ private short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer (secs)\r
+ */\r
+ private short _kaTimer;\r
+\r
+ /**\r
+ Maps a PEP-ID to a connection\r
+ */\r
+ private Hashtable _connectionMap;\r
+ // map < String(PEPID), COPSPdpOSConnection > ConnectionMap;\r
+\r
+ /**\r
+ * Policy data processing object\r
+ */\r
+ private COPSPdpOSDataProcess _process;\r
+\r
+ /**\r
+ * Creates a PDP Agent\r
+ *\r
+ * @param clientType COPS Client-type\r
+ * @param process Object to perform policy data processing\r
+ */\r
+ public COPSPdpOSAgent(short clientType, COPSPdpOSDataProcess process) {\r
+ _serverPort = WELL_KNOWN_PDP_PORT;\r
+ _kaTimer = KA_TIMER_VALUE;\r
+ _acctTimer = ACCT_TIMER_VALUE;\r
+\r
+ _clientType = clientType;\r
+ _connectionMap = new Hashtable(40);\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Creates a PDP Agent\r
+ *\r
+ * @param port Port to listen to\r
+ * @param clientType COPS Client-type\r
+ * @param process Object to perform policy data processing\r
+ */\r
+ public COPSPdpOSAgent(int port, short clientType, COPSPdpOSDataProcess process) {\r
+ _serverPort = port;\r
+\r
+ _kaTimer = KA_TIMER_VALUE;\r
+ _acctTimer = ACCT_TIMER_VALUE;\r
+\r
+ _clientType = clientType;\r
+ _connectionMap = new Hashtable(40);\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Sets the keep-alive timer value\r
+ * @param kaTimer Keep alive timer value (secs)\r
+ */\r
+ public void setKaTimer (short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets the accounting timer value\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAcctTimer (short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the value of the keep-alive timer\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer () {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the accounting timer value\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer () {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the PEPs connected to this PDP\r
+ * @return An <tt>Enumeration</tt> of all connected PEPs\r
+ */\r
+ public Enumeration getConnectedPEPIds() {\r
+ return _connectionMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets the connection map\r
+ * @return A <tt>Hashtable</tt> holding the connection map\r
+ */\r
+ public Hashtable getConnectionMap() {\r
+ return _connectionMap;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return The client-type\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Disconnects a PEP\r
+ * @param pepID PEP-ID of the PEP to be disconnected\r
+ * @param error COPS Error to be reported as a reason\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ public void disconnect (String pepID, COPSError error) throws COPSException, IOException {\r
+ COPSPdpOSConnection pdpConn = (COPSPdpOSConnection) _connectionMap.get(pepID);\r
+\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ if (error != null)\r
+ closeMsg.add(error);\r
+\r
+ closeMsg.writeData(pdpConn.getSocket());\r
+ pdpConn.close();\r
+ pdpConn = null;\r
+ }\r
+\r
+ /**\r
+ * Requests a COPS sync for a PEP\r
+ * @param pepID PEP-ID of the PEP to be synced\r
+ * @throws COPSException\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sync(String pepID) throws COPSException, COPSPdpException {\r
+ COPSPdpOSConnection pdpConn = (COPSPdpOSConnection) _connectionMap.get(pepID);\r
+ pdpConn.syncAllRequestState();\r
+ }\r
+\r
+ /**\r
+ * Removes a PEP from the connection map\r
+ * @param pepID PEP-ID of the PEP to be removed\r
+ */\r
+ public void delete (String pepID) {\r
+ _connectionMap.remove(pepID);\r
+ }\r
+\r
+ /**\r
+ * Runs the PDP process\r
+ */\r
+ public void run() {\r
+ try {\r
+ _serverSocket = new ServerSocket (_serverPort);\r
+\r
+ //Loop through for Incoming messages\r
+\r
+ // server infinite loop\r
+ while (true) {\r
+ // Wait for an incoming connection from a PEP\r
+ Socket socket = _serverSocket.accept();\r
+\r
+ // COPSDebug.out(getClass().getName(),"New connection accepted " +\r
+ // socket.getInetAddress() +\r
+ // ":" + socket.getPort());\r
+\r
+ // We're waiting for an OPN message\r
+ try {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(socket);\r
+ if (msg.getHeader().isAClientOpen()) {\r
+ handleClientOpenMsg(socket, msg);\r
+ } else {\r
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ try {\r
+ socket.close();\r
+ } catch (Exception ex) {};\r
+ }\r
+ } catch (Exception e) { // COPSException, IOException\r
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,\r
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);\r
+ try {\r
+ socket.close();\r
+ } catch (Exception ex) {};\r
+ }\r
+ }\r
+ } catch (IOException e) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handles a COPS client-open message\r
+ * @param conn Socket to the PEP\r
+ * @param msg <tt>COPSMsg</tt> holding the client-open message\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException {\r
+ COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;\r
+ COPSPepId pepId = cMsg.getPepId();\r
+\r
+ // Validate Client Type\r
+ if (msg.getHeader().getClientType() != _clientType) {\r
+ // Unsupported client type\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Unsupported client type");\r
+ }\r
+\r
+ // PEPId is mandatory\r
+ if (pepId == null) {\r
+ // Mandatory COPS object missing\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Mandatory COPS object missing (PEPId)");\r
+ }\r
+\r
+ // Support\r
+ if ( (cMsg.getClientSI() != null) ||\r
+ (cMsg.getPdpAddress() != null) ||\r
+ (cMsg.getIntegrity() != null)) {\r
+\r
+ // Unsupported objects\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");\r
+ }\r
+\r
+ // Connection accepted\r
+ COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());\r
+ COPSKATimer katimer = new COPSKATimer(_kaTimer);\r
+ COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);\r
+ COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();\r
+ acceptMsg.add(ahdr);\r
+ acceptMsg.add(katimer) ;\r
+ if (_acctTimer != 0) acceptMsg.add(acctTimer);\r
+ acceptMsg.writeData(conn);\r
+\r
+ COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process);\r
+ pdpConn.setKaTimer(_kaTimer);\r
+ if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);\r
+ new Thread(pdpConn).start();\r
+ _connectionMap.put(pepId.getData().str(),pdpConn);\r
+ }\r
+}\r
--- /dev/null
+package org.umu.cops.ospdp;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKAMsg;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * Class for managing an outsourcing connection at the PDP side.\r
+ */\r
+public class COPSPdpOSConnection implements Runnable {\r
+ /**\r
+ Socket connected to PEP\r
+ */\r
+ private Socket _sock;\r
+\r
+ /**\r
+ PEP identifier\r
+ */\r
+ private COPSPepId _pepId;\r
+\r
+ /**\r
+ Time of the latest keep-alive sent\r
+ */\r
+ private Date _lastKa;\r
+\r
+ /**\r
+ Opcode of the latest message sent\r
+ */\r
+ private byte _lastmessage;\r
+\r
+ /**\r
+ * Time of the latest keep-alive received\r
+ */\r
+ protected Date _lastRecKa;\r
+\r
+ /**\r
+ Maps a Client Handle to a Handler\r
+ */\r
+ protected Hashtable _managerMap;\r
+ // map < String(COPSHandle), COPSPdpHandler> HandlerMap;\r
+\r
+ /**\r
+ * PDP policy data processor class\r
+ */\r
+ protected COPSPdpOSDataProcess _process;\r
+\r
+ /**\r
+ Accounting timer value (secs)\r
+ */\r
+ protected short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer value (secs)\r
+ */\r
+ protected short _kaTimer;\r
+\r
+ /**\r
+ COPS error returned by PEP\r
+ */\r
+ protected COPSError _error;\r
+\r
+ /**\r
+ * Creates a new PDP connection\r
+ *\r
+ * @param pepId PEP-ID of the connected PEP\r
+ * @param sock Socket connected to PEP\r
+ * @param process Object for processing policy data\r
+ */\r
+ public COPSPdpOSConnection(COPSPepId pepId, Socket sock, COPSPdpOSDataProcess process) {\r
+ _sock = sock;\r
+ _pepId = pepId;\r
+\r
+ _lastKa = new Date();\r
+ _lastmessage = COPSHeader.COPS_OP_OPN;\r
+ _managerMap = new Hashtable(20);\r
+\r
+ _kaTimer = 0;\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Gets the time of that latest keep-alive sent\r
+ * @return Time of that latest keep-alive sent\r
+ */\r
+ public Date getLastKAlive() {\r
+ return _lastKa;\r
+ }\r
+\r
+ /**\r
+ * Sets the keep-alive timer value\r
+ * @param kaTimer Keep-alive timer value (secs)\r
+ */\r
+ public void setKaTimer(short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the keep-alive timer value\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer() {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets the accounting timer value\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAccTimer(short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the accounting timer value\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer() {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the latest COPS message\r
+ * @return Code of the latest message sent\r
+ */\r
+ public byte getLastMessage() {\r
+ return _lastmessage;\r
+ }\r
+\r
+ /**\r
+ * Gets active handles\r
+ * @return An <tt>Enumeration</tt> holding all active handles\r
+ */\r
+ public Enumeration getHandles() {\r
+ return _managerMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets the handle map\r
+ * @return A <tt>Hashtable</tt> holding the handle map\r
+ */\r
+ public Hashtable getReqStateMans() {\r
+ return _managerMap;\r
+ }\r
+\r
+ /**\r
+ * Gets the PEP-ID\r
+ * @return The ID of the PEP, as a <tt>String</tt>\r
+ */\r
+ public String getPepId() {\r
+ return _pepId.getData().str();\r
+ }\r
+\r
+ /**\r
+ * Checks whether the socket to the PEP is closed or not\r
+ * @return <tt>true</tt> if closed, <tt>false</tt> otherwise\r
+ */\r
+ public boolean isClosed() {\r
+ return _sock.isClosed();\r
+ }\r
+\r
+ /**\r
+ * Closes the socket to the PEP\r
+ * @throws IOException\r
+ */\r
+ protected void close()\r
+ throws IOException {\r
+ _sock.close();\r
+ }\r
+\r
+ /**\r
+ * Gets the socket to the PEP\r
+ * @return Socket connected to the PEP\r
+ */\r
+ public Socket getSocket() {\r
+ return _sock;\r
+ }\r
+\r
+ /**\r
+ * Main loop\r
+ */\r
+ public void run () {\r
+ Date _lastSendKa = new Date();\r
+ _lastRecKa = new Date();\r
+ try {\r
+ while (!_sock.isClosed()) {\r
+ if (_sock.getInputStream().available() != 0) {\r
+ _lastmessage = processMessage(_sock);\r
+ _lastRecKa = new Date();\r
+ }\r
+\r
+ // Keep Alive\r
+ if (_kaTimer > 0) {\r
+ // Timeout at PDP\r
+ int _startTime = (int) (_lastRecKa.getTime());\r
+ int cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > _kaTimer*1000) {\r
+ _sock.close();\r
+ // Notify all Request State Managers\r
+ notifyNoKAAllReqStateMan();\r
+ }\r
+\r
+ // Send to PEP\r
+ _startTime = (int) (_lastSendKa.getTime());\r
+ cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > ((_kaTimer*3/4)*1000)) {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
+ COPSKAMsg msg = new COPSKAMsg();\r
+\r
+ msg.add(hdr);\r
+\r
+ COPSTransceiver.sendMsg(msg, _sock);\r
+ _lastSendKa = new Date();\r
+ }\r
+ }\r
+\r
+ try {\r
+ Thread.sleep(500);\r
+ } catch (Exception e) {};\r
+\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ }\r
+\r
+ // connection closed by server\r
+ // COPSDebug.out(getClass().getName(),"Connection closed by client");\r
+ try {\r
+ _sock.close();\r
+ } catch (IOException e) {};\r
+\r
+ // Notify all Request State Managers\r
+ try {\r
+ notifyCloseAllReqStateMan();\r
+ } catch (COPSPdpException e) {};\r
+ }\r
+\r
+ /**\r
+ * Gets a COPS message from the socket and processes it\r
+ * @param conn Socket connected to the PEP\r
+ * @return Type of COPS message\r
+ */\r
+ private byte processMessage(Socket conn)\r
+ throws COPSPdpException, COPSException, IOException {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
+\r
+ if (msg.getHeader().isAClientClose()) {\r
+ handleClientCloseMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_CC;\r
+ } else if (msg.getHeader().isAKeepAlive()) {\r
+ handleKeepAliveMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_KA;\r
+ } else if (msg.getHeader().isARequest()) {\r
+ handleRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_REQ;\r
+ } else if (msg.getHeader().isAReport()) {\r
+ handleReportMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_RPT;\r
+ } else if (msg.getHeader().isADeleteReq()) {\r
+ handleDeleteRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_DRQ;\r
+ } else if (msg.getHeader().isASyncComplete()) {\r
+ handleSyncComplete(conn, msg);\r
+ return COPSHeader.COPS_OP_SSC;\r
+ } else {\r
+ throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handle Client Close Message, close the passed connection\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ */\r
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
+ _error = cMsg.getError();\r
+\r
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
+\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ conn.close();\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Gets the occurred COPS Error\r
+ * @return <tt>COPSError</tt> object\r
+ */\r
+ protected COPSError getError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Handle Keep Alive Message\r
+ *\r
+ * <Keep-Alive> ::= <Common Header>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
+ COPSKAMsg cMsg = (COPSKAMsg) msg;\r
+\r
+ COPSKAMsg kaMsg = (COPSKAMsg) msg;\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ kaMsg.writeData(conn);\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Handle Delete Request Message\r
+ *\r
+ * <Delete Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Reason>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;\r
+ // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ // Delete clientHandler\r
+ if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {\r
+ // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +\r
+ // cMsg.getClientHandle().getId().getData());\r
+ }\r
+\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processDeleteRequestState(cMsg);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Handle Request Message\r
+ *\r
+ * <Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {\r
+ COPSReqMsg reqMsg = (COPSReqMsg) msg;\r
+ COPSContext cntxt = reqMsg.getContext();\r
+ COPSHeader header = reqMsg.getHeader();\r
+ //short reqType = cntxt.getRequestType();\r
+ short cType = header.getClientType();\r
+\r
+ // Support\r
+ if (reqMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpOSReqStateMan man;\r
+ man = (COPSPdpOSReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ man = new COPSPdpOSReqStateMan(cType, reqMsg.getClientHandle().getId().str());\r
+ _managerMap.put(reqMsg.getClientHandle().getId().str(),man);\r
+ man.setDataProcess(_process);\r
+ man.initRequestState(_sock);\r
+\r
+ // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +\r
+ // header.getClientType() + " msgType=" +\r
+ // cntxt.getMessageType() + ", connId=" + conn.toString());\r
+ }\r
+\r
+ man.processRequest(reqMsg);\r
+ }\r
+\r
+ /**\r
+ * Handle Report Message\r
+ *\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleReportMsg(Socket conn, COPSMsg msg) throws COPSPdpException {\r
+ COPSReportMsg repMsg = (COPSReportMsg) msg;\r
+ // COPSHandle handle = repMsg.getClientHandle();\r
+ // COPSHeader header = repMsg.getHeader();\r
+\r
+ // Support\r
+ if (repMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processReport(repMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method handleSyncComplete\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleSyncComplete(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
+ // COPSHandle handle = cMsg.getClientHandle();\r
+ // COPSHeader header = cMsg.getHeader();\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processSyncComplete(cMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Requests a COPS sync from the PEP\r
+ * @throws COPSException\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncAllRequestState()\r
+ throws COPSException, COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.syncRequestState();\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyCloseAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processClosedConnection(_error);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyNoKAAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processNoKAConnection();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospdp;\r
+\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSError;\r
+\r
+/**\r
+ * Abstract class for implementing policy data processing classes for outsourcing PDPs.\r
+ */\r
+abstract public class COPSPdpOSDataProcess {\r
+ /**\r
+ * Gets the policies to be uninstalled\r
+ * @param man The associated request state manager\r
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
+ */\r
+ abstract public Vector getRemovePolicy(COPSPdpOSReqStateMan man);\r
+ /**\r
+ * Gets the policies to be installed\r
+ * @param man The associated request state manager\r
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
+ */\r
+ abstract public Vector getInstallPolicy(COPSPdpOSReqStateMan man);\r
+ /**\r
+ * Makes a decision from the supplied request data\r
+ * @param man The associated request state manager\r
+ * @param reqSIs Client specific data suppplied in the COPS request\r
+ */\r
+ abstract public void setClientData(COPSPdpOSReqStateMan man, Vector reqSIs);\r
+ /**\r
+ * Builds a failure report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void failReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
+ /**\r
+ * Builds a success report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void successReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
+ /**\r
+ * Builds an accounting report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void acctReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
+ /**\r
+ * Notifies that no accounting report has been received\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyNoAcctReport (COPSPdpOSReqStateMan man);\r
+\r
+ /**\r
+ * Notifies a keep-alive timeout\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyNoKAliveReceived (COPSPdpOSReqStateMan man);\r
+\r
+ /**\r
+ * Notifies that the connection has been closed\r
+ * @param man The associated request state manager\r
+ * @param error Reason\r
+ */\r
+ public abstract void notifyClosedConnection (COPSPdpOSReqStateMan man, COPSError error);\r
+\r
+ /**\r
+ * Notifies that a request state has been deleted\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyDeleteRequestState (COPSPdpOSReqStateMan man);\r
+\r
+ /**\r
+ * Notifies that a request state has been closed\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void closeRequestState(COPSPdpOSReqStateMan man);\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospdp;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSDecision;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPS message transceiver class for outsourcing connections at the PDP side.\r
+ */\r
+public class COPSPdpOSMsgSender {\r
+ /**\r
+ * Socket connected to PEP\r
+ */\r
+ protected Socket _sock;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Creates a COPSPepMsgSender\r
+ *\r
+ * @param clientType COPS client-type\r
+ * @param clientHandle Client handle\r
+ * @param sock Socket to the PEP\r
+ */\r
+ public COPSPdpOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
+ // COPS Handle\r
+ _handle = clientHandle;\r
+ _clientType = clientType;\r
+\r
+ _sock = sock;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Sends a decision message which was requested by the PEP\r
+ * @param removeDecs Decisions to be removed\r
+ * @param installDecs Decisions to be installed\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendSolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {\r
+ sendDecision(removeDecs, installDecs, true);\r
+ }\r
+\r
+ /**\r
+ * Sends a decision message which was not requested by the PEP\r
+ * @param removeDecs Decisions to be removed\r
+ * @param installDecs Decisions to be installed\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendUnsolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {\r
+ sendDecision(removeDecs, installDecs, false);\r
+ }\r
+\r
+ /**\r
+ * Sends a decision message to the PEP\r
+ * @param removeDecs Decisions to be removed\r
+ * @param installDecs Decisions to be installed\r
+ * @param solicited <tt>true</tt> if the PEP requested this decision, <tt>false</tt> otherwise\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendDecision(Vector removeDecs, Vector installDecs, boolean solicited) throws COPSPdpException {\r
+ // Common Header holding the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ if (solicited)\r
+ hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED);\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle handle = new COPSHandle();\r
+ handle.setId(getClientHandle().getId());\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(handle);\r
+\r
+ // Decisions (no flags supplied)\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+\r
+ // Remove Decisions\r
+ // <Decision: Flags>\r
+ if (removeDecs.size() > 0) {\r
+ COPSDecision rdec1 = new COPSDecision();\r
+ rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
+\r
+ decisionMsg.addDecision(rdec1, cntxt);\r
+\r
+ Enumeration removeDecsEnum = removeDecs.elements();\r
+ while (removeDecsEnum.hasMoreElements())\r
+ decisionMsg.addDecision((COPSDecision) removeDecsEnum.nextElement(), cntxt);\r
+ }\r
+\r
+ // Install Decisions\r
+ // <Decision: Flags>\r
+ if (installDecs.size() > 0) {\r
+ COPSDecision idec1 = new COPSDecision();\r
+ idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
+\r
+ decisionMsg.addDecision(idec1, cntxt);\r
+\r
+ Enumeration installDecsEnum = installDecs.elements();\r
+ while (installDecsEnum.hasMoreElements())\r
+ decisionMsg.addDecision((COPSDecision) installDecsEnum.nextElement(), cntxt);\r
+ /**\r
+ COPSIntegrity intr = new COPSIntegrity();\r
+ intr.setKeyId(19);\r
+ intr.setSeqNum(9);\r
+ intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
+ decisionMsg.add(intr);\r
+ /**/\r
+ }\r
+ } catch (COPSException e) {\r
+ e.printStackTrace();\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ //** Send decision\r
+ //**\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**FIXME: unused?\r
+ * Sends a message asking that the request state be deleted\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendDeleteRequestState() throws COPSPdpException {\r
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>)\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * <Decision: Flags> ::= Remove Request-State\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request (default UNSOLICITED)\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ // Decisions\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+ // <Decision: Flags>\r
+ COPSDecision dec = new COPSDecision();\r
+ dec.setCmdCode(COPSDecision.DEC_REMOVE);\r
+ dec.setFlags(COPSDecision.F_REQSTATE);\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(clienthandle);\r
+ decisionMsg.addDecision(dec, cntxt);\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method sendOpenNewRequestState\r
+ *\r
+ * @throws COPSPdpException\r
+ *\r
+ */\r
+ //FIXME: Unused?\r
+ public void sendOpenNewRequestState() throws COPSPdpException {\r
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>)\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * <Decision: Flags> ::= Install Request-State\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request (default UNSOLICITED)\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ // Decisions\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+ // <Decision: Flags>\r
+ COPSDecision dec = new COPSDecision();\r
+ dec.setCmdCode(COPSDecision.DEC_INSTALL);\r
+ dec.setFlags(COPSDecision.F_REQSTATE);\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(clienthandle);\r
+ decisionMsg.addDecision(dec, cntxt);\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a message asking for a COPS sync operation\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendSyncRequestState()\r
+ throws COPSPdpException {\r
+ /* <Synchronize State Request> ::= <Common Header>\r
+ * [<Client Handle>]\r
+ * [<Integrity>]\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(clienthandle);\r
+ } catch (Exception e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospdp;\r
+\r
+import java.net.Socket;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReportType;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * State manager class for outsourcing requests, at the PDP side.\r
+ */\r
+public class COPSPdpOSReqStateMan {\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request received\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions sent\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report received\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request state finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New request state solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete request state solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC request sent\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * SYNC completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * Keep-alive timeout\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * Accounting timeout\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Object for performing policy data processing\r
+ */\r
+ protected COPSPdpOSDataProcess _process;\r
+\r
+ /**\r
+ * Current state of the request being managed\r
+ */\r
+ protected short _status;\r
+\r
+ /** COPS message transceiver used to send COPS messages */\r
+ protected COPSPdpOSMsgSender _sender;\r
+\r
+ /**\r
+ * Creates a request state manager\r
+ * @param clientType Client-type\r
+ * @param clientHandle Client handle\r
+ */\r
+ public COPSPdpOSReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+\r
+ _status = ST_CREATE;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the status of the request\r
+ * @return Request state value\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Gets the policy data processing object\r
+ * @return Policy data processing object\r
+ */\r
+ public COPSPdpOSDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Sets the policy data processing object\r
+ * @param process Policy data processing object\r
+ */\r
+ public void setDataProcess(COPSPdpOSDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Called when COPS sync is completed\r
+ * @param repMsg COPS sync message\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
+ throws COPSPdpException {\r
+\r
+ _status = ST_SYNCALL;\r
+\r
+ // maybe we should notifySyncComplete ...\r
+ }\r
+\r
+ /**\r
+ * Initializes a new request state over a socket\r
+ * @param sock Socket to the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void initRequestState(Socket sock)\r
+ throws COPSPdpException {\r
+ // Inits an object for sending COPS messages to the PDP\r
+ _sender = new COPSPdpOSMsgSender(_clientType, _handle, sock);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+ /**\r
+ * Processes a COPS request\r
+ * @param msg COPS request received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processRequest(COPSReqMsg msg) throws COPSPdpException {\r
+ Vector clientSIs = msg.getClientSI();\r
+\r
+ //** Here we must retrieve a decision depending on the\r
+ //** supplied ClientSIs\r
+ /*Vector removeDecs = new Vector();\r
+ Vector installDecs = new Vector();*/\r
+ _process.setClientData(this, clientSIs);\r
+\r
+ Vector removeDecs = _process.getRemovePolicy(this);\r
+ Vector installDecs = _process.getInstallPolicy(this);\r
+\r
+ //** We create a SOLICITED decision\r
+ //**\r
+ _sender.sendSolicitedDecision(removeDecs, installDecs);\r
+ _status = ST_DECS;\r
+ }\r
+\r
+ /**\r
+ * Processes a report\r
+ * @param msg Report message from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processReport(COPSReportMsg msg) throws COPSPdpException {\r
+ //** Analyze the report\r
+ //**\r
+\r
+ /*\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
+ * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
+ *\r
+ * Important, <Named ClientSI> is not parsed\r
+ */\r
+\r
+ // COPSHeader hdrmsg = msg.getHeader();\r
+ // COPSHandle handlemsg = msg.getClientHandle();\r
+\r
+ // Report Type\r
+ COPSReportType rtypemsg = msg.getReport();\r
+\r
+ // Named ClientSI\r
+ Vector clientSIs = msg.getClientSI();\r
+\r
+ //** We should act here in accordance with\r
+ //** the received report\r
+ if (rtypemsg.isSuccess()) {\r
+ _status = ST_REPORT;\r
+ _process.successReport(this, clientSIs);\r
+ } else if (rtypemsg.isFailure()) {\r
+ _status = ST_REPORT;\r
+ _process.failReport(this, clientSIs);\r
+ } else if (rtypemsg.isAccounting()) {\r
+ _status = ST_ACCT;\r
+ _process.acctReport(this, clientSIs);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Called when connection is closed\r
+ * @param error Reason\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processClosedConnection(COPSError error)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ /**\r
+ * Called when no keep-alive is received\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processNoKAConnection()\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ /**\r
+ * Deletes the request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void finalizeRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendDeleteRequestState();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Asks for a COPS sync\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendSyncRequestState();\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ /**\r
+ * Opens a new request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void openNewRequestState()//FIXME: unused?\r
+ throws COPSPdpException {\r
+ _sender.sendOpenNewRequestState();\r
+ _status = ST_NEW;\r
+ }\r
+\r
+ /**\r
+ * Processes a COPS delete message\r
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.ospep;\r
+\r
+/**\r
+ * COPS PEP Exception\r
+ *\r
+ * @version COPSPepException.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPepException extends Exception {\r
+\r
+ private int rc;\r
+ final static int GENERAL_ERROR = 0x00000001;\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message.\r
+ * @param msg Exception message\r
+ */\r
+\r
+ public COPSPepException(String msg) {\r
+ super(msg);\r
+ rc=0;\r
+ }\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message and return code.\r
+ * @param msg Exception message\r
+ * @param retCode Return code\r
+ */\r
+ public COPSPepException(String msg, int retCode) {\r
+ super(msg);\r
+ rc = retCode;\r
+ }\r
+\r
+ /**\r
+ * Returns the return code of the exception\r
+ *\r
+ * @return Exception's return code\r
+ *\r
+ */\r
+ public int returnCode() {\r
+ return rc;\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+import java.io.IOException;\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSAcctTimer;\r
+import org.umu.cops.stack.COPSClientAcceptMsg;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSClientOpenMsg;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKATimer;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * This is a outsourcing COPS PEP. Responsible for making\r
+ * connection to the PDP and maintaining it\r
+ */\r
+public class COPSPepOSAgent {\r
+ /**\r
+ PEP's identifier\r
+ */\r
+ private String _pepID;\r
+\r
+ /**\r
+ PEP's client-type\r
+ */\r
+ private short _clientType;\r
+\r
+ /**\r
+ PDP host name\r
+ */\r
+ private String _psHost;\r
+\r
+ /**\r
+ PDP port\r
+ */\r
+ private int _psPort;\r
+\r
+ /**\r
+ PEP-PDP connection manager\r
+ */\r
+ private COPSPepOSConnection _conn;\r
+\r
+ /**\r
+ COPS error returned by the PDP\r
+ */\r
+ private COPSError _error;\r
+\r
+ /**\r
+ * Policy data processor class\r
+ */\r
+ private COPSPepOSDataProcess _process;\r
+\r
+ /**\r
+ * Creates a PEP agent\r
+ * @param pepID PEP-ID\r
+ * @param clientType Client-type\r
+ */\r
+ public COPSPepOSAgent(String pepID, short clientType) {\r
+ _pepID = pepID;\r
+ _clientType = clientType;\r
+ }\r
+\r
+ /**\r
+ * Creates a PEP agent with a PEP-ID equal to "noname"\r
+ * @param clientType Client-type\r
+ */\r
+ public COPSPepOSAgent(short clientType) {\r
+ // PEPId\r
+ try {\r
+ _pepID = InetAddress.getLocalHost().getHostName();\r
+ } catch (Exception e) {\r
+ _pepID = "noname";\r
+ }\r
+\r
+ _clientType = clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the identifier of the PEP\r
+ * @return PEP-ID\r
+ */\r
+ public String getPepID() {\r
+ return _pepID;\r
+ }\r
+\r
+ /**\r
+ * Sets the policy data processor\r
+ * @param aDataProcess Data processor class\r
+ */\r
+ public void setDataProcess(COPSPepOSDataProcess aDataProcess) {\r
+ this._process = aDataProcess;\r
+ }\r
+\r
+ /**\r
+ * Gets the COPS client-type\r
+ * @return PEP's client-type\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets PDP host name\r
+ * @return PDP host name\r
+ */\r
+ public String getPDPName() {\r
+ return _psHost;\r
+ }\r
+\r
+ /**\r
+ * Gets the port of the PDP\r
+ * @return PDP port\r
+ */\r
+ public int getPDPPort() {\r
+ return _psPort;\r
+ }\r
+\r
+ /**\r
+ * Connects to a PDP\r
+ * @param psHost PDP host name\r
+ * @param psPort PDP port\r
+ * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise\r
+ * @throws java.net.UnknownHostException\r
+ * @throws java.io.IOException\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ */\r
+ public boolean connect(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException {\r
+ // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");\r
+ _psHost = psHost;\r
+ _psPort = psPort;\r
+\r
+ // Check whether it already exists\r
+ if (_conn == null)\r
+ _conn = processConnection(psHost,psPort);\r
+ else {\r
+ // Check whether it's closed\r
+ if (_conn.isClosed())\r
+ _conn = processConnection(psHost,psPort);\r
+ else {\r
+ disconnect(null);\r
+ _conn = processConnection(psHost,psPort);\r
+ }\r
+ }\r
+\r
+ return (_conn != null);\r
+ }\r
+\r
+ /**\r
+ * Gets the connection manager\r
+ * @return PEP-PDP connection manager object\r
+ */\r
+ public COPSPepOSConnection getConnection() {\r
+ return (_conn);\r
+ }\r
+\r
+ /**\r
+ * Gets the COPS error returned by the PDP\r
+ * @return <tt>COPSError</tt> returned by PDP\r
+ */\r
+ public COPSError getConnectionError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Disconnects from the PDP\r
+ * @param error Reason\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ public void disconnect(COPSError error) throws COPSException, IOException {\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ if (error != null)\r
+ closeMsg.add(error);\r
+\r
+ closeMsg.writeData(_conn.getSocket());\r
+ _conn.close();\r
+ _conn = null;\r
+ }\r
+\r
+ /**\r
+ * Adds a request state to the connection manager.\r
+ * @param clientSIs The client data from the outsourcing event\r
+ * @return The newly created connection manager\r
+ * @throws COPSPepException\r
+ * @throws COPSException\r
+ */\r
+ public COPSPepOSReqStateMan addRequestState(COPSHandle handle, Vector clientSIs) throws COPSPepException, COPSException {\r
+ if (_conn != null)\r
+ return _conn.addRequestState(handle.getId().str(), _process, clientSIs);\r
+\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Queries the connection manager to delete a request state\r
+ * @param man Request state manager\r
+ * @throws COPSPepException\r
+ * @throws COPSException\r
+ */\r
+ public void deleteRequestState (COPSPepOSReqStateMan man) throws COPSPepException, COPSException {\r
+ if (_conn != null)\r
+ _conn.deleteRequestState(man);\r
+ }\r
+\r
+ /**\r
+ * Gets all the request state managers\r
+ * @return A <tt>Hashtable</tt> holding all active request state managers\r
+ */\r
+ public Hashtable getReqStateMans() {\r
+ if (_conn != null)\r
+ return _conn.getReqStateMans();\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Establish connection to PDP's IP address\r
+ *\r
+ * <Client-Open> ::= <Common Header>\r
+ * <PEPID>\r
+ * [<ClientSI>]\r
+ * [<LastPDPAddr>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]\r
+ *\r
+ * <Client-Accept> ::= <Common Header>\r
+ * <KA Timer>\r
+ * [<ACCT Timer>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not send [<Integrity>]\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<PDPRedirAddr>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not send [<PDPRedirAddr>], [<Integrity>]\r
+ *\r
+ * @throws UnknownHostException\r
+ * @throws IOException\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ private COPSPepOSConnection processConnection(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException {\r
+ // Build OPN\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);\r
+\r
+ COPSPepId pepId = new COPSPepId();\r
+ COPSData d = new COPSData(_pepID);\r
+ pepId.setData(d);\r
+\r
+ COPSClientOpenMsg msg = new COPSClientOpenMsg();\r
+ msg.add(hdr);\r
+ msg.add(pepId);\r
+\r
+ // Create socket and send OPN\r
+ InetAddress addr = InetAddress.getByName(psHost);\r
+ Socket socket = new Socket(addr,psPort);\r
+ msg.writeData(socket);\r
+\r
+ // Get response\r
+ COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);\r
+\r
+ if (recvmsg.getHeader().isAClientAccept()) {\r
+ COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ throw new COPSPepException("Unsupported object (Integrity)");\r
+ }\r
+\r
+ // Mandatory KATimer\r
+ COPSKATimer kt = cMsg.getKATimer();\r
+ if (kt == null)\r
+ throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");\r
+ short _kaTimeVal = kt.getTimerVal();\r
+\r
+ // ACTimer\r
+ COPSAcctTimer at = cMsg.getAcctTimer();\r
+ short _acctTimer = 0;\r
+ if (at != null)\r
+ _acctTimer = at.getTimerVal();\r
+\r
+ // Create connection manager\r
+ COPSPepOSConnection conn = new COPSPepOSConnection(_clientType, socket);\r
+ conn.setKaTimer(_kaTimeVal);\r
+ conn.setAcctTimer(_acctTimer);\r
+ new Thread(conn).start();\r
+\r
+ return conn;\r
+ } else if (recvmsg.getHeader().isAClientClose()) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;\r
+ _error = cMsg.getError();\r
+ socket.close();\r
+ return null;\r
+ } else { // other message types are unexpected\r
+ throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Creates a new request state when the outsourcing event is detected.\r
+ * @param handle The COPS handle for this request\r
+ * @param clientSIs The client specific data for this request\r
+ */\r
+ public void dispatchEvent(COPSHandle handle, Vector clientSIs) {\r
+ try {\r
+ addRequestState(handle, clientSIs);\r
+ } catch (Exception e) {\r
+ System.err.println("COPSPepOSAgent: " + e.toString());\r
+ }\r
+ }\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKAMsg;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * COPSPepConnection represents a PEP-PDP Connection Manager.\r
+ * Responsible for processing messages received from PDP.\r
+ */\r
+public class COPSPepOSConnection implements Runnable {\r
+ /** Socket connected to PDP */\r
+ protected Socket _sock;\r
+\r
+ /** Time to wait responses (milliseconds), default is 10 seconds */\r
+ protected int _responseTime;\r
+\r
+ /** COPS Client-type */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ Accounting timer value (secs)\r
+ */\r
+ protected short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer value (secs)\r
+ */\r
+ protected short _kaTimer;\r
+\r
+ /**\r
+ * Time of the latest keep-alive received\r
+ */\r
+ protected Date _lastRecKa;\r
+\r
+ /**\r
+ Opcode of the latest message sent\r
+ */\r
+ protected byte _lastmessage;\r
+\r
+ /**\r
+ Maps a COPS Client Handle to a Request State Manager\r
+ */\r
+ protected Hashtable _managerMap;\r
+ // map < String(COPSHandle), COPSPepOSReqStateMan>;\r
+\r
+ /**\r
+ COPS error returned by PDP\r
+ */\r
+ protected COPSError _error;\r
+\r
+ /**\r
+ * Creates a new PEP connection\r
+ * @param clientType PEP's client-type\r
+ * @param sock Socket connected to PDP\r
+ */\r
+ public COPSPepOSConnection(short clientType, Socket sock) {\r
+ _clientType = clientType;\r
+ _sock = sock;\r
+\r
+ // Timers\r
+ _acctTimer = 0;\r
+ _kaTimer = 0;\r
+ _responseTime = 10000;\r
+ _lastmessage = COPSHeader.COPS_OP_CAT;\r
+\r
+ _managerMap = new Hashtable(20);\r
+ }\r
+\r
+ /**\r
+ * Gets the response time\r
+ * @return Response time value (msecs)\r
+ */\r
+ public int getResponseTime() {\r
+ return _responseTime;\r
+ }\r
+\r
+ /**\r
+ * Gets the socket connected to the PDP\r
+ * @return Socket connected to PDP\r
+ */\r
+ public Socket getSocket() {\r
+ return _sock;\r
+ }\r
+\r
+ /**\r
+ * Gets keep-alive timer\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer () {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets accounting timer\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer () {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets active COPS handles\r
+ * @return An <tt>Enumeration</tt> holding all active handles\r
+ */\r
+ protected Enumeration getHandles() {\r
+ return _managerMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets all request state managers\r
+ * @return A <tt>Hashatable</tt> holding all request state managers\r
+ */\r
+ protected Hashtable getReqStateMans() {\r
+ return _managerMap;\r
+ }\r
+\r
+ /**\r
+ * Checks whether the socket to the PDP is closed or not\r
+ * @return <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise\r
+ */\r
+ public boolean isClosed() {\r
+ return _sock.isClosed();\r
+ }\r
+\r
+ /**\r
+ * Closes the socket\r
+ *\r
+ * @throws java.io.IOException\r
+ */\r
+ protected void close() throws IOException {\r
+ _sock.close();\r
+ }\r
+\r
+ /**\r
+ * Gets the opcode of the lastest message sent\r
+ * @return Message opcode\r
+ */\r
+ public byte getLastmessage() {\r
+ return _lastmessage;\r
+ }\r
+\r
+ /**\r
+ * Sets response time\r
+ * @param respTime Response time value (msecs)\r
+ */\r
+ public void setResponseTime(int respTime) {\r
+ _responseTime = respTime;\r
+ };\r
+\r
+ /**\r
+ * Sets keep-alive timer\r
+ * @param kaTimer Keep-alive timer value (secs)\r
+ */\r
+ public void setKaTimer(short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets accounting timer\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAcctTimer(short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Message-processing loop\r
+ */\r
+ public void run () {\r
+ Date _lastSendKa = new Date();\r
+ Date _lastSendAcc = new Date();\r
+ _lastRecKa = new Date();\r
+\r
+ try {\r
+ while (!_sock.isClosed()) {\r
+ if (_sock.getInputStream().available() != 0) {\r
+ _lastmessage = processMessage(_sock);\r
+ _lastRecKa = new Date();\r
+ }\r
+\r
+ // Keep Alive\r
+ if (_kaTimer > 0) {\r
+ // Timeout del PDP\r
+ int _startTime = (int) (_lastRecKa.getTime());\r
+ int cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > _kaTimer*1000) {\r
+ _sock.close();\r
+ // Notify all Request State Managers\r
+ notifyNoKAAllReqStateMan();\r
+ }\r
+\r
+ // Send to PEP\r
+ _startTime = (int) (_lastSendKa.getTime());\r
+ cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
+ COPSKAMsg msg = new COPSKAMsg();\r
+\r
+ msg.add(hdr);\r
+\r
+ COPSTransceiver.sendMsg(msg, _sock);\r
+ _lastSendKa = new Date();\r
+ }\r
+ }\r
+\r
+ // Accounting\r
+ if (_acctTimer > 0) {\r
+ int _startTime = (int) (_lastSendAcc.getTime());\r
+ int cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > ((_acctTimer*3/4)*1000)) {\r
+ // Notify all Request State Managers\r
+ notifyAcctAllReqStateMan();\r
+ _lastSendAcc = new Date();\r
+ }\r
+ }\r
+\r
+ try {\r
+ Thread.sleep(500);\r
+ } catch (Exception e) {};\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ }\r
+\r
+ // connection closed by server\r
+ // COPSDebug.out(getClass().getName(),"Connection closed by server");\r
+ try {\r
+ _sock.close();\r
+ } catch (IOException e) {};\r
+\r
+ // Notify all Request State Managers\r
+ try {\r
+ notifyCloseAllReqStateMan();\r
+ } catch (COPSPepException e) {};\r
+ }\r
+\r
+ /**\r
+ * Gets a COPS message from the socket and processes it\r
+ * @param conn Socket connected to the PDP\r
+ * @return COPS message type\r
+ * @throws COPSPepException\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ protected byte processMessage(Socket conn) throws COPSPepException, COPSException, IOException {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
+\r
+ if (msg.getHeader().isAClientClose()) {\r
+ handleClientCloseMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_CC;\r
+ } else if (msg.getHeader().isADecision()) {\r
+ handleDecisionMsg(/*OJO conn, */msg);\r
+ return COPSHeader.COPS_OP_DEC;\r
+ } else if (msg.getHeader().isASyncStateReq()) {\r
+ handleSyncStateReqMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_SSQ;\r
+ } else if (msg.getHeader().isAKeepAlive()) {\r
+ handleKeepAliveMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_KA;\r
+ } else {\r
+ throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handle Client Close Message, close the passed connection\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ */\r
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
+ _error = cMsg.getError();\r
+\r
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
+\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null)\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED, "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+ conn.close();\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Gets the COPS error\r
+ * @return <tt>COPSError</tt> returned by PDP\r
+ */\r
+ protected COPSError getError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Handle Keep Alive Message\r
+ *\r
+ * <Keep-Alive> ::= <Common Header>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
+ COPSKAMsg cMsg = (COPSKAMsg) msg;\r
+\r
+ // COPSDebug.out(getClass().getName(),"Get KAlive Msg");\r
+\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null)\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED, "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+ // must we do anything else?\r
+\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Method handleDecisionMsg\r
+ *\r
+ * <Decision Message> ::= <Common Header: Flag SOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>) | <Error>\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * [<ClientSI Decision Data: Outsourcing>]\r
+ * <Decision: Flags> ::= <Command-Code> NULLFlag\r
+ * <Command-Code> ::= NULLDecision | Install | Remove\r
+ * <ClientSI Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
+ * <Install Decision> ::= *(<PRID> <EPD>)\r
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
+ *\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleDecisionMsg(/*OJO Socket conn, */COPSMsg msg) throws COPSPepException {\r
+ COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;\r
+ COPSHandle handle = dMsg.getClientHandle();\r
+ COPSPepOSReqStateMan manager = (COPSPepOSReqStateMan) _managerMap.get(handle.getId().str());\r
+ manager.processDecision(dMsg);\r
+ }\r
+\r
+ /**\r
+ * Method handleSyncStateReqMsg\r
+ *\r
+ * <Synchronize State> ::= <Common Header>\r
+ * [<Client Handle>]\r
+ * [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleSyncStateReqMsg(Socket conn, COPSMsg msg) throws COPSPepException {\r
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
+ // COPSHandle handle = cMsg.getClientHandle();\r
+ // COPSHeader header = cMsg.getHeader();\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null)\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+ COPSPepOSReqStateMan manager = (COPSPepOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+\r
+ if (manager == null)\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ else\r
+ manager.processSyncStateRequest(cMsg);\r
+ }\r
+\r
+ /**\r
+ * Adds a new request state\r
+ * @param clientHandle Client's handle\r
+ * @param process Policy data processing object\r
+ * @param clientSIs Client data from the outsourcing event\r
+ * @return The newly created request state manager\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ */\r
+ protected COPSPepOSReqStateMan addRequestState(String clientHandle, COPSPepOSDataProcess process, Vector clientSIs) throws COPSException, COPSPepException {\r
+ COPSPepOSReqStateMan manager = new COPSPepOSReqStateMan(_clientType, clientHandle);\r
+ if (_managerMap.get(clientHandle) != null)\r
+ throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);\r
+\r
+ manager.setDataProcess(process);\r
+ manager.setClientSI(clientSIs);\r
+ _managerMap.put(clientHandle, manager);\r
+ manager.initRequestState(_sock);\r
+ return manager;\r
+ }\r
+\r
+ /**\r
+ * Deletes a request state\r
+ * @param manager Request state manager\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ */\r
+ protected void deleteRequestState(COPSPepOSReqStateMan manager) throws COPSException, COPSPepException {\r
+ manager.finalizeRequestState();\r
+ }\r
+\r
+ private void notifyCloseAllReqStateMan() throws COPSPepException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processClosedConnection(_error);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyNoKAAllReqStateMan() throws COPSPepException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processNoKAConnection();\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyAcctAllReqStateMan() throws COPSPepException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processAcctReport();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+\r
+/**\r
+ * Abstract class for implementing policy data processing classes for outsourcing PEPs.\r
+ */\r
+public abstract class COPSPepOSDataProcess {\r
+ /**\r
+ * Applies the decisions from the PDP\r
+ * @param man The request state manager\r
+ * @param dMsg The decisions message\r
+ * @return <tt>true</tt> if failed (reports indicate failure), <tt>false</tt> otherwise\r
+ */\r
+ public abstract boolean setDecisions(COPSPepOSReqStateMan man, COPSDecisionMsg dMsg);\r
+\r
+ /**\r
+ * Gets the report data\r
+ * @param man The request state manager\r
+ * @return A <tt>Vector</tt> holding the report data\r
+ */\r
+ public abstract Vector getReportData(COPSPepOSReqStateMan man);\r
+\r
+ /**\r
+ * Gets the supplied client data\r
+ * @param man The request state manager\r
+ * @return A <tt>Vector</tt> holding the client data\r
+ */\r
+ public abstract Vector getClientData(COPSPepOSReqStateMan man);\r
+\r
+ /**\r
+ * Gets the account data\r
+ * @param man The request state manager\r
+ * @return A <tt>Vector</tt> holding the account data\r
+ */\r
+ public abstract Vector getAcctData(COPSPepOSReqStateMan man);\r
+\r
+ /**\r
+ * Called when the connection is closed\r
+ * @param man The request state manager\r
+ * @param error Reason\r
+ */\r
+ public abstract void notifyClosedConnection (COPSPepOSReqStateMan man, COPSError error);\r
+\r
+ /**\r
+ * Called when the keep-alive message is not received\r
+ * @param man The request state manager\r
+ */\r
+ public abstract void notifyNoKAliveReceived (COPSPepOSReqStateMan man);\r
+\r
+ /**\r
+ * Process a PDP request to close a Request State\r
+ * @param man The request state manager\r
+ */\r
+ public abstract void closeRequestState(COPSPepOSReqStateMan man);\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+/**\r
+ * Abstract class for creating listeners for outsourcing events.\r
+ */\r
+public abstract class COPSPepOSEventListener extends Thread {\r
+ /**\r
+ * COPSPepOSAgent to be waked up upon event detection.\r
+ */\r
+ protected COPSPepOSAgent _agent;\r
+\r
+ /**\r
+ * Sets the COPS agent to be waked up.\r
+ * @param anAgent A COPSPepOSAgent\r
+ */\r
+ public void setAgent(COPSPepOSAgent anAgent) {\r
+ _agent = anAgent;\r
+ }\r
+\r
+ /**\r
+ * This must implement event detection, and wake up\r
+ * the COPS agent when it occurs. The steps are:\r
+ * <ul>\r
+ * <li>Detect the outsourcing event</li>\r
+ * <li>Build a <tt>Vector clientSIs</tt> from the event</li>\r
+ * <li>Generate a <tt>COPSHandle handle</tt> for the request</li>\r
+ * <li>Invoke <tt>_agent.dispatchEvent(handle, clientSIs)</tt></li></ul>\r
+ */\r
+ public abstract void run();\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSClientSI;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSReason;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReportType;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPS message transceiver class for outsourcing connections at the PEP side.\r
+ */\r
+public class COPSPepOSMsgSender {\r
+ /**\r
+ * Socket connection to PDP\r
+ */\r
+ protected Socket _sock;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Creates a COPSPepMsgSender\r
+ *\r
+ * @param clientType Client-type\r
+ * @param clientHandle Client handle\r
+ * @param sock Socket connected to the PDP\r
+ */\r
+ public COPSPepOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
+ // COPS Handle\r
+ _handle = clientHandle;\r
+ _clientType = clientType;\r
+\r
+ _sock = sock;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Sends a request to the PDP.\r
+ * The PEP establishes a request state client handle for which the\r
+ * remote PDP may maintain state.\r
+ * @param clientSIs Client data\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendRequest(Vector clientSIs) throws COPSPepException {\r
+ // Create COPS Message\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType);\r
+\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0);\r
+\r
+ COPSHandle handle = _handle;\r
+\r
+ COPSReqMsg msg = new COPSReqMsg();\r
+ try {\r
+ msg.add(hdr) ;\r
+ msg.add(handle) ;\r
+ msg.add(cntxt) ;\r
+\r
+ Enumeration clientSIEnum = clientSIs.elements();\r
+ while (clientSIEnum.hasMoreElements())\r
+ msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
+ } catch (COPSException e) {\r
+ throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage());\r
+ }\r
+\r
+ // Send message\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a failure report to the PDP. This report message notifies the PDP\r
+ * of failure when carrying out the PDP's decision, or when reporting\r
+ * an accounting related state change.\r
+ * @param clientSIs Report data\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendFailReport(Vector clientSIs) throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report FAIL\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.FAILURE);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+\r
+ Enumeration clientSIEnum = clientSIs.elements();\r
+ while (clientSIEnum.hasMoreElements())\r
+ msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a success report to the PDP. This report message notifies the PDP\r
+ * of success when carrying out the PDP's decision, or when reporting\r
+ * an accounting related state change.\r
+ * @param clientSIs Report data\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendSuccessReport(Vector clientSIs) throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report SUCESS\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.SUCCESS);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+\r
+ Enumeration clientSIEnum = clientSIs.elements();\r
+ while (clientSIEnum.hasMoreElements())\r
+ msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends an accounting report to the PDP\r
+ * @param clientSIs Report data\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendAcctReport(Vector clientSIs) throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report SUCCESS\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.ACCT);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+\r
+ Enumeration clientSIEnum = clientSIs.elements();\r
+ while (clientSIEnum.hasMoreElements())\r
+ msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a sync-complete message to the PDP. This indicates the\r
+ * end of a synchronization requested by the PDP.\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendSyncComplete() throws COPSPepException {\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType);\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = _handle;\r
+\r
+ COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(clienthandle);\r
+ } catch (Exception e) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a delete request to the PDP.\r
+ * When sent from the PEP this message indicates to the remote PDP that\r
+ * the state identified by the client handle is no longer\r
+ * available/relevant.\r
+ * @throws COPSPepException\r
+ */\r
+ public void sendDeleteRequest() throws COPSPepException {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType);\r
+ COPSHandle handle = _handle;\r
+\r
+ // *** TODO: use real reason codes\r
+ COPSReason reason = new COPSReason((short) 234, (short) 345);\r
+\r
+ COPSDeleteMsg msg = new COPSDeleteMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(handle);\r
+ msg.add(reason);\r
+ msg.writeData(_sock);\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+package org.umu.cops.ospep;\r
+\r
+import java.net.Socket;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * State manager class for outsourcing requests, at the PEP side.\r
+ */\r
+public class COPSPepOSReqStateMan {\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request sent\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions received\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report sent\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request State finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New Request State solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete Request State solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC request received\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * Sync completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * Keep-alive timeout\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * Accounting timeout\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ Object for performing policy data processing\r
+ */\r
+ protected COPSPepOSDataProcess _process;\r
+\r
+ /**\r
+ * ClientSI data from signaling.\r
+ */\r
+ protected Vector _clientSIs;\r
+\r
+ /**\r
+ * Current state of the request being managed\r
+ */\r
+ protected short _status;\r
+\r
+ /**\r
+ COPS message transceiver used to send COPS messages\r
+ */\r
+ protected COPSPepOSMsgSender _sender;\r
+\r
+ /**\r
+ * Sync state\r
+ */\r
+ protected boolean _syncState;\r
+\r
+ /**\r
+ * Creates a state request manager\r
+ * @param clientType Client-type\r
+ * @param clientHandle Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSPepOSReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+ _syncState = true;\r
+ _status = ST_CREATE;\r
+ _clientSIs = null;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Sets the client SI data.\r
+ * @param someClientSIs Client SI data built by the event listener\r
+ */\r
+ public void setClientSI(Vector someClientSIs) {\r
+ _clientSIs = someClientSIs;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the request status\r
+ * @return Request status value\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Gets the policy data processing object\r
+ *\r
+ * @return Policy data processing object\r
+ *\r
+ */\r
+ public COPSPepOSDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Sets the policy data processing object\r
+ *\r
+ * @param process Policy data processing object\r
+ *\r
+ */\r
+ public void setDataProcess(COPSPepOSDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Initializes a new request state over a socket\r
+ * @param sock Socket to the PDP\r
+ * @throws COPSPepException\r
+ */\r
+ protected void initRequestState(Socket sock) throws COPSPepException {\r
+ // Inits an object for sending COPS messages to the PDP\r
+ _sender = new COPSPepOSMsgSender(_clientType, _handle, sock);\r
+\r
+ // If an object exists for retrieving the PEP features,\r
+ // use it for retrieving them.\r
+ /* Hashtable clientSIs;\r
+ if (_process != null)\r
+ clientSIs = _process.getClientData(this);\r
+ else\r
+ clientSIs = null;*/\r
+\r
+ // Semd the request\r
+ _sender.sendRequest(_clientSIs);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+ /**\r
+ * Deletes the request state\r
+ * @throws COPSPepException\r
+ */\r
+ protected void finalizeRequestState() throws COPSPepException {\r
+ _sender.sendDeleteRequest();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Processes the decision message\r
+ * @param dMsg Decision message from the PDP\r
+ * @throws COPSPepException\r
+ */\r
+ protected void processDecision(COPSDecisionMsg dMsg) throws COPSPepException {\r
+ // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
+\r
+ //Hashtable decisionsPerContext = dMsg.getDecisions();\r
+\r
+ //** Applies decisions to the configuration\r
+ //_process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
+ // second param changed to dMsg so that the data processor\r
+ // can check the 'solicited' flag\r
+ boolean isFailReport = _process.setDecisions(this, dMsg /*decisionsPerContext*/);\r
+ _status = ST_DECS;\r
+\r
+ if (isFailReport) {\r
+ // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
+ _sender.sendFailReport(_process.getReportData(this));\r
+ } else {\r
+ // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
+ _sender.sendSuccessReport(_process.getReportData(this));\r
+ }\r
+ _status = ST_REPORT;\r
+\r
+ if (!_syncState) {\r
+ _sender.sendSyncComplete();\r
+ _syncState = true;\r
+ _status = ST_SYNCALL;\r
+ }\r
+ }\r
+\r
+\r
+ /**\r
+ * Processes a COPS delete message\r
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PDP\r
+ * @throws COPSPepException\r
+ */\r
+ protected void processDeleteRequestState(COPSDecisionMsg dMsg) throws COPSPepException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+ /**\r
+ * Processes the message SycnStateRequest.\r
+ * The message SycnStateRequest indicates that the remote PDP\r
+ * wishes the client (which appears in the common header)\r
+ * to re-send its state.\r
+ *\r
+ * @param ssMsg The sync request from the PDP\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processSyncStateRequest(COPSSyncStateMsg ssMsg) throws COPSPepException {\r
+ _syncState = false;\r
+ // If an object exists for retrieving the PEP features,\r
+ // use it for retrieving them.\r
+\r
+ // Send the request\r
+ _sender.sendRequest(_clientSIs);\r
+\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ /**\r
+ * Called when connection is closed\r
+ * @param error Reason\r
+ * @throws COPSPepException\r
+ */\r
+ protected void processClosedConnection(COPSError error) throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ /**\r
+ * Called when no keep-alive is received\r
+ * @throws COPSPepException\r
+ */\r
+ protected void processNoKAConnection() throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ /**\r
+ * Processes the accounting report\r
+ * @throws COPSPepException\r
+ */\r
+ protected void processAcctReport() throws COPSPepException {\r
+ Vector report = new Vector();\r
+\r
+ if (_process != null)\r
+ report = _process.getAcctData(this);\r
+\r
+ _sender.sendAcctReport(report);\r
+\r
+ _status = ST_ACCT;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+import java.io.IOException;\r
+import java.net.ServerSocket;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSAcctTimer;\r
+import org.umu.cops.stack.COPSClientAcceptMsg;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSClientOpenMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKATimer;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * Core PDP agent for provisioning\r
+ */\r
+public class COPSPdpAgent extends Thread {\r
+ /** Well-known port for COPS */\r
+ public static final int WELL_KNOWN_PDP_PORT = 3288;\r
+ /** Default keep-alive timer value (secs) */\r
+ public static final short KA_TIMER_VALUE = 30;\r
+ /** Default accounting timer value (secs) */\r
+ public static final short ACCT_TIMER_VALUE = 0;\r
+\r
+ /**\r
+ PDP host IP\r
+ */\r
+ private ServerSocket _serverSocket;\r
+\r
+ /**\r
+ PDP host port\r
+ */\r
+ private int _serverPort;\r
+\r
+ /**\r
+ Client-type of connecting PEP\r
+ */\r
+ private short _clientType;\r
+\r
+ /**\r
+ Accounting timer (secs)\r
+ */\r
+ private short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer (secs)\r
+ */\r
+ private short _kaTimer;\r
+\r
+ /**\r
+ Maps a PEP-ID to a connection\r
+ */\r
+ private Hashtable _connectionMap;\r
+ // map < String(PEPID), COPSPdpConnection > ConnectionMap;\r
+\r
+ /**\r
+ * Policy data processing object\r
+ */\r
+ private COPSPdpDataProcess _process;\r
+\r
+ /**\r
+ * Creates a PDP Agent\r
+ *\r
+ * @param clientType COPS Client-type\r
+ * @param process Object to perform policy data processing\r
+ */\r
+ public COPSPdpAgent(short clientType, COPSPdpDataProcess process) {\r
+ _serverPort = WELL_KNOWN_PDP_PORT;\r
+ _kaTimer = KA_TIMER_VALUE;\r
+ _acctTimer = ACCT_TIMER_VALUE;\r
+\r
+ _clientType = clientType;\r
+ _connectionMap = new Hashtable(40);\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Creates a PDP Agent\r
+ *\r
+ * @param port Port to listen to\r
+ * @param clientType COPS Client-type\r
+ * @param process Object to perform policy data processing\r
+ */\r
+ public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) {\r
+ _serverPort = port;\r
+\r
+ _kaTimer = KA_TIMER_VALUE;\r
+ _acctTimer = ACCT_TIMER_VALUE;\r
+\r
+ _clientType = clientType;\r
+ _connectionMap = new Hashtable(40);\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Sets the keep-alive timer value\r
+ * @param kaTimer Keep alive timer value (secs)\r
+ */\r
+ public void setKaTimer (short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets the accounting timer value\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAcctTimer (short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the value of the keep-alive timer\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer () {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the accounting timer value\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer () {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the PEPs connected to this PDP\r
+ * @return An <tt>Enumeration</tt> of all connected PEPs\r
+ */\r
+ public Enumeration getConnectedPEPIds() {\r
+ return _connectionMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets the connection map\r
+ * @return A <tt>Hashtable</tt> holding the connection map\r
+ */\r
+ public Hashtable getConnectionMap() {\r
+ return _connectionMap;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return The client-type\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Disconnects a PEP\r
+ * @param pepID PEP-ID of the PEP to be disconnected\r
+ * @param error COPS Error to be reported as a reason\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ public void disconnect (String pepID, COPSError error)\r
+ throws COPSException, IOException {\r
+\r
+ COPSPdpConnection pdpConn = (COPSPdpConnection) _connectionMap.get(pepID);\r
+\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ if (error != null)\r
+ closeMsg.add(error);\r
+\r
+ closeMsg.writeData(pdpConn.getSocket());\r
+ pdpConn.close();\r
+ pdpConn = null;\r
+ }\r
+\r
+ /**\r
+ * Requests a COPS sync for a PEP\r
+ * @param pepID PEP-ID of the PEP to be synced\r
+ * @throws COPSException\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sync (String pepID)\r
+ throws COPSException, COPSPdpException {\r
+\r
+ COPSPdpConnection pdpConn = (COPSPdpConnection) _connectionMap.get(pepID);\r
+ pdpConn.syncAllRequestState();\r
+ }\r
+\r
+ /**\r
+ * Removes a PEP from the connection map\r
+ * @param pepID PEP-ID of the PEP to be removed\r
+ */\r
+ public void delete (String pepID) {\r
+ _connectionMap.remove(pepID);\r
+ }\r
+\r
+\r
+ /**\r
+ * Runs the PDP process\r
+ */\r
+ public void run() {\r
+ try {\r
+ _serverSocket = new ServerSocket (_serverPort);\r
+\r
+ //Loop through for Incoming messages\r
+\r
+ // server infinite loop\r
+ while (true) {\r
+\r
+ // Wait for an incoming connection from a PEP\r
+ Socket socket = _serverSocket.accept();\r
+\r
+ // COPSDebug.out(getClass().getName(),"New connection accepted " +\r
+ // socket.getInetAddress() +\r
+ // ":" + socket.getPort());\r
+\r
+ // We're waiting for an OPN message\r
+ try {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(socket);\r
+ if (msg.getHeader().isAClientOpen()) {\r
+ handleClientOpenMsg(socket, msg);\r
+ } else {\r
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ try {\r
+ socket.close();\r
+ } catch (Exception ex) {};\r
+ }\r
+ } catch (Exception e) { // COPSException, IOException\r
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,\r
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);\r
+ try {\r
+ socket.close();\r
+ } catch (Exception ex) {};\r
+ }\r
+ }\r
+ } catch (IOException e) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ return;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handles a COPS client-open message\r
+ * @param conn Socket to the PEP\r
+ * @param msg <tt>COPSMsg</tt> holding the client-open message\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ private void handleClientOpenMsg(Socket conn, COPSMsg msg)\r
+ throws COPSException, IOException {\r
+ COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;\r
+ COPSPepId pepId = cMsg.getPepId();\r
+\r
+ // Validate Client Type\r
+ if (msg.getHeader().getClientType() != _clientType) {\r
+ // Unsupported client type\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Unsupported client type");\r
+ }\r
+\r
+ // PEPId is mandatory\r
+ if (pepId == null) {\r
+ // Mandatory COPS object missing\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Mandatory COPS object missing (PEPId)");\r
+ }\r
+\r
+ // Support\r
+ if ( (cMsg.getClientSI() != null) ||\r
+ (cMsg.getPdpAddress() != null) ||\r
+ (cMsg.getIntegrity() != null)) {\r
+\r
+ // Unsupported objects\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
+ COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ closeMsg.add(err);\r
+ try {\r
+ closeMsg.writeData(conn);\r
+ } catch (IOException unae) {}\r
+\r
+ throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");\r
+ }\r
+\r
+ // Connection accepted\r
+ COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());\r
+ COPSKATimer katimer = new COPSKATimer(_kaTimer);\r
+ COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);\r
+ COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();\r
+ acceptMsg.add(ahdr);\r
+ acceptMsg.add(katimer) ;\r
+ if (_acctTimer != 0) acceptMsg.add(acctTimer);\r
+ acceptMsg.writeData(conn);\r
+\r
+ COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process);\r
+ pdpConn.setKaTimer(_kaTimer);\r
+ if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);\r
+ new Thread(pdpConn).start();\r
+ _connectionMap.put(pepId.getData().str(),pdpConn);\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKAMsg;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * Class for managing an provisioning connection at the PDP side.\r
+ */\r
+public class COPSPdpConnection implements Runnable {\r
+\r
+ /**\r
+ Socket connected to PEP\r
+ */\r
+ private Socket _sock;\r
+\r
+ /**\r
+ PEP identifier\r
+ */\r
+ private COPSPepId _pepId;\r
+\r
+ /**\r
+ Time of the latest keep-alive sent\r
+ */\r
+ private Date _lastKa;\r
+\r
+ /**\r
+ Opcode of the latest message sent\r
+ */\r
+ private byte _lastmessage;\r
+\r
+ /**\r
+ * Time of the latest keep-alive received\r
+ */\r
+ protected Date _lastRecKa;\r
+\r
+ /**\r
+ Maps a Client Handle to a Handler\r
+ */\r
+ protected Hashtable _managerMap;\r
+ // map < String(COPSHandle), COPSPdpHandler> HandlerMap;\r
+\r
+ /**\r
+ * PDP policy data processor class\r
+ */\r
+ protected COPSPdpDataProcess _process;\r
+\r
+ /**\r
+ Accounting timer value (secs)\r
+ */\r
+ protected short _acctTimer;\r
+\r
+ /**\r
+ Keep-alive timer value (secs)\r
+ */\r
+ protected short _kaTimer;\r
+\r
+ /**\r
+ COPS error returned by PEP\r
+ */\r
+ protected COPSError _error;\r
+\r
+ /**\r
+ * Creates a new PDP connection\r
+ *\r
+ * @param pepId PEP-ID of the connected PEP\r
+ * @param sock Socket connected to PEP\r
+ * @param process Object for processing policy data\r
+ */\r
+ public COPSPdpConnection(COPSPepId pepId, Socket sock, COPSPdpDataProcess process) {\r
+ _sock = sock;\r
+ _pepId = pepId;\r
+\r
+ _lastKa = new Date();\r
+ _lastmessage = COPSHeader.COPS_OP_OPN;\r
+ _managerMap = new Hashtable(20);\r
+\r
+ _kaTimer = 0;\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Gets the time of that latest keep-alive sent\r
+ * @return Time of that latest keep-alive sent\r
+ */\r
+ public Date getLastKAlive() {\r
+ return _lastKa;\r
+ }\r
+\r
+ /**\r
+ * Sets the keep-alive timer value\r
+ * @param kaTimer Keep-alive timer value (secs)\r
+ */\r
+ public void setKaTimer(short kaTimer) {\r
+ _kaTimer = kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the keep-alive timer value\r
+ * @return Keep-alive timer value (secs)\r
+ */\r
+ public short getKaTimer() {\r
+ return _kaTimer;\r
+ }\r
+\r
+ /**\r
+ * Sets the accounting timer value\r
+ * @param acctTimer Accounting timer value (secs)\r
+ */\r
+ public void setAccTimer(short acctTimer) {\r
+ _acctTimer = acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the accounting timer value\r
+ * @return Accounting timer value (secs)\r
+ */\r
+ public short getAcctTimer() {\r
+ return _acctTimer;\r
+ }\r
+\r
+ /**\r
+ * Gets the latest COPS message\r
+ * @return Code of the latest message sent\r
+ */\r
+ public byte getLastMessage() {\r
+ return _lastmessage;\r
+ }\r
+\r
+ /**\r
+ * Gets active handles\r
+ * @return An <tt>Enumeration</tt> holding all active handles\r
+ */\r
+ public Enumeration getHandles() {\r
+ return _managerMap.keys();\r
+ }\r
+\r
+ /**\r
+ * Gets the handle map\r
+ * @return A <tt>Hashtable</tt> holding the handle map\r
+ */\r
+ public Hashtable getReqStateMans() {\r
+ return _managerMap;\r
+ }\r
+\r
+ /**\r
+ * Gets the PEP-ID\r
+ * @return The ID of the PEP, as a <tt>String</tt>\r
+ */\r
+ public String getPepId() {\r
+ return _pepId.getData().str();\r
+ }\r
+\r
+ /**\r
+ * Checks whether the socket to the PEP is closed or not\r
+ * @return <tt>true</tt> if closed, <tt>false</tt> otherwise\r
+ */\r
+ public boolean isClosed() {\r
+ return _sock.isClosed();\r
+ }\r
+\r
+ /**\r
+ * Closes the socket to the PEP\r
+ * @throws IOException\r
+ */\r
+ protected void close()\r
+ throws IOException {\r
+ _sock.close();\r
+ }\r
+\r
+ /**\r
+ * Gets the socket to the PEP\r
+ * @return Socket connected to the PEP\r
+ */\r
+ public Socket getSocket() {\r
+ return _sock;\r
+ }\r
+\r
+ /**\r
+ * Main loop\r
+ */\r
+ public void run () {\r
+ Date _lastSendKa = new Date();\r
+ _lastRecKa = new Date();\r
+ try {\r
+ while (!_sock.isClosed()) {\r
+ if (_sock.getInputStream().available() != 0) {\r
+ _lastmessage = processMessage(_sock);\r
+ _lastRecKa = new Date();\r
+ }\r
+\r
+ // Keep Alive\r
+ if (_kaTimer > 0) {\r
+ // Timeout at PDP\r
+ int _startTime = (int) (_lastRecKa.getTime());\r
+ int cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > _kaTimer*1000) {\r
+ _sock.close();\r
+ // Notify all Request State Managers\r
+ notifyNoKAAllReqStateMan();\r
+ }\r
+\r
+ // Send to PEP\r
+ _startTime = (int) (_lastSendKa.getTime());\r
+ cTime = (int) (new Date().getTime());\r
+\r
+ if ((int)(cTime - _startTime) > ((_kaTimer*3/4)*1000)) {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
+ COPSKAMsg msg = new COPSKAMsg();\r
+\r
+ msg.add(hdr);\r
+\r
+ COPSTransceiver.sendMsg(msg, _sock);\r
+ _lastSendKa = new Date();\r
+ }\r
+ }\r
+\r
+ try {\r
+ Thread.sleep(500);\r
+ } catch (Exception e) {};\r
+\r
+ }\r
+ } catch (Exception e) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+ }\r
+\r
+ // connection closed by server\r
+ // COPSDebug.out(getClass().getName(),"Connection closed by client");\r
+ try {\r
+ _sock.close();\r
+ } catch (IOException e) {};\r
+\r
+ // Notify all Request State Managers\r
+ try {\r
+ notifyCloseAllReqStateMan();\r
+ } catch (COPSPdpException e) {};\r
+ }\r
+\r
+ /**\r
+ * Gets a COPS message from the socket and processes it\r
+ * @param conn Socket connected to the PEP\r
+ * @return Type of COPS message\r
+ */\r
+ private byte processMessage(Socket conn)\r
+ throws COPSPdpException, COPSException, IOException {\r
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
+\r
+ if (msg.getHeader().isAClientClose()) {\r
+ handleClientCloseMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_CC;\r
+ } else if (msg.getHeader().isAKeepAlive()) {\r
+ handleKeepAliveMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_KA;\r
+ } else if (msg.getHeader().isARequest()) {\r
+ handleRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_REQ;\r
+ } else if (msg.getHeader().isAReport()) {\r
+ handleReportMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_RPT;\r
+ } else if (msg.getHeader().isADeleteReq()) {\r
+ handleDeleteRequestMsg(conn, msg);\r
+ return COPSHeader.COPS_OP_DRQ;\r
+ } else if (msg.getHeader().isASyncComplete()) {\r
+ handleSyncComplete(conn, msg);\r
+ return COPSHeader.COPS_OP_SSC;\r
+ } else {\r
+ throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Handle Client Close Message, close the passed connection\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ */\r
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
+ _error = cMsg.getError();\r
+\r
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
+\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ conn.close();\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Gets the occurred COPS Error\r
+ * @return <tt>COPSError</tt> object\r
+ */\r
+ protected COPSError getError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Handle Keep Alive Message\r
+ *\r
+ * <Keep-Alive> ::= <Common Header>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
+ COPSKAMsg cMsg = (COPSKAMsg) msg;\r
+\r
+ COPSKAMsg kaMsg = (COPSKAMsg) msg;\r
+ try {\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ kaMsg.writeData(conn);\r
+ } catch (Exception unae) { };\r
+ }\r
+\r
+ /**\r
+ * Handle Delete Request Message\r
+ *\r
+ * <Delete Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Reason>\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;\r
+ // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +\r
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ // Delete clientHandler\r
+ if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {\r
+ // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +\r
+ // cMsg.getClientHandle().getId().getData());\r
+ }\r
+\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processDeleteRequestState(cMsg);\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Handle Request Message\r
+ *\r
+ * <Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleRequestMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ COPSReqMsg reqMsg = (COPSReqMsg) msg;\r
+ COPSContext cntxt = reqMsg.getContext();\r
+ COPSHeader header = reqMsg.getHeader();\r
+ //short reqType = cntxt.getRequestType();\r
+ short cType = header.getClientType();\r
+\r
+ // Support\r
+ if (reqMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpReqStateMan man;\r
+ man = (COPSPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+\r
+ man = new COPSPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());\r
+ _managerMap.put(reqMsg.getClientHandle().getId().str(),man);\r
+ man.setDataProcess(_process);\r
+ man.initRequestState(_sock);\r
+\r
+ // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +\r
+ // header.getClientType() + " msgType=" +\r
+ // cntxt.getMessageType() + ", connId=" + conn.toString());\r
+ }\r
+\r
+ man.processRequest(reqMsg);\r
+ }\r
+\r
+ /**\r
+ * Handle Report Message\r
+ *\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<Integrity>]\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleReportMsg(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSReportMsg repMsg = (COPSReportMsg) msg;\r
+ // COPSHandle handle = repMsg.getClientHandle();\r
+ // COPSHeader header = repMsg.getHeader();\r
+\r
+ // Support\r
+ if (repMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processReport(repMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method handleSyncComplete\r
+ *\r
+ * @param conn a Socket\r
+ * @param msg a COPSMsg\r
+ *\r
+ */\r
+ private void handleSyncComplete(Socket conn, COPSMsg msg)\r
+ throws COPSPdpException {\r
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
+ // COPSHandle handle = cMsg.getClientHandle();\r
+ // COPSHeader header = cMsg.getHeader();\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+ }\r
+\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+ if (man == null) {\r
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+ } else {\r
+ man.processSyncComplete(cMsg);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Requests a COPS sync from the PEP\r
+ * @throws COPSException\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncAllRequestState()\r
+ throws COPSException, COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.syncRequestState();\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyCloseAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processClosedConnection(_error);\r
+ }\r
+ }\r
+ }\r
+\r
+ private void notifyNoKAAllReqStateMan()\r
+ throws COPSPdpException {\r
+ if (_managerMap.size() > 0) {\r
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+ String handle = (String) e.nextElement();\r
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(handle);\r
+\r
+ man.processNoKAConnection();\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.stack.COPSError;\r
+\r
+/**\r
+ * Abstract class for implementing policy data processing classes for provisioning PDPs.\r
+ */\r
+abstract public class COPSPdpDataProcess {\r
+ /**\r
+ * Gets the policies to be uninstalled\r
+ * @param man The associated request state manager\r
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
+ */\r
+ abstract public Hashtable getRemovePolicy(COPSPdpReqStateMan man);\r
+ /**\r
+ * Gets the policies to be installed\r
+ * @param man The associated request state manager\r
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
+ */\r
+ abstract public Hashtable getInstallPolicy(COPSPdpReqStateMan man);\r
+ /**\r
+ * Makes a decision from the supplied request data\r
+ * @param man The associated request state manager\r
+ * @param reqSIs Client specific data suppplied in the COPS request\r
+ */\r
+ abstract public void setClientData(COPSPdpReqStateMan man, Hashtable reqSIs);\r
+ /**\r
+ * Builds a failure report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void failReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
+ /**\r
+ * Builds a success report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void successReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
+ /**\r
+ * Builds an accounting report\r
+ * @param man The associated request state manager\r
+ * @param reportSIs Report data\r
+ */\r
+ abstract public void acctReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
+ /**\r
+ * Notifies that no accounting report has been received\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyNoAcctReport (COPSPdpReqStateMan man);\r
+\r
+ /**\r
+ * Notifies a keep-alive timeout\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyNoKAliveReceived (COPSPdpReqStateMan man);\r
+\r
+ /**\r
+ * Notifies that the connection has been closed\r
+ * @param man The associated request state manager\r
+ * @param error Reason\r
+ */\r
+ public abstract void notifyClosedConnection (COPSPdpReqStateMan man, COPSError error);\r
+\r
+ /**\r
+ * Notifies that a request state has been deleted\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void notifyDeleteRequestState (COPSPdpReqStateMan man);\r
+\r
+ /**\r
+ * Notifies that a request state has been closed\r
+ * @param man The associated request state manager\r
+ */\r
+ public abstract void closeRequestState(COPSPdpReqStateMan man);\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+/**\r
+ * Exception class for PDP errors\r
+ *\r
+ * @version COPSPdpException.java, v 2.00 2004\r
+ *\r
+ */\r
+\r
+public class COPSPdpException extends Exception {\r
+\r
+ private int rc;\r
+ final static int GENERAL_ERROR = 0x00000001;\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message.\r
+ * @param msg Exception message\r
+ */\r
+ public COPSPdpException(String msg) {\r
+ super(msg);\r
+ rc=0;\r
+ }\r
+\r
+ /**\r
+ * Creates a <tt>COPSPdpException</tt> with the given message and return code.\r
+ * @param msg Exception message\r
+ * @param retCode Return code\r
+ */\r
+ public COPSPdpException(String msg, int retCode) {\r
+ super(msg);\r
+ rc = retCode;\r
+ }\r
+\r
+ /**\r
+ * Gets the return code of the exception\r
+ * @return Exception's return code\r
+ */\r
+ public int returnCode() {\r
+ return rc;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDecision;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSPrEPD;\r
+import org.umu.cops.stack.COPSPrID;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPS message transceiver class for provisioning connections at the PDP side.\r
+ */\r
+public class COPSPdpMsgSender {\r
+\r
+ /**\r
+ * Socket connected to PEP\r
+ */\r
+ protected Socket _sock;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Creates a COPSPepMsgSender\r
+ *\r
+ * @param clientType COPS client-type\r
+ * @param clientHandle Client handle\r
+ * @param sock Socket to the PEP\r
+ */\r
+ public COPSPdpMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
+ // COPS Handle\r
+ _handle = clientHandle;\r
+ _clientType = clientType;\r
+\r
+ _sock = sock;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Sends a decision message\r
+ * @param removeDecs Decisions to be removed\r
+ * @param installDecs Decisions to be installed\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendDecision(Hashtable removeDecs, Hashtable installDecs)\r
+ throws COPSPdpException {\r
+ /* <Decision Message> ::= <Common Header: Flag SOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>) | <Error>\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * [<Named Decision Data: Provisioning>]\r
+ * <Decision: Flags> ::= <Command-Code> NULLFlag\r
+ * <Command-Code> ::= NULLDecision | Install | Remove\r
+ * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
+ * <Install Decision> ::= *(<PRID> <EPD>)\r
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
+ *\r
+ * Very important, this is actually being treated like this:\r
+ * <Install Decision> ::= <PRID> | <EPD>\r
+ * <Remove Decision> ::= <PRID> | <PPRID>\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+ hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED);\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle handle = new COPSHandle();\r
+ handle.setId(getClientHandle().getId());\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(handle);\r
+\r
+ // Decisions (no flags supplied)\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+\r
+ // Remove Decisions\r
+ // <Decision: Flags>\r
+ if (removeDecs.size() > 0) {\r
+ COPSDecision rdec1 = new COPSDecision();\r
+ rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
+\r
+ decisionMsg.addDecision(rdec1, cntxt);\r
+\r
+ for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) removeDecs.get(strprid);\r
+\r
+ // <Named Decision Data: Provisioning> (PRID)\r
+ COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+ // <Named Decision Data: Provisioning> (EPD)\r
+ COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ decisionMsg.addDecision(dec2, cntxt);\r
+ decisionMsg.addDecision(dec3, cntxt);\r
+ }\r
+ }\r
+\r
+ // Install Decisions\r
+ // <Decision: Flags>\r
+ if (installDecs.size() > 0) {\r
+ COPSDecision idec1 = new COPSDecision();\r
+ idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
+\r
+ decisionMsg.addDecision(idec1, cntxt);\r
+\r
+ for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) installDecs.get(strprid);\r
+\r
+ // <Named Decision Data: Provisioning> (PRID)\r
+ COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+ // <Named Decision Data: Provisioning> (EPD)\r
+ COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ decisionMsg.addDecision(dec2, cntxt);\r
+ decisionMsg.addDecision(dec3, cntxt);\r
+ }\r
+\r
+ /**\r
+ COPSIntegrity intr = new COPSIntegrity();\r
+ intr.setKeyId(19);\r
+ intr.setSeqNum(9);\r
+ intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
+ decisionMsg.add(intr);\r
+ /**/\r
+ }\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ //** Send the decision\r
+ //**\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a decision message which was not requested by the PEP\r
+ * @param removeDecs Decisions to be removed\r
+ * @param installDecs Decisions to be installed\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendUnsolicitedDecision(Hashtable removeDecs, Hashtable installDecs)\r
+ throws COPSPdpException {\r
+ //** Example of an UNSOLICITED decision\r
+ //**\r
+\r
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>) | <Error>\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * [<Named Decision Data: Provisioning>]\r
+ * <Decision: Flags> ::= <Command-Code> NULLFlag\r
+ * <Command-Code> ::= NULLDecision | Install | Remove\r
+ * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
+ * <Install Decision> ::= *(<PRID> <EPD>)\r
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
+ *\r
+ * Very important, this is actually being treated like this:\r
+ * <Install Decision> ::= <PRID> | <EPD>\r
+ * <Remove Decision> ::= <PRID> | <PPRID>\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle handle = new COPSHandle();\r
+ handle.setId(getClientHandle().getId());\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(handle);\r
+\r
+ // Decisions (no flags supplied)\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+\r
+ // Remove Decisions\r
+ // <Decision: Flags>\r
+ COPSDecision rdec1 = new COPSDecision();\r
+ rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
+\r
+ decisionMsg.addDecision(rdec1, cntxt);\r
+\r
+ for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) removeDecs.get(strprid);\r
+\r
+ // <Named Decision Data: Provisioning> (PRID)\r
+ COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+ // <Named Decision Data: Provisioning> (EPD)\r
+ COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ decisionMsg.addDecision(dec2, cntxt);\r
+ decisionMsg.addDecision(dec3, cntxt);\r
+ }\r
+\r
+ // Install Decisions\r
+ // <Decision: Flags>\r
+ COPSDecision idec1 = new COPSDecision();\r
+ idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
+\r
+ decisionMsg.addDecision(idec1, cntxt);\r
+\r
+ for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) installDecs.get(strprid);\r
+\r
+ // <Named Decision Data: Provisioning> (PRID)\r
+ COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+ // <Named Decision Data: Provisioning> (EPD)\r
+ COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ decisionMsg.addDecision(dec2, cntxt);\r
+ decisionMsg.addDecision(dec3, cntxt);\r
+ }\r
+\r
+ /**\r
+ COPSIntegrity intr = new COPSIntegrity();\r
+ intr.setKeyId(19);\r
+ intr.setSeqNum(9);\r
+ intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
+ decisionMsg.add(intr);\r
+ /**/\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ //** Send the decision\r
+ //**\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a message asking that the request state be deleted\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendDeleteRequestState()\r
+ throws COPSPdpException {\r
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>)\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * <Decision: Flags> ::= Remove Request-State\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request (default UNSOLICITED)\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ // Decisions\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+ // <Decision: Flags>\r
+ COPSDecision dec = new COPSDecision();\r
+ dec.setCmdCode(COPSDecision.DEC_REMOVE);\r
+ dec.setFlags(COPSDecision.F_REQSTATE);\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(clienthandle);\r
+ decisionMsg.addDecision(dec, cntxt);\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a request asking that a new request state be created\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendOpenNewRequestState()\r
+ throws COPSPdpException {\r
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
+ * <Client Handle>\r
+ * *(<Decision>)\r
+ * [<Integrity>]\r
+ * <Decision> ::= <Context>\r
+ * <Decision: Flags>\r
+ * <Decision: Flags> ::= Install Request-State\r
+ *\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request (default UNSOLICITED)\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ // Decisions\r
+ // <Context>\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
+ // <Decision: Flags>\r
+ COPSDecision dec = new COPSDecision();\r
+ dec.setCmdCode(COPSDecision.DEC_INSTALL);\r
+ dec.setFlags(COPSDecision.F_REQSTATE);\r
+\r
+ COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
+ try {\r
+ decisionMsg.add(hdr);\r
+ decisionMsg.add(clienthandle);\r
+ decisionMsg.addDecision(dec, cntxt);\r
+ } catch (COPSException e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ decisionMsg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Sends a message asking for a COPS sync operation\r
+ * @throws COPSPdpException\r
+ */\r
+ public void sendSyncRequestState()\r
+ throws COPSPdpException {\r
+ /* <Synchronize State Request> ::= <Common Header>\r
+ * [<Client Handle>]\r
+ * [<Integrity>]\r
+ */\r
+\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType());\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = new COPSHandle();\r
+ clienthandle.setId(_handle.getId());\r
+\r
+ COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(clienthandle);\r
+ } catch (Exception e) {\r
+ throw new COPSPdpException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpdp;\r
+\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSClientSI;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSPrObjBase;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReportType;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * State manager class for provisioning requests, at the PDP side.\r
+ */\r
+public class COPSPdpReqStateMan {\r
+\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request received\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions sent\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report received\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request State finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New Request State solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete Request State solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC request sent\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * SYNC completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * Keep-alive timeout\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * Accounting timeout\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * COPS client-type that identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * COPS client handle used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Object for performing policy data processing\r
+ */\r
+ protected COPSPdpDataProcess _process;\r
+\r
+ /**\r
+ * Current state of the request being managed\r
+ */\r
+ protected short _status;\r
+\r
+ /** COPS message transceiver used to send COPS messages */\r
+ protected COPSPdpMsgSender _sender;\r
+\r
+ /**\r
+ * Creates a request state manager\r
+ * @param clientType Client-type\r
+ * @param clientHandle Client handle\r
+ */\r
+ public COPSPdpReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+\r
+ _status = ST_CREATE;\r
+ }\r
+\r
+ /**\r
+ * Gets the client handle\r
+ * @return Client's <tt>COPSHandle</tt>\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Gets the client-type\r
+ * @return Client-type value\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the status of the request\r
+ * @return Request state value\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Gets the policy data processing object\r
+ * @return Policy data processing object\r
+ */\r
+ public COPSPdpDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Sets the policy data processing object\r
+ * @param process Policy data processing object\r
+ */\r
+ public void setDataProcess(COPSPdpDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Called when COPS sync is completed\r
+ * @param repMsg COPS sync message\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
+ throws COPSPdpException {\r
+\r
+ _status = ST_SYNCALL;\r
+\r
+ // maybe we should notifySyncComplete ...\r
+ }\r
+\r
+ /**\r
+ * Initializes a new request state over a socket\r
+ * @param sock Socket to the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void initRequestState(Socket sock)\r
+ throws COPSPdpException {\r
+ // Inits an object for sending COPS messages to the PEP\r
+ _sender = new COPSPdpMsgSender(_clientType, _handle, sock);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+ /**\r
+ * Processes a COPS request\r
+ * @param msg COPS request received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processRequest(COPSReqMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ COPSHeader hdrmsg = msg.getHeader();\r
+ COPSHandle handlemsg = msg.getClientHandle();\r
+ COPSContext contextmsg = msg.getContext();\r
+\r
+ //** Analyze the request\r
+ //**\r
+\r
+ /* <Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
+ *\r
+ * Very important, this is actually being treated like this:\r
+ * <Named ClientSI> ::= <PRID> | <EPD>\r
+ *\r
+\r
+ // Named ClientSI\r
+ Vector clientSIs = msg.getClientSI();\r
+ Hashtable reqSIs = new Hashtable(40);\r
+ String strobjprid = new String();\r
+ for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
+ switch (obj.getSNum())\r
+ {\r
+ case COPSPrObjBase.PR_PRID:\r
+ strobjprid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ reqSIs.put(strobjprid, obj.getData().str());\r
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ //** Here we must retrieve a decision depending on\r
+ //** the supplied ClientSIs\r
+ // reqSIs is a hashtable with the prid and epds\r
+\r
+ // ................\r
+ //\r
+ Hashtable removeDecs = new Hashtable();\r
+ Hashtable installDecs = new Hashtable();\r
+ _process.setClientData(this, reqSIs);\r
+\r
+ removeDecs = _process.getRemovePolicy(this);\r
+ installDecs = _process.getInstallPolicy(this);\r
+\r
+ //** We create the SOLICITED decision\r
+ //**\r
+ _sender.sendDecision(removeDecs, installDecs);\r
+ _status = ST_DECS;\r
+ */\r
+ }\r
+\r
+ /**\r
+ * Processes a report\r
+ * @param msg Report message from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processReport(COPSReportMsg msg)\r
+ throws COPSPdpException {\r
+\r
+ //** Analyze the report\r
+ //**\r
+\r
+ /*\r
+ * <Report State> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Report Type>\r
+ * *(<Named ClientSI>)\r
+ * [<Integrity>]\r
+ * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
+ * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
+ *\r
+ * Important, <Named ClientSI> is not parsed\r
+ */\r
+\r
+ // COPSHeader hdrmsg = msg.getHeader();\r
+ // COPSHandle handlemsg = msg.getClientHandle();\r
+\r
+ // Report Type\r
+ COPSReportType rtypemsg = msg.getReport();\r
+\r
+ // Named ClientSI\r
+ Vector clientSIs = msg.getClientSI();\r
+ Hashtable repSIs = new Hashtable(40);\r
+ String strobjprid = new String();\r
+ for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ strobjprid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ repSIs.put(strobjprid, obj.getData().str());\r
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ //** Here we must act in accordance with\r
+ //** the report received\r
+ if (rtypemsg.isSuccess()) {\r
+ _status = ST_REPORT;\r
+ _process.successReport(this, repSIs);\r
+ } else if (rtypemsg.isFailure()) {\r
+ _status = ST_REPORT;\r
+ _process.failReport(this, repSIs);\r
+ } else if (rtypemsg.isAccounting()) {\r
+ _status = ST_ACCT;\r
+ _process.acctReport(this, repSIs);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Called when connection is closed\r
+ * @param error Reason\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processClosedConnection(COPSError error)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ /**\r
+ * Called when no keep-alive is received\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processNoKAConnection()\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ /**\r
+ * Deletes the request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void finalizeRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendDeleteRequestState();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Asks for a COPS sync\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void syncRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendSyncRequestState();\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ /**\r
+ * Opens a new request state\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void openNewRequestState()\r
+ throws COPSPdpException {\r
+ _sender.sendOpenNewRequestState();\r
+ _status = ST_NEW;\r
+ }\r
+\r
+ /**\r
+ * Processes a COPS delete message\r
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
+ * @throws COPSPdpException\r
+ */\r
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
+ throws COPSPdpException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpep;\r
+\r
+import java.io.IOException;\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.stack.COPSAcctTimer;\r
+import org.umu.cops.stack.COPSClientAcceptMsg;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSClientOpenMsg;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKATimer;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSPepId;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * This is a provisioning COPS PEP. Responsible for making\r
+ * connection to the PDP and maintaining it\r
+ */\r
+public class COPSPepAgent {\r
+\r
+ /**\r
+ PEP's Identifier\r
+ */\r
+ private String _pepID;\r
+\r
+ /**\r
+ PEP's client-type\r
+ */\r
+ private short _clientType;\r
+\r
+ /**\r
+ PDP host name\r
+ */\r
+ private String _psHost;\r
+\r
+ /**\r
+ PDP port\r
+ */\r
+ private int _psPort;\r
+\r
+ /**\r
+ PEP-PDP connection manager\r
+ */\r
+ private COPSPepConnection _conn;\r
+\r
+ /**\r
+ COPS error returned by PDP\r
+ */\r
+ private COPSError _error;\r
+\r
+ /**\r
+ * Creates a PEP agent\r
+ * @param pepID PEP-ID\r
+ * @param clientType Client-type\r
+ */\r
+ public COPSPepAgent(String pepID, short clientType) {\r
+ _pepID = pepID;\r
+ _clientType = clientType;\r
+ }\r
+\r
+ /**\r
+ * Creates a PEP agent with a PEP-ID equal to "noname"\r
+ * @param clientType Client-type\r
+ */\r
+ public COPSPepAgent(short clientType) {\r
+\r
+ // PEPId\r
+ try {\r
+ _pepID = InetAddress.getLocalHost().getHostName();\r
+ } catch (Exception e) {\r
+ _pepID = "noname";\r
+ }\r
+\r
+ _clientType = clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets the identifier of the PEP\r
+ * @return PEP-ID\r
+ */\r
+ public String getPepID() {\r
+ return _pepID;\r
+ }\r
+\r
+ /**\r
+ * Gets the COPS client-type\r
+ * @return PEP's client-type\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Gets PDP host name\r
+ * @return PDP host name\r
+ */\r
+ public String getPDPName() {\r
+ return _psHost;\r
+ }\r
+\r
+ /**\r
+ * Gets the port of the PDP\r
+ * @return PDP port\r
+ */\r
+ public int getPDPPort() {\r
+ return _psPort;\r
+ }\r
+\r
+ /**\r
+ * Connects to a PDP\r
+ * @param psHost PDP host name\r
+ * @param psPort PDP port\r
+ * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise\r
+ * @throws java.net.UnknownHostException\r
+ * @throws java.io.IOException\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ */\r
+ public boolean connect(String psHost, int psPort)\r
+ throws UnknownHostException, IOException, COPSException, COPSPepException {\r
+\r
+ // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");\r
+ _psHost = psHost;\r
+ _psPort = psPort;\r
+\r
+ // Check whether it already exists\r
+ if (_conn == null)\r
+ _conn = processConnection(psHost,psPort);\r
+ else {\r
+ // Check if it's closed\r
+ if (_conn.isClosed()) {\r
+ _conn = processConnection(psHost,psPort);\r
+ } else {\r
+ disconnect(null);\r
+ _conn = processConnection(psHost,psPort);\r
+ }\r
+ }\r
+\r
+ return (_conn != null);\r
+ }\r
+\r
+ /**\r
+ * Gets the connection manager\r
+ * @return PEP-PDP connection manager object\r
+ */\r
+ public COPSPepConnection getConnection () {\r
+ return (_conn);\r
+ }\r
+\r
+ /**\r
+ * Gets the COPS error returned by the PDP\r
+ * @return <tt>COPSError</tt> returned by PDP\r
+ */\r
+ public COPSError getConnectionError() {\r
+ return _error;\r
+ }\r
+\r
+ /**\r
+ * Disconnects from the PDP\r
+ * @param error Reason\r
+ * @throws COPSException\r
+ * @throws IOException\r
+ */\r
+ public void disconnect(COPSError error)\r
+ throws COPSException, IOException {\r
+\r
+ COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
+ COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
+ closeMsg.add(cHdr);\r
+ if (error != null)\r
+ closeMsg.add(error);\r
+\r
+ closeMsg.writeData(_conn.getSocket());\r
+ _conn.close();\r
+ _conn = null;\r
+ }\r
+\r
+ /**\r
+ * Adds a request state to the connection manager.\r
+ * @return The newly created connection manager\r
+ * @throws COPSPepException\r
+ * @throws COPSException\r
+ */\r
+ public COPSPepReqStateMan addRequestState (String handle, COPSPepDataProcess process)\r
+ throws COPSPepException, COPSException {\r
+ if (_conn != null) {\r
+ return _conn.addRequestState(handle, process);\r
+ }\r
+ return null;\r
+ }\r
+\r
+\r
+ /**\r
+ * Queries the connection manager to delete a request state\r
+ * @param man Request state manager\r
+ * @throws COPSPepException\r
+ * @throws COPSException\r
+ */\r
+ public void deleteRequestState (COPSPepReqStateMan man)\r
+ throws COPSPepException, COPSException {\r
+ if (_conn != null)\r
+ _conn.deleteRequestState(man);\r
+ }\r
+\r
+ /**\r
+ * Gets all the request state managers\r
+ * @return A <tt>Hashtable</tt> holding all active request state managers\r
+ */\r
+ public Hashtable getReqStateMans() {\r
+ if (_conn != null)\r
+ return _conn.getReqStateMans();\r
+ return null;\r
+ }\r
+\r
+ /**\r
+ * Establish connection to PDP's IP address\r
+ *\r
+ * <Client-Open> ::= <Common Header>\r
+ * <PEPID>\r
+ * [<ClientSI>]\r
+ * [<LastPDPAddr>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]\r
+ *\r
+ * <Client-Accept> ::= <Common Header>\r
+ * <KA Timer>\r
+ * [<ACCT Timer>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not send [<Integrity>]\r
+ *\r
+ * <Client-Close> ::= <Common Header>\r
+ * <Error>\r
+ * [<PDPRedirAddr>]\r
+ * [<Integrity>]\r
+ *\r
+ * Not send [<PDPRedirAddr>], [<Integrity>]\r
+ *\r
+ * @throws UnknownHostException\r
+ * @throws IOException\r
+ * @throws COPSException\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ private COPSPepConnection processConnection(String psHost, int psPort)\r
+ throws UnknownHostException, IOException, COPSException, COPSPepException {\r
+ // Build OPN\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);\r
+\r
+ COPSPepId pepId = new COPSPepId();\r
+ COPSData d = new COPSData(_pepID);\r
+ pepId.setData(d);\r
+\r
+ COPSClientOpenMsg msg = new COPSClientOpenMsg();\r
+ msg.add(hdr);\r
+ msg.add(pepId);\r
+\r
+ // Create Socket and send OPN\r
+ InetAddress addr = InetAddress.getByName(psHost);\r
+ Socket socket = new Socket(addr,psPort);\r
+ msg.writeData(socket);\r
+\r
+ // Receive the response\r
+ COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);\r
+\r
+ if (recvmsg.getHeader().isAClientAccept()) {\r
+ COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;\r
+\r
+ // Support\r
+ if (cMsg.getIntegrity() != null) {\r
+ throw new COPSPepException("Unsupported object (Integrity)");\r
+ }\r
+\r
+ // Mandatory KATimer\r
+ COPSKATimer kt = cMsg.getKATimer();\r
+ if (kt == null)\r
+ throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");\r
+ short _kaTimeVal = kt.getTimerVal();\r
+\r
+ // ACTimer\r
+ COPSAcctTimer at = cMsg.getAcctTimer();\r
+ short _acctTimer = 0;\r
+ if (at != null)\r
+ _acctTimer = at.getTimerVal();\r
+\r
+ // Create the connection manager\r
+ COPSPepConnection conn = new COPSPepConnection(_clientType, socket);\r
+ conn.setKaTimer(_kaTimeVal);\r
+ conn.setAcctTimer(_acctTimer);\r
+ new Thread(conn).start();\r
+\r
+ return conn;\r
+ } else if (recvmsg.getHeader().isAClientClose()) {\r
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;\r
+ _error = cMsg.getError();\r
+ socket.close();\r
+ return null;\r
+ } else { // messages of other types are not expected\r
+ throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import org.umu.cops.common.COPSDebug;
+import org.umu.cops.stack.COPSClientCloseMsg;
+import org.umu.cops.stack.COPSContext;
+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.COPSHandle;
+import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSKAMsg;
+import org.umu.cops.stack.COPSMsg;
+import org.umu.cops.stack.COPSSyncStateMsg;
+import org.umu.cops.stack.COPSTransceiver;
+
+/**
+ * COPSPepConnection represents a PEP-PDP Connection Manager.
+ * Responsible for processing messages received from PDP.
+ */
+public class COPSPepConnection implements Runnable {
+
+ /** Socket connected to PDP */
+ protected Socket _sock;
+
+ /** Time to wait responses (milliseconds), default is 10 seconds */
+ protected int _responseTime;
+
+ /** COPS Client-type */
+ protected short _clientType;
+
+ /**
+ Accounting timer value (secs)
+ */
+ protected short _acctTimer;
+
+ /**
+ Keep-alive timer value (secs)
+ */
+ protected short _kaTimer;
+
+ /**
+ * Time of the latest keep-alive received
+ */
+ protected Date _lastRecKa;
+
+ /**
+ Opcode of the latest message sent
+ */
+ protected byte _lastmessage;
+
+ /**
+ Maps a COPS Client Handle to a Request State Manager
+ */
+ protected Hashtable _managerMap;
+ // map < String(COPSHandle), COPSPepReqStateMan>;
+
+ /**
+ COPS error returned by PDP
+ */
+ protected COPSError _error;
+
+ /**
+ * Creates a new PEP connection
+ * @param clientType PEP's client-type
+ * @param sock Socket connected to PDP
+ */
+ public COPSPepConnection(short clientType, Socket sock) {
+
+ _clientType = clientType;
+ _sock = sock;
+
+ // Timers
+ _acctTimer = 0;
+ _kaTimer = 0;
+ _responseTime = 10000;
+ _lastmessage = COPSHeader.COPS_OP_CAT;
+
+ _managerMap = new Hashtable(20);
+ }
+
+ /**
+ * Gets the response time
+ * @return Response time value (msecs)
+ */
+ public int getResponseTime() {
+ return _responseTime;
+ }
+
+ /**
+ * Gets the socket connected to the PDP
+ * @return Socket connected to PDP
+ */
+ public Socket getSocket() {
+ return _sock;
+ }
+
+ /**
+ * Gets keep-alive timer
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer () {
+ return _kaTimer;
+ }
+
+ /**
+ * Gets accounting timer
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer () {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets active COPS handles
+ * @return An <tt>Enumeration</tt> holding all active handles
+ */
+ protected Enumeration getHandles() {
+ return _managerMap.keys();
+ }
+
+ /**
+ * Gets all request state managers
+ * @return A <tt>Hashatable</tt> holding all request state managers
+ */
+ protected Hashtable getReqStateMans() {
+ return _managerMap;
+ }
+
+ /**
+ * Checks whether the socket to the PDP is closed or not
+ * @return <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise
+ */
+ public boolean isClosed() {
+ return _sock.isClosed();
+ }
+
+ /**
+ * Closes the socket
+ *
+ * @throws java.io.IOException
+ */
+ protected void close()
+ throws IOException {
+ _sock.close();
+ }
+
+ /**
+ * Gets the opcode of the lastest message sent
+ * @return Message opcode
+ */
+ public byte getLastmessage() {
+ return _lastmessage;
+ }
+
+ /**
+ * Sets response time
+ * @param respTime Response time value (msecs)
+ */
+ public void setResponseTime(int respTime) {
+ _responseTime = respTime;
+ };
+
+ /**
+ * Sets keep-alive timer
+ * @param kaTimer Keep-alive timer value (secs)
+ */
+ public void setKaTimer (short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Sets accounting timer
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAcctTimer (short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Message-processing loop
+ */
+ public void run () {
+ Date _lastSendKa = new Date();
+ Date _lastSendAcc = new Date();
+ _lastRecKa = new Date();
+ try {
+ while (!_sock.isClosed()) {
+ if (_sock.getInputStream().available() != 0) {
+ _lastmessage = processMessage(_sock);
+ _lastRecKa = new Date();
+ }
+
+ // Keep Alive
+ if (_kaTimer > 0) {
+ // Timeout at PDP
+ int _startTime = (int) (_lastRecKa.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((int)(cTime - _startTime) > _kaTimer*1000) {
+ _sock.close();
+ // Notify all Request State Managers
+ notifyNoKAAllReqStateMan();
+ }
+
+ // Send to PEP
+ _startTime = (int) (_lastSendKa.getTime());
+ cTime = (int) (new Date().getTime());
+
+ if ((int)(cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);
+ COPSKAMsg msg = new COPSKAMsg();
+
+ msg.add(hdr);
+
+ COPSTransceiver.sendMsg(msg, _sock);
+ _lastSendKa = new Date();
+ }
+ }
+
+ // Accounting
+ if (_acctTimer > 0) {
+ int _startTime = (int) (_lastSendAcc.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((int)(cTime - _startTime) > ((_acctTimer*3/4)*1000)) {
+ // Notify all Request State Managers
+ notifyAcctAllReqStateMan();
+ _lastSendAcc = new Date();
+ }
+ }
+
+ try {
+ Thread.sleep(500);
+ } catch (Exception e) {};
+ }
+ } catch (Exception e) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
+ }
+
+ // connection closed by server
+ // COPSDebug.out(getClass().getName(),"Connection closed by server");
+ try {
+ _sock.close();
+ } catch (IOException e) {};
+
+ // Notify all Request State Managers
+ try {
+ notifyCloseAllReqStateMan();
+ } catch (COPSPepException e) {};
+ }
+
+ /**
+ * Gets a COPS message from the socket and processes it
+ * @param conn Socket connected to the PDP
+ * @return COPS message type
+ * @throws COPSPepException
+ * @throws COPSException
+ * @throws IOException
+ */
+ protected byte processMessage(Socket conn)
+ throws COPSPepException, COPSException, IOException {
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+
+ if (msg.getHeader().isAClientClose()) {
+ handleClientCloseMsg(conn, msg);
+ return COPSHeader.COPS_OP_CC;
+ } else if (msg.getHeader().isADecision()) {
+ handleDecisionMsg(conn, msg);
+ return COPSHeader.COPS_OP_DEC;
+ } else if (msg.getHeader().isASyncStateReq()) {
+ handleSyncStateReqMsg(conn, msg);
+ return COPSHeader.COPS_OP_SSQ;
+ } else if (msg.getHeader().isAKeepAlive()) {
+ handleKeepAliveMsg(conn, msg);
+ return COPSHeader.COPS_OP_KA;
+ } else {
+ throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");
+ }
+ }
+
+ /**
+ * Handle Client Close Message, close the passed connection
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ */
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
+ _error = cMsg.getError();
+
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
+
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ conn.close();
+ } catch (Exception unae) { };
+ }
+
+ /**
+ * Method getError
+ *
+ * @return a COPSError
+ *
+ */
+ protected COPSError getError() {
+ return _error;
+ }
+
+ /**
+ * Handle Keep Alive Message
+ *
+ * <Keep-Alive> ::= <Common Header>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
+ COPSKAMsg cMsg = (COPSKAMsg) msg;
+
+ // COPSDebug.out(getClass().getName(),"Get KAlive Msg");
+
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ // should we do anything else?? ....
+
+ } catch (Exception unae) { };
+ }
+
+ /**
+ * Method handleDecisionMsg
+ *
+ * <Decision Message> ::= <Common Header: Flag SOLICITED>
+ * <Client Handle>
+ * *(<Decision>) | <Error>
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * [<Named Decision Data: Provisioning>]
+ * <Decision: Flags> ::= <Command-Code> NULLFlag
+ * <Command-Code> ::= NULLDecision | Install | Remove
+ * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>
+ * <Install Decision> ::= *(<PRID> <EPD>)
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)
+ *
+ * Very important, this is actually being treated like this:
+ * <Install Decision> ::= <PRID> | <EPD>
+ * <Remove Decision> ::= <PRID> | <PPRID>
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleDecisionMsg(Socket conn, COPSMsg msg)
+ throws COPSPepException {
+ COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;
+ COPSHandle handle = dMsg.getClientHandle();
+ Hashtable decisions = dMsg.getDecisions();
+
+ for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
+
+ COPSContext context = (COPSContext) e.nextElement();
+ Vector v = (Vector) decisions.get(context);
+
+ Enumeration ee = v.elements();
+ if (ee.hasMoreElements()) {
+ COPSDecision decision = (COPSDecision) ee.nextElement();
+
+ // Get the associated manager
+ COPSPepReqStateMan manager = (COPSPepReqStateMan) _managerMap.get(handle.getId().str());
+ if (manager == null)
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
+
+ // Check message type
+ if (decision.getFlags() == COPSDecision.F_REQSTATE) {
+ if (decision.isRemoveDecision())
+ // Delete Request State
+ manager.processDeleteRequestState(dMsg);
+ else
+ // Open new Request State
+ handleOpenNewRequestStateMsg(conn, handle);
+ } else
+ // Decision
+ manager.processDecision(dMsg);
+ }
+ }
+ }
+
+
+ /**
+ * Method handleOpenNewRequestStateMsg
+ *
+ * @param conn a Socket
+ * @param handle a COPSHandle
+ *
+ */
+ private void handleOpenNewRequestStateMsg(Socket conn, COPSHandle handle)
+ throws COPSPepException {
+
+ COPSPepReqStateMan manager = (COPSPepReqStateMan) _managerMap.get(handle.getId().str());
+ if (manager == null)
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
+
+ manager.processOpenNewRequestState();
+ }
+
+ /**
+ * Method handleSyncStateReqMsg
+ *
+ * <Synchronize State> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleSyncStateReqMsg(Socket conn, COPSMsg msg)
+ throws COPSPepException {
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
+ // COPSHandle handle = cMsg.getClientHandle();
+ // COPSHeader header = cMsg.getHeader();
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
+ "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ COPSPepReqStateMan manager = (COPSPepReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
+ if (manager == null) {
+ COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
+ } else {
+ manager.processSyncStateRequest(cMsg);
+ }
+ }
+
+ /**
+ * Method createRequestState
+ *
+ * @param clientHandle a String
+ * @param process a COPSPepDataProcess
+ *
+ * @return a COPSPepmanager
+ *
+ * @throws COPSException
+ * @throws COPSPepException
+ *
+ */
+ protected COPSPepReqStateMan addRequestState(String clientHandle, COPSPepDataProcess process)
+ throws COPSException, COPSPepException {
+ COPSPepReqStateMan manager = new COPSPepReqStateMan(_clientType,clientHandle);
+ if (_managerMap.get(clientHandle) != null)
+ throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);
+
+ manager.setDataProcess(process);
+ _managerMap.put(clientHandle,manager);
+ manager.initRequestState(_sock);
+ return manager;
+ }
+
+ /**
+ * Method deleteRequestState
+ *
+ * @param manager a COPSPepReqStateMan
+ *
+ * @throws COPSException
+ * @throws COPSPepException
+ *
+ */
+ protected void deleteRequestState(COPSPepReqStateMan manager)
+ throws COPSException, COPSPepException {
+ manager.finalizeRequestState();
+ }
+
+ private void notifyCloseAllReqStateMan()
+ throws COPSPepException {
+ if (_managerMap.size() > 0) {
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
+ String handle = (String) e.nextElement();
+ COPSPepReqStateMan man = (COPSPepReqStateMan) _managerMap.get(handle);
+
+ man.processClosedConnection(_error);
+ }
+ }
+ }
+
+ private void notifyNoKAAllReqStateMan()
+ throws COPSPepException {
+ if (_managerMap.size() > 0) {
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
+ String handle = (String) e.nextElement();
+ COPSPepReqStateMan man = (COPSPepReqStateMan) _managerMap.get(handle);
+
+ man.processNoKAConnection();
+ }
+ }
+ }
+
+ private void notifyAcctAllReqStateMan()
+ throws COPSPepException {
+ if (_managerMap.size() > 0) {
+ for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
+ String handle = (String) e.nextElement();
+ COPSPepReqStateMan man = (COPSPepReqStateMan) _managerMap.get(handle);
+
+ man.processAcctReport();
+ }
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import java.util.Hashtable;
+
+import org.umu.cops.stack.COPSError;
+
+/**
+ * COPSPepDataProcess process policy data and events.
+ *
+ * @version COPSPepDataProcess.java, v 2.00 2004
+ *
+ */
+public abstract class COPSPepDataProcess {
+
+ /**
+ * Establish PDP decisions
+ *
+ * @param removeDecs
+ * @param installDecs
+ * @param errorDecs
+ */
+
+ public abstract void setDecisions(COPSPepReqStateMan man, Hashtable removeDecs, Hashtable installDecs, Hashtable errorDecs);
+
+ /**
+ * If the report is fail, return true
+ *
+ * @return
+ */
+ public abstract boolean isFailReport(COPSPepReqStateMan man);
+
+ /**
+ * Return Report Data
+ *
+ * @return
+ */
+ public abstract Hashtable getReportData(COPSPepReqStateMan man);
+
+ /**
+ * Return Client Data
+ *
+ * @return
+ */
+ public abstract Hashtable getClientData(COPSPepReqStateMan man);
+
+ /**
+ * Return Accouting Data
+ *
+ * @return
+ */
+ public abstract Hashtable getAcctData(COPSPepReqStateMan man);
+
+ /**
+ * Notify the connection closed
+ *
+ * @param error
+ */
+ public abstract void notifyClosedConnection (COPSPepReqStateMan man, COPSError error);
+
+ /**
+ * Notify the KAlive timeout
+ */
+ public abstract void notifyNoKAliveReceived (COPSPepReqStateMan man);
+
+ /**
+ * Process a PDP request to close a Request State
+ *
+ * @param man Request State Manager
+ */
+ public abstract void closeRequestState(COPSPepReqStateMan man);
+
+ /**
+ * Process a PDP request to open a new Request State
+ *
+ * @param man
+ */
+ public abstract void newRequestState(COPSPepReqStateMan man);
+}
+
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpep;\r
+\r
+/**\r
+ * COPS PEP Exception\r
+ *\r
+ * @version COPSPepException.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPepException extends Exception {\r
+\r
+ private int rc;\r
+ final static int GENERAL_ERROR = 0x00000001;\r
+\r
+ public COPSPepException(String s) {\r
+ super(s);\r
+ rc=0;\r
+ }\r
+\r
+ public COPSPepException(String msg, int retCode) {\r
+ super(msg);\r
+ rc = retCode;\r
+ }\r
+\r
+ /**\r
+ * Return error code\r
+ *\r
+ * @return error code\r
+ *\r
+ */\r
+ public int returnCode() {\r
+ return rc;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpep;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import org.umu.cops.stack.COPSClientSI;\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDeleteMsg;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSPrEPD;\r
+import org.umu.cops.stack.COPSPrID;\r
+import org.umu.cops.stack.COPSReason;\r
+import org.umu.cops.stack.COPSReportMsg;\r
+import org.umu.cops.stack.COPSReportType;\r
+import org.umu.cops.stack.COPSReqMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPSPepMsgSender sends COPS messages to PDP.\r
+ *\r
+ * @version COPSPepMsgSender.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPepMsgSender {\r
+\r
+ /**\r
+ * Socket connection to PDP\r
+ */\r
+ protected Socket _sock;\r
+\r
+ /**\r
+ * The client-type identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * The client handle is used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ * Create a COPSPepMsgSender\r
+ *\r
+ * @param clientType client-type\r
+ * @param clientHandle client handle\r
+ * @param sock socket of PDP connection\r
+ */\r
+ public COPSPepMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
+ // COPS Handle\r
+ _handle = clientHandle;\r
+ _clientType = clientType;\r
+\r
+ _sock = sock;\r
+ }\r
+\r
+ /**\r
+ * Return client handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Return client-type\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Send Request to PDP.\r
+ * The PEP establishes a request state client handle for which the\r
+ * remote PDP may maintain state.\r
+ *\r
+ * @param clientSIs a Hashtable\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ public void sendRequest(Hashtable clientSIs)\r
+ throws COPSPepException {\r
+ // Create COPS Message\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType);\r
+ COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0);\r
+\r
+ COPSHandle handle = _handle;\r
+\r
+ // Add the clientSIs\r
+ COPSReqMsg msg = new COPSReqMsg();\r
+ try {\r
+ msg.add(hdr) ;\r
+ msg.add(handle) ;\r
+ msg.add(cntxt) ;\r
+\r
+ if (clientSIs.size() > 0) {\r
+ for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) clientSIs.get(strprid);\r
+\r
+ // (PRID)\r
+ COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+\r
+ // (EPD)\r
+ COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ msg.add(cSi);\r
+ msg.add(cSi2);\r
+ }\r
+ }\r
+\r
+ } catch (COPSException e) {\r
+ throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage());\r
+ }\r
+\r
+ // Send message\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Send Fail Report to PDP.\r
+ * The RPT message is used by the PEP to communicate to the PDP its\r
+ * success or failure in carrying out the PDP's decision, or to report\r
+ * an accounting related change in state.\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ public void sendFailReport(Hashtable clientSIs)\r
+ throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report FAIL\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.FAILURE);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+ if (clientSIs.size() > 0) {\r
+ for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) clientSIs.get(strprid);\r
+\r
+ // (PRID)\r
+ COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+\r
+ // (EPD)\r
+ COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ msg.add(cSi);\r
+ msg.add(cSi2);\r
+ }\r
+ }\r
+\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Send Succes Report to PDP.\r
+ * The RPT message is used by the PEP to communicate to the PDP its\r
+ * success or failure in carrying out the PDP's decision, or to report\r
+ * an accounting related change in state.\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ public void sendSuccessReport(Hashtable clientSIs)\r
+ throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report SUCESS\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.SUCCESS);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+\r
+ if (clientSIs.size() > 0) {\r
+ for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) clientSIs.get(strprid);\r
+\r
+ // (PRID)\r
+ COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+\r
+ // (EPD)\r
+ COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ msg.add(cSi);\r
+ msg.add(cSi2);\r
+ }\r
+ }\r
+\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ public void sendAcctReport(Hashtable clientSIs)\r
+ throws COPSPepException {\r
+ COPSReportMsg msg = new COPSReportMsg();\r
+ // Report SUCESS\r
+ try {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
+ COPSHandle hnd = _handle;\r
+\r
+ COPSReportType report = new COPSReportType(COPSReportType.ACCT);\r
+\r
+ msg.add(hdr);\r
+ msg.add(hnd);\r
+ msg.add(report);\r
+\r
+ if (clientSIs.size() > 0) {\r
+ for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
+ String strprid = (String) e.nextElement();\r
+ String strepd = (String) clientSIs.get(strprid);\r
+\r
+ // (PRID)\r
+ COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrID prid = new COPSPrID();\r
+ prid.setData(new COPSData(strprid));\r
+ cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
+\r
+ // (EPD)\r
+ COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
+ COPSPrEPD epd = new COPSPrEPD();\r
+ epd.setData(new COPSData(strepd));\r
+ cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
+\r
+ msg.add(cSi);\r
+ msg.add(cSi2);\r
+ }\r
+ }\r
+\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Send Sync State Complete to PDP.\r
+ * The Synchronize State Complete is sent by the PEP to the PDP after\r
+ * the PDP sends a synchronize state request to the PEP and the PEP has\r
+ * finished synchronization.\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ public void sendSyncComplete()\r
+ throws COPSPepException {\r
+ // Common Header with the same ClientType as the request\r
+ COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType);\r
+\r
+ // Client Handle with the same clientHandle as the request\r
+ COPSHandle clienthandle = _handle;\r
+\r
+ COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(clienthandle);\r
+ } catch (Exception e) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Send Delete Request to PDP.\r
+ * When sent from the PEP this message indicates to the remote PDP that\r
+ * the state identified by the client handle is no longer\r
+ * available/relevant.\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ public void sendDeleteRequest()\r
+ throws COPSPepException {\r
+ COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType);\r
+ COPSHandle handle = _handle;\r
+\r
+ // *** TODO: send a real reason\r
+ COPSReason reason = new COPSReason((short) 234, (short) 345);\r
+\r
+ COPSDeleteMsg msg = new COPSDeleteMsg();\r
+ try {\r
+ msg.add(hdr);\r
+ msg.add(handle);\r
+ msg.add(reason);\r
+ } catch (COPSException ex) {\r
+ throw new COPSPepException("Error making Msg");\r
+ }\r
+ try {\r
+ msg.writeData(_sock);\r
+ } catch (IOException e) {\r
+ throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2004 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.prpep;\r
+\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.stack.COPSContext;\r
+import org.umu.cops.stack.COPSData;\r
+import org.umu.cops.stack.COPSDecision;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSPrObjBase;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+\r
+/**\r
+ * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)\r
+ * in PEP.\r
+ *\r
+ * The client handle is used to identify a unique request state for a\r
+ * single PEP per client-type. Client handles are chosen by the PEP and\r
+ * are opaque to the PDP. The PDP simply uses the request handle to\r
+ * uniquely identify the request state for a particular Client-Type over\r
+ * a particular TCP connection and generically tie its decisions to a\r
+ * corresponding request. Client handles are initiated in request\r
+ * messages and are then used by subsequent request, decision, and\r
+ * report messages to reference the same request state. When the PEP is\r
+ * ready to remove a local request state, it will issue a delete message\r
+ * to the PDP for the corresponding client handle. A handle MUST be\r
+ * explicitly deleted by the PEP before it can be used by the PEP to\r
+ * identify a new request state. Handles referring to different request\r
+ * states MUST be unique within the context of a particular TCP\r
+ * connection and client-type.\r
+ *\r
+ * @version COPSPepReqStateMan.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSPepReqStateMan {\r
+\r
+ /**\r
+ * Request State created\r
+ */\r
+ public final static short ST_CREATE = 1;\r
+ /**\r
+ * Request sent\r
+ */\r
+ public final static short ST_INIT = 2;\r
+ /**\r
+ * Decisions received\r
+ */\r
+ public final static short ST_DECS = 3;\r
+ /**\r
+ * Report sent\r
+ */\r
+ public final static short ST_REPORT = 4;\r
+ /**\r
+ * Request State finalized\r
+ */\r
+ public final static short ST_FINAL = 5;\r
+ /**\r
+ * New Request State solicited\r
+ */\r
+ public final static short ST_NEW = 6;\r
+ /**\r
+ * Delete Request State solicited\r
+ */\r
+ public final static short ST_DEL = 7;\r
+ /**\r
+ * SYNC Request received\r
+ */\r
+ public final static short ST_SYNC = 8;\r
+ /**\r
+ * SYNC Completed\r
+ */\r
+ public final static short ST_SYNCALL = 9;\r
+ /**\r
+ * Close Connection received\r
+ */\r
+ public final static short ST_CCONN = 10;\r
+ /**\r
+ * KAlive Time out\r
+ */\r
+ public final static short ST_NOKA = 11;\r
+ /**\r
+ * ACCT Time out\r
+ */\r
+ public final static short ST_ACCT = 12;\r
+\r
+ /**\r
+ * The client-type identifies the policy client\r
+ */\r
+ protected short _clientType;\r
+\r
+ /**\r
+ * The client handle is used to uniquely identify a particular\r
+ * PEP's request for a client-type\r
+ */\r
+ protected COPSHandle _handle;\r
+\r
+ /**\r
+ The PolicyDataProcess is used to process policy data in the PEP\r
+ */\r
+ protected COPSPepDataProcess _process;\r
+\r
+ /**\r
+ * State Request State\r
+ */\r
+ protected short _status;\r
+\r
+ /**\r
+ The Msg Sender is used to send COPS messages\r
+ */\r
+ protected COPSPepMsgSender _sender;\r
+\r
+ /**\r
+ * Sync State\r
+ */\r
+ protected boolean _syncState;\r
+\r
+ /**\r
+ * Create a State Request Manager\r
+ *\r
+ * @param clientHandle a Client Handle\r
+ *\r
+ */\r
+ public COPSPepReqStateMan(short clientType, String clientHandle) {\r
+ // COPS Handle\r
+ _handle = new COPSHandle();\r
+ COPSData id = new COPSData(clientHandle);\r
+ _handle.setId(id);\r
+ // client-type\r
+ _clientType = clientType;\r
+ _syncState = true;\r
+ _status = ST_CREATE;\r
+ }\r
+\r
+ /**\r
+ * Return client handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _handle;\r
+ }\r
+\r
+ /**\r
+ * Return client-type\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getClientType() {\r
+ return _clientType;\r
+ }\r
+\r
+ /**\r
+ * Return Request State status\r
+ *\r
+ * @return s short\r
+ */\r
+ public short getStatus() {\r
+ return _status;\r
+ }\r
+\r
+ /**\r
+ * Return the Policy Data Process\r
+ *\r
+ * @return a PolicyConfigure\r
+ *\r
+ */\r
+ public COPSPepDataProcess getDataProcess() {\r
+ return _process;\r
+ }\r
+\r
+ /**\r
+ * Establish the Policy Data Process\r
+ *\r
+ * @param process a PolicyConfigure\r
+ *\r
+ */\r
+ public void setDataProcess(COPSPepDataProcess process) {\r
+ _process = process;\r
+ }\r
+\r
+ /**\r
+ * Init Request State\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void initRequestState(Socket sock)\r
+ throws COPSPepException {\r
+ // Inits an object for sending COPS messages to the PDP\r
+ _sender = new COPSPepMsgSender(_clientType, _handle, sock);\r
+\r
+ // If an object for retrieving PEP features exists,\r
+ // use it for retrieving them\r
+ Hashtable clientSIs;\r
+ if (_process != null)\r
+ clientSIs = _process.getClientData(this);\r
+ else\r
+ clientSIs = null;\r
+\r
+ // Send the request\r
+ _sender.sendRequest(clientSIs);\r
+\r
+ // Initial state\r
+ _status = ST_INIT;\r
+ }\r
+\r
+ /**\r
+ * Finalize Request State\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void finalizeRequestState()\r
+ throws COPSPepException {\r
+ _sender.sendDeleteRequest();\r
+ _status = ST_FINAL;\r
+ }\r
+\r
+ /**\r
+ * Process the message Decision\r
+ *\r
+ * @param dMsg a COPSDecisionMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processDecision(COPSDecisionMsg dMsg)\r
+ throws COPSPepException {\r
+ // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
+\r
+ // COPSHandle handle = dMsg.getClientHandle();\r
+ Hashtable decisions = dMsg.getDecisions();\r
+\r
+ Hashtable removeDecs = new Hashtable(40);\r
+ Hashtable installDecs = new Hashtable(40);\r
+ Hashtable errorDecs = new Hashtable(40);\r
+ for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) decisions.get(context);\r
+ Enumeration ee = v.elements();\r
+ COPSDecision cmddecision = (COPSDecision) ee.nextElement();\r
+\r
+ // cmddecision --> we must check whether it is an error!\r
+\r
+ if (cmddecision.isInstallDecision()) {\r
+ String prid = new String();\r
+ for (; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ prid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ installDecs.put(prid, obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (cmddecision.isRemoveDecision()) {\r
+\r
+ String prid = new String();\r
+ for (; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+\r
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
+ switch (obj.getSNum()) {\r
+ case COPSPrObjBase.PR_PRID:\r
+ prid = obj.getData().str();\r
+ break;\r
+ case COPSPrObjBase.PR_EPD:\r
+ removeDecs.put(prid, obj.getData().str());\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ //** Apply decisions to the configuration\r
+ _process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
+ _status = ST_DECS;\r
+\r
+\r
+ if (_process.isFailReport(this)) {\r
+ // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
+ _sender.sendFailReport(_process.getReportData(this));\r
+ } else {\r
+ // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
+ _sender.sendSuccessReport(_process.getReportData(this));\r
+ }\r
+ _status = ST_REPORT;\r
+\r
+ if (!_syncState) {\r
+ _sender.sendSyncComplete();\r
+ _syncState = true;\r
+ _status = ST_SYNCALL;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Process the message NewRequestState\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processOpenNewRequestState()\r
+ throws COPSPepException {\r
+\r
+ if (_process != null)\r
+ _process.newRequestState(this);\r
+\r
+ _status = ST_NEW;\r
+ }\r
+\r
+ /**\r
+ * Process the message DeleteRequestState\r
+ *\r
+ * @param dMsg a COPSDecisionMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processDeleteRequestState(COPSDecisionMsg dMsg)\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.closeRequestState(this);\r
+\r
+ _status = ST_DEL;\r
+ }\r
+\r
+ /**\r
+ * Process the message SycnStateRequest.\r
+ * The message SycnStateRequest indicates that the remote PDP\r
+ * wishes the client (which appears in the common header)\r
+ * to re-send its state.\r
+ *\r
+ * @param ssMsg a COPSSyncStateMsg\r
+ *\r
+ * @throws COPSPepException\r
+ *\r
+ */\r
+ protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)\r
+ throws COPSPepException {\r
+ _syncState = false;\r
+ // If an object for retrieving PEP features exists,\r
+ // use it for retrieving them\r
+ Hashtable clientSIs;\r
+ if (_process != null)\r
+ clientSIs = _process.getClientData(this);\r
+ else\r
+ clientSIs = null;\r
+\r
+ // Send request\r
+ _sender.sendRequest(clientSIs);\r
+\r
+ _status = ST_SYNC;\r
+ }\r
+\r
+ protected void processClosedConnection(COPSError error)\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyClosedConnection(this, error);\r
+\r
+ _status = ST_CCONN;\r
+ }\r
+\r
+ protected void processNoKAConnection()\r
+ throws COPSPepException {\r
+ if (_process != null)\r
+ _process.notifyNoKAliveReceived(this);\r
+\r
+ _status = ST_NOKA;\r
+ }\r
+\r
+ protected void processAcctReport()\r
+ throws COPSPepException {\r
+\r
+ Hashtable report = new Hashtable();\r
+ if (_process != null)\r
+ report = _process.getAcctData(this);\r
+\r
+ _sender.sendAcctReport(report);\r
+\r
+ _status = ST_ACCT;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Accounting Timer Object\r
+ *\r
+ * @version COPSAcctTimer.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSAcctTimer extends COPSTimer {\r
+\r
+ public COPSAcctTimer() {\r
+ super ((short) 1);\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ACCT_TIMER);\r
+ _objHdr.setCType((byte) 1);\r
+ }\r
+\r
+ ///\r
+ public COPSAcctTimer(short timeVal) {\r
+ super(timeVal);\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ACCT_TIMER);\r
+ _objHdr.setCType((byte) 1);\r
+ }\r
+\r
+ ///\r
+ /**\r
+ * Method isAcctTimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAcctTimer() {\r
+ return true;\r
+ }\r
+\r
+ ///\r
+ protected COPSAcctTimer(byte[] dataPtr) {\r
+ super (dataPtr);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Client Accept Message\r
+ *\r
+ * @version COPSClientAcceptMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSClientAcceptMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSKATimer _kaTimer;\r
+ private COPSAcctTimer _acctTimer;\r
+ private COPSIntegrity _integrity;\r
+\r
+ ///Constructor\r
+ public COPSClientAcceptMsg() {\r
+ _kaTimer = null;\r
+ _acctTimer = null;\r
+ _integrity = null;\r
+ }\r
+\r
+ ///Create object from data\r
+ protected COPSClientAcceptMsg(byte[] data) throws COPSException {\r
+ parse(data);\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_kaTimer == null))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT)\r
+ throw new COPSException ("Error Header (no COPS_OP_CAT)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Timer object to the message\r
+ *\r
+ * @param timer a COPSTimer\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSTimer timer) throws COPSException {\r
+ if (timer.isKATimer()) {\r
+ _kaTimer = (COPSKATimer) timer;\r
+ } else {\r
+ _acctTimer = (COPSAcctTimer) timer;\r
+ }\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Integrity objects\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Method getKATimer\r
+ *\r
+ * @return a COPSKATimer\r
+ *\r
+ */\r
+ public COPSKATimer getKATimer() {\r
+ return _kaTimer;\r
+ };\r
+\r
+ /**\r
+ * Returns true if has a account timer object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasAcctTimer() {\r
+ return (_acctTimer != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasAcctTimer() before calling\r
+ *\r
+ * @return a COPSAcctTimer\r
+ *\r
+ */\r
+ public COPSAcctTimer getAcctTimer() {\r
+ return (_acctTimer);\r
+ }\r
+\r
+ /**\r
+ * Returns true if has a Integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Writes data to a given socket id\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_kaTimer != null) _kaTimer.writeData(id);\r
+ if (_acctTimer != null) _acctTimer.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_KA: {\r
+ _kaTimer = new COPSKATimer(buf);\r
+ _dataStart += _kaTimer.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_ACCT_TIMER: {\r
+ _acctTimer = new COPSAcctTimer(buf);\r
+ _dataStart += _acctTimer.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT)\r
+ throw new COPSException("Error Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_kaTimer != null) len += _kaTimer.getDataLength();\r
+ if (_acctTimer != null) len += _acctTimer.getDataLength();\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_kaTimer != null)\r
+ _kaTimer.dump(os);\r
+\r
+ if (_acctTimer != null)\r
+ _acctTimer.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Client Close Message\r
+ *\r
+ * @version COPSClientCloseMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSClientCloseMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSError _error;\r
+ private COPSIntegrity _integrity;\r
+\r
+\r
+ public COPSClientCloseMsg() {\r
+ _error = null;\r
+ _integrity = null;\r
+ }\r
+\r
+ protected COPSClientCloseMsg(byte[] data) throws COPSException {\r
+ parse (data);\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_error == null))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_CC)\r
+ throw new COPSException ("Error Header (no COPS_OP_CC)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Error object\r
+ *\r
+ * @param error a COPSError\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSError error) throws COPSException {\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_error != null)\r
+ throw new COPSException ("No null Error");\r
+ _error = error;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Integrity objects\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Method getError\r
+ *\r
+ * @return a COPSError\r
+ *\r
+ */\r
+ public COPSError getError() {\r
+ return (_error);\r
+ }\r
+\r
+ /**\r
+ * Returns true If it has integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Write object data to given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_error != null) _error.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_ERROR: {\r
+ _error = new COPSError(buf);\r
+ _dataStart += _error.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_CC)\r
+ throw new COPSException("Error Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ int len = 0;\r
+ if (_error != null) len += _error.getDataLength();\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_error != null)\r
+ _error.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Client Open Message\r
+ *\r
+ * @version COPSClientOpenMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSClientOpenMsg extends COPSMsg {\r
+\r
+ private COPSPepId _pepId;\r
+ private COPSClientSI _clientSI;\r
+ private COPSPdpAddress _pdpAddress;\r
+ private COPSIntegrity _integrity;\r
+\r
+ public COPSClientOpenMsg() {\r
+ _pepId = null;\r
+ _clientSI = null;\r
+ _pdpAddress = null;\r
+ _integrity = null;\r
+ _hdr = null;\r
+ }\r
+\r
+ protected COPSClientOpenMsg(byte[] data) throws COPSException {\r
+ _pepId = null;\r
+ _clientSI = null;\r
+ _pdpAddress = null;\r
+ _integrity = null;\r
+ _hdr = null;\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Method writeData\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null)_hdr.writeData(id);\r
+ if (_pepId != null) _pepId.writeData(id);\r
+ if (_clientSI != null) _clientSI.writeData(id);\r
+ if (_pdpAddress != null) _pdpAddress.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN)\r
+ throw new COPSException ("Error Header (no COPS_OP_OPN)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add PEP Identification Object\r
+ *\r
+ * @param pepid a COPSPepId\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSPepId pepid) throws COPSException {\r
+ if (pepid == null)\r
+ throw new COPSException ("Null COPSPepId");\r
+ if (!pepid.isPepId())\r
+ throw new COPSException ("Error COPSPepId");\r
+ _pepId = pepid;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Client Specific Information Object\r
+ *\r
+ * @param clientSI a COPSClientSI\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSClientSI clientSI) throws COPSException {\r
+ if (clientSI == null)\r
+ throw new COPSException ("Null COPSClientSI");\r
+ if (!clientSI.isClientSI())\r
+ throw new COPSException ("Error COPSClientSI");\r
+ _clientSI = clientSI;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add PDP Address\r
+ *\r
+ * @param pdpAddr a COPSPdpAddress\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSPdpAddress pdpAddr) throws COPSException {\r
+ if (pdpAddr == null)\r
+ throw new COPSException ("Null COPSPdpAddress");\r
+ if (!pdpAddr.isLastPdpAddress())\r
+ throw new COPSException ("Error COPSPdpAddress");\r
+ _pdpAddress = pdpAddr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_pepId == null))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Method getPepId\r
+ *\r
+ * @return a COPSPepId\r
+ *\r
+ */\r
+ public COPSPepId getPepId() {\r
+ return _pepId;\r
+ }\r
+\r
+ /**\r
+ * Method hasClientSI\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasClientSI() {\r
+ return (_clientSI != null);\r
+ }\r
+\r
+ /**\r
+ * Method getClientSI\r
+ *\r
+ * @return a COPSClientSI\r
+ *\r
+ */\r
+ public COPSClientSI getClientSI() {\r
+ return (_clientSI);\r
+ }\r
+\r
+ /**\r
+ * Method hasPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasPdpAddress() {\r
+ return (_pdpAddress != null);\r
+ }\r
+\r
+ /**\r
+ * Method getPdpAddress\r
+ *\r
+ * @return a COPSPdpAddress\r
+ *\r
+ */\r
+ public COPSPdpAddress getPdpAddress() {\r
+ return _pdpAddress;\r
+ }\r
+\r
+ /**\r
+ * Method hasIntegrity\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ }\r
+\r
+ /**\r
+ * Method getIntegrity\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return _integrity;\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ private void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_pepId != null) len += _pepId.getDataLength();\r
+ if (_clientSI != null) len += _clientSI.getDataLength();\r
+ if (_pdpAddress != null) len += _pdpAddress.getDataLength();\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ parseHeader(data);\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_PEPID: {\r
+ _pepId = new COPSPepId(buf);\r
+ _dataStart += _pepId.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_LAST_PDP_ADDR: {\r
+ if (objHdr.getCType() == 1) {\r
+ _pdpAddress = new COPSIpv4LastPdpAddr(buf);\r
+ } else if (objHdr.getCType() == 2) {\r
+ _pdpAddress = new COPSIpv6LastPdpAddr(buf);\r
+ }\r
+ _dataStart += _pdpAddress.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_CSI: {\r
+ _clientSI = new COPSClientSI(buf);\r
+ _dataStart += _clientSI.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN)\r
+ throw new COPSException("Error Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_pepId != null)\r
+ _pepId.dump(os);\r
+\r
+ if (_clientSI != null)\r
+ _clientSI.dump(os);\r
+\r
+ if (_pdpAddress != null)\r
+ _pdpAddress.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Client Specific Information Object\r
+ *\r
+ * @version COPSClientSI.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSClientSI extends COPSObjBase {\r
+ public final static byte CSI_SIGNALED = 1;\r
+ public final static byte CSI_NAMED = 2;\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private COPSData _data;\r
+ private COPSData _padding;\r
+\r
+ ///\r
+ public COPSClientSI(byte type) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_CSI);\r
+ _objHdr.setCType(type);\r
+ }\r
+\r
+ public COPSClientSI(byte cnum, byte ctype) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(cnum);\r
+ _objHdr.setCType(ctype);\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a ClientSI object\r
+ */\r
+ protected COPSClientSI(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ //Get the length of data following the obj header\r
+ short dLen = (short) (_objHdr.getDataLength() - 4);\r
+ COPSData d = new COPSData(dataPtr, 4, dLen);\r
+ setData(d);\r
+ }\r
+\r
+ /**\r
+ * Method setData\r
+ *\r
+ * @param data a COPSData\r
+ *\r
+ */\r
+ public void setData(COPSData data) {\r
+ _data = data;\r
+ if (_data.length() % 4 != 0) {\r
+ int padLen = 4 - _data.length() % 4;\r
+ _padding = getPadding(padLen);\r
+ }\r
+ _objHdr.setDataLength((short) _data.length());\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return (short) (_objHdr.getDataLength() + lpadding);\r
+ }\r
+\r
+ /**\r
+ * Method getData\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getData() {\r
+ return _data;\r
+ };\r
+\r
+ /**\r
+ * Method isClientSI\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isClientSI() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+ COPSUtil.writeData(id, _data.getData(), _data.length());\r
+ if (_padding != null) {\r
+ COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("client-SI: " + _data.str() + "\n").getBytes());\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Context Object\r
+ *\r
+ * @version COPSContext.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSContext extends COPSObjBase {\r
+\r
+ public final static byte IN_ADMIN = 0x01;\r
+ public final static byte RES_ALLOC = 0x02;\r
+ public final static byte OUT = 0x04;\r
+ public final static byte CONFIG = 0x08;\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private short _rType;\r
+ private short _mType;\r
+\r
+ ///\r
+ public COPSContext(short rType, short mType ) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_CONTEXT);\r
+ _objHdr.setCType((byte) 1);\r
+ _rType = rType;\r
+ _mType = mType;\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a Context object\r
+ */\r
+ protected COPSContext(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _rType |= ((short) dataPtr[4]) << 8;\r
+ _rType |= ((short) dataPtr[5]) & 0xFF;\r
+\r
+ _mType |= ((short) dataPtr[6]) << 8;\r
+ _mType |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ _objHdr.setDataLength( (short) 4);\r
+ }\r
+\r
+ /**\r
+ * Write object in network byte order to a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_rType >> 8);\r
+ buf[1] = (byte) _rType;\r
+\r
+ buf[2] = (byte) (_mType >> 8);\r
+ buf[3] = (byte) _mType;\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * Returns the detail description of the request type\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getDescription() {\r
+ String retStr = new String();\r
+ if ((_rType & 0x01) != 0) {\r
+ retStr += (retStr.length() != 0) ? "," : "";\r
+ retStr += "Incoming Message/Admission Control";\r
+ }\r
+ if ((_rType & 0x02) != 0) {\r
+ retStr += (retStr.length() != 0) ? "," : "";\r
+ retStr += "Resource allocation";\r
+ }\r
+ if ((_rType & 0x04) != 0) {\r
+ retStr += (retStr.length() != 0) ? "," : "";\r
+ retStr += "Outgoing message";\r
+ }\r
+ if ((_rType & 0x08) != 0) {\r
+ retStr += (retStr.length() != 0) ? "," : "";\r
+ retStr += "Configuration";\r
+ }\r
+ return retStr;\r
+ }\r
+\r
+ /**\r
+ * Method isIncomingMessage\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIncomingMessage() {\r
+ return (_rType & IN_ADMIN) != 0;\r
+ };\r
+\r
+ /**\r
+ * Method isAdminControl\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAdminControl() {\r
+ return (_rType & IN_ADMIN) != 0;\r
+ };\r
+\r
+ /**\r
+ * Method isResourceAllocationReq\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isResourceAllocationReq() {\r
+ return (_rType & RES_ALLOC) != 0;\r
+ };\r
+\r
+ /**\r
+ * Method isOutgoingMessage\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isOutgoingMessage() {\r
+ return (_rType & OUT) != 0;\r
+ };\r
+\r
+ /**\r
+ * Method isConfigRequest\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isConfigRequest() {\r
+ return (_rType & CONFIG) != 0;\r
+ };\r
+\r
+ /**\r
+ * Method getMessageType\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getMessageType() {\r
+ return (_mType) ;\r
+ };\r
+\r
+ /**\r
+ * Method getRequestType\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getRequestType() {\r
+ return (_rType);\r
+ };\r
+\r
+ /**\r
+ * Method isContext\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isContext() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("context: " + getDescription() + "," + _mType + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Data\r
+ *\r
+ * @version COPSData.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSData {\r
+\r
+ private byte[] _dataBuf;\r
+ private int _dLen;\r
+\r
+ public COPSData() {\r
+ _dataBuf = null;\r
+ _dLen = 0;\r
+ }\r
+\r
+ public COPSData(byte[] dPtr, int offset, int dLen) {\r
+ _dataBuf = new byte[dLen];\r
+ System.arraycopy(dPtr,offset,_dataBuf,0,dLen);\r
+ _dLen = dLen;\r
+ }\r
+\r
+ public COPSData(String data) {\r
+ _dLen = data.getBytes().length;\r
+ _dataBuf = new byte[_dLen];\r
+ System.arraycopy(data.getBytes(),0,_dataBuf,0,_dLen);\r
+ }\r
+\r
+ /**\r
+ * Method getData\r
+ *\r
+ * @return a byte[]\r
+ *\r
+ */\r
+ public byte[] getData() {\r
+ return _dataBuf;\r
+ }\r
+\r
+ /**\r
+ * Method length\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int length() {\r
+ return _dLen;\r
+ }\r
+\r
+ /**\r
+ * Method str\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String str() {\r
+ return new String (_dataBuf);\r
+ }\r
+\r
+ public String toString() {\r
+ return str();\r
+ }\r
+\r
+ public boolean equals(Object obj) {\r
+ return (((COPSData) obj).toString().equals(str()));\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Decision\r
+ *\r
+ * @version COPSDecision.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSDecision extends COPSObjBase {\r
+\r
+ // CType\r
+ public final static byte DEC_DEF = 1;\r
+ public final static byte DEC_STATELESS = 2;\r
+ public final static byte DEC_REPL = 3;\r
+ public final static byte DEC_CSI = 4;\r
+ public final static byte DEC_NAMED = 5;\r
+\r
+ // Command\r
+ public final static byte DEC_NULL = 0;\r
+ public final static byte DEC_INSTALL = 1;\r
+ public final static byte DEC_REMOVE = 2;\r
+\r
+ // Flags\r
+ public final static byte F_REQERROR = 0x1;\r
+ public final static byte F_REQSTATE = 0x2;\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ private COPSData _data;\r
+ private short _cmdCode;\r
+ private short _flags;\r
+ private COPSData _padding;\r
+\r
+ /**\r
+ Constructor to create a Decision object. By default creates\r
+ a decision object which is of fixed length.\r
+ */\r
+ public COPSDecision(byte cType) {\r
+ _objHdr = new COPSObjHeader();\r
+ _cmdCode = 0;\r
+ _flags = 0;\r
+ _objHdr.setCNum(COPSObjHeader.COPS_DEC);\r
+ _objHdr.setCType(cType);\r
+ if (cType == DEC_DEF) _objHdr.setDataLength( (short) 4);\r
+ }\r
+\r
+ public COPSDecision() {\r
+ _objHdr = new COPSObjHeader();\r
+ _cmdCode = 0;\r
+ _flags = 0;\r
+ _objHdr.setCNum(COPSObjHeader.COPS_DEC);\r
+ _objHdr.setCType(DEC_DEF);\r
+ _objHdr.setDataLength( (short) 4);\r
+ }\r
+\r
+ /**\r
+ Initialize the decision object with values from COPSObj header\r
+ */\r
+ protected COPSDecision(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _cmdCode = 0;\r
+ _flags = 0;\r
+ if (_objHdr.getCType() == DEC_DEF) {\r
+ _cmdCode |= ((short) dataPtr[4]) << 8;\r
+ _cmdCode |= ((short) dataPtr[5]) & 0xFF;\r
+ _flags |= ((short) dataPtr[6]) << 8;\r
+ _flags |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ _objHdr.setDataLength((short) 4);\r
+ } else {\r
+ int dLen = _objHdr.getDataLength() - 4;\r
+ COPSData d = new COPSData(dataPtr, 4, dLen);\r
+ setData(d);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method getDataLength\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return ((short) (_objHdr.getDataLength() + lpadding));\r
+ }\r
+\r
+\r
+\r
+ /**\r
+ * Get the associated data if decision object is of cType 2 or higher\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getData() {\r
+ return (_data);\r
+ }\r
+\r
+ /**\r
+ * Set the decision data if decision object is of cType 2 or higher\r
+ *\r
+ * @param data a COPSData\r
+ *\r
+ */\r
+ public void setData(COPSData data) {\r
+ if (data.length() % 4 != 0) {\r
+ int padLen = 4 - data.length() % 4;\r
+ _padding = getPadding(padLen);\r
+ }\r
+ _data = data;\r
+ _objHdr.setDataLength((short) data.length());\r
+ }\r
+\r
+ /**\r
+ * Retruns true if cType = 1\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isFlagSet() {\r
+ return ( _objHdr.getCType() == 1);\r
+ };\r
+\r
+ /**\r
+ * If cType == 1 , get the flags associated\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getFlags() {\r
+ return (_flags);\r
+ };\r
+\r
+ /**\r
+ * If cType == 1 ,set the cmd code\r
+ *\r
+ * @param cCode a byte\r
+ *\r
+ */\r
+ public void setCmdCode(byte cCode) {\r
+ _cmdCode = (short) cCode;\r
+ }\r
+\r
+ /**\r
+ * If cType == 1 ,set the cmd flags\r
+ *\r
+ * @param flags a short\r
+ *\r
+ */\r
+ public void setFlags(short flags) {\r
+ _flags = flags;\r
+ }\r
+\r
+ /**\r
+ * Method isNullDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isNullDecision() {\r
+ return ( _cmdCode == 0);\r
+ };\r
+\r
+ /**\r
+ * Method isInstallDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isInstallDecision() {\r
+ return ( _cmdCode == 1);\r
+ };\r
+\r
+ /**\r
+ * Method isRemoveDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isRemoveDecision() {\r
+ return ( _cmdCode == 2);\r
+ };\r
+\r
+ /**\r
+ * Method getTypeStr\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getTypeStr() {\r
+ switch (_objHdr.getCType()) {\r
+ case DEC_DEF:\r
+ return "Default";\r
+ case DEC_STATELESS:\r
+ return "Stateless data";\r
+ case DEC_REPL:\r
+ return "Replacement data";\r
+ case DEC_CSI:\r
+ return "Client specific decision data";\r
+ case DEC_NAMED:\r
+ return "Named decision data";\r
+ default:\r
+ return "Unknown";\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Method isDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isDecision() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Method isLocalDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isLocalDecision() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Writes data to a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ if (_objHdr.getCType() >= 2) {\r
+ COPSUtil.writeData(id, _data.getData(), _data.length());\r
+ if (_padding != null) {\r
+ COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
+ }\r
+ } else {\r
+ byte[] buf = new byte[4];\r
+ buf[0] = (byte) (_cmdCode >> 8);\r
+ buf[1] = (byte) _cmdCode;\r
+ buf[2] = (byte) (_flags >> 8);\r
+ buf[3] = (byte) _flags;\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+\r
+ if (_objHdr.getCType() == 1) {\r
+ os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes());\r
+ os.write(new String("Command code: " + _cmdCode + "\n").getBytes());\r
+ os.write(new String("Command flags: " + _flags + "\n").getBytes());\r
+ } else {\r
+ os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes());\r
+ os.write(new String("Data: " + _data.str() + "\n").getBytes());\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * COPS Decision Message\r
+ *\r
+ * @version COPSDecisionMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSDecisionMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSHandle _clientHandle;\r
+ private COPSError _error;\r
+ private Hashtable _decisions;\r
+ private COPSIntegrity _integrity;\r
+ private COPSContext _decContext;\r
+ private COPSClientSI _decSI;\r
+\r
+ ///\r
+ public COPSDecisionMsg() {\r
+ _clientHandle = null;\r
+ _error = null;\r
+ _decisions = new Hashtable(20);\r
+ _integrity = null;\r
+ _decContext = null;\r
+ _decSI = null;\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) {\r
+ throw new COPSException("Bad message format");\r
+ }\r
+ }\r
+\r
+ ///\r
+ protected COPSDecisionMsg(byte[] data) throws COPSException {\r
+ _decisions = new Hashtable(20);\r
+ _clientHandle = null;\r
+ _error = null;\r
+ _integrity = null;\r
+ _decContext = null;\r
+ _decSI = null;\r
+\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Parses the data and fills COPSDecisionMsg with its constituents\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_HANDLE: {\r
+ _clientHandle = new COPSHandle(buf);\r
+ _dataStart += _clientHandle.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_CONTEXT: {\r
+ //dec context\r
+ _decContext = new COPSContext(buf);\r
+ _dataStart += _decContext.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_ERROR: {\r
+ _error = new COPSError(buf);\r
+ _dataStart += _error.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_DEC: {\r
+ COPSDecision decs = new COPSDecision(buf);\r
+ _dataStart += decs.getDataLength();\r
+ addDecision(decs, _decContext);\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC)\r
+ throw new COPSException ("Error Header (no COPS_OP_DEC)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add client handle to the message\r
+ *\r
+ * @param handle a COPSHandle\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHandle handle) throws COPSException {\r
+ if (handle == null)\r
+ throw new COPSException ("Null Handle");\r
+ _clientHandle = handle;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add an Error object\r
+ *\r
+ * @param error a COPSError\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSError error) throws COPSException {\r
+ if (_decisions.size() != 0)\r
+ throw new COPSException ("No null decisions");\r
+ if (_error != null)\r
+ throw new COPSException ("No null error");\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("No null integrity");\r
+ _error = error;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add one or more local decision object for a given decision context\r
+ * the context is optional, if null all decision object are tided to\r
+ * message context\r
+ *\r
+ * @param decision a COPSDecision\r
+ * @param context a COPSContext\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void addDecision(COPSDecision decision, COPSContext context) throws COPSException {\r
+ //Either error or decision can be added\r
+ //If error is aleady there assert\r
+ if (_error != null)\r
+ throw new COPSException ("No null error");\r
+\r
+ if (decision.isLocalDecision())\r
+ throw new COPSException ("Is local decision");\r
+\r
+ Vector v = (Vector) _decisions.get(context);\r
+ if (v == null) v = new Vector();\r
+\r
+ if (decision.isFlagSet()) {//Commented out as advised by Felix\r
+ //if (v.size() != 0)\r
+ //{\r
+ //Only one set of decision flags is allowed\r
+ //for each context\r
+ // throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");\r
+ //}\r
+ } else {\r
+ if (v.size() == 0) {\r
+ //The flags decision must precede any other\r
+ //decision message, since the decision is not\r
+ //flags throw exception\r
+ throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");\r
+ }\r
+ }\r
+ v.add(decision);\r
+ _decisions.put(context,v);\r
+\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+ /**\r
+ * Add clientSI object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSClientSI clientSI) throws COPSException {\r
+ if (clientSI == null)\r
+ throw new COPSException ("Null clientSI");\r
+ /*\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ */\r
+ _decSI = clientSI;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_clientHandle != null) _clientHandle.writeData(id);\r
+ if (_error != null) _error.writeData(id);\r
+\r
+ //Display decisions\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ context.writeData(id);\r
+\r
+ for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+ decision.writeData(id);\r
+ }\r
+ }\r
+\r
+ if (_decSI != null) _decSI.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Method getHeader\r
+ *\r
+ * @return a COPSHeader\r
+ *\r
+ */\r
+ public COPSHeader getHeader() {\r
+ return _hdr;\r
+ }\r
+\r
+ /**\r
+ * Method getClientHandle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _clientHandle;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has error object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasError() {\r
+ return (_error != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasError() before calling\r
+ *\r
+ * @return a COPSError\r
+ *\r
+ */\r
+ public COPSError getError() {\r
+ return _error;\r
+ };\r
+\r
+ /**\r
+ * Returns a map of decision for which is an arry of context and vector\r
+ * of associated decision object.\r
+ *\r
+ * @return a Hashtable\r
+ *\r
+ */\r
+ public Hashtable getDecisions() {\r
+ return _decisions;\r
+ };\r
+\r
+ /**\r
+ * Returns true if it has integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return _integrity;\r
+ };\r
+\r
+ /**\r
+ * Method setMsgLength\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_clientHandle != null)\r
+ len += _clientHandle.getDataLength();\r
+ if (_error != null)\r
+ len += _error.getDataLength();\r
+\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ len += context.getDataLength();\r
+\r
+ for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+ len += decision.getDataLength();\r
+ }\r
+ }\r
+ if (_decSI != null) {\r
+ len += _decSI.getDataLength();\r
+ }\r
+ if (_integrity != null) {\r
+ len += _integrity.getDataLength();\r
+ }\r
+\r
+ _hdr.setMsgLength((int) len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_clientHandle != null)\r
+ _clientHandle.dump(os);\r
+ if (_error != null)\r
+ _error.dump(os);\r
+\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ context.dump(os);\r
+\r
+ for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
+ COPSDecision decision = (COPSDecision) ee.nextElement();\r
+ decision.dump(os);\r
+ }\r
+ }\r
+ if (_decSI != null) {\r
+ _decSI.dump(os);\r
+ }\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Delete Message (RFC 2748 pag. 24)\r
+ *\r
+ * When sent from the PEP this message indicates to the remote PDP that\r
+ * the state identified by the client handle is no longer\r
+ * available/relevant. This information will then be used by the remote\r
+ * PDP to initiate the appropriate housekeeping actions. The reason code\r
+ * object is interpreted with respect to the client-type and signifies\r
+ * the reason for the removal.\r
+ *\r
+ * The format of the Delete Request State message is as follows:\r
+ *\r
+ * <Delete Request> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Reason>\r
+ * [<Integrity>]\r
+ *\r
+ *\r
+ * @version COPSDeleteMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSDeleteMsg extends COPSMsg {\r
+ /* COPSHeader coming from base class */\r
+ private COPSHandle _clientHandle;\r
+ private COPSReason _reason;\r
+ private COPSIntegrity _integrity;\r
+\r
+ public COPSDeleteMsg() {\r
+ _clientHandle = null;\r
+ _reason = null;\r
+ _integrity = null;\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSDeleteMsg object\r
+ */\r
+ protected COPSDeleteMsg(byte[] data) throws COPSException {\r
+ _clientHandle = null;\r
+ _reason = null;\r
+ _integrity = null;\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Checks the sanity of COPS message and throw an\r
+ * COPSException when data is bad.\r
+ *\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_clientHandle == null) || (_reason == null))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ)\r
+ throw new COPSException ("Error Header (no COPS_OP_DRQ)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Reason object to the message\r
+ *\r
+ * @param reason a COPSReason\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSReason reason) throws COPSException {\r
+ if (_reason != null)\r
+ throw new COPSException ("No null Reason");\r
+\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("No null Integrity");\r
+ _reason = reason;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Handle object\r
+ *\r
+ * @param handle a COPSHandle\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHandle handle) throws COPSException {\r
+ if (handle == null)\r
+ throw new COPSException ("Null Handle");\r
+ _clientHandle = handle;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Get Client Handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _clientHandle;\r
+ };\r
+\r
+ /**\r
+ * Get Reason\r
+ *\r
+ * @return a COPSReason\r
+ *\r
+ */\r
+ public COPSReason getReason() {\r
+ return _reason;\r
+ };\r
+\r
+ /**\r
+ * Returns true if it has integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ };\r
+\r
+ /**\r
+ * Get Integrity. Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Writes data to given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_clientHandle != null) _clientHandle.writeData(id);\r
+ if (_reason != null) _reason.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_HANDLE: {\r
+ _clientHandle = new COPSHandle(buf);\r
+ _dataStart += _clientHandle.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_REASON_CODE: {\r
+ _reason = new COPSReason(buf);\r
+ _dataStart += _reason.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ)\r
+ throw new COPSException("Error Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_clientHandle != null) len += _clientHandle.getDataLength();\r
+ if (_reason != null) len += _reason.getDataLength();\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_clientHandle != null)\r
+ _clientHandle.dump(os);\r
+\r
+ if (_reason != null)\r
+ _reason.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Error\r
+ *\r
+ * @version COPSError.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSError extends COPSObjBase {\r
+\r
+ public final static byte COPS_ERR_BAD_HANDLE = 1;\r
+ public final static byte COPS_ERR_BAD_HANDLE_REF = 2;\r
+ public final static byte COPS_ERR_BAD_MSG_FORMAT = 3;\r
+ public final static byte COPS_ERR_FAIL_PROCESS = 4;\r
+ public final static byte COPS_ERR_MISSING_INFO = 5;\r
+ public final static byte COPS_ERR_UNSUPPORTED_CLIENT_TYPE = 6;\r
+ public final static byte COPS_ERR_MANDATORY_OBJECT_MISSING = 7;\r
+ public final static byte COPS_ERR_CLIENT_FAILURE = 8;\r
+ public final static byte COPS_ERR_COMM_FAILURE = 9;\r
+ public final static byte COPS_ERR_UNKNOWN = 10;\r
+ public final static byte COPS_ERR_SHUTTING_DOWN = 11;\r
+ public final static byte COPS_ERR_PDP_REDIRECT = 12;\r
+ public final static byte COPS_ERR_UNKNOWN_OBJECT = 13;\r
+ public final static byte COPS_ERR_AUTH_FAILURE = 14;\r
+ public final static byte COPS_ERR_AUTH_REQUIRED = 15;\r
+ public final static byte COPS_ERR_MA = 16;\r
+\r
+ private final static String G_errmsgArray[] = {\r
+ "Unknown.",\r
+ "Bad handle.",\r
+ "Invalid handle reference.",\r
+ "Bad message format (Malformed message).",\r
+ "Unable to process.",\r
+ "Mandatory client-specific info missing.",\r
+ "Unsupported client-type",\r
+ "Mandatory COPS object missing.",\r
+ "Client failure.",\r
+ "Communication failure.",\r
+ "Unknown.",\r
+ "Shutting down.",\r
+ "Redirect to preferred server.",\r
+ "Unknown COPS object",\r
+ "Authentication failure.",\r
+ "Authentication required.",\r
+ };\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private short _errCode;\r
+ private short _errSubCode;\r
+\r
+ public COPSError(short errCode, short subCode) {\r
+ _objHdr = new COPSObjHeader();\r
+ _errCode = errCode;\r
+ _errSubCode = subCode;\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ERROR);\r
+ _objHdr.setCType((byte) 1);\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ protected COPSError(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _errCode |= ((short) dataPtr[4]) << 8;\r
+ _errCode |= ((short) dataPtr[5]) & 0xFF;\r
+ _errSubCode |= ((short) dataPtr[6]) << 8;\r
+ _errSubCode |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ // _objHdr.setDataLength(sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ public short getErrCode() {\r
+ return _errCode;\r
+ }\r
+ \r
+ public short getErrSubCode() {\r
+ return _errSubCode;\r
+ }\r
+ /**\r
+ * Returns size in number of octects\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return (_objHdr.getDataLength());\r
+ };\r
+\r
+ /**\r
+ * Method getDescription\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getDescription() {\r
+ String errStr1;\r
+ String errStr2;\r
+\r
+ ///Get the details from the error code\r
+ errStr1 = G_errmsgArray[_errCode];\r
+ //TODO - define error sub-codes\r
+ errStr2 = "";\r
+ return (errStr1 + ":" + errStr2);\r
+ }\r
+\r
+ /**\r
+ * Method isError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isError() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Writes object to given network socket in network byte order\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_errCode >> 8);\r
+ buf[1] = (byte) _errCode;\r
+ buf[2] = (byte) (_errSubCode >> 8);\r
+ buf[3] = (byte) _errSubCode;\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Error Code: " + _errCode + "\n").getBytes());\r
+ os.write(new String("Error Sub Code: " + _errSubCode + "\n").getBytes());\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+/**\r
+ * COPS Exception\r
+ *\r
+ * @version COPSException.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSException extends Exception {\r
+\r
+ private int rc;\r
+ final static int GENERAL_ERROR = 0x00000001;\r
+\r
+ public COPSException(String s) {\r
+ super(s);\r
+ rc=0;\r
+ }\r
+\r
+ public COPSException(String msg, int retCode) {\r
+ super(msg);\r
+ rc = retCode;\r
+ }\r
+\r
+ /**\r
+ * Method returnCode\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int returnCode() {\r
+ return rc;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Handle Object (RFC 2748 pag. 9)\r
+ *\r
+ * The Handle Object encapsulates a unique value that identifies an\r
+ * installed state. This identification is used by most COPS operations.\r
+ *\r
+ * C-Num = 1\r
+ *\r
+ * C-Type = 1, Client Handle.\r
+ *\r
+ * Variable-length field, no implied format other than it is unique from\r
+ * other client handles from the same PEP (a.k.a. COPS TCP connection)\r
+ * for a particular client-type. It is always initially chosen by the\r
+ * PEP and then deleted by the PEP when no longer applicable. The client\r
+ * handle is used to refer to a request state initiated by a particular\r
+ * PEP and installed at the PDP for a client-type. A PEP will specify a\r
+ * client handle in its Request messages, Report messages and Delete\r
+ * messages sent to the PDP. In all cases, <b>the client handle is used to\r
+ * uniquely identify a particular PEP's request for a client-type</b>.\r
+ *\r
+ * The client handle value is set by the PEP and is opaque to the PDP.\r
+ * The PDP simply performs a byte-wise comparison on the value in this\r
+ * object with respect to the handle object values of other currently\r
+ * installed requests.\r
+ *\r
+ * @version COPSHandle.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSHandle extends COPSObjBase {\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private COPSData _id;\r
+ private COPSData _padding;\r
+\r
+ public COPSHandle() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_HANDLE);\r
+ _objHdr.setCType((byte) 1);\r
+ _padding = new COPSData();\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSHandle object\r
+ */\r
+ protected COPSHandle(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ //Get the length of data following the obj header\r
+ int dLen = _objHdr.getDataLength() - 4;\r
+ COPSData d = new COPSData (dataPtr, 4, dLen);\r
+ setId(d);\r
+ }\r
+\r
+ /**\r
+ * Set handle value\r
+ *\r
+ * @param id a COPSData\r
+ *\r
+ */\r
+ public void setId(COPSData id) {\r
+ _id = id;\r
+ if ((id.length() % 4) != 0) {\r
+ int padLen = 4 - (_id.length() % 4);\r
+ _padding = getPadding(padLen);\r
+ }\r
+ _objHdr.setDataLength((short) _id.length());\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return ((short) (_objHdr.getDataLength() + lpadding));\r
+ }\r
+\r
+ /**\r
+ * Get handle value\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getId() {\r
+ return _id;\r
+ }\r
+\r
+ /**\r
+ * Always return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isClientHandle() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write data in network byte order on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ COPSUtil.writeData(id, _id.getData(), _id.length());\r
+ if (_padding != null) {\r
+ COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("client-handle: " + _id.str() + "\n").getBytes());\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Header (RFC 2748 pag. 6)\r
+ *\r
+ * Each COPS message consists of the COPS header followed by a number of\r
+ * typed objects.\r
+ *\r
+ * 0 1 2 3\r
+ * +--------------+--------------+--------------+--------------+\r
+ * |Version| Flags| Op Code | Client-type |\r
+ * +--------------+--------------+--------------+--------------+\r
+ * | Message Length |\r
+ * +--------------+--------------+--------------+--------------+\r
+ *\r
+ * Global note: //// implies field is reserved, set to 0.\r
+ *\r
+ * The fields in the header are:\r
+ * Version: 4 bits\r
+ * COPS version number. Current version is 1.\r
+ *\r
+ * Flags: 4 bits\r
+ * Defined flag values (all other flags MUST be set to 0):\r
+ * 0x1 Solicited Message Flag Bit\r
+ * This flag is set when the message is solicited by\r
+ * another COPS message. This flag is NOT to be set\r
+ * (value=0) unless otherwise specified.\r
+ *\r
+ * Op Code: 8 bits\r
+ * The COPS operations:\r
+ * 1 = Request (REQ)\r
+ * 2 = Decision (DEC)\r
+ * 3 = Report State (RPT)\r
+ * 4 = Delete Request State (DRQ)\r
+ * 5 = Synchronize State Req (SSQ)\r
+ * 6 = Client-Open (OPN)\r
+ * 7 = Client-Accept (CAT)\r
+ * 8 = Client-Close (CC)\r
+ * 9 = Keep-Alive (KA)\r
+ * 10= Synchronize Complete (SSC)\r
+ *\r
+ * Client-type: 16 bits\r
+ *\r
+ *\r
+ * @version COPSHeader.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSHeader {\r
+\r
+ public final static byte COPS_OP_REQ = 1;\r
+ public final static byte COPS_OP_DEC = 2;\r
+ public final static byte COPS_OP_RPT = 3;\r
+ public final static byte COPS_OP_DRQ = 4;\r
+ public final static byte COPS_OP_SSQ = 5;\r
+ public final static byte COPS_OP_OPN = 6;\r
+ public final static byte COPS_OP_CAT = 7;\r
+ public final static byte COPS_OP_CC = 8;\r
+ public final static byte COPS_OP_KA = 9;\r
+ public final static byte COPS_OP_SSC = 10;\r
+\r
+ public final static byte COPS_FLAG_NULL = 0;\r
+ public final static byte COPS_FLAG_SOLICITED = 1;\r
+\r
+ private byte _versionNflg;\r
+ private byte _opCode;\r
+ private short _cType;\r
+ private int _msgLength;\r
+\r
+ public COPSHeader() {\r
+ _versionNflg = 0x10;\r
+ _opCode = 0;\r
+ _cType = 0;\r
+ _msgLength = 0;\r
+ }\r
+\r
+ public COPSHeader(byte opCode, short clientType) {\r
+ _versionNflg = 0x10;\r
+ _opCode = opCode;\r
+ _cType = clientType;\r
+ _msgLength = 0;\r
+ if (isAKeepAlive()) _cType = 0;\r
+ }\r
+\r
+ public COPSHeader(byte opCode) {\r
+ _versionNflg = 0x10;\r
+ _opCode = opCode;\r
+ _cType = 0;\r
+ _msgLength = 0;\r
+ if (isAKeepAlive()) _cType = 0;\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSHeader object\r
+ */\r
+ public COPSHeader(byte[] buf) {\r
+ _versionNflg = (byte) buf[0];\r
+ _opCode = (byte) buf[1];\r
+ _cType |= ((short) buf[2]) << 8;\r
+ _cType |= ((short) buf[3]) & 0xFF;\r
+ _msgLength |= ((short) buf[4]) << 24;\r
+ _msgLength |= ((short) buf[5]) << 16;\r
+ _msgLength |= ((short) buf[6]) << 8;\r
+ _msgLength |= ((short) buf[7]) & 0xFF;\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message Request, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isARequest() {\r
+ return (_opCode == COPS_OP_REQ);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message Decision, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isADecision() {\r
+ return (_opCode == COPS_OP_DEC);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message Report, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAReport() {\r
+ return (_opCode == COPS_OP_RPT);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message DeleteRequest, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isADeleteReq() {\r
+ return (_opCode == COPS_OP_DRQ);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message SyncStateReq, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isASyncStateReq() {\r
+ return (_opCode == COPS_OP_SSQ);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message ClientOpen, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAClientOpen() {\r
+ return (_opCode == COPS_OP_OPN);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message ClientAccept, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAClientAccept() {\r
+ return (_opCode == COPS_OP_CAT);\r
+ }\r
+\r
+ /**\r
+ * If operation code corresponds with a message ClientClose, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAClientClose() {\r
+ return (_opCode == COPS_OP_CC);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message KeepAlive, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAKeepAlive() {\r
+ return (_opCode == COPS_OP_KA);\r
+ }\r
+\r
+ /**\r
+ * If the operation code corresponds with a message SSC, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isASyncComplete() {\r
+ return (_opCode == COPS_OP_SSC);\r
+ }\r
+\r
+ /**\r
+ * Get message length\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getMsgLength() {\r
+ return _msgLength;\r
+ }\r
+\r
+ /**\r
+ * Get header length\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getHdrLength() {\r
+ // return (sizeof(u_int32_t) * 2);\r
+ return ( 8 );\r
+ }\r
+\r
+ /**\r
+ * Get Operation Code\r
+ *\r
+ * @return a byte\r
+ *\r
+ */\r
+ public byte getOpCode() {\r
+ return _opCode;\r
+ }\r
+\r
+ /**\r
+ * Set the solicitation flag\r
+ *\r
+ * @param flg a byte\r
+ *\r
+ */\r
+ public void setFlag(byte flg) {\r
+ _versionNflg &= 0x10;\r
+ _versionNflg |= flg;\r
+ }\r
+\r
+ /**\r
+ * Returns the flags field\r
+ * @return aByte Flags field in header\r
+ */\r
+ public byte getFlags() { //OJO\r
+ return (byte) (_versionNflg & 0x0f);\r
+ }\r
+\r
+ /**\r
+ * Set the client-type\r
+ *\r
+ * @param cType a short\r
+ *\r
+ */\r
+ public void setClientType(short cType) {\r
+ _cType = cType;\r
+ };\r
+\r
+ /**\r
+ * Set the message length\r
+ *\r
+ * @param len an int\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void setMsgLength(int len) throws COPSException {\r
+ if ((len % 4) != 0)\r
+ throw new COPSException ("Message is not aligned on 32 bit intervals");\r
+ _msgLength = len + 8;\r
+ }\r
+\r
+ /**\r
+ * Get client-type\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getClientType() {\r
+ return (_cType);\r
+ };\r
+\r
+ /**\r
+ * Always return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isCOPSHeader() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Writes object to given network socket in network byte order\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ byte buf[] = new byte[8];\r
+\r
+ buf[0] = (byte) _versionNflg;\r
+ buf[1] = (byte) _opCode;\r
+ buf[2] = (byte) (_cType >> 8);\r
+ buf[3] = (byte) _cType;\r
+ buf[4] = (byte) (_msgLength >> 24);\r
+ buf[5] = (byte) (_msgLength >> 16);\r
+ buf[6] = (byte) (_msgLength >> 8);\r
+ buf[7] = (byte) _msgLength;\r
+\r
+ COPSUtil.writeData(id, buf, 8);\r
+ }\r
+\r
+ /**\r
+ * Get an object textual description\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String toString() {\r
+ String str = new String();\r
+\r
+ str += "**MSG HEADER** \n";\r
+ str += "Version: " + (_versionNflg >> 4) + "\n";\r
+ str += "Flags: " + (_versionNflg & 0x01) + "\n";\r
+ str += "OpCode: " + _opCode + "\n";\r
+ str += "Client-type: " + _cType + "\n";\r
+ str += "Message-length(bytes): " + _msgLength + "\n";\r
+ return str;\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ os.write(new String("**MSG HEADER**" + "\n").getBytes());\r
+ os.write(new String("Version: " + (_versionNflg >> 4) + "\n").getBytes());\r
+ os.write(new String("Flags: " + (_versionNflg & 0x01) + "\n").getBytes());\r
+ os.write(new String("OpCode: " + _opCode + "\n").getBytes());\r
+ os.write(new String("Client-type: " + _cType + "\n").getBytes());\r
+ os.write(new String("Message-length(bytes): " + _msgLength + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Integrity Object\r
+ *\r
+ * @version COPSIntegrity.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIntegrity extends COPSObjBase {\r
+ private COPSObjHeader _objHdr;\r
+ private int _keyId;\r
+ private int _seqNum;\r
+ private COPSData _keyDigest;\r
+ private COPSData _padding;\r
+\r
+ public COPSIntegrity() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_MSG_INTEGRITY);\r
+ _objHdr.setCType((byte) 1);\r
+ _keyId = 0;\r
+ _seqNum = 0;\r
+ }\r
+\r
+ public COPSIntegrity(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _keyId |= ((short) dataPtr[4]) << 24;\r
+ _keyId |= ((short) dataPtr[5]) << 16;\r
+ _keyId |= ((short) dataPtr[6]) << 8;\r
+ _keyId |= ((short) dataPtr[7]) & 0xFF;\r
+ _seqNum |= ((short) dataPtr[8]) << 24;\r
+ _seqNum |= ((short) dataPtr[9]) << 16;\r
+ _seqNum |= ((short) dataPtr[10]) << 8;\r
+ _seqNum |= ((short) dataPtr[11]) & 0xFF;\r
+\r
+ int dLen = _objHdr.getDataLength() - 12;\r
+ COPSData d = new COPSData(dataPtr, 12, dLen);\r
+ setKeyDigest(d);\r
+ }\r
+\r
+ /**\r
+ * Method setKeyId\r
+ *\r
+ * @param keyId an int\r
+ *\r
+ */\r
+ public void setKeyId(int keyId) {\r
+ _keyId = keyId;\r
+ };\r
+\r
+ /**\r
+ * Method setSeqNum\r
+ *\r
+ * @param seqNum an int\r
+ *\r
+ */\r
+ public void setSeqNum(int seqNum) {\r
+ _seqNum = seqNum;\r
+ };\r
+\r
+ /**\r
+ * Method setKeyDigest\r
+ *\r
+ * @param keyDigest a COPSData\r
+ *\r
+ */\r
+ public void setKeyDigest(COPSData keyDigest) {\r
+ _keyDigest = keyDigest;\r
+ if (_keyDigest.length() % 4 != 0) {\r
+ int padLen = 4 - _keyDigest.length() % 4;\r
+ _padding = getPadding(padLen);\r
+ }\r
+ // _objHdr.setDataLength(sizeof(u_int32_t)\r
+ // + sizeof(u_int32_t) + _keyDigest.length());\r
+ _objHdr.setDataLength((short) (8 + _keyDigest.length()));\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return ((short) (_objHdr.getDataLength() + lpadding));\r
+ }\r
+\r
+ /**\r
+ * Method getKeyId\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getKeyId() {\r
+ return _keyId;\r
+ };\r
+\r
+ /**\r
+ * Method getSeqNum\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getSeqNum() {\r
+ return _seqNum;\r
+ };\r
+\r
+ /**\r
+ * Method getKeyDigest\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getKeyDigest() {\r
+ return _keyDigest;\r
+ };\r
+\r
+ /**\r
+ * Method isMessageIntegrity\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isMessageIntegrity() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[8];\r
+ buf[0] = (byte) (_keyId >> 24);\r
+ buf[1] = (byte) (_keyId >> 16);\r
+ buf[2] = (byte) (_keyId >> 8);\r
+ buf[3] = (byte) _keyId;\r
+ buf[4] = (byte) (_seqNum >> 24);\r
+ buf[5] = (byte) (_seqNum >> 16);\r
+ buf[6] = (byte) (_seqNum >> 8);\r
+ buf[7] = (byte) _seqNum;\r
+ COPSUtil.writeData(id, buf, 8);\r
+\r
+ COPSUtil.writeData(id, _keyDigest.getData(), _keyDigest.length());\r
+ if (_padding != null) {\r
+ COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Key Id: " + _keyId + "\n").getBytes());\r
+ os.write(new String("Sequence: " + _seqNum + "\n").getBytes());\r
+ os.write(new String("Key digest: " + _keyDigest.str() + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Interface\r
+ *\r
+ * @version COPSInterface.java, v 1.00 2003\r
+ *\r
+ */\r
+abstract class COPSInterface extends COPSObjBase {\r
+ /**\r
+ * Method isIpv4Address\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ protected boolean isIpv4Address() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isIpv6Address\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ protected boolean isIpv6Address() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isInInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ protected boolean isInInterface() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isOutInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ protected boolean isOutInterface() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ protected boolean isInterface() {\r
+ return true;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv4 Address\r
+ *\r
+ * @version COPSIpv4Address.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv4Address {\r
+\r
+ private byte[] _addr;\r
+\r
+ public COPSIpv4Address() {\r
+ _addr = new byte[4];\r
+ }\r
+\r
+ public COPSIpv4Address(String hostName) throws UnknownHostException {\r
+ setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr = InetAddress.getByName(hostName).getAddress();\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return InetAddress.getByAddress(_addr).getHostName();\r
+ }\r
+\r
+ /**\r
+ * Method getIpAddress\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getIpAddress() {\r
+ int ipaddr = 0;\r
+\r
+ ipaddr |= ((int) _addr[0]) << 24;\r
+ ipaddr |= ((int) _addr[1]) << 16;\r
+ ipaddr |= ((int) _addr[2]) << 8;\r
+ ipaddr |= ((int) _addr[3]) & 0xFF;\r
+\r
+ return ipaddr;\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param dataPtr a byte[]\r
+ *\r
+ */\r
+ public void parse(byte[] dataPtr) {\r
+ new ByteArrayInputStream(dataPtr).read(_addr,0,4);\r
+ }\r
+\r
+ /**\r
+ * Method getDataLength\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return (4);\r
+ }\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ COPSUtil.writeData(id, _addr, 4);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS IPv4 Input Address\r
+ *\r
+ * @version COPSIpv4InInterface.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv4InInterface extends COPSIpv4Interface {\r
+ public COPSIpv4InInterface() {\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ININTF);\r
+ }\r
+\r
+ public COPSIpv4InInterface(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method className\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String className() {\r
+ return "COPSIpv4InInterface";\r
+ }\r
+\r
+ /**\r
+ * Method isInInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isInInterface() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv4 Interface\r
+ *\r
+ * @version COPSIpv4Interface.java, v 1.00 2003\r
+ *\r
+ */\r
+public abstract class COPSIpv4Interface extends COPSInterface {\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ private COPSIpv4Address _addr;\r
+ private int _ifindex;\r
+\r
+\r
+ /**\r
+ * Method isIpv4Address\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv4Address() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr.setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return (_addr.getIpName());\r
+ }\r
+\r
+ /**\r
+ * Method getIpAddress\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getIpAddress() {\r
+ return (_addr.getIpAddress());\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ protected COPSIpv4Interface() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCType((byte) 1);\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ protected COPSIpv4Interface(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ byte[] buf = new byte[4];\r
+ System.arraycopy(dataPtr,4,buf,0,4);\r
+\r
+ _addr.parse(buf);\r
+\r
+ _ifindex |= ((int) dataPtr[8]) << 24;\r
+ _ifindex |= ((int) dataPtr[9]) << 16;\r
+ _ifindex |= ((int) dataPtr[10]) << 8;\r
+ _ifindex |= ((int) dataPtr[11]) & 0xFF;\r
+\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+/**\r
+ * COPS IPv4 Last PDP Address\r
+ *\r
+ * @version COPSIpv4LastPdpAddr.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv4LastPdpAddr extends COPSIpv4PdpAddress {\r
+\r
+ public COPSIpv4LastPdpAddr() {\r
+ super();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_LAST_PDP_ADDR);\r
+ }\r
+\r
+ public COPSIpv4LastPdpAddr(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method isLastPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isLastPdpAddress() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Ipv4PdpAddress" + "\n").getBytes());\r
+ os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes());\r
+ os.write(new String("Port: " + _tcpPort + "\n").getBytes());\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS IPv4 Output Interface\r
+ *\r
+ * @version COPSIpv4OutInterface.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv4OutInterface extends COPSIpv4Interface {\r
+ public COPSIpv4OutInterface() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ININTF);\r
+ }\r
+\r
+ public COPSIpv4OutInterface(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method className\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String className() {\r
+ return "COPSIpv4OutInterface";\r
+ }\r
+\r
+ /**\r
+ * Method isInInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isInInterface() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ }\r
+\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv4 PDP Address\r
+ *\r
+ * @version COPSIpv4PdpAddress.java, v 1.00 2003\r
+ *\r
+ */\r
+abstract public class COPSIpv4PdpAddress extends COPSPdpAddress {\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ protected COPSIpv4Address _addr;\r
+ private short _reserved;\r
+ protected short _tcpPort;\r
+\r
+ protected COPSIpv4PdpAddress() {\r
+ _addr = new COPSIpv4Address();\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCType((byte) 1);\r
+ // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ protected COPSIpv4PdpAddress(byte[] dataPtr) {\r
+ _addr = new COPSIpv4Address();\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ byte[] buf = new byte[4];\r
+ System.arraycopy(dataPtr,2,buf,0,4);\r
+ _addr.parse(buf);\r
+\r
+ _reserved |= ((short) dataPtr[8]) << 8;\r
+ _reserved |= ((short) dataPtr[9]) & 0xFF;\r
+ _tcpPort |= ((short) dataPtr[10]) << 8;\r
+ _tcpPort |= ((short) dataPtr[11]) & 0xFF;\r
+\r
+ // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr.setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method setTcpPort\r
+ *\r
+ * @param port a short\r
+ *\r
+ */\r
+ public void setTcpPort(short port) {\r
+ _tcpPort = port;\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return (_addr.getIpName());\r
+ }\r
+\r
+ /**\r
+ * Method getTcpPort\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ short getTcpPort() {\r
+ return _tcpPort;\r
+ };\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * Method isIpv6PdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv6PdpAddress() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ //\r
+ _objHdr.writeData(id);\r
+ _addr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+ buf[0] = (byte) (_reserved & 0xFF);\r
+ buf[1] = (byte) (_reserved << 8);\r
+ buf[2] = (byte) (_tcpPort & 0xFF);\r
+ buf[3] = (byte) (_tcpPort << 8);\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.IOException;\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv6 Address\r
+ *\r
+ * @version COPSIpv6Address.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv6Address {\r
+\r
+ private byte[] _addr;\r
+\r
+ public COPSIpv6Address() {\r
+ _addr = new byte[16];\r
+ }\r
+\r
+ public COPSIpv6Address(String hostName) throws UnknownHostException {\r
+ setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr = InetAddress.getByName(hostName).getAddress();\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return InetAddress.getByAddress(_addr).getHostName();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param dataPtr a byte[]\r
+ *\r
+ */\r
+ public void parse(byte[] dataPtr) {\r
+ new ByteArrayInputStream(dataPtr).read(_addr,0,16);\r
+ }\r
+\r
+ /**\r
+ * Method getDataLength\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return (16);\r
+ }\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ COPSUtil.writeData(id, _addr, 16);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS IPv6 Input Interface\r
+ *\r
+ * @version COPSIpv6InInterface.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv6InInterface extends COPSIpv6Interface {\r
+ public COPSIpv6InInterface() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ININTF);\r
+ }\r
+\r
+ public COPSIpv6InInterface(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method className\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String className() {\r
+ return "COPSIpv6InInterface";\r
+ }\r
+\r
+ /**\r
+ * Method isInInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isInInterface() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv6 Interface\r
+ *\r
+ * @version COPSIpv6Interface.java, v 1.00 2003\r
+ *\r
+ */\r
+public abstract class COPSIpv6Interface extends COPSInterface {\r
+\r
+ /**\r
+ * Method isIpv6Address\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv6Address() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr.setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return (_addr.getIpName());\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ protected COPSIpv6Interface() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCType((byte) 2);\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ protected COPSIpv6Interface(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ byte[] buf = new byte[4];\r
+ System.arraycopy(dataPtr,4,buf,0,16);\r
+\r
+ _addr.parse(buf);\r
+\r
+ _ifindex |= ((int) dataPtr[20]) << 24;\r
+ _ifindex |= ((int) dataPtr[21]) << 16;\r
+ _ifindex |= ((int) dataPtr[22]) << 8;\r
+ _ifindex |= ((int) dataPtr[23]) & 0xFF;\r
+\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ private COPSIpv6Address _addr;\r
+ private int _ifindex;\r
+}\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+/**\r
+ * COPS IPv6 Last PDP Address\r
+ *\r
+ * @version COPSIpv6LastPdpAddr.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv6LastPdpAddr extends COPSIpv6PdpAddress {\r
+\r
+ public COPSIpv6LastPdpAddr() {\r
+ super();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_LAST_PDP_ADDR);\r
+ }\r
+\r
+ public COPSIpv6LastPdpAddr(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method isLastPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isLastPdpAddress() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Ipv6PdpAddress" + "\n").getBytes());\r
+ os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes());\r
+ os.write(new String("Port: " + _tcpPort + "\n").getBytes());\r
+ }\r
+};\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS IPv6 Output Interface\r
+ *\r
+ * @version COPSIpv6OutInterface.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSIpv6OutInterface extends COPSIpv6Interface {\r
+ public COPSIpv6OutInterface() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_ININTF);\r
+ }\r
+\r
+ public COPSIpv6OutInterface(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method className\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String className() {\r
+ return "COPSIpv6OutInterface";\r
+ }\r
+\r
+ /**\r
+ * Method isInInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isInInterface() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * COPS IPv6 PDP Address\r
+ *\r
+ * @version COPSIpv6PdpAddress.java, v 1.00 2003\r
+ *\r
+ */\r
+abstract public class COPSIpv6PdpAddress extends COPSPdpAddress {\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ protected COPSIpv6Address _addr;\r
+ private short _reserved;\r
+ protected short _tcpPort;\r
+\r
+ protected COPSIpv6PdpAddress() {\r
+ _addr = new COPSIpv6Address();\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCType((byte) 2);\r
+ // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ protected COPSIpv6PdpAddress(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ byte[] buf = new byte[16];\r
+ System.arraycopy(dataPtr,2,buf,0,16);\r
+ _addr.parse(buf);\r
+\r
+ _reserved |= ((short) dataPtr[20]) << 8;\r
+ _reserved |= ((short) dataPtr[21]) & 0xFF;\r
+ _tcpPort |= ((short) dataPtr[22]) << 8;\r
+ _tcpPort |= ((short) dataPtr[23]) & 0xFF;\r
+\r
+ // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
+ }\r
+\r
+ /**\r
+ * Method setIpAddress\r
+ *\r
+ * @param hostName a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public void setIpAddress(String hostName) throws UnknownHostException {\r
+ _addr.setIpAddress(hostName);\r
+ }\r
+\r
+ /**\r
+ * Method setTcpPort\r
+ *\r
+ * @param port a short\r
+ *\r
+ */\r
+ public void setTcpPort(short port) {\r
+ _tcpPort = port;\r
+ }\r
+\r
+ /**\r
+ * Method getIpName\r
+ *\r
+ * @return a String\r
+ *\r
+ * @throws UnknownHostException\r
+ *\r
+ */\r
+ public String getIpName() throws UnknownHostException {\r
+ return (_addr.getIpName());\r
+ }\r
+\r
+ /**\r
+ * Method getTcpPort\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ short getTcpPort() {\r
+ return _tcpPort;\r
+ };\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * Method isIpv6PdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv6PdpAddress() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ //\r
+ _objHdr.writeData(id);\r
+ _addr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+ buf[0] = (byte) (_reserved >> 8);\r
+ buf[1] = (byte) _reserved;\r
+ buf[2] = (byte) (_tcpPort >> 8);\r
+ buf[3] = (byte) _tcpPort ;\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Keep Alive Message\r
+ *\r
+ * @version COPSKAMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSKAMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSIntegrity _integrity;\r
+\r
+ public COPSKAMsg() {\r
+ _integrity = null;\r
+ }\r
+\r
+ protected COPSKAMsg(byte[] data) throws COPSException {\r
+ _integrity = null;\r
+ parse(data);\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ //The client type in the header MUST always be set to 0\r
+ //as KA is used for connection verification.RFC 2748\r
+ if ((_hdr == null) && (_hdr.getClientType() != 0))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_KA)\r
+ throw new COPSException ("Error Header (no COPS_OP_KA)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Integrity objects\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has Integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ };\r
+\r
+ /**\r
+ * Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Writes data to given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_KA)\r
+ throw new COPSException("Error Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ private void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Keep Alive Timer\r
+ *\r
+ * @version COPSKATimer.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSKATimer extends COPSTimer {\r
+\r
+ public COPSKATimer() {\r
+ super ((short) 1);\r
+ _objHdr.setCNum(COPSObjHeader.COPS_KA);\r
+ _objHdr.setCType((byte) 1);\r
+ }\r
+\r
+ ///\r
+ public COPSKATimer(short timeVal) {\r
+ super(timeVal);\r
+ _objHdr.setCNum(COPSObjHeader.COPS_KA);\r
+ _objHdr.setCType((byte) 1);\r
+ }\r
+\r
+ /**\r
+ * Method isKATimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isKATimer() {\r
+ return true;\r
+ }\r
+\r
+ protected COPSKATimer(byte[] dataPtr) {\r
+ super (dataPtr);\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS LPDP Decision Object\r
+ *\r
+ * @version COPSLPDPDecision.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSLPDPDecision extends COPSDecision {\r
+\r
+ /**\r
+ Constructor to create a Local Decision object.\r
+ */\r
+ public COPSLPDPDecision(byte cType) {\r
+ super (cType);\r
+ _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC);\r
+ }\r
+\r
+ public COPSLPDPDecision() {\r
+ super ();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC);\r
+ }\r
+\r
+ /**\r
+ * Method isLocalDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isLocalDecision() {\r
+ return true;\r
+ }\r
+\r
+ protected COPSLPDPDecision(byte[] data) {\r
+ super (data);\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Message\r
+ *\r
+ * @version COPSMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+abstract public class COPSMsg {\r
+\r
+ protected COPSHeader _hdr;\r
+ protected int _dataLength;\r
+ protected int _dataStart;\r
+\r
+ /**\r
+ * Method getHeader\r
+ *\r
+ * @return a COPSHeader\r
+ *\r
+ */\r
+ public COPSHeader getHeader() {\r
+ return _hdr;\r
+ }\r
+\r
+ /**\r
+ * Method writeData\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public abstract void writeData(Socket id) throws IOException;\r
+\r
+ /**\r
+ * Method getMsgLength\r
+ *\r
+ * @return an int\r
+ *\r
+ */\r
+ public int getMsgLength() {\r
+ return _hdr.getMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected abstract void parse(COPSHeader hdr, byte[] data) throws COPSException;\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected abstract void parse(byte[] data) throws COPSException;\r
+\r
+ /**\r
+ * Method parseHeader\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parseHeader(byte[] data) throws COPSException {\r
+ _dataLength = 0;\r
+ _dataStart = 0;\r
+ if (_hdr == null) {\r
+ // _hdr = new COPSHeader(COPSHeader.COPS_OP_CAT);\r
+ _hdr = new COPSHeader(data);\r
+ _dataStart += 8;\r
+ _dataLength = _hdr.getMsgLength();\r
+ } else {\r
+ //header is already read\r
+ _dataLength = _hdr.getMsgLength() - 8;\r
+ }\r
+\r
+ //validate the message length\r
+ //Should fill on the 32bit boundary\r
+ if ((_hdr.getMsgLength() % 4 != 0)) {\r
+ throw new COPSException("Bad message format: COPS message is not on 32 bit bounday");\r
+ }\r
+ }\r
+\r
+ /** Checks the sanity of COPS message and throw an\r
+ COPSBadDataException when data is bad.\r
+ */\r
+ public abstract void checkSanity()throws COPSException;\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ os.write(new String("COPS Message").getBytes());\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+/**\r
+ * COPS Message Parser\r
+ *\r
+ * @version COPSMsgParser.java, v 1.00 2003\r
+ *\r
+ */\r
+\r
+// import org.umu.cops.common.COPSDebug;\r
+\r
+public class COPSMsgParser {\r
+ ///\r
+ public COPSMsgParser() {\r
+\r
+ }\r
+\r
+ /** Parses the given COPS data and returns a COPSMsg object\r
+ * with COPS object filed in.The COPSMsg object is allocated in the\r
+ * call and it is the responsibility of the caller to free the memory\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @return a COPSMsg\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public COPSMsg parse(byte[] data) throws COPSException {\r
+ COPSHeader hdr = new COPSHeader(data);\r
+\r
+ byte[] buf = new byte[data.length - 8];\r
+ System.arraycopy(data,8,buf,0,data.length - 8);\r
+\r
+ return (parse(hdr, buf));\r
+ }\r
+\r
+ /**\r
+ * Parse the message with given header , the data is pointing\r
+ * to the data following the header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @return a COPSMsg\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public COPSMsg parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ COPSMsg copsMsg = null;\r
+ short cCode = hdr.getOpCode();\r
+ switch (cCode) {\r
+ case COPSHeader.COPS_OP_REQ: {\r
+ // COPSDebug.out(getClass().getName(), "Creating REQ msg");\r
+ copsMsg = new COPSReqMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_DEC: {\r
+ // COPSDebug.out(getClass().getName(), "Creating DEC msg");\r
+ copsMsg = new COPSDecisionMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_RPT: {\r
+ // COPSDebug.out(getClass().getName(), "Creating RPT msg");\r
+ copsMsg = new COPSReportMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_DRQ: {\r
+ // COPSDebug.out(getClass().getName(), "Creating DRQ msg");\r
+ copsMsg = new COPSDeleteMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_OPN: {\r
+ // COPSDebug.out(getClass().getName(), "Creating Client-Open msg");\r
+ copsMsg = new COPSClientOpenMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_CAT: {\r
+ // COPSDebug.out(getClass().getName(), "Creating Client-Accept msg");\r
+ copsMsg = new COPSClientAcceptMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_CC: {\r
+ // COPSDebug.out(getClass().getName(), "Creating Client-Close msg");\r
+ copsMsg = new COPSClientCloseMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_KA: {\r
+ // COPSDebug.out(getClass().getName(), "Creating KA msg");\r
+ copsMsg = new COPSKAMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_SSQ: {\r
+ // COPSDebug.out(getClass().getName(), "Creating Sync-State Request msg");\r
+ copsMsg = new COPSSyncStateMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ case COPSHeader.COPS_OP_SSC: {\r
+ // COPSDebug.out(getClass().getName(), "Creating Sync-State Complete msg");\r
+ copsMsg = new COPSSyncStateMsg();\r
+ copsMsg.parse(hdr, data);\r
+ }\r
+ break;\r
+ default:\r
+ // COPSDebug.out(getClass().getName(), "Unknown message type");\r
+ break;\r
+ }\r
+\r
+\r
+ // if(copsMsg != null)\r
+ // try { copsMsg.dump(COPSDebug.out); } catch (Exception e) {};\r
+\r
+ return copsMsg;\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * COPS Object\r
+ *\r
+ * @version COPSObjBase.java, v 1.00 2003\r
+ *\r
+ */\r
+public abstract class COPSObjBase {\r
+ /**\r
+ * Add padding in the data, if the data does not fall on 32-bit boundary\r
+ *\r
+ * @param len an int\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ static COPSData getPadding(int len) {\r
+ byte[] padBuf = new byte[len];\r
+ Arrays.fill(padBuf, (byte) 0);\r
+ COPSData d = new COPSData(padBuf, 0, len);\r
+ return d;\r
+ }\r
+\r
+ /**\r
+ * Writes data to a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public abstract void writeData(Socket id) throws IOException;\r
+\r
+ /**\r
+ * Method getDataLength\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ short getDataLength() {\r
+ return 0;\r
+ }\r
+\r
+ /**\r
+ * Method isCOPSHeader\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isCOPSHeader() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isClientHandle\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isClientHandle() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isContext\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isContext() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isInterface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isInterface() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isDecision() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isLocalDecision\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isLocalDecision() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isReport\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isReport() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isError() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isTimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isTimer() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isPepId\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isPepId() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isReason\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isReason() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isPdpAddress() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isClientSI\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isClientSI() {\r
+ return false;\r
+ }\r
+\r
+ /**\r
+ * Method isMessageIntegrity\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ boolean isMessageIntegrity() {\r
+ return false;\r
+ }\r
+\r
+};\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Object Header\r
+ *\r
+ * @version COPSObjHeader.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSObjHeader extends COPSObjBase {\r
+\r
+ public final static byte COPS_HANDLE = 1;\r
+ public final static byte COPS_CONTEXT = 2;\r
+ public final static byte COPS_ININTF = 3;\r
+ public final static byte COPS_OUTINTF = 4;\r
+ public final static byte COPS_REASON_CODE = 5;\r
+ public final static byte COPS_DEC = 6;\r
+ public final static byte COPS_LPDP_DEC = 7;\r
+ public final static byte COPS_ERROR = 8;\r
+ public final static byte COPS_CSI = 9;\r
+ public final static byte COPS_KA = 10;\r
+ public final static byte COPS_PEPID = 11;\r
+ public final static byte COPS_RPT = 12;\r
+ public final static byte COPS_PDP_REDIR = 13;\r
+ public final static byte COPS_LAST_PDP_ADDR = 14;\r
+ public final static byte COPS_ACCT_TIMER = 15;\r
+ public final static byte COPS_MSG_INTEGRITY = 16;\r
+\r
+ private short _len;\r
+ private byte _cNum;\r
+ private byte _cType;\r
+\r
+ public COPSObjHeader(byte cNum, byte cType) {\r
+ _len = 4;\r
+ _cNum = cNum;\r
+ _cType = cType;\r
+ }\r
+\r
+ public COPSObjHeader() {\r
+ _len = 4;\r
+ _cNum = 0;\r
+ _cType = 0;\r
+ }\r
+\r
+ protected COPSObjHeader(byte[] data) {\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Get the data length in number of octets\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return _len;\r
+ };\r
+\r
+ /**\r
+ * Get the class information identifier cNum\r
+ *\r
+ * @return a byte\r
+ *\r
+ */\r
+ public byte getCNum() {\r
+ return _cNum;\r
+ };\r
+\r
+ /**\r
+ * Get the type per cNum\r
+ *\r
+ * @return a byte\r
+ *\r
+ */\r
+ public byte getCType() {\r
+ return _cType;\r
+ };\r
+\r
+ /**\r
+ * Get stringified CNum\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getStrCNum() {\r
+ switch (getCNum()) {\r
+ case COPS_HANDLE:\r
+ return ("Client-handle");\r
+ case COPS_CONTEXT:\r
+ return ("Context");\r
+ case COPS_ININTF:\r
+ return ("In-Interface");\r
+ case COPS_OUTINTF:\r
+ return ("Out-Interface");\r
+ case COPS_REASON_CODE:\r
+ return ("Reason");\r
+ case COPS_DEC:\r
+ return ("Decision");\r
+ case COPS_LPDP_DEC:\r
+ return ("Local-Decision");\r
+ case COPS_ERROR:\r
+ return ("Error");\r
+ case COPS_CSI:\r
+ return ("Client-SI");\r
+ case COPS_KA:\r
+ return ("KA-timer");\r
+ case COPS_PEPID:\r
+ return ("PEP-id");\r
+ case COPS_RPT:\r
+ return ("Report");\r
+ case COPS_PDP_REDIR:\r
+ return ("Redirect PDP addr");\r
+ case COPS_LAST_PDP_ADDR:\r
+ return ("Last PDP addr");\r
+ case COPS_ACCT_TIMER:\r
+ return ("Account-Timer");\r
+ case COPS_MSG_INTEGRITY:\r
+ return ("Message-Integrity");\r
+ default:\r
+ return ("Unknown");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Set the obj length, the length is the length of the data following\r
+ * the object header.The length of the object header (4 bytes) is added\r
+ * to the length passed.\r
+ *\r
+ * @param len a short\r
+ *\r
+ */\r
+ public void setDataLength(short len) {\r
+ //Add the length of the header also\r
+ _len = (short) (len + 4);\r
+ }\r
+\r
+ /**\r
+ * Set the class of information cNum\r
+ *\r
+ * @param cNum a byte\r
+ *\r
+ */\r
+ public void setCNum(byte cNum) {\r
+ _cNum = cNum;\r
+ } ;\r
+\r
+ /**\r
+ * Set the type defined per cNum\r
+ *\r
+ * @param cType a byte\r
+ *\r
+ */\r
+ public void setCType(byte cType) {\r
+ _cType = cType;\r
+ } ;\r
+\r
+ /**\r
+ * Method checkDataLength\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void checkDataLength() throws COPSException {\r
+\r
+ }\r
+\r
+ /**\r
+ * Writes data to a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_len >> 8);\r
+ buf[1] = (byte) _len;\r
+ buf[2] = (byte) _cNum;\r
+ buf[3] = (byte) _cType;\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ /**\r
+ * Method parse\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ */\r
+ public void parse(byte[] data) {\r
+ _len = 0;\r
+ _len |= ((short) data[0]) << 8;\r
+ _len |= ((short) data[1]) & 0xFF;\r
+ _cNum |= data[2];\r
+ _cType |= data[3];\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ os.write(new String("**" + getStrCNum() + "**" + "\n").getBytes());\r
+ os.write(new String("Length: " + _len + "\n").getBytes());\r
+ os.write(new String("C-num: " + _cNum + "\n").getBytes());\r
+ os.write(new String("C-type: " + _cType + "\n").getBytes());\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+\r
+/**\r
+ * COPS PDP Address\r
+ *\r
+ * @version COPSPdpAddress.java, v 1.00 2003\r
+ *\r
+ */\r
+abstract public class COPSPdpAddress extends COPSObjBase {\r
+\r
+ /**\r
+ * Method isPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPdpAddress() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Method isIpv4PdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv4PdpAddress() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isIpv6PdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isIpv6PdpAddress() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isLastPdpAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isLastPdpAddress() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isPdpredirectAddress\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPdpredirectAddress() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ abstract public void dump(OutputStream os) throws IOException;\r
+};\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS PEP Identification Object\r
+ *\r
+ * @version COPSPepId.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPepId extends COPSObjBase {\r
+\r
+ COPSObjHeader _objHdr;\r
+ COPSData _data;\r
+ COPSData _padding;\r
+\r
+ public COPSPepId() {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_PEPID);\r
+ _objHdr.setCType((byte) 1);\r
+ }\r
+\r
+ protected COPSPepId(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ //Get the length of data following the obj header\r
+ short dLen = (short) (_objHdr.getDataLength() - 4);\r
+ COPSData d = new COPSData (dataPtr, 4, dLen);\r
+ setData(d);\r
+ }\r
+\r
+ /**\r
+ * Method setData\r
+ *\r
+ * @param data a COPSData\r
+ *\r
+ */\r
+ public void setData(COPSData data) {\r
+ _data = data;\r
+ if (_data.length() % 4 != 0) {\r
+ int padLen = 4 - _data.length() % 4;\r
+ _padding = getPadding(padLen);\r
+ }\r
+ _objHdr.setDataLength((short)_data.length());\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return ((short) (_objHdr.getDataLength() + lpadding));\r
+ }\r
+\r
+ /**\r
+ * Method getData\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getData() {\r
+ return _data;\r
+ };\r
+\r
+ /**\r
+ * Method isPepId\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPepId() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Write data to given netwrok socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+ COPSUtil.writeData(id, _data.getData(), _data.length());\r
+ if (_padding != null) {\r
+ COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("PEPID: " + _data.str() + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Provisioning Class Error\r
+ *\r
+ * @version COPSPrClassError.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrClassError extends COPSPrError {\r
+\r
+ public final static byte C_spaceExhausted = 1;\r
+ public final static byte C_instanceInvalid = 2;\r
+ public final static byte C_attrValueInvalid = 3;\r
+ public final static byte C_attrValueSupLimited = 4;\r
+ public final static byte C_attrEnumSupLimited = 5;\r
+ public final static byte C_attrMaxLengthExceeded = 6;\r
+ public final static byte C_attrRefUnknown = 7;\r
+ public final static byte C_notifyOnly = 8;\r
+ public final static byte C_unknownPrc = 9;\r
+ public final static byte C_tooFewAttrs = 10;\r
+ public final static byte C_invalidAttrType = 11;\r
+ public final static byte C_deletedInRef = 12;\r
+ public final static byte C_specificError = 13;\r
+ public final static byte C_errmax = 14;\r
+\r
+ private final static String CerrTable[] = {\r
+ "Reserved",\r
+ "No more instances may currently be installed in the given class",\r
+ "Invalid class instance",\r
+ "Invalid attribute value",\r
+ "The value for attribute not currently supported by the device",\r
+ "The enumeration for attribute not currently supported by the device",\r
+ "Attribute length exceeds device limitations",\r
+ "Unknown attribute reference",\r
+ "Only supported for use by request or report",\r
+ "Class not supported by PEP",\r
+ "Too few attributes",\r
+ "Invalid attribute type",\r
+ "Reference to deleted instance",\r
+ "PRC specific error, check subcode for more details"\r
+ };\r
+\r
+ public COPSPrClassError(short eCode, short eSubCode) {\r
+ super (eCode, eSubCode);\r
+ _sNum = COPSPrObjBase.PR_CPERR;\r
+ _sType = COPSPrObjBase.PR_BER;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrClassError object\r
+ */\r
+ protected COPSPrClassError(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method isPRCClassError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRCClassError() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Method strError\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String strError() {\r
+ return CerrTable[_errCode];\r
+ };\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Provisioning EPD\r
+ *\r
+ * @version COPSPrEPD.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrEPD extends COPSPrObjBase {\r
+\r
+ public COPSPrEPD() {\r
+ _sNum = COPSPrObjBase.PR_EPD;\r
+ _sType = COPSPrObjBase.PR_XML;\r
+ }\r
+\r
+ /**\r
+ * Method isEncodedInstanceData\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isEncodedInstanceData() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrEPD object\r
+ */\r
+ protected COPSPrEPD(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+\r
+};\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Provisioning Error\r
+ *\r
+ * @version COPSPrError.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrError extends COPSPrObjBase {\r
+\r
+ protected short _errCode;\r
+ protected short _errSubCode;\r
+\r
+ public COPSPrError(short eCode, short eSubCode) {\r
+ _errCode = eCode;\r
+ _errSubCode = eSubCode;\r
+ _len = 8;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrGlobalError object\r
+ */\r
+ protected COPSPrError(byte[] dataPtr) {\r
+ _dataRep = null;\r
+\r
+ _len |= ((short) dataPtr[0]) << 8;\r
+ _len |= ((short) dataPtr[1]) & 0xFF;\r
+\r
+ _sNum |= ((short) dataPtr[2]) << 8;\r
+ _sNum |= ((short) dataPtr[3]) & 0xFF;\r
+\r
+ _errCode |= ((short) dataPtr[4]) << 8;\r
+ _errCode |= ((short) dataPtr[5]) & 0xFF;\r
+\r
+ _errSubCode |= ((short) dataPtr[6]) << 8;\r
+ _errSubCode |= ((short) dataPtr[7]) & 0xFF;\r
+ }\r
+\r
+ /**\r
+ * Method strError\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String strError() {\r
+ return "Error";\r
+ }\r
+\r
+ /**\r
+ * Method setData\r
+ *\r
+ * @param data a COPSData\r
+ *\r
+ */\r
+ public void setData(COPSData data) { } ;\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ byte[] dataRep = getDataRep();\r
+ COPSUtil.writeData(id, dataRep, dataRep.length);\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return 8;\r
+ }\r
+\r
+ /**\r
+ * Method getDataRep\r
+ *\r
+ * @return a byte[]\r
+ *\r
+ */\r
+ public byte[] getDataRep() {\r
+ _dataRep = new byte[getDataLength()];\r
+\r
+ _dataRep[0] = (byte) (_len >> 8);\r
+ _dataRep[1] = (byte) _len;\r
+ _dataRep[2] = (byte) (_sNum >> 8);\r
+ _dataRep[3] = (byte) _sNum;\r
+ _dataRep[4] = (byte) (_errCode >> 8);\r
+ _dataRep[5] = (byte) _errCode;\r
+ _dataRep[6] = (byte) (_errSubCode >> 8);\r
+ _dataRep[7] = (byte) _errSubCode;\r
+\r
+ return _dataRep;\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Provisioning Error PRID\r
+ *\r
+ * @version COPSPrErrorPRID.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrErrorPRID extends COPSPrObjBase {\r
+\r
+ public COPSPrErrorPRID() {\r
+ _sNum = COPSPrObjBase.PR_IDERR;\r
+ _sType = COPSPrObjBase.PR_BER;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrErrorPRID object\r
+ */\r
+ protected COPSPrErrorPRID(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method isErrorPRID\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isErrorPRID() {\r
+ return true;\r
+ }\r
+\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Provisioning Global Error\r
+ *\r
+ * @version COPSPrGlobalError.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrGlobalError extends COPSPrError {\r
+\r
+ public final static byte G_availMemoryLow = 1;\r
+ public final static byte G_availMemoryExhausted = 2;\r
+ public final static byte G_unknownASN1Tag = 3;\r
+ public final static byte G_maxMsgSizeExceeded = 4;\r
+ public final static byte G_unknownError = 5;\r
+ public final static byte G_maxReqStateOpen = 6;\r
+ public final static byte G_invalidASN1Length = 7;\r
+ public final static byte G_invalidObjPad = 8;\r
+ public final static byte G_unknownPIBData = 9;\r
+ public final static byte G_unknownCOPSPrObj = 10;\r
+ public final static byte G_malformedDec = 11;\r
+ public final static byte G_errmax = 12;\r
+\r
+\r
+ private final static String GerrTable[] = {\r
+ "Reserved",\r
+ "Available memory low",\r
+ "Available memory exhausted",\r
+ "Unknown ASN.1 tag",\r
+ "Max. message size exceeded",\r
+ "Unknown error",\r
+ "No more Request-states can be created by the PEP",\r
+ "ASN.1 object length was incorrect",\r
+ "Object was not properly padded",\r
+ "Unknown PIB data",\r
+ "Unknown COPS-PR object",\r
+ "Melformed decision"\r
+ };\r
+\r
+ ///\r
+ COPSPrGlobalError(short eCode, short eSubCode) {\r
+ super(eCode, eSubCode);\r
+ _sNum = COPSPrObjBase.PR_GPERR;\r
+ _sType = COPSPrObjBase.PR_BER;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrGlobalError object\r
+ */\r
+ protected COPSPrGlobalError(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+\r
+ /**\r
+ * Method isGlobalPrError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isGlobalPrError() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Method strError\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String strError() {\r
+ return GerrTable[_errCode];\r
+ };\r
+\r
+};\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Provisioning ID\r
+ *\r
+ * @version COPSPrID.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrID extends COPSPrObjBase {\r
+\r
+ public COPSPrID() {\r
+ _sNum = COPSPrObjBase.PR_PRID;\r
+ _sType = COPSPrObjBase.PR_XML;\r
+ }\r
+\r
+ ///Parse the data and create a PrID object\r
+ protected COPSPrID(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+\r
+ /**\r
+ * Method isPRID\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRID() {\r
+ return true;\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Arrays;\r
+\r
+/**\r
+ * COPS Provisioning Object Base\r
+ *\r
+ * @version COPSPrObjBase.java, v 1.01 2003\r
+ *\r
+ */\r
+public class COPSPrObjBase {\r
+ public final static byte PR_PRID = 1;\r
+ public final static byte PR_PPRID = 2;\r
+ public final static byte PR_EPD = 3;\r
+ public final static byte PR_GPERR = 4;\r
+ public final static byte PR_CPERR = 5;\r
+ public final static byte PR_IDERR = 6;\r
+\r
+ public final static byte PR_BER = 1;\r
+ public final static byte PR_XML = 2;\r
+\r
+ protected short _len;\r
+ protected byte _sNum;\r
+ protected byte _sType;\r
+ protected COPSData _data;\r
+ protected COPSData _padding;\r
+\r
+ protected byte[] _dataRep;\r
+ ///\r
+ protected COPSPrObjBase() {\r
+ _dataRep = null;\r
+ }\r
+\r
+ public COPSPrObjBase(byte[] dataPtr) {\r
+ _dataRep = null;\r
+\r
+ _len |= ((short) dataPtr[0]) << 8;\r
+ _len |= ((short) dataPtr[1]) & 0xFF;\r
+\r
+ _sNum |= ((short) dataPtr[2]) << 8;\r
+ _sNum |= ((short) dataPtr[3]) & 0xFF;\r
+\r
+ //Get the length of data following the obj header\r
+ short dLen = (short) (_len - 4);\r
+ COPSData d = new COPSData(dataPtr, 4, dLen);\r
+ setData(d);\r
+ }\r
+\r
+ /**\r
+ * Add padding in the data, if the Provisioning data does\r
+ * not fall on 32-bit boundary\r
+ *\r
+ * @param len an int\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getPadding(int len) {\r
+ byte[] padBuf = new byte[len];\r
+ Arrays.fill(padBuf, (byte) 0);\r
+ COPSData d = new COPSData(padBuf, 0, len);\r
+ return d;\r
+ }\r
+\r
+ /**\r
+ * Method isPRID\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRID() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isPRIDPrefix\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRIDPrefix() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isEncodedInstanceData\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isEncodedInstanceData() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isGlobalPrError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isGlobalPrError() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isPRCClassError\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRCClassError() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isErrorPRID\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isErrorPRID() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method setData\r
+ *\r
+ * @param data a COPSData\r
+ *\r
+ */\r
+ public void setData(COPSData data) {\r
+ _data = data;\r
+ if (_data.length() % 4 != 0) {\r
+ int padLen = 4 - (_data.length() % 4);\r
+ _padding = getPadding(padLen);\r
+ }\r
+ _len = (short) (_data.length() + 4);\r
+ }\r
+\r
+ /**\r
+ * Get the class information identifier cNum\r
+ *\r
+ * @return a byte\r
+ *\r
+ */\r
+ public byte getSNum() {\r
+ return _sNum;\r
+ };\r
+\r
+ /**\r
+ * Get the type per sNum\r
+ *\r
+ * @return a byte\r
+ *\r
+ */\r
+ public byte getSType() {\r
+ return _sType;\r
+ };\r
+\r
+ /**\r
+ * Get stringified CNum\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getStrSNum() {\r
+ switch (getSNum()) {\r
+ case PR_PRID:\r
+ return ("PRID");\r
+ case PR_PPRID:\r
+ return ("PRID Prefix");\r
+ case PR_EPD:\r
+ return ("EPD");\r
+ case PR_GPERR:\r
+ return ("GPERR");\r
+ case PR_CPERR:\r
+ return ("CPERR");\r
+ case PR_IDERR:\r
+ return ("IDERR");\r
+ default:\r
+ return ("Unknown");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ //Header length contains the header+data length\r
+ int lpadding = 0;\r
+ if (_padding != null) lpadding = _padding.length();\r
+ return ( (short) (_len + lpadding));\r
+ }\r
+\r
+ /**\r
+ * Method getData\r
+ *\r
+ * @return a COPSData\r
+ *\r
+ */\r
+ public COPSData getData() {\r
+ return _data;\r
+ };\r
+\r
+ /**\r
+ * Write data on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ byte[] dataRep = getDataRep();\r
+ COPSUtil.writeData(id, dataRep, dataRep.length);\r
+ }\r
+\r
+ /**\r
+ * Get the binary data contained in the object\r
+ *\r
+ * @return a byte[]\r
+ *\r
+ */\r
+ public byte[] getDataRep() {\r
+ _dataRep = new byte[getDataLength()];\r
+\r
+ _dataRep[0] = (byte) (_len >> 8);\r
+ _dataRep[1] = (byte) _len;\r
+ _dataRep[2] = (byte) (_sNum >> 8);\r
+ _dataRep[3] = (byte) _sNum;\r
+\r
+ System.arraycopy(_data.getData(), 0, _dataRep, 4, _data.length());\r
+\r
+ if (_padding != null) {\r
+ System.arraycopy(_padding.getData(), 0, _dataRep, 4 + _data.length(), _padding.length());\r
+ }\r
+\r
+ return _dataRep;\r
+ }\r
+\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+\r
+\r
+/**\r
+ * COPS Prefix Provisioning ID\r
+ *\r
+ * @version COPSPrefixPrID.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSPrefixPrID extends COPSPrObjBase {\r
+\r
+ ///\r
+ public COPSPrefixPrID() {\r
+ _sNum = COPSPrObjBase.PR_PPRID;\r
+ _sType = COPSPrObjBase.PR_XML;\r
+ }\r
+\r
+ /**\r
+ * Method isPRIDPrefix\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isPRIDPrefix() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ Parse the data and create a PrefixPrID object\r
+ */\r
+ protected COPSPrefixPrID(byte[] dataPtr) {\r
+ super(dataPtr);\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Reason Object (RFC 2748 pag. 12)\r
+ *\r
+ * This object specifies the reason why the request state was deleted.\r
+ * It appears in the delete request (DRQ) message. The Reason Sub-code\r
+ * field is reserved for more detailed client-specific reason codes\r
+ * defined in the corresponding documents.\r
+ *\r
+ * C-Num = 5, C-Type = 1\r
+ *\r
+ * 0 1 2 3\r
+ * +--------------+--------------+--------------+--------------+\r
+ * | Reason-Code | Reason Sub-code |\r
+ * +--------------+--------------+--------------+--------------+\r
+ *\r
+ * Reason Code:\r
+ * 1 = Unspecified\r
+ * 2 = Management\r
+ * 3 = Preempted (Another request state takes precedence)\r
+ * 4 = Tear (Used to communicate a signaled state removal)\r
+ * 5 = Timeout (Local state has timed-out)\r
+ * 6 = Route Change (Change invalidates request state)\r
+ * 7 = Insufficient Resources (No local resource available)\r
+ * 8 = PDP's Directive (PDP decision caused the delete)\r
+ * 9 = Unsupported decision (PDP decision not supported)\r
+ * 10= Synchronize Handle Unknown\r
+ * 11= Transient Handle (stateless event)\r
+ * 12= Malformed Decision (could not recover)\r
+ * 13= Unknown COPS Object from PDP:\r
+ * Sub-code (octet 2) contains unknown object's C-Num\r
+ * and (octet 3) contains unknown object's C-Type.\r
+ *\r
+ * @version COPSReason.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSReason extends COPSPrObjBase {\r
+\r
+ public final static String[] G_msgArray = {\r
+ "Unknown.",\r
+ "Unspecified.",\r
+ "Management.",\r
+ "Preempted (Another request state takes precedence).",\r
+ "Tear (Used to communicate a signaled state removal).",\r
+ "Timeout ( Local state has timed-out).",\r
+ "Route change (Change invalidates request state).",\r
+ "Insufficient Resources.",\r
+ "PDP's Directive.",\r
+ "Unsupported decision.",\r
+ "Synchronize handle unknown.",\r
+ "Transient handle.",\r
+ "Malformed decision.",\r
+ "Unknown COPS object from PDP.",\r
+ };\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private short _reasonCode;\r
+ private short _reasonSubCode;\r
+\r
+ ///\r
+ public COPSReason(short reasonCode, short subCode) {\r
+ _objHdr = new COPSObjHeader();\r
+ _reasonCode = reasonCode;\r
+ _reasonSubCode = subCode;\r
+ _objHdr.setCNum(COPSObjHeader.COPS_REASON_CODE);\r
+ _objHdr.setCType((byte) 1);\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSReason object\r
+ */\r
+ protected COPSReason(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _reasonCode |= ((short) dataPtr[4]) << 8;\r
+ _reasonCode |= ((short) dataPtr[5]) & 0xFF;\r
+ _reasonSubCode |= ((short) dataPtr[6]) << 8;\r
+ _reasonSubCode |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * Get Reason description\r
+ *\r
+ * @return a String\r
+ *\r
+ */\r
+ public String getDescription() {\r
+ String reasonStr1;\r
+ String reasonStr2;\r
+\r
+ ///Get the details from the error code\r
+ reasonStr1 = G_msgArray[_reasonCode];\r
+ //TODO - defind reason sub-codes\r
+ reasonStr2 = "";\r
+ return (reasonStr1 + ":" + reasonStr2);\r
+ }\r
+\r
+ /**\r
+ * Always return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isReason() {\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Write object in network byte order to a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_reasonCode >> 8);\r
+ buf[1] = (byte) _reasonCode;\r
+ buf[2] = (byte) (_reasonSubCode >> 8);\r
+ buf[3] = (byte) _reasonSubCode;\r
+\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Reason Code: " + _reasonCode + "\n").getBytes());\r
+ os.write(new String("Reason Sub Code: " + _reasonSubCode + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * COPS Report Message (RFC 2748 pag. 25)\r
+ *\r
+ * The RPT message is used by the PEP to communicate to the PDP its\r
+ * success or failure in carrying out the PDP's decision, or to report\r
+ * an accounting related change in state. The Report-Type specifies the\r
+ * kind of report and the optional ClientSI can carry additional\r
+ * information per Client-Type.\r
+ *\r
+ * For every DEC message containing a configuration context that is\r
+ * received by a PEP, the PEP MUST generate a corresponding Report State\r
+ * message with the Solicited Message flag set describing its success or\r
+ * failure in applying the configuration decision. In addition,\r
+ * outsourcing decisions from the PDP MAY result in a corresponding\r
+ * solicited Report State from the PEP depending on the context and the\r
+ * type of client. RPT messages solicited by decisions for a given\r
+ * Client Handle MUST set the Solicited Message flag and MUST be sent in\r
+ * the same order as their corresponding Decision messages were\r
+ * received. There MUST never be more than one Report State message\r
+ * generated with the Solicited Message flag set per Decision.\r
+ *\r
+ * The Report State may also be used to provide periodic updates of\r
+ * client specific information for accounting and state monitoring\r
+ * purposes depending on the type of the client. In such cases the\r
+ * accounting report type should be specified utilizing the appropriate\r
+ * client specific information object.\r
+ *\r
+ * <Report State> ::== <Common Header>\r
+ * <Client Handle>\r
+ * <Report-Type>\r
+ * [<ClientSI>]\r
+ * [<Integrity>]\r
+ *\r
+ * @version COPSReportMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSReportMsg extends COPSMsg {\r
+ /* COPSHeader coming from base class */\r
+ private COPSHandle _clientHandle;\r
+ private COPSReportType _report;\r
+ private Vector _clientSI;\r
+ private COPSIntegrity _integrity;\r
+\r
+ public COPSReportMsg() {\r
+ _clientHandle = null;\r
+ _report = null;\r
+ _integrity = null;\r
+ _clientSI = new Vector(20);\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSReportMsg object\r
+ */\r
+ protected COPSReportMsg (byte[] data) throws COPSException {\r
+ _clientHandle = null;\r
+ _report = null;\r
+ _integrity = null;\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Checks the sanity of COPS message and throw an\r
+ * COPSException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_clientHandle == null) || (_report == null))\r
+ throw new COPSException("Bad message format");\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)\r
+ throw new COPSException ("Error Header (no COPS_OP_REQ)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Report object to the message\r
+ *\r
+ * @param report a COPSReportType\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSReportType report) throws COPSException {\r
+ if (report == null)\r
+ throw new COPSException ("Null Handle");\r
+\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("No null Handle");\r
+\r
+ _report = report;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add client handle to the message\r
+ *\r
+ * @param handle a COPSHandle\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHandle handle) throws COPSException {\r
+ if (handle == null)\r
+ throw new COPSException ("Null Handle");\r
+\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("No null Handle");\r
+\r
+ _clientHandle = handle;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add one or more clientSI objects\r
+ *\r
+ * @param clientSI a COPSClientSI\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSClientSI clientSI) throws COPSException {\r
+ if (clientSI == null)\r
+ throw new COPSException ("Null ClientSI");\r
+ _clientSI.add(clientSI);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Get client Handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _clientHandle;\r
+ }\r
+\r
+ /**\r
+ * Get report type\r
+ *\r
+ * @return a COPSReportType\r
+ *\r
+ */\r
+ public COPSReportType getReport() {\r
+ return _report;\r
+ }\r
+\r
+ /**\r
+ * Get clientSI\r
+ *\r
+ * @return a Vector\r
+ *\r
+ */\r
+ public Vector getClientSI() {\r
+ return _clientSI;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has Integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ }\r
+\r
+\r
+ /**\r
+ * Get Integrity. Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Writes data to given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ //checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_clientHandle != null) _clientHandle.writeData(id);\r
+ if (_report != null) _report.writeData(id);\r
+\r
+ for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ clientSI.writeData(id);\r
+ }\r
+\r
+ if (_integrity != null) _integrity.writeData(id);\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_HANDLE: {\r
+ _clientHandle = new COPSHandle(buf);\r
+ _dataStart += _clientHandle.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_RPT: {\r
+ _report = new COPSReportType(buf);\r
+ _dataStart += _report.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_CSI: {\r
+ COPSClientSI csi = new COPSClientSI(buf);\r
+ _dataStart += csi.getDataLength();\r
+ _clientSI.add(csi);\r
+ }\r
+ break;\r
+\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)\r
+ throw new COPSException ("Null Header");\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_clientHandle != null) len += _clientHandle.getDataLength();\r
+ if (_report != null) len += _report.getDataLength();\r
+\r
+ for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ len += clientSI.getDataLength();\r
+ }\r
+\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_clientHandle != null)\r
+ _clientHandle.dump(os);\r
+\r
+ if (_report != null)\r
+ _report.dump(os);\r
+\r
+ for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ clientSI.dump(os);\r
+ }\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Report Type (RFC 2748 pag. 16\r
+ *\r
+ * The Type of Report on the request state associated with a handle:\r
+ *\r
+ * C-Num = 12, C-Type = 1\r
+ *\r
+ * 0 1 2 3\r
+ * +--------------+--------------+--------------+--------------+\r
+ * | Report-Type | ///////////// |\r
+ * +--------------+--------------+--------------+--------------+\r
+ *\r
+ * Report-Type:\r
+ * 1 = Success : Decision was successful at the PEP\r
+ * 2 = Failure : Decision could not be completed by PEP\r
+ * 3 = Accounting: Accounting update for an installed state\r
+ *\r
+ *\r
+ * @version COPSReportType.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSReportType extends COPSPrObjBase {\r
+\r
+ public final static String[] msgMap = {\r
+ "Unknown",\r
+ "Success",\r
+ "Failure",\r
+ "Accounting",\r
+ };\r
+\r
+ private COPSObjHeader _objHdr;\r
+ private short _rType;\r
+ private short _reserved;\r
+\r
+ public final static short SUCCESS = 1;\r
+ public final static short FAILURE = 2;\r
+ public final static short ACCT = 3;\r
+\r
+ public COPSReportType(short rType) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.setCNum(COPSObjHeader.COPS_RPT);\r
+ _objHdr.setCType((byte) 1);\r
+ _rType = rType;\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSReportType object\r
+ */\r
+ protected COPSReportType(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _rType |= ((short) dataPtr[4]) << 8;\r
+ _rType |= ((short) dataPtr[5]) & 0xFF;\r
+ _reserved |= ((short) dataPtr[6]) << 8;\r
+ _reserved |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * If it is Success, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isSuccess() {\r
+ return (_rType == SUCCESS );\r
+ };\r
+\r
+ /**\r
+ * If it is Failure, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isFailure() {\r
+ return (_rType == FAILURE);\r
+ };\r
+\r
+ /**\r
+ * If it is Accounting, return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAccounting() {\r
+ return (_rType == ACCT);\r
+ };\r
+\r
+ /**\r
+ * Always return true\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isReport() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Write data in network byte order on a given network socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_rType >> 8);\r
+ buf[1] = (byte) _rType;\r
+ buf[2] = (byte) (_reserved >> 8);\r
+ buf[3] = (byte) _reserved;\r
+\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Report: " + msgMap[_rType] + "\n").getBytes());\r
+ }\r
+}\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * COPS Request Message (RFC 2748 pag. 22)\r
+ *\r
+ * The PEP establishes a request state client handle for which the\r
+ * remote PDP may maintain state. The remote PDP then uses this handle\r
+ * to refer to the exchanged information and decisions communicated over\r
+ * the TCP connection to a particular PEP for a given client-type.\r
+ *\r
+ * Once a stateful handle is established for a new request, any\r
+ * subsequent modifications of the request can be made using the REQ\r
+ * message specifying the previously installed handle. The PEP is\r
+ * responsible for notifying the PDP whenever its local state changes so\r
+ * the PDP's state will be able to accurately mirror the PEP's state.\r
+ *\r
+ * The format of the Request message is as follows:\r
+ *\r
+ * <Request Message> ::= <Common Header>\r
+ * <Client Handle>\r
+ * <Context>\r
+ * [<IN-Int>]\r
+ * [<OUT-Int>]\r
+ * [<ClientSI(s)>]\r
+ * [<LPDPDecision(s)>]\r
+ * [<Integrity>]\r
+ *\r
+ * <ClientSI(s)> ::= <ClientSI> | <ClientSI(s)> <ClientSI>\r
+ *\r
+ * <LPDPDecision(s)> ::= <LPDPDecision> |\r
+ * <LPDPDecision(s)> <LPDPDecision>\r
+ *\r
+ * <LPDPDecision> ::= [<Context>]\r
+ * <LPDPDecision: Flags>\r
+ * [<LPDPDecision: Stateless Data>]\r
+ * [<LPDPDecision: Replacement Data>]\r
+ * [<LPDPDecision: ClientSI Data>]\r
+ * [<LPDPDecision: Named Data>]\r
+ *\r
+ * The context object is used to determine the context within which all\r
+ * the other objects are to be interpreted. It also is used to determine\r
+ * the kind of decision to be returned from the policy server. This\r
+ * decision might be related to admission control, resource allocation,\r
+ * object forwarding and substitution, or configuration.\r
+ *\r
+ * The interface objects are used to determine the corresponding\r
+ * interface on which a signaling protocol message was received or is\r
+ * about to be sent. They are typically used if the client is\r
+ * participating along the path of a signaling protocol or if the client\r
+ * is requesting configuration data for a particular interface.\r
+ *\r
+ * ClientSI, the client specific information object, holds the client-\r
+ * type specific data for which a policy decision needs to be made. In\r
+ * the case of configuration, the Named ClientSI may include named\r
+ * information about the module, interface, or functionality to be\r
+ * configured. The ordering of multiple ClientSIs is not important.\r
+ *\r
+ * Finally, LPDPDecision object holds information regarding the local\r
+ * decision made by the LPDP.\r
+ *\r
+ * Malformed Request messages MUST result in the PDP specifying a\r
+ * Decision message with the appropriate error code.\r
+ *\r
+ * @version COPSReqMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSReqMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSHandle _clientHandle;\r
+ private COPSContext _context;\r
+ private COPSInterface _inInterface;\r
+ private COPSInterface _outInterface;\r
+ private Vector _clientSIs;\r
+ private Hashtable _decisions;\r
+ private COPSIntegrity _integrity;\r
+ private COPSContext _lpdpContext;\r
+\r
+ public COPSReqMsg() {\r
+ _clientHandle = null;\r
+ _context = null;\r
+ _inInterface = null;\r
+ _outInterface = null;\r
+ _clientSIs = new Vector(20);\r
+ _decisions = new Hashtable();\r
+ _integrity = null;\r
+ _lpdpContext = null;\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSReqMsg object\r
+ */\r
+ protected COPSReqMsg(byte[] data) throws COPSException {\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Checks the sanity of COPS message and throw an\r
+ * COPSBadDataException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if ((_hdr == null) || (_clientHandle == null) || (_context == null)) {\r
+ throw new COPSException("Bad message format");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Add an IN or OUT interface object\r
+ *\r
+ * @param inter a COPSInterface\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSInterface inter) throws COPSException {\r
+ if (!(inter.isInInterface() || inter.isOutInterface()))\r
+ throw new COPSException ("No Interface");\r
+\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("Integrity should be the last one");\r
+\r
+ if (inter.isInInterface()) {\r
+ if (_inInterface != null)\r
+ throw new COPSException ("Object inInterface exits");\r
+\r
+ if (inter.isIpv4Address()) {\r
+ COPSIpv4InInterface inInter = (COPSIpv4InInterface) inter;\r
+ _inInterface = inInter;\r
+ } else {\r
+ COPSIpv6InInterface inInter = (COPSIpv6InInterface) inter;\r
+ _inInterface = inInter;\r
+ }\r
+ } else {\r
+ if (_outInterface != null)\r
+ throw new COPSException ("Object outInterface exits");\r
+\r
+ if (inter.isIpv4Address()) {\r
+ COPSIpv4OutInterface outInter = (COPSIpv4OutInterface) inter;\r
+ _outInterface = outInter;\r
+ } else {\r
+ COPSIpv6OutInterface outInter = (COPSIpv6OutInterface) inter;\r
+ _outInterface = outInter;\r
+ }\r
+ }\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add header to the message\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if (hdr.getOpCode() != COPSHeader.COPS_OP_REQ)\r
+ throw new COPSException ("Error Header (no COPS_OP_REQ)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add Context object to the message\r
+ *\r
+ * @param context a COPSContext\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSContext context) throws COPSException {\r
+ if (context == null)\r
+ throw new COPSException ("Null Context");\r
+ _context = context;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add client handle to the message\r
+ *\r
+ * @param handle a COPSHandle\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHandle handle) throws COPSException {\r
+ if (handle == null)\r
+ throw new COPSException ("Null Handle");\r
+ _clientHandle = handle;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add one or more clientSI objects\r
+ *\r
+ * @param clientSI a COPSClientSI\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSClientSI clientSI) throws COPSException {\r
+ if (clientSI == null)\r
+ throw new COPSException ("Null ClientSI");\r
+ _clientSIs.add(clientSI);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add one or more local decision object for a given decision context\r
+ * the context is optional, if null all decision object are tided to\r
+ * message context\r
+ *\r
+ * @param decision a COPSLPDPDecision\r
+ * @param context a COPSContext\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void addLocalDecision(COPSLPDPDecision decision, COPSContext context) throws COPSException {\r
+ if (!decision.isLocalDecision())\r
+ throw new COPSException ("Local Decision");\r
+\r
+ Vector v = (Vector) _decisions.get(context);\r
+ if (decision.isFlagSet()) {\r
+ if (v.size() != 0) {\r
+ //Only one set of decision flags is allowed\r
+ //for each context\r
+ throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");\r
+ }\r
+ } else {\r
+ if (v.size() == 0) {\r
+ //The flags decision must precede any other\r
+ //decision message, since the decision is not\r
+ //flags throw exception\r
+ throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");\r
+ }\r
+ }\r
+ v.add(decision);\r
+ _decisions.put(context,v);\r
+\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_clientHandle != null) _clientHandle.writeData(id);\r
+ if (_context != null) _context.writeData(id);\r
+\r
+ for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ clientSI.writeData(id);\r
+ }\r
+\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ context.writeData(id);\r
+\r
+ for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
+ COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
+ decision.writeData(id);\r
+ }\r
+ }\r
+\r
+ if (_integrity != null) _integrity.writeData(id);\r
+\r
+ }\r
+\r
+ /**\r
+ * Return Header\r
+ *\r
+ * @return a COPSHeader\r
+ *\r
+ */\r
+ public COPSHeader getHeader() {\r
+ return _hdr;\r
+ }\r
+\r
+ /**\r
+ * Return client Handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _clientHandle;\r
+ }\r
+\r
+ /**\r
+ * Return Context\r
+ *\r
+ * @return a COPSContext\r
+ *\r
+ */\r
+ public COPSContext getContext() {\r
+ return _context;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has In Interface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasInInterface() {\r
+ return (_inInterface == null);\r
+ }\r
+\r
+ /**\r
+ * Should check hasInInterface() before calling\r
+ *\r
+ * @return a COPSInterface\r
+ *\r
+ */\r
+ public COPSInterface getInInterface() {\r
+ return _inInterface;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has Out interface\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasOutInterface() {\r
+ return (_outInterface == null);\r
+ }\r
+\r
+ /**\r
+ * Should check hasOutInterface() before calling\r
+ *\r
+ * @return a COPSInterface\r
+ *\r
+ */\r
+ public COPSInterface getOutInterface() {\r
+ return _outInterface;\r
+ }\r
+\r
+ /**\r
+ * Returns a vector if ClientSI objects\r
+ *\r
+ * @return a Vector\r
+ *\r
+ */\r
+ public Vector getClientSI() {\r
+ return _clientSIs;\r
+ }\r
+\r
+ /**\r
+ * Returns a HashTable of any local decisions\r
+ *\r
+ * @return a Hashtable\r
+ *\r
+ */\r
+ public Hashtable getLpdpDecisions() {\r
+ return _decisions;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has Integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity == null);\r
+ }\r
+\r
+ /**\r
+ * Get Integrity. Should check hasIntegrity() becfore calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return _integrity;\r
+ }\r
+\r
+ /**\r
+ * Parses the data and fills COPSReqMsg with its constituents\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_HANDLE: {\r
+ _clientHandle = new COPSHandle(buf);\r
+ _dataStart += _clientHandle.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_CONTEXT: {\r
+ if (_context == null) {\r
+ //Message context\r
+ _context = new COPSContext(buf);\r
+ _dataStart += _context.getDataLength();\r
+ } else {\r
+ //lpdp context\r
+ _lpdpContext = new COPSContext(buf);\r
+ _dataStart += _lpdpContext.getDataLength();\r
+ }\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_ININTF: {\r
+ if (objHdr.getCType() == 1) {\r
+ _inInterface = new COPSIpv4InInterface(buf);\r
+ } else {\r
+ _inInterface = new COPSIpv6InInterface(buf);\r
+ }\r
+ _dataStart += _inInterface.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_OUTINTF: {\r
+ if (objHdr.getCType() == 1) {\r
+ _outInterface = new COPSIpv4OutInterface(buf);\r
+ } else {\r
+ _outInterface = new COPSIpv6OutInterface(buf);\r
+ }\r
+ _dataStart += _outInterface.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_LPDP_DEC: {\r
+ COPSLPDPDecision lpdp = new COPSLPDPDecision(buf);\r
+ _dataStart += lpdp.getDataLength();\r
+ addLocalDecision(lpdp, _lpdpContext);\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_CSI: {\r
+ COPSClientSI csi = new COPSClientSI (buf);\r
+ _dataStart += csi.getDataLength();\r
+ _clientSIs.add(csi);\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+\r
+ }\r
+\r
+ /**\r
+ * Parses the data and fills that follows the header hdr and fills COPSReqMsg\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+\r
+ if (_clientHandle != null)\r
+ len += _clientHandle.getDataLength();\r
+\r
+ if (_context != null)\r
+ len += _context.getDataLength();\r
+\r
+ for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ len += clientSI.getDataLength();\r
+ }\r
+\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ len += context.getDataLength();\r
+\r
+ for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
+ COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
+ len += decision.getDataLength();\r
+ }\r
+ }\r
+\r
+ if (_integrity != null) {\r
+ len += _integrity.getDataLength();\r
+ }\r
+\r
+ _hdr.setMsgLength((int) len);\r
+\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_clientHandle != null)\r
+ _clientHandle.dump(os);\r
+\r
+ if (_context != null)\r
+ _context.dump(os);\r
+\r
+ for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
+ COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
+ clientSI.dump(os);\r
+ }\r
+\r
+ //Display any local decisions\r
+ for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
+\r
+ COPSContext context = (COPSContext) e.nextElement();\r
+ Vector v = (Vector) _decisions.get(context);\r
+ context.dump(os);\r
+\r
+ for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
+ COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
+ decision.dump(os);\r
+ }\r
+ }\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Sync State Message (RFC 2748 pag. 26 and pag. 29\r
+ *\r
+ * The format of the Synchronize State Query message is as follows:\r
+ *\r
+ * <Synchronize State> ::= <Common Header>\r
+ * [<Client Handle>]\r
+ * [<Integrity>]\r
+ *\r
+ * This message indicates that the remote PDP wishes the client (which\r
+ * appears in the common header) to re-send its state. If the optional\r
+ * Client Handle is present, only the state associated with this handle\r
+ * is synchronized. If the PEP does not recognize the requested handle,\r
+ * it MUST immediately send a DRQ message to the PDP for the handle that\r
+ * was specified in the SSQ message. If no handle is specified in the\r
+ * SSQ message, all the active client state MUST be synchronized with\r
+ * the PDP.\r
+ *\r
+ * The client performs state synchronization by re-issuing request\r
+ * queries of the specified client-type for the existing state in the\r
+ * PEP. When synchronization is complete, the PEP MUST issue a\r
+ * synchronize state complete message to the PDP.\r
+ *\r
+ * <Synchronize State Complete> ::= <Common Header>\r
+ * [<Client Handle>]\r
+ * [<Integrity>]\r
+ *\r
+ * The Client Handle object only needs to be included if the corresponding\r
+ * Synchronize State Message originally referenced a specific handle.\r
+ *\r
+ * @version COPSSyncStateMsg.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSSyncStateMsg extends COPSMsg {\r
+\r
+ /* COPSHeader coming from base class */\r
+ private COPSHandle _clientHandle;\r
+ private COPSIntegrity _integrity;\r
+\r
+ public COPSSyncStateMsg() {\r
+ _clientHandle = null;\r
+ _integrity = null;\r
+ }\r
+\r
+ /**\r
+ Parse data and create COPSSyncStateMsg object\r
+ */\r
+ protected COPSSyncStateMsg(byte[] data) throws COPSException {\r
+ _clientHandle = null;\r
+ _integrity = null;\r
+ parse(data);\r
+ }\r
+\r
+ /**\r
+ * Checks the sanity of COPS message and throw an\r
+ * COPSException when data is bad.\r
+ */\r
+ public void checkSanity() throws COPSException {\r
+ if (_hdr == null) {\r
+ throw new COPSException("Bad message format");\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Add message header\r
+ *\r
+ * @param hdr a COPSHeader\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHeader hdr) throws COPSException {\r
+ if (hdr == null)\r
+ throw new COPSException ("Null Header");\r
+ if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
+ (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
+ throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
+ _hdr = hdr;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add client handle to the message\r
+ *\r
+ * @param handle a COPSHandle\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSHandle handle) throws COPSException {\r
+ if (handle == null)\r
+ throw new COPSException ("Null Handle");\r
+\r
+ //Message integrity object should be the very last one\r
+ //If it is already added\r
+ if (_integrity != null)\r
+ throw new COPSException ("No null Handle");\r
+\r
+ _clientHandle = handle;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Add integrity object\r
+ *\r
+ * @param integrity a COPSIntegrity\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ public void add (COPSIntegrity integrity) throws COPSException {\r
+ if (integrity == null)\r
+ throw new COPSException ("Null Integrity");\r
+ if (!integrity.isMessageIntegrity())\r
+ throw new COPSException ("Error Integrity");\r
+ _integrity = integrity;\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * If the optional Client Handle is present, only the state associated\r
+ * with this handle is synchronized. If no handle is specified in the\r
+ * SSQ message, all the active client state MUST be synchronized with\r
+ * the PDP.\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasClientHandle() {\r
+ return (_clientHandle != null);\r
+ }\r
+\r
+ /**\r
+ * Get client Handle\r
+ *\r
+ * @return a COPSHandle\r
+ *\r
+ */\r
+ public COPSHandle getClientHandle() {\r
+ return _clientHandle;\r
+ }\r
+\r
+ /**\r
+ * Returns true if it has integrity object\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean hasIntegrity() {\r
+ return (_integrity != null);\r
+ }\r
+\r
+ /**\r
+ * Get Integrity. Should check hasIntegrity() before calling\r
+ *\r
+ * @return a COPSIntegrity\r
+ *\r
+ */\r
+ public COPSIntegrity getIntegrity() {\r
+ return (_integrity);\r
+ }\r
+\r
+ /**\r
+ * Writes data to given socket\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ // checkSanity();\r
+ if (_hdr != null) _hdr.writeData(id);\r
+ if (_clientHandle != null) _clientHandle.writeData(id);\r
+ if (_integrity != null) _integrity.writeData(id);\r
+\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(byte[] data) throws COPSException {\r
+ super.parseHeader(data);\r
+\r
+ while (_dataStart < _dataLength) {\r
+ byte[] buf = new byte[data.length - _dataStart];\r
+ System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
+\r
+ COPSObjHeader objHdr = new COPSObjHeader (buf);\r
+ switch (objHdr.getCNum()) {\r
+ case COPSObjHeader.COPS_HANDLE: {\r
+ _clientHandle = new COPSHandle(buf);\r
+ _dataStart += _clientHandle.getDataLength();\r
+ }\r
+ break;\r
+ case COPSObjHeader.COPS_MSG_INTEGRITY: {\r
+ _integrity = new COPSIntegrity(buf);\r
+ _dataStart += _integrity.getDataLength();\r
+ }\r
+ break;\r
+ default: {\r
+ throw new COPSException("Bad Message format, unknown object type");\r
+ }\r
+ }\r
+ }\r
+ checkSanity();\r
+ }\r
+\r
+ /**\r
+ * Parse data\r
+ *\r
+ * @param hdr a COPSHeader\r
+ * @param data a byte[]\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
+\r
+ if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
+ (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
+ throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
+\r
+ _hdr = hdr;\r
+ parse(data);\r
+ setMsgLength();\r
+ }\r
+\r
+ /**\r
+ * Set the message length, base on the set of objects it contains\r
+ *\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ protected void setMsgLength() throws COPSException {\r
+ short len = 0;\r
+ if (_clientHandle != null) len += _clientHandle.getDataLength();\r
+ if (_integrity != null) len += _integrity.getDataLength();\r
+ _hdr.setMsgLength(len);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _hdr.dump(os);\r
+\r
+ if (_clientHandle != null)\r
+ _clientHandle.dump(os);\r
+\r
+ if (_integrity != null) {\r
+ _integrity.dump(os);\r
+ }\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+\r
+/**\r
+ * COPS Timer Object\r
+ *\r
+ * @version COPSTimer.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSTimer extends COPSObjBase {\r
+\r
+ protected COPSObjHeader _objHdr;\r
+ private short _reserved;\r
+ private short _timerValue;\r
+\r
+ /**\r
+ * Returns size in number of octects, including header\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getDataLength() {\r
+ //Add the size of the header also\r
+ return (_objHdr.getDataLength());\r
+ }\r
+\r
+ /**\r
+ * Method getTimerVal\r
+ *\r
+ * @return a short\r
+ *\r
+ */\r
+ public short getTimerVal() {\r
+ return _timerValue;\r
+ };\r
+\r
+ /**\r
+ * Method isTimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isTimer() {\r
+ return true;\r
+ };\r
+\r
+ /**\r
+ * Method isKATimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isKATimer() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Method isAcctTimer\r
+ *\r
+ * @return a boolean\r
+ *\r
+ */\r
+ public boolean isAcctTimer() {\r
+ return false;\r
+ };\r
+\r
+ /**\r
+ * Write data to given socket in Network byte order\r
+ *\r
+ * @param id a Socket\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void writeData(Socket id) throws IOException {\r
+ _objHdr.writeData(id);\r
+\r
+ byte[] buf = new byte[4];\r
+\r
+ buf[0] = (byte) (_reserved >> 8);\r
+ buf[1] = (byte) _reserved;\r
+ buf[2] = (byte) (_timerValue >> 8);\r
+ buf[3] = (byte) _timerValue;\r
+ COPSUtil.writeData(id, buf, 4);\r
+ }\r
+\r
+ protected COPSTimer(short timeVal) {\r
+ _objHdr = new COPSObjHeader();\r
+ //Time range is 1 - 65535 seconds\r
+ _timerValue = timeVal;\r
+ // _objHdr.setDataLength(sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ * Receive data that is in netwrok byte order and fill in the obj.\r
+ */\r
+ protected COPSTimer(byte[] dataPtr) {\r
+ _objHdr = new COPSObjHeader();\r
+ _objHdr.parse(dataPtr);\r
+ // _objHdr.checkDataLength();\r
+\r
+ _reserved |= ((short) dataPtr[4]) << 8;\r
+ _reserved |= ((short) dataPtr[5]) & 0xFF;\r
+ _timerValue |= ((short) dataPtr[6]) << 8;\r
+ _timerValue |= ((short) dataPtr[7]) & 0xFF;\r
+\r
+ // _objHdr.setDataLength(sizeof(u_int32_t));\r
+ _objHdr.setDataLength((short) 4);\r
+ }\r
+\r
+ /**\r
+ * Write an object textual description in the output stream\r
+ *\r
+ * @param os an OutputStream\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ public void dump(OutputStream os) throws IOException {\r
+ _objHdr.dump(os);\r
+ os.write(new String("Timer val: " + _timerValue + "\n").getBytes());\r
+ }\r
+\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+\r
+// import org.umu.cops.common.COPSDebug;\r
+\r
+/**\r
+ * COPS Transceiver\r
+ *\r
+ * @version COPSTransceiver.java, v 1.00 2003\r
+ *\r
+ */\r
+public class COPSTransceiver {\r
+\r
+ /**\r
+ * Method sendMsg\r
+ *\r
+ * @param msg a COPSMsg\r
+ * @param fd a Socket\r
+ *\r
+ * @throws IOException\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ static public void sendMsg(COPSMsg msg, Socket fd) throws IOException, COPSException {\r
+ // COPSDebug.out("COPSTransceiver", "sendMsg ******************************** START" );\r
+\r
+ msg.checkSanity();\r
+ msg.writeData(fd);\r
+\r
+ // COPSDebug.out("COPSTransceiver", "sendMsg ******************************** END" );\r
+ }\r
+\r
+ /**\r
+ * Method receiveMsg\r
+ *\r
+ * @param fd a Socket\r
+ *\r
+ * @return a COPSMsg\r
+ *\r
+ * @throws IOException\r
+ * @throws COPSException\r
+ *\r
+ */\r
+ static public COPSMsg receiveMsg (Socket fd) throws IOException, COPSException {\r
+ int nread = 0;\r
+ byte[] hBuf = new byte[8];\r
+\r
+ // COPSDebug.out("COPSTransceiver", "receiveMsg ******************************** START" );\r
+\r
+ nread = COPSUtil.readData(fd, hBuf, 8);\r
+\r
+ if (nread == 0) {\r
+ throw new COPSException("Error reading connection");\r
+ }\r
+\r
+ if (nread != 8) {\r
+ throw new COPSException("Bad COPS message");\r
+ }\r
+\r
+ COPSHeader hdr = new COPSHeader(hBuf);\r
+ int dataLen = hdr.getMsgLength() - hdr.getHdrLength();\r
+ // COPSDebug.out("COPSTransceiver", "COPS Msg length :[" + dataLen + "]\n" );\r
+ byte[] buf = new byte[dataLen + 1];\r
+ nread = 0;\r
+\r
+ nread = COPSUtil.readData(fd, buf, dataLen);\r
+ buf[dataLen] = (byte) '\0';\r
+ // COPSDebug.out("COPSTransceiver", "Data read length:[" + nread + "]\n");\r
+\r
+ if (nread != dataLen) {\r
+ throw new COPSException("Bad COPS message");\r
+ }\r
+\r
+ COPSMsgParser prser = new COPSMsgParser();\r
+ COPSMsg msg = prser.parse(hdr, buf);\r
+\r
+ // COPSDebug.out("COPSTransceiver", "Message received");\r
+\r
+ // COPSDebug.out("COPSTransceiver", "receiveMsg ******************************** END" );\r
+ return msg;\r
+ }\r
+}\r
+\r
--- /dev/null
+/*\r
+ * Copyright (c) 2003 University of Murcia. All rights reserved.\r
+ * --------------------------------------------------------------\r
+ * For more information, please see <http://www.umu.euro6ix.org/>.\r
+ */\r
+\r
+package org.umu.cops.stack;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+\r
+/**\r
+ * COPS Utils\r
+ *\r
+ * @version COPSUtil.java, v 2.00 2004\r
+ *\r
+ */\r
+public class COPSUtil {\r
+\r
+ /**\r
+ * Method writeData\r
+ *\r
+ * @param id a Socket\r
+ * @param data a byte[]\r
+ * @param len an int\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ static void writeData(Socket id, byte[] data, int len) throws IOException {\r
+ OutputStream output;\r
+ output = id.getOutputStream();\r
+\r
+ output.write(data,0,len);\r
+ }\r
+\r
+ /**\r
+ * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error\r
+ * bRead returns the bytes read\r
+ *\r
+ * @param connId a Socket\r
+ * @param dataRead a byte[]\r
+ * @param nchar an int\r
+ *\r
+ * @return an int\r
+ *\r
+ * @throws IOException\r
+ *\r
+ */\r
+ static int readData(Socket connId, byte[] dataRead, int nchar) throws IOException {\r
+ InputStream input;\r
+ input = connId.getInputStream();\r
+\r
+ int nread = 0;\r
+ int startTime = (int) (new Date().getTime());\r
+ do {\r
+ if (input.available() != 0) {\r
+ nread += input.read(dataRead,nread,nchar-nread);\r
+ startTime = (int) (new Date().getTime());\r
+ } else {\r
+ int nowTime = (int) (new Date().getTime());\r
+ if ((int)(nowTime - startTime) > 2000)\r
+ break;\r
+ }\r
+ } while (nread != nchar);\r
+\r
+ return nread;\r
+ }\r
+}\r
+\r
--- /dev/null
+#----------------------------------------------------------------------------------
+# This file contains the common properties of the PCMM
+#----------------------------------------------------------------------------------
+#Port used by the PCMM
+pcmm.port=3918
+#Pool size, determining the number of connections that could be established with CMTSs
+pcmm.ps.pool.size=32
+#Default keep-alive timer value (secs)
+pcmm.keep.alive.timer = 30
+#Default accounting timer value (secs)
+pcmm.accounting.timer = 0;
+#default mask
+pcmm.default.mask=0.0.0.0
+#timeout for the connection in ms
+pcmm.default.timeout=-1
\ No newline at end of file
--- /dev/null
+package org.pcmm.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.gates.impl.BestEffortService;
+
+public class BestEffortServiceTest {
+
+ private BestEffortService be;
+
+ @Before
+ public void init() {
+ be = new BestEffortService((byte) 7);
+ be.getAuthorizedEnvelop().setMinimumReservedTrafficRate(192);
+ be.getCommittedEnvelop().setRequiredAttributeMask(938);
+ be.getReservedEnvelop().setTrafficPriority((byte) 5);
+ }
+
+ @Test
+ public void testGetAsBinaryArray() {
+ assertTrue(be.getAsBinaryArray().length == 116);
+ }
+
+ @Test
+ public void testBestEffortServiceByteArray() {
+ assertTrue(new BestEffortService(be.getAsBinaryArray())
+ .getAuthorizedEnvelop().getMinimumReservedTrafficRate() == 192);
+ assertTrue(new BestEffortService(be.getAsBinaryArray())
+ .getReservedEnvelop().getTrafficPriority() == 5);
+ assertTrue(new BestEffortService(be.getAsBinaryArray())
+ .getCommittedEnvelop().getRequiredAttributeMask() == 938);
+
+ }
+
+ @Test
+ public void testGetEnvelop() {
+ assertTrue(be.getEnvelop() == 7);
+ }
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.test;
+
+import org.pcmm.rcd.ICMTS;
+import org.pcmm.rcd.IPCMMPolicyServer;
+import org.pcmm.rcd.IPCMMPolicyServer.IPSCMTSClient;
+import org.pcmm.rcd.impl.CMTS;
+import org.pcmm.rcd.impl.PCMMPolicyServer;
+
+/**
+ *
+ */
+public class Main {
+
+ /**
+ * @param args
+ */
+ public static void main(String[] args) {
+ ICMTS icmts = new CMTS();
+ icmts.startServer();
+ IPCMMPolicyServer ps = new PCMMPolicyServer();
+ IPSCMTSClient client = ps.requestCMTSConnection("localhost");
+ client.gateSet();
+ // IWorkerPool pool = new WorkerPool(2);
+ // IWorker worker = new Worker(new Callable<String>() {
+ // @Override
+ // public String call() throws Exception {
+ // System.out
+ // .println("Main.main(...).new Callable() {...}.call()");
+ // return null;
+ // }
+ // });
+ // IWorker worker2 = new Worker(new Callable<String>() {
+ // @Override
+ // public String call() throws Exception {
+ // System.out
+ // .println("|||||||Main.main(...).new Callable() {...}.call()||||||||||||");
+ // return null;
+ // }
+ // });
+ // pool.schedule(worker2, 2000);
+ // pool.schedule(worker, 500);
+ // pool.recycle();
+
+
+ }
+}
--- /dev/null
+package org.pcmm.test;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.gates.IPCMMError;
+import org.pcmm.gates.impl.PCMMError;
+
+public class PCErrorTest {
+
+ IPCMMError error;
+
+ @Before
+ public void init() {
+ error = new PCMMError();
+ error.setErrorCode((short) 1);
+ }
+
+ @Test
+ public void testGetDescription() {
+ for (IPCMMError.Description d : IPCMMError.Description.values()) {
+ error.setErrorCode(d.getCode());
+ Assert.assertNotNull(error.getDescription());
+ System.out.println(error.getDescription());
+ }
+
+ }
+
+}
--- /dev/null
+/**
+ *
+ */
+package org.pcmm.test;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.pcmm.utils.PCMMUtils;
+
+/**
+ * @author RH030971
+ *
+ */
+public class PCMMGateReqTest {
+
+ /**
+ * Test method for
+ * {@link org.pcmm.gates.impl.PCMMGateReq#PCMMGateReq(byte[])}.
+ */
+ @Test
+ public void testPCMMGateReqByteArray() {
+/*
+ new PCMMGateReq(
+ PCMMUtils
+ .ReadBinaryDump("traces/COPSReportClientSI09871088-5329-44ff-b1db-0ea3a544de1e.bin"));
+
+*/
+ }
+
+ /**
+ * Test method for {@link org.pcmm.gates.impl.PCMMGateReq#getData()}.
+ */
+ @Test
+ public void testGetData() {
+ // fail("Not yet implemented");
+ }
+
+}
--- /dev/null
+package org.pcmm.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.pcmm.objects.PCMMIDHolder;
+import org.pcmm.objects.PCMMResourceSet;
+import org.pcmm.objects.PCMMResourcesMapper;
+
+public class PCMMResourceSetTest {
+
+
+ @Test
+ public void testGetMappedResources() {
+
+ int flowID=100;
+ short trId=(short)123;
+ //typical use of PCMMresourceSet to add a new mapping
+ PCMMResourceSet.getInstance().mapResources( /* flow ID */flowID,
+ new PCMMResourcesMapper<Short, PCMMIDHolder>(/* transactionID */(short)trId,
+ /* PCMMIDHolder */new PCMMIDHolder(/* flowID */flowID, /* gateID */0, /* transactionID */trId)));
+
+ // if we want to retrieve or update mapped data
+ PCMMIDHolder holder = (PCMMIDHolder) PCMMResourceSet.getInstance().getMappedResources(/* flow ID */flowID).getValue();
+ short transID=(short) PCMMResourceSet.getInstance().getMappedResources(/* flow ID */flowID).getKey();
+
+ assertTrue(holder.getFlowID()==flowID);
+ assertTrue(holder.getTransactionID()==trId);
+ assertTrue(transID==trId);
+ //update gate ID
+ holder.setGateID(/*gate ID*/ 1234568);
+
+ assertTrue(((PCMMIDHolder) PCMMResourceSet.getInstance().getMappedResources(/* flow ID */flowID).getValue()).getGateID()==1234568);
+
+
+
+ }
+
+}
--- /dev/null
+package org.pcmm.test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.pcmm.rcd.ICMTS;
+import org.pcmm.rcd.IPCMMPolicyServer;
+import org.pcmm.rcd.IPCMMPolicyServer.IPSCMTSClient;
+import org.pcmm.rcd.impl.CMTS;
+import org.pcmm.rcd.impl.PCMMPolicyServer;
+
+public class PCMMWorkflowTest {
+
+ /**
+ * CMTS emulator, when testing with a real CMTS this should be set to null
+ * and shoudln't be started
+ */
+ private static ICMTS cmts;
+ /**
+ * CMTS host address, when testing with a real CMTS this should be CMTS
+ * address
+ */
+ private static InetAddress host;
+
+ private static IPCMMPolicyServer server;
+ private static IPSCMTSClient client;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ // comment this when using real CMTS
+ // ###################################
+ cmts = new CMTS();
+ cmts.startServer();
+ // ###################################
+
+ server = new PCMMPolicyServer();
+ try {
+ // this should be set to the cmts host ex :
+ // InetAddress.getByName("10.10.10.10") or
+ // InetAddress.getByName("my-cmts-host-name")
+ host = InetAddress.getLocalHost();
+ assertNotNull(host);
+ } catch (UnknownHostException uhe) {
+ fail("could not get host address ");
+ }
+ setupConnection();
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ tearDown();
+ if (cmts != null)
+ cmts.stopServer();
+ }
+
+ public static void setupConnection() {
+ client = server.requestCMTSConnection(host);
+ assertNotNull(client);
+ }
+
+ public static void tearDown() throws Exception {
+ assertNotNull(client);
+ assertTrue("Client disconnection failed", client.disconnect());
+ }
+
+
+ //@Test
+ public void testGateSet() {
+ assertNotNull(client);
+ assertTrue("Gate-Set failed", client.gateSet());
+ }
+
+ //@Test
+ public void testGateDelete() {
+ assertNotNull(client);
+ assertTrue("Gate-Delete failed", client.gateDelete());
+
+ }
+
+ //@Test
+ public void testGateInfo() {
+ assertNotNull(client);
+ assertTrue("Gate-Info failed", client.gateInfo());
+ }
+
+ //@Test
+ public void testGateSynchronize() {
+ assertNotNull(client);
+ assertTrue("Gate-Synchronize failed", client.gateSynchronize());
+ }
+
+}
--- /dev/null
+This package contains the test set for the PCMM driver,
+To test the whole workflow use the junit based test : PCMMWorkflowTest.java
\ No newline at end of file
<packaging>pom</packaging>
<modules>
+ <module>packetcable-driver</module>
<module>packetcable-model</module>
<module>packetcable-consumer</module>
<module>packetcable-provider</module>