/**
@header@
*/
package org.pcmm;
import org.pcmm.gates.ITransactionID;
import org.pcmm.gates.impl.PCMMGateReq;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.prpdp.COPSPdpException;
import org.umu.cops.stack.*;
import java.net.Socket;
import java.util.*;
/**
* State manager class for provisioning requests, at the PDP side.
*/
public class PCMMPdpReqStateMan {
public final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);
/**
* Request State created
*/
public final static short ST_CREATE = 1;
/**
* Request received
*/
public final static short ST_INIT = 2;
/**
* Decisions sent
*/
public final static short ST_DECS = 3;
/**
* Report received
*/
public final static short ST_REPORT = 4;
/**
* Request State finalized
*/
public final static short ST_FINAL = 5;
/**
* New Request State solicited
*/
public final static short ST_NEW = 6;
/**
* Delete Request State solicited
*/
public final static short ST_DEL = 7;
/**
* SYNC request sent
*/
public final static short ST_SYNC = 8;
/**
* SYNC completed
*/
public final static short ST_SYNCALL = 9;
/**
* Close connection received
*/
public final static short ST_CCONN = 10;
/**
* Keep-alive timeout
*/
public final static short ST_NOKA = 11;
/**
* Accounting timeout
*/
public final static short ST_ACCT = 12;
/**
* COPS client-type that identifies the policy client
*/
protected short _clientType;
/**
* COPS client handle used to uniquely identify a particular
* PEP's request for a client-type
*/
protected COPSHandle _handle;
/**
* Object for performing policy data processing
*/
protected PCMMPdpDataProcess _process;
/**
* Current state of the request being managed
*/
protected short _status;
/** COPS message transceiver used to send COPS messages */
protected PCMMPdpMsgSender _sender;
/**
* Creates a request state manager
* @param clientType Client-type
* @param clientHandle Client handle
*/
public PCMMPdpReqStateMan(short clientType, String clientHandle) {
_handle = new COPSHandle(new COPSData(clientHandle));
_clientType = clientType;
_status = ST_CREATE;
}
/**
* Gets the client handle
* @return Client's COPSHandle
*/
public COPSHandle getClientHandle() {
return _handle;
}
/**
* Gets the client-type
* @return Client-type value
*/
public short getClientType() {
return _clientType;
}
/**
* Gets the status of the request
* @return Request state value
*/
public short getStatus() {
return _status;
}
/**
* Gets the policy data processing object
* @return Policy data processing object
*/
public PCMMPdpDataProcess getDataProcess() {
return _process;
}
/**
* Sets the policy data processing object
* @param process Policy data processing object
*/
public void setDataProcess(PCMMPdpDataProcess process) {
_process = process;
}
/**
* Called when COPS sync is completed
* @param repMsg COPS sync message
* @throws COPSPdpException
*/
protected void processSyncComplete(COPSSyncStateMsg repMsg)
throws COPSPdpException {
_status = ST_SYNCALL;
// maybe we should notifySyncComplete ...
}
/**
* Initializes a new request state over a socket
* @param sock Socket to the PEP
* @throws COPSPdpException
*/
protected void initRequestState(Socket sock)
throws COPSPdpException {
// Inits an object for sending COPS messages to the PEP
_sender = new PCMMPdpMsgSender(_clientType, _handle, sock);
// Initial state
_status = ST_INIT;
}
/**
* Processes a COPS request
* @param msg COPS request received from the PEP
* @throws COPSPdpException
*/
protected void processRequest(COPSReqMsg msg)
throws COPSPdpException {
COPSHeader hdrmsg = msg.getHeader();
COPSHandle handlemsg = msg.getClientHandle();
COPSContext contextmsg = msg.getContext();
//** Analyze the request
//**
/* ::=
*
*
* *()
* []
* ::= <*( )>
*
* Very important, this is actually being treated like this:
* ::= |
*
// Named ClientSI
Vector clientSIs = msg.getClientSI();
Hashtable reqSIs = new Hashtable(40);
String strobjprid = new String();
for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {
COPSClientSI clientSI = (COPSClientSI) e.nextElement();
COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
switch (obj.getSNum())
{
case COPSPrObjBase.PR_PRID:
strobjprid = obj.getData().str();
break;
case COPSPrObjBase.PR_EPD:
reqSIs.put(strobjprid, obj.getData().str());
// COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
// COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
break;
default:
break;
}
}
//** Here we must retrieve a decision depending on
//** the supplied ClientSIs
// reqSIs is a hashtable with the prid and epds
// ................
//
Hashtable removeDecs = new Hashtable();
Hashtable installDecs = new Hashtable();
_process.setClientData(this, reqSIs);
removeDecs = _process.getRemovePolicy(this);
installDecs = _process.getInstallPolicy(this);
//** We create the SOLICITED decision
//**
_sender.sendDecision(removeDecs, installDecs);
_status = ST_DECS;
*/
}
/**
* Processes a report
* @param msg Report message from the PEP
* @throws COPSPdpException
*/
protected void processReport(COPSReportMsg msg)
throws COPSPdpException {
//** Analyze the report
//**
/*
* ::=
*
*
* *()
* []
* ::= <[] *()>
* ::= *()
*
* Important, is not parsed
*/
// COPSHeader hdrmsg = msg.getHeader();
// COPSHandle handlemsg = msg.getClientHandle();
// WriteBinaryDump("COPSReportMessage", msg.getData().getData());
// Report Type
COPSReportType rtypemsg = msg.getReport();
// Named ClientSI
Vector clientSIs = msg.getClientSI();
COPSClientSI myclientSI = (COPSClientSI) msg.getClientSI().elementAt(0);
byte[] data = Arrays.copyOfRange(myclientSI.getData().getData(), 0, myclientSI.getData().getData().length );
// PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);
logger.info("PCMMGateReq Parse Gate Message");
PCMMGateReq gateMsg = new PCMMGateReq(data);
// TODO - Determine why this Map is being populated but never used???
Map repSIs = new HashMap<>();
String strobjprid = "";
for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {
COPSClientSI clientSI = (COPSClientSI) e.nextElement();
COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
switch (obj.getSNum()) {
case COPSPrObjBase.PR_PRID:
logger.info("COPSPrObjBase.PR_PRID");
strobjprid = obj.getData().str();
break;
case COPSPrObjBase.PR_EPD:
logger.info("COPSPrObjBase.PR_EPD");
repSIs.put(strobjprid, obj.getData().str());
// COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
// COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
break;
default:
logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());
logger.error("PRID: " + strobjprid);
logger.error("EPD: " + obj.getData().str());
break;
}
}
logger.info("rtypemsg process");
//** Here we must act in accordance with
//** the report received
if (rtypemsg.isSuccess()) {
logger.info("rtypemsg success");
_status = ST_REPORT;
if (_process != null)
_process.successReport(this, gateMsg);
else {
if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {
logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID());
if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())
PCMMGlobalConfig.setGateID1(0);
if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2())
PCMMGlobalConfig.setGateID2(0);
}
if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck ) {
logger.info("GateSetAck: GateID = " + gateMsg.getGateID().getGateID());
if (0 == PCMMGlobalConfig.getGateID1())
PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());
if (0 == PCMMGlobalConfig.getGateID2())
PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());
}
}
} else if (rtypemsg.isFailure()) {
logger.info("rtypemsg failure");
_status = ST_REPORT;
if (_process != null)
_process.failReport(this, gateMsg);
else
logger.info("Gate message error - " + gateMsg.getError().toString());
} else if (rtypemsg.isAccounting()) {
logger.info("rtypemsg account");
_status = ST_ACCT;
if (_process != null)
_process.acctReport(this, gateMsg);
}
logger.info("Out processReport");
}
/**
* Called when connection is closed
* @param error Reason
* @throws COPSPdpException
*/
protected void processClosedConnection(COPSError error)
throws COPSPdpException {
if (_process != null)
_process.notifyClosedConnection(this, error);
_status = ST_CCONN;
}
/**
* Called when no keep-alive is received
* @throws COPSPdpException
*/
protected void processNoKAConnection()
throws COPSPdpException {
if (_process != null)
_process.notifyNoKAliveReceived(this);
_status = ST_NOKA;
}
/**
* Deletes the request state
* @throws COPSPdpException
*/
protected void finalizeRequestState()
throws COPSPdpException {
_sender.sendDeleteRequestState();
_status = ST_FINAL;
}
/**
* Asks for a COPS sync
* @throws COPSPdpException
*/
protected void syncRequestState()
throws COPSPdpException {
_sender.sendSyncRequestState();
_status = ST_SYNC;
}
/**
* Opens a new request state
* @throws COPSPdpException
*/
protected void openNewRequestState()
throws COPSPdpException {
_sender.sendOpenNewRequestState();
_status = ST_NEW;
}
/**
* Processes a COPS delete message
* @param dMsg COPSDeleteMsg received from the PEP
* @throws COPSPdpException
*/
protected void processDeleteRequestState(COPSDeleteMsg dMsg)
throws COPSPdpException {
if (_process != null)
_process.closeRequestState(this);
_status = ST_DEL;
}
}