-/**\r
- @header@\r
- */\r
-\r
-package org.pcmm;\r
-\r
-/*\r
-import java.io.*;\r
-import java.util.UUID.*;\r
-*/\r
-import org.pcmm.gates.ITransactionID;\r
-import org.pcmm.gates.impl.PCMMGateReq;\r
-import org.umu.cops.common.COPSDebug;\r
-import org.umu.cops.prpdp.COPSPdpException;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Arrays;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-/*\r
-import org.pcmm.base.IPCMMBaseObject;\r
-import org.pcmm.gates.IAMID;\r
-import org.pcmm.gates.IGateID;\r
-import org.pcmm.gates.ISubscriberID;\r
-import org.pcmm.gates.IPCError;\r
-import org.pcmm.gates.impl.AMID;\r
-import org.pcmm.gates.impl.GateID;\r
-import org.pcmm.gates.impl.SubscriberID;\r
-import org.pcmm.gates.impl.TransactionID;\r
-import org.pcmm.gates.impl.PCError;\r
-*/\r
-\r
-\r
-\r
-\r
-/**\r
- * State manager class for provisioning requests, at the PDP side.\r
- */\r
-public class PCMMPdpReqStateMan {\r
-\r
- /**\r
- * Request State created\r
- */\r
- public final static short ST_CREATE = 1;\r
- /**\r
- * Request received\r
- */\r
- public final static short ST_INIT = 2;\r
- /**\r
- * Decisions sent\r
- */\r
- public final static short ST_DECS = 3;\r
- /**\r
- * Report received\r
- */\r
- public final static short ST_REPORT = 4;\r
- /**\r
- * Request State finalized\r
- */\r
- public final static short ST_FINAL = 5;\r
- /**\r
- * New Request State solicited\r
- */\r
- public final static short ST_NEW = 6;\r
- /**\r
- * Delete Request State solicited\r
- */\r
- public final static short ST_DEL = 7;\r
- /**\r
- * SYNC request sent\r
- */\r
- public final static short ST_SYNC = 8;\r
- /**\r
- * SYNC completed\r
- */\r
- public final static short ST_SYNCALL = 9;\r
- /**\r
- * Close connection received\r
- */\r
- public final static short ST_CCONN = 10;\r
- /**\r
- * Keep-alive timeout\r
- */\r
- public final static short ST_NOKA = 11;\r
- /**\r
- * Accounting timeout\r
- */\r
- public final static short ST_ACCT = 12;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Object for performing policy data processing\r
- */\r
- protected PCMMPdpDataProcess _process;\r
-\r
- /**\r
- * Current state of the request being managed\r
- */\r
- protected short _status;\r
-\r
- /** COPS message transceiver used to send COPS messages */\r
- protected PCMMPdpMsgSender _sender;\r
-\r
- /**\r
- * Creates a request state manager\r
- * @param clientType Client-type\r
- * @param clientHandle Client handle\r
- */\r
- public PCMMPdpReqStateMan(short clientType, String clientHandle) {\r
- _handle = new COPSHandle(new COPSData(clientHandle));\r
- _clientType = clientType;\r
- _status = ST_CREATE;\r
- }\r
-\r
- /**\r
- * Gets the client handle\r
- * @return Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return Client-type value\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Gets the status of the request\r
- * @return Request state value\r
- */\r
- public short getStatus() {\r
- return _status;\r
- }\r
-\r
- /**\r
- * Gets the policy data processing object\r
- * @return Policy data processing object\r
- */\r
- public PCMMPdpDataProcess getDataProcess() {\r
- return _process;\r
- }\r
-\r
- /**\r
- * Sets the policy data processing object\r
- * @param process Policy data processing object\r
- */\r
- public void setDataProcess(PCMMPdpDataProcess process) {\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Called when COPS sync is completed\r
- * @param repMsg COPS sync message\r
- * @throws COPSPdpException\r
- */\r
- protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
- throws COPSPdpException {\r
-\r
- _status = ST_SYNCALL;\r
-\r
- // maybe we should notifySyncComplete ...\r
- }\r
-\r
- /**\r
- * Initializes a new request state over a socket\r
- * @param sock Socket to the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void initRequestState(Socket sock)\r
- throws COPSPdpException {\r
- // Inits an object for sending COPS messages to the PEP\r
- _sender = new PCMMPdpMsgSender(_clientType, _handle, sock);\r
-\r
- // Initial state\r
- _status = ST_INIT;\r
- }\r
-\r
-\r
-\r
- /**\r
- * Processes a COPS request\r
- * @param msg COPS request received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processRequest(COPSReqMsg msg)\r
- throws COPSPdpException {\r
-\r
- COPSHeader hdrmsg = msg.getHeader();\r
- COPSHandle handlemsg = msg.getClientHandle();\r
- COPSContext contextmsg = msg.getContext();\r
-\r
- //** Analyze the request\r
- //**\r
-\r
- /* <Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Context>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
- *\r
- * Very important, this is actually being treated like this:\r
- * <Named ClientSI> ::= <PRID> | <EPD>\r
- *\r
-\r
- // Named ClientSI\r
- Vector clientSIs = msg.getClientSI();\r
- Hashtable reqSIs = new Hashtable(40);\r
- String strobjprid = new String();\r
- for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
- switch (obj.getSNum())\r
- {\r
- case COPSPrObjBase.PR_PRID:\r
- strobjprid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- reqSIs.put(strobjprid, obj.getData().str());\r
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- //** Here we must retrieve a decision depending on\r
- //** the supplied ClientSIs\r
- // reqSIs is a hashtable with the prid and epds\r
-\r
- // ................\r
- //\r
- Hashtable removeDecs = new Hashtable();\r
- Hashtable installDecs = new Hashtable();\r
- _process.setClientData(this, reqSIs);\r
-\r
- removeDecs = _process.getRemovePolicy(this);\r
- installDecs = _process.getInstallPolicy(this);\r
-\r
- //** We create the SOLICITED decision\r
- //**\r
- _sender.sendDecision(removeDecs, installDecs);\r
- _status = ST_DECS;\r
- */\r
- }\r
-\r
- /**\r
- * Processes a report\r
- * @param msg Report message from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processReport(COPSReportMsg msg)\r
- throws COPSPdpException {\r
-\r
- //** Analyze the report\r
- //**\r
-\r
- /*\r
- * <Report State> ::= <Common Header>\r
- * <Client Handle>\r
- * <Report Type>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
- * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
- *\r
- * Important, <Named ClientSI> is not parsed\r
- */\r
-\r
- // COPSHeader hdrmsg = msg.getHeader();\r
- // COPSHandle handlemsg = msg.getClientHandle();\r
-\r
- // WriteBinaryDump("COPSReportMessage", msg.getData().getData());\r
- // Report Type\r
- COPSReportType rtypemsg = msg.getReport();\r
-\r
- // Named ClientSI\r
- Vector clientSIs = msg.getClientSI();\r
- COPSClientSI myclientSI = (COPSClientSI) msg.getClientSI().elementAt(0);\r
- byte[] data = Arrays.copyOfRange(myclientSI.getData().getData(), 0, myclientSI.getData().getData().length );\r
-\r
- // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);\r
- System.out.println("PCMMGateReq Parse Gate Message");\r
- PCMMGateReq gateMsg = new PCMMGateReq(data);\r
-\r
- Hashtable repSIs = new Hashtable(40);\r
- String strobjprid = new String();\r
- for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
- switch (obj.getSNum()) {\r
- case COPSPrObjBase.PR_PRID:\r
- System.out.println("COPSPrObjBase.PR_PRID");\r
- strobjprid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- System.out.println("COPSPrObjBase.PR_EPD");\r
- repSIs.put(strobjprid, obj.getData().str());\r
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
- break;\r
- default:\r
- COPSDebug.err(getClass().getName(),"Object s-num: " + obj.getSNum() + "stype " + obj.getSType());\r
- COPSDebug.err(getClass().getName(),"PRID: " + strobjprid);\r
- COPSDebug.err(getClass().getName(),"EPD: " + obj.getData().str());\r
- break;\r
- }\r
- }\r
-\r
- System.out.println("rtypemsg process");\r
- //** Here we must act in accordance with\r
- //** the report received\r
- if (rtypemsg.isSuccess()) {\r
- System.out.println("rtypemsg success");\r
- _status = ST_REPORT;\r
- if (_process != null)\r
- _process.successReport(this, gateMsg);\r
- else\r
-{\r
- if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {\r
- System.out.println(getClass().getName()+ ": GateDeleteAck ");\r
- System.out.println(getClass().getName()+ ": GateID = " + gateMsg.getGateID().getGateID());\r
- if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())\r
- PCMMGlobalConfig.setGateID1(0);\r
- if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2())\r
- PCMMGlobalConfig.setGateID2(0);\r
-\r
- }\r
- if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) {\r
- System.out.println(getClass().getName()+ ": GateSetAck ");\r
- System.out.println(getClass().getName()+ ": GateID = " + gateMsg.getGateID().getGateID());\r
- if (0 == PCMMGlobalConfig.getGateID1())\r
- PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());\r
- if (0 == PCMMGlobalConfig.getGateID2())\r
- PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());\r
- }\r
-\r
-}\r
- } else if (rtypemsg.isFailure()) {\r
- System.out.println("rtypemsg failure");\r
- _status = ST_REPORT;\r
- if (_process != null)\r
- _process.failReport(this, gateMsg);\r
-else\r
-{\r
- System.out.println(getClass().getName()+ ": " + gateMsg.getError().toString());\r
-}\r
-\r
- } else if (rtypemsg.isAccounting()) {\r
- System.out.println("rtypemsg account");\r
- _status = ST_ACCT;\r
- if (_process != null)\r
- _process.acctReport(this, gateMsg);\r
- }\r
- System.out.println("Out processReport");\r
- }\r
-\r
- /**\r
- * Called when connection is closed\r
- * @param error Reason\r
- * @throws COPSPdpException\r
- */\r
- protected void processClosedConnection(COPSError error)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyClosedConnection(this, error);\r
-\r
- _status = ST_CCONN;\r
- }\r
-\r
- /**\r
- * Called when no keep-alive is received\r
- * @throws COPSPdpException\r
- */\r
- protected void processNoKAConnection()\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyNoKAliveReceived(this);\r
-\r
- _status = ST_NOKA;\r
- }\r
-\r
- /**\r
- * Deletes the request state\r
- * @throws COPSPdpException\r
- */\r
- protected void finalizeRequestState()\r
- throws COPSPdpException {\r
- _sender.sendDeleteRequestState();\r
- _status = ST_FINAL;\r
- }\r
-\r
- /**\r
- * Asks for a COPS sync\r
- * @throws COPSPdpException\r
- */\r
- protected void syncRequestState()\r
- throws COPSPdpException {\r
- _sender.sendSyncRequestState();\r
- _status = ST_SYNC;\r
- }\r
-\r
- /**\r
- * Opens a new request state\r
- * @throws COPSPdpException\r
- */\r
- protected void openNewRequestState()\r
- throws COPSPdpException {\r
- _sender.sendOpenNewRequestState();\r
- _status = ST_NEW;\r
- }\r
-\r
- /**\r
- * Processes a COPS delete message\r
- * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.closeRequestState(this);\r
-\r
- _status = ST_DEL;\r
- }\r
-\r
-}\r
+/*
+ * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
+ */
+
+package org.pcmm;
+
+import org.pcmm.gates.IGateID;
+import org.pcmm.gates.IPCMMError.ErrorCode;
+import org.pcmm.gates.IPCMMGate;
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.ITransactionID.GateCommandType;
+import org.pcmm.gates.impl.PCMMError;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.prpdp.COPSPdpException;
+import org.umu.cops.prpdp.COPSPdpReqStateMan;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * State manager class for provisioning requests, at the PDP side.
+ */
+public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
+
+ private final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);
+
+ /**
+ * Object for performing policy data processing
+ */
+ protected final PCMMPdpDataProcess _thisProcess;
+
+ /** COPS message transceiver used to send COPS messages */
+ protected final PCMMPdpMsgSender _sender;
+
+ /**
+ * Creates a request state manager
+ * @param clientType Client-type
+ * @param clientHandle Client handle
+ */
+ // TODO - consider sending in the COPSHandle object instead
+ public PCMMPdpReqStateMan(final short clientType, final COPSHandle clientHandle, final PCMMPdpDataProcess process,
+ final Socket socket) {
+ super(clientType, clientHandle, process, socket);
+ this._thisProcess = process;
+ _sender = new PCMMPdpMsgSender(_clientType, _handle, _socket);
+ // Initial state
+ _status = Status.ST_INIT;
+ }
+
+ @Override
+ public void processRequest(final COPSReqMsg msg) throws COPSPdpException {
+ // TODO - Implement me - see commented out code from history prior to May 4, 2015...
+ }
+
+ // TODO - break apart this method
+ @Override
+ protected void processReport(final COPSReportMsg msg) throws COPSPdpException {
+ // Report Type
+ final COPSReportType rtypemsg = msg.getReport();
+
+ if (msg.getClientSI() != null) {
+ final COPSClientSI clientSI = msg.getClientSI();
+ // Named ClientSI
+ final byte[] data = Arrays.copyOfRange(clientSI.getData().getData(), 0, clientSI.getData().getData().length);
+
+ // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);
+ logger.info("PCMMGateReq Parse Gate Message");
+ final PCMMGateReq gateMsg = PCMMGateReq.parse(data);
+
+ // TODO FIXME - Why is this Map being filled but never used???
+ final Map<String, String> repSIs = new HashMap<>();
+ String strobjprid = "";
+ final COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ logger.info("COPSPrObjBase.PR_PRID");
+ // TODO FIXME - this value is never used
+ strobjprid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ logger.info("COPSPrObjBase.PR_EPD");
+ // TODO FIXME - strobjprid is always empty
+ repSIs.put(strobjprid, obj.getData().str());
+ logger.info("PRID: " + strobjprid);
+ logger.info("EPD: " + obj.getData().str());
+ break;
+ default:
+ logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());
+ logger.error("PRID: " + strobjprid);
+ logger.error("EPD: " + obj.getData().str());
+ break;
+ }
+
+ logger.info("rtypemsg process");
+ //** Here we must act in accordance with
+ //** the report received
+
+ // retrieve and remove the transactionId to gate request map entry
+ // see PCMMPdpMsgSender.sendGateSet(IPCMMGate gate)
+ final ITransactionID trID = gateMsg.getTransactionID();
+ final Short trIDnum = trID.getTransactionIdentifier();
+
+ logger.info("Removing gate from cache with key - " + trIDnum);
+ final IPCMMGate gate = PCMMGlobalConfig.transactionGateMap.remove(trIDnum);
+ if (gate != null) {
+ // capture the "error" message if any
+ gate.setError(gateMsg.getError());
+ logger.info("Setting error on gate - " + gateMsg.getError());
+ }else {
+ logger.error("processReport(): gateReq not found for transactionID {}", trIDnum);
+ return;
+ }
+
+ if (rtypemsg.getReportType().equals(ReportType.SUCCESS)) {
+ logger.info("rtypemsg success");
+ _status = Status.ST_REPORT;
+ final IGateID gateID = gateMsg.getGateID();
+ logger.info("Setting gate ID on gate object - " + gateID);
+ gate.setGateID(gateID);
+ if (_thisProcess != null)
+ _thisProcess.successReport(this, gateMsg);
+ } else {
+ final String cmdType;
+ if (trID.getGateCommandType().equals(GateCommandType.GATE_DELETE_ACK)) {
+ cmdType = "GateDeleteAck";
+ } else if (trID.getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
+ cmdType = "GateSetAck";
+ } else cmdType = null;
+ // capture the gateId from the response message
+ final IGateID gateID = gateMsg.getGateID();
+ logger.info("Setting gate ID on gate object - " + gateID);
+ gate.setGateID(gateID);
+
+ if (gateID != null) {
+ int gateIdInt = gateID.getGateID();
+ String gateIdHex = String.format("%08x", gateIdInt);
+ logger.info(getClass().getName() + ": " + cmdType + ": GateID = " + gateIdHex);
+ } else {
+ logger.warn("Gate ID is null");
+ }
+ }
+ if (rtypemsg.getReportType().equals(ReportType.FAILURE)) {
+ logger.info("rtypemsg failure");
+ _status = Status.ST_REPORT;
+ if (_thisProcess != null)
+ _thisProcess.failReport(this, gateMsg);
+ else
+ if (gateMsg.getError() != null)
+ logger.info("Gate message error - " + gateMsg.getError().toString());
+ else {
+ // TODO - Determine if this is the correct error code
+ final PCMMError error = new PCMMError(ErrorCode.UNK_GATE_CMD);
+ gate.setError(error);
+ logger.warn("Gate request failed without an error, setting one - " + error);
+ }
+ } else if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) {
+ logger.info("rtypemsg account");
+ _status = Status.ST_ACCT;
+ if (_thisProcess != null)
+ _thisProcess.acctReport(this, gateMsg);
+ }
+
+ // let the waiting gateSet/gateDelete sender proceed
+ // TODO - see PCMMService#processReport() gate.notify(). Should determine a better means to
+ // TODO - handle this synchronization.
+ logger.info("Notify gate request has been updated with ID - " + gate.getGateID());
+ synchronized(gate) {
+ gate.notify();
+ }
+ logger.info("Out processReport");
+ }
+ }
+
+}