Merge changes I99dfd3ce,Ib55b1ca2,I584ed58f,I0020da7e,If9376252
authorThomas Kee <xsited@yahoo.com>
Sat, 18 Apr 2015 00:00:45 +0000 (00:00 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Sat, 18 Apr 2015 00:00:46 +0000 (00:00 +0000)
* changes:
  Removed existing \t (tab) characters per code review to change 18467 from Alexis de Talhouet.
  Removed existing \r characters per code review to change 18469 from Alexis de Talhouet.
  Replaced System.err.println() call with a logger.
  Replaced System.out.println() calls with a logger.
  Replaced System.out.println() calls with a logger and removed several compiler warnings.

packetcable-driver/src/main/java/org/pcmm/rcd/impl/PCMMPolicyServer.java
packetcable-driver/src/main/java/org/pcmm/utils/PCMMUtils.java
packetcable-driver/src/main/java/org/umu/cops/ospep/COPSPepOSAgent.java

index bd763ebe24bb8c45ba1314f34a6f31a4ab98b99e..06419eaccf29b9bc84e92c6b079c072474682cbf 100644 (file)
  */
 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.*;
 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.gates.impl.*;
 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.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 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;
+import org.umu.cops.stack.*;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Properties;
 
 /**
- * 
  * 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;
-               }
-       }
+public class PCMMPolicyServer extends AbstractPCMMServer implements IPCMMPolicyServer {
+
+    public final static Logger logger = LoggerFactory.getLogger(PCMMPolicyServer.class);
+
+    /**
+     * 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 = (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 = 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 = 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 = 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 = 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;
+            // 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) {
+                    logger.error("Error getByName", unae);
+                }
+                ((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) {
+                    logger.error("Error getByName", unae);
+                }
+                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;
+        }
+    }
 
 }
index 4762370c55d408114bb21679a6b92ed3a8d7e4bc..bb2abe5244e6069a5b142f4c52f14ebaceed35f2 100644 (file)
@@ -3,6 +3,9 @@
  */
 package org.pcmm.utils;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -10,12 +13,14 @@ import java.io.IOException;
 
 public class PCMMUtils {
 
+    public final static Logger logger = LoggerFactory.getLogger(PCMMUtils.class);
+
     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);
+            logger.info("Open fileName " + fileName);
             FileOutputStream outputStream = new FileOutputStream(fileName);
 
             // write() writes as many bytes from the buffer
@@ -29,9 +34,9 @@ public class PCMMUtils {
             // Always close files.
             outputStream.close();
 
-            System.out.println("Wrote " + buffer.length + " bytes");
+            logger.info("Wrote " + buffer.length + " bytes");
         } catch (IOException ex) {
-            System.out.println("Error writing file '" + fileName + "'");
+            logger.error("Error writing file '" + fileName + "'", ex);
             // Or we could just do this:
             // ex.printStackTrace();
         }
@@ -53,12 +58,12 @@ public class PCMMUtils {
             // Always close files.
             inputStream.close();
 
-            System.out.println("Read " + total + " bytes");
+            logger.info("Read " + total + " bytes");
             return buffer;
         } catch (FileNotFoundException ex) {
-            System.out.println("Unable to open file '" + fileName + "'");
+            logger.error("Unable to open file '" + fileName + "'", ex);
         } catch (IOException ex) {
-            System.out.println("Error reading file '" + fileName + "'");
+            logger.error("Error reading file '" + fileName + "'", ex);
             // Or we could just do this:
             // ex.printStackTrace();
         }
index 9c80a38d094a2206dc5945f40851a0a8d7646141..4cd8256b0d41aefc7ccef8a4e921ba3ed4c369c3 100644 (file)
-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
+package org.umu.cops.ospep;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Hashtable;
+import java.util.Vector;
+
+/**
+ * This is a outsourcing COPS PEP. Responsible for making
+ * connection to the PDP and maintaining it
+ */
+public class COPSPepOSAgent {
+
+    public final static Logger logger = LoggerFactory.getLogger(COPSPepOSAgent.class);
+
+    /**
+        PEP's identifier
+     */
+    private String _pepID;
+
+    /**
+        PEP's client-type
+     */
+    private short _clientType;
+
+    /**
+        PDP host name
+     */
+    private String _psHost;
+
+    /**
+        PDP port
+     */
+    private int _psPort;
+
+    /**
+        PEP-PDP connection manager
+     */
+    private COPSPepOSConnection _conn;
+
+    /**
+        COPS error returned by the PDP
+     */
+    private COPSError _error;
+
+    /**
+     * Policy data processor class
+     */
+    private COPSPepOSDataProcess _process;
+
+    /**
+     * Creates a PEP agent
+     * @param    pepID              PEP-ID
+     * @param    clientType         Client-type
+     */
+    public COPSPepOSAgent(String pepID, short clientType) {
+        _pepID = pepID;
+        _clientType = clientType;
+    }
+
+    /**
+     * Creates a PEP agent with a PEP-ID equal to "noname"
+     * @param    clientType         Client-type
+     */
+    public COPSPepOSAgent(short clientType) {
+        // PEPId
+        try {
+            _pepID = InetAddress.getLocalHost().getHostName();
+        } catch (Exception e) {
+            _pepID = "noname";
+        }
+
+        _clientType = clientType;
+    }
+
+    /**
+     * Gets the identifier of the PEP
+     * @return  PEP-ID
+     */
+    public String getPepID() {
+        return _pepID;
+    }
+
+    /**
+     * Sets the policy data processor
+     * @param aDataProcess  Data processor class
+     */
+    public void setDataProcess(COPSPepOSDataProcess aDataProcess) {
+        this._process = aDataProcess;
+    }
+
+    /**
+     * Gets the COPS client-type
+     * @return  PEP's client-type
+     */
+    public short getClientType() {
+        return _clientType;
+    }
+
+    /**
+     * Gets PDP host name
+     * @return  PDP host name
+     */
+    public String getPDPName() {
+        return _psHost;
+    }
+
+    /**
+     * Gets the port of the PDP
+     * @return  PDP port
+     */
+    public int getPDPPort() {
+        return _psPort;
+    }
+
+    /**
+     * Connects to a PDP
+     * @param    psHost              PDP host name
+     * @param    psPort              PDP port
+     * @return   <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 IOException, COPSException, COPSPepException {
+        // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");
+        _psHost = psHost;
+        _psPort = psPort;
+
+        // Check whether it already exists
+        if (_conn == null)
+            _conn = processConnection(psHost,psPort);
+        else {
+            // Check whether it's closed
+            if (_conn.isClosed())
+                _conn = processConnection(psHost,psPort);
+            else {
+                disconnect(null);
+                _conn = processConnection(psHost,psPort);
+            }
+        }
+
+        return (_conn != null);
+    }
+
+    /**
+     * Gets the connection manager
+     * @return  PEP-PDP connection manager object
+     */
+    public COPSPepOSConnection getConnection() {
+        return (_conn);
+    }
+
+    /**
+     * Gets the COPS error returned by the PDP
+     * @return   <tt>COPSError</tt> returned by PDP
+     */
+    public COPSError getConnectionError() {
+        return _error;
+    }
+
+    /**
+     * Disconnects from the PDP
+     * @param error Reason
+     * @throws COPSException
+     * @throws IOException
+     */
+    public void disconnect(COPSError error) throws COPSException, IOException {
+        COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);
+        COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
+        closeMsg.add(cHdr);
+        if (error != null)
+            closeMsg.add(error);
+
+        closeMsg.writeData(_conn.getSocket());
+        _conn.close();
+        _conn = null;
+    }
+
+    /**
+     * Adds a request state to the connection manager.
+     * @param clientSIs The client data from the outsourcing event
+     * @return  The newly created connection manager
+     * @throws COPSPepException
+     * @throws COPSException
+     */
+    public COPSPepOSReqStateMan addRequestState(COPSHandle handle, Vector clientSIs) throws COPSPepException, COPSException {
+        if (_conn != null)
+            return _conn.addRequestState(handle.getId().str(), _process, clientSIs);
+
+        return null;
+    }
+
+    /**
+     * Queries the connection manager to delete a request state
+     * @param man   Request state manager
+     * @throws COPSPepException
+     * @throws COPSException
+     */
+    public void deleteRequestState (COPSPepOSReqStateMan man) throws COPSPepException, COPSException {
+        if (_conn != null)
+            _conn.deleteRequestState(man);
+    }
+
+    /**
+     * Gets all the request state managers
+     * @return  A <tt>Hashtable</tt> holding all active request state managers
+     */
+    public Hashtable getReqStateMans() {
+        if (_conn != null)
+            return _conn.getReqStateMans();
+        return null;
+    }
+
+    /**
+     * 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 COPSPepOSConnection processConnection(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException {
+        // Build OPN
+        COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);
+
+        COPSPepId pepId = new COPSPepId();
+        COPSData d = new COPSData(_pepID);
+        pepId.setData(d);
+
+        COPSClientOpenMsg msg = new COPSClientOpenMsg();
+        msg.add(hdr);
+        msg.add(pepId);
+
+        // Create socket and send OPN
+        InetAddress addr = InetAddress.getByName(psHost);
+        Socket socket = new Socket(addr,psPort);
+        msg.writeData(socket);
+
+        // Get response
+        COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
+
+        if (recvmsg.getHeader().isAClientAccept()) {
+            COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
+
+            // Support
+            if (cMsg.getIntegrity() != null) {
+                throw new COPSPepException("Unsupported object (Integrity)");
+            }
+
+            // Mandatory KATimer
+            COPSKATimer kt = cMsg.getKATimer();
+            if (kt == null)
+                throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");
+            short _kaTimeVal = kt.getTimerVal();
+
+            // ACTimer
+            COPSAcctTimer at = cMsg.getAcctTimer();
+            short _acctTimer = 0;
+            if (at != null)
+                _acctTimer = at.getTimerVal();
+
+            // Create connection manager
+            COPSPepOSConnection conn = new COPSPepOSConnection(_clientType, socket);
+            conn.setKaTimer(_kaTimeVal);
+            conn.setAcctTimer(_acctTimer);
+            new Thread(conn).start();
+
+            return conn;
+        } else if (recvmsg.getHeader().isAClientClose()) {
+            COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
+            _error = cMsg.getError();
+            socket.close();
+            return null;
+        } else { // other message types are unexpected
+            throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
+        }
+    }
+
+    /**
+     * Creates a new request state when the outsourcing event is detected.
+     * @param handle The COPS handle for this request
+     * @param clientSIs The client specific data for this request
+     */
+    public void dispatchEvent(COPSHandle handle, Vector clientSIs) {
+        try {
+            addRequestState(handle, clientSIs);
+        } catch (Exception e) {
+            logger.error("Error adding request state", e);
+        }
+    }
+}