import org.umu.cops.prpdp.COPSPdpAgent;
import org.umu.cops.prpdp.COPSPdpException;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Core PDP agent for provisioning
* Policy data processing object
*/
private PCMMPdpDataProcess _process;
- private MMVersionInfo _mminfo;
private COPSHandle _handle;
- private short _transactionID;
+// private short _transactionID;
+
+ /**
+ * Temporary until can refactor PdpAgent classes
+ */
+ @Deprecated
+ private final Map<String, PCMMPdpConnection> _connectionMap;
/**
* Creates a PDP Agent
super(psPort, clientType, null);
this._process = process;
this.psHost = psHost;
+ this._connectionMap = new ConcurrentHashMap<>();
}
/**
try {
logger.info("PDP COPSTransceiver.receiveMsg");
COPSMsg msg = COPSTransceiver.receiveMsg(socket);
- if (msg.getHeader().isAClientOpen()) {
+ if (msg.getHeader().getOpCode().equals(OPCode.OPN)) {
logger.info("PDP msg.getHeader().isAClientOpen");
handleClientOpenMsg(socket, msg);
} else {
* @throws COPSException
* @throws IOException
*/
- private void handleClientOpenMsg(Socket conn, COPSMsg msg)
- throws COPSException, IOException {
- COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
- COPSPepId pepId = cMsg.getPepId();
+ private void handleClientOpenMsg(final Socket conn, final COPSMsg msg) throws COPSException, IOException {
+ final COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
+ final COPSPepId pepId = cMsg.getPepId();
// Validate Client Type
if (msg.getHeader().getClientType() != getClientType()) {
// Unsupported client type
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
- .getHeader().getClientType());
- COPSError err = new COPSError(
- COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
- closeMsg.add(cHdr);
- closeMsg.add(err);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA), null, null);
try {
closeMsg.writeData(conn);
} catch (IOException unae) {
// PEPId is mandatory
if (pepId == null) {
// Mandatory COPS object missing
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
- .getHeader().getClientType());
- COPSError err = new COPSError(
- COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
- closeMsg.add(cHdr);
- closeMsg.add(err);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA), null, null);
try {
closeMsg.writeData(conn);
} catch (IOException unae) {
setPepId(pepId);
// Support
if ((cMsg.getClientSI() != null) ) {
- _mminfo = new MMVersionInfo(cMsg
- .getClientSI().getData().getData());
- logger.info("CMTS sent MMVersion info : major:"
- + _mminfo.getMajorVersionNB() + " minor:"
- + _mminfo.getMinorVersionNB());
+ final MMVersionInfo _mminfo = new MMVersionInfo(cMsg.getClientSI().getData().getData());
+ logger.info("CMTS sent MMVersion info : major:" + _mminfo.getMajorVersionNB() + " minor:" +
+ _mminfo.getMinorVersionNB());
} else {
- // Unsupported objects
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
- .getHeader().getClientType());
- COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT,
- (short) 0);
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
- closeMsg.add(cHdr);
- closeMsg.add(err);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
try {
closeMsg.writeData(conn);
} catch (IOException unae) {
*/
// Connection accepted
- COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg
- .getHeader().getClientType());
- COPSKATimer katimer = new COPSKATimer(getKaTimer());
- COPSAcctTimer acctTimer = new COPSAcctTimer(getAcctTimer());
- COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
- acceptMsg.add(ahdr);
- acceptMsg.add(katimer);
+ final COPSKATimer katimer = new COPSKATimer(getKaTimer());
+ final COPSAcctTimer acctTimer = new COPSAcctTimer(getAcctTimer());
+ final COPSClientAcceptMsg acceptMsg;
if (getAcctTimer() != 0)
- acceptMsg.add(acctTimer);
+ acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer, acctTimer, null);
+ else
+ acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer, null, null);
+
acceptMsg.writeData(conn);
// XXX - handleRequestMsg
try {
logger.info("PDP COPSTransceiver.receiveMsg");
COPSMsg rmsg = COPSTransceiver.receiveMsg(socket);
// Client-Close
- if (rmsg.getHeader().isAClientClose()) {
+ if (rmsg.getHeader().getOpCode().equals(OPCode.CC)) {
logger.info("Client close description - " + ((COPSClientCloseMsg) rmsg).getError().getDescription());
// close the socket
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg
- .getHeader().getClientType());
- COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT,
- (short) 0);
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
- closeMsg.add(cHdr);
- closeMsg.add(err);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
try {
closeMsg.writeData(conn);
} catch (IOException unae) {
throw new COPSException("CMTS requetsed Client-Close");
} else {
// Request
- if (rmsg.getHeader().isARequest()) {
+ if (rmsg.getHeader().getOpCode().equals(OPCode.REQ)) {
COPSReqMsg rMsg = (COPSReqMsg) rmsg;
_handle = rMsg.getClientHandle();
} else
logger.info("PDP Thread(pdpConn).start");
new Thread(pdpConn).start();
- getConnectionMap().put(pepId.getData().str(), pdpConn);
+ _connectionMap.put(pepId.getData().str(), pdpConn);
}
/**
import org.slf4j.LoggerFactory;
import org.umu.cops.prpdp.COPSPdpException;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Class for managing an provisioning connection at the PDP side.
*/
private COPSPepId _pepId;
- /**
- Time of the latest keep-alive sent
- */
- private Date _lastKa;
-
- /**
- Opcode of the latest message sent
- */
- private byte _lastmessage;
-
/**
* Time of the latest keep-alive received
*/
/**
Maps a Client Handle to a Handler
*/
- protected Hashtable _managerMap;
- // map < String(COPSHandle), COPSPdpHandler> HandlerMap;
+ protected Map<String, PCMMPdpReqStateMan> _managerMap;
/**
* PDP policy data processor class
public PCMMPdpConnection(COPSPepId pepId, Socket sock, PCMMPdpDataProcess process) {
_sock = sock;
_pepId = pepId;
-
- _lastKa = new Date();
- _lastmessage = COPSHeader.COPS_OP_OPN;
- _managerMap = new Hashtable(20);
-
+ _managerMap = new ConcurrentHashMap<>();
_kaTimer = 120;
_process = process;
}
- /**
- * Gets the time of that latest keep-alive sent
- * @return Time of that latest keep-alive sent
- */
- public Date getLastKAlive() {
- return _lastKa;
- }
-
/**
* Sets the keep-alive timer value
* @param kaTimer Keep-alive timer value (secs)
*/
- public void setKaTimer(short kaTimer) {
+ public void setKaTimer(final short kaTimer) {
_kaTimer = kaTimer;
}
- /**
- * Gets the keep-alive timer value
- * @return Keep-alive timer value (secs)
- */
- public short getKaTimer() {
- return _kaTimer;
- }
-
/**
* Sets the accounting timer value
* @param acctTimer Accounting timer value (secs)
*/
- public void setAccTimer(short acctTimer) {
+ public void setAccTimer(final short acctTimer) {
_acctTimer = acctTimer;
}
return _acctTimer;
}
- /**
- * Gets the latest COPS message
- * @return Code of the latest message sent
- */
- public byte getLastMessage() {
- return _lastmessage;
- }
-
- /**
- * Gets active handles
- * @return An <tt>Enumeration</tt> holding all active handles
- */
- public Enumeration getHandles() {
- return _managerMap.keys();
- }
-
/**
* Gets the handle map
* @return A <tt>Hashtable</tt> holding the handle map
*/
- public Hashtable getReqStateMans() {
- return _managerMap;
- }
-
- /**
- * Gets the PEP-ID
- * @return The ID of the PEP, as a <tt>String</tt>
- */
- public String getPepId() {
- return _pepId.getData().str();
+ public Map<String, PCMMPdpReqStateMan> getReqStateMans() {
+ // Defensive copy
+ return new HashMap<>(_managerMap);
}
/**
try {
while (!_sock.isClosed()) {
if (_sock.getInputStream().available() != 0) {
- _lastmessage = processMessage(_sock);
+ processMessage(_sock);
_lastRecKa = new Date();
}
int _startTime = (int) (_lastRecKa.getTime());
int cTime = (int) (new Date().getTime());
- if ((int)(cTime - _startTime) > _kaTimer*1000) {
+ if ((cTime - _startTime) > _kaTimer*1000) {
_sock.close();
// Notify all Request State Managers
notifyNoKAAllReqStateMan();
_startTime = (int) (_lastSendKa.getTime());
cTime = (int) (new Date().getTime());
- if ((cTime - _startTime) > ((_kaTimer * 3/4) * 1000)) {
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);
- COPSKAMsg msg = new COPSKAMsg();
-
- msg.add(hdr);
-
+ if ((cTime - _startTime) > ((_kaTimer*3/4)*1000)) {
+ // TODO - determine what is the client type to be used here?
+ final COPSKAMsg msg = new COPSKAMsg(null);
COPSTransceiver.sendMsg(msg, _sock);
_lastSendKa = new Date();
}
/**
* Gets a COPS message from the socket and processes it
* @param conn Socket connected to the PEP
- * @return Type of COPS message
*/
- private byte processMessage(Socket conn)
- throws COPSPdpException, COPSException, IOException {
- COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+ private void processMessage(final Socket conn) throws COPSPdpException, COPSException, IOException {
+ final COPSMsg msg = COPSTransceiver.receiveMsg(conn);
- if (msg.getHeader().isAClientClose()) {
+ if (msg.getHeader().getOpCode().equals(OPCode.CC)) {
handleClientCloseMsg(conn, msg);
- return COPSHeader.COPS_OP_CC;
- } else if (msg.getHeader().isAKeepAlive()) {
+ } else if (msg.getHeader().getOpCode().equals(OPCode.KA)) {
handleKeepAliveMsg(conn, msg);
- return COPSHeader.COPS_OP_KA;
- } else if (msg.getHeader().isARequest()) {
+ } else if (msg.getHeader().getOpCode().equals(OPCode.REQ)) {
handleRequestMsg(conn, msg);
- return COPSHeader.COPS_OP_REQ;
- } else if (msg.getHeader().isAReport()) {
+ } else if (msg.getHeader().getOpCode().equals(OPCode.RPT)) {
handleReportMsg(conn, msg);
- return COPSHeader.COPS_OP_RPT;
- } else if (msg.getHeader().isADeleteReq()) {
+ } else if (msg.getHeader().getOpCode().equals(OPCode.DRQ)) {
handleDeleteRequestMsg(conn, msg);
- return COPSHeader.COPS_OP_DRQ;
- } else if (msg.getHeader().isASyncComplete()) {
+ } else if (msg.getHeader().getOpCode().equals(OPCode.SSQ)) {
handleSyncComplete(conn, msg);
- return COPSHeader.COPS_OP_SSC;
} else {
throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
}
private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
_error = cMsg.getError();
-
- // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
-
try {
// Support
if (cMsg.getIntegrity() != null) {
* @param msg a COPSMsg
*
*/
- private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)
- throws COPSPdpException {
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {
COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;
// COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +
// conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");
// Delete clientHandler
if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {
+ // TODO - Determine what to do here???
// COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +
// cMsg.getClientHandle().getId().getData());
}
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
+ final PCMMPdpReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());
if (man == null) {
logger.warn("State manager not found");
} else {
* @param msg a COPSMsg
*
*/
- private void handleRequestMsg(Socket conn, COPSMsg msg)
- throws COPSPdpException {
+ private void handleRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {
- COPSReqMsg reqMsg = (COPSReqMsg) msg;
- COPSContext cntxt = reqMsg.getContext();
- COPSHeader header = reqMsg.getHeader();
+ final COPSReqMsg reqMsg = (COPSReqMsg) msg;
+// COPSContext cntxt = reqMsg.getContext();
+ final COPSHeader header = reqMsg.getHeader();
//short reqType = cntxt.getRequestType();
- short cType = header.getClientType();
+ final short cType = header.getClientType();
// Support
if (reqMsg.getIntegrity() != null) {
}
PCMMPdpReqStateMan man;
- man = (PCMMPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());
+ man = _managerMap.get(reqMsg.getClientHandle().getId().str());
if (man == null) {
man = new PCMMPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());
- _managerMap.put(reqMsg.getClientHandle().getId().str(),man);
+ _managerMap.put(reqMsg.getClientHandle().getId().str(), man);
man.setDataProcess(_process);
man.initRequestState(_sock);
logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
}
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());
+ final PCMMPdpReqStateMan man = _managerMap.get(repMsg.getClientHandle().getId().str());
if (man == null) {
logger.warn("State manager not found");
} else {
logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
}
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
+ final PCMMPdpReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());
if (man == null) {
logger.warn("State manager not found");
} else {
* @throws COPSException
* @throws COPSPdpException
*/
- protected void syncAllRequestState()
- throws COPSException, COPSPdpException {
- if (_managerMap.size() > 0) {
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
- String handle = (String) e.nextElement();
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
-
- man.syncRequestState();
- }
+ protected void syncAllRequestState() throws COPSException, COPSPdpException {
+ for (final PCMMPdpReqStateMan man : _managerMap.values()) {
+ man.syncRequestState();
}
}
- private void notifyCloseAllReqStateMan()
- throws COPSPdpException {
- if (_managerMap.size() > 0) {
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
- String handle = (String) e.nextElement();
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
-
- man.processClosedConnection(_error);
- }
+ private void notifyCloseAllReqStateMan() throws COPSPdpException {
+ for (final PCMMPdpReqStateMan man : _managerMap.values()) {
+ man.processClosedConnection(_error);
}
}
- private void notifyNoKAAllReqStateMan()
- throws COPSPdpException {
- if (_managerMap.size() > 0) {
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
- String handle = (String) e.nextElement();
- PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
-
- man.processNoKAConnection();
- }
+ private void notifyNoKAAllReqStateMan() throws COPSPdpException {
+ for (final PCMMPdpReqStateMan man : _managerMap.values()) {
+ man.processNoKAConnection();
}
}
import org.slf4j.LoggerFactory;
import org.umu.cops.prpdp.COPSPdpException;
import org.umu.cops.stack.*;
-import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSHeader.OPCode;
import org.umu.cops.stack.COPSObjHeader.CType;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
//temp
//pcmm
* @param sock
* Socket to the PEP
*/
- public PCMMPdpMsgSender(short clientType, COPSHandle clientHandle,
- Socket sock) {
+ public PCMMPdpMsgSender(final short clientType, final COPSHandle clientHandle, final Socket sock) {
// COPS Handle
_handle = clientHandle;
_clientType = clientType;
_sock = sock;
}
- public PCMMPdpMsgSender(short clientType, short tID,
- COPSHandle clientHandle, Socket sock) {
+ public PCMMPdpMsgSender(final short clientType, final short tID, final COPSHandle clientHandle,
+ final Socket sock) {
// COPS Handle
_handle = clientHandle;
_clientType = clientType;
/**
* Sends a PCMM GateSet COPS Decision message
- *
- * @param
+ * @param gate - the gate
* @throws COPSPdpException
*/
- public void sendGateSet(IPCMMGate gate)
- throws COPSPdpException {
- // Common Header with the same ClientType as the request
-
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- // Client Handle with the same clientHandle as the request
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
- ITransactionID trID = new TransactionID();
+ public void sendGateSet(final IPCMMGate gate) throws COPSPdpException {
+ final ITransactionID trID = new TransactionID();
// set transaction ID to gate set
trID.setGateCommandType(ITransactionID.GateSet);
// new pcmm specific clientsi
- COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
- byte[] data = gate.getData();
- clientSD.setData(new COPSData(data, 0, data.length));
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(handle);
- // Decisions (no flags supplied)
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- COPSDecision install = new COPSDecision();
- install.setCmdCode(COPSDecision.DEC_INSTALL);
- install.setFlags(COPSDecision.F_REQERROR);
- decisionMsg.addDecision(install, cntxt);
- decisionMsg.add(clientSD); // setting up the gate
- /*
- try {
- decisionMsg.dump(System.out);
- } catch (IOException unae) {
- System.out.println("Error dumping " + unae.getMessage());
- }
- */
-
- } catch (COPSException e) {
- logger.error("Error making Msg", e);
- }
+ final byte[] data = gate.getData();
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR,
+ new COPSData(data, 0, data.length)));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
+ decisionMap, null);
+// new COPSClientSI(CSIType.SIGNALED, new COPSData(data, 0, data.length)), decisionMap);
+ // new COPSClientSI(CNum.DEC, (byte) 4, new COPSData(data, 0, data.length), null));
// ** Send the GateSet Decision
// **
try {
decisionMsg.writeData(_sock);
} catch (IOException e) {
- logger.error("Failed to send the decision, reason: ", e);
+ logger.error("Failed to send the decision", e);
}
}
/**
* Sends a PCMM GateSet COPS Decision message
*
- * @param
+ * @param num - the number
* @throws COPSPdpException
*/
- public void sendGateSetDemo(int num)
- throws COPSPdpException {
-
- // Common Header with the same ClientType as the request
-
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- // Client Handle with the same clientHandle as the request
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
-
- IPCMMGate gate = new PCMMGateReq();
- ITransactionID trID = new TransactionID();
-
- IAMID amid = new AMID();
- ISubscriberID subscriberID = new SubscriberID();
- IGateSpec gateSpec = new GateSpec();
- IClassifier classifier = new Classifier();
- IExtendedClassifier eclassifier = new ExtendedClassifier();
+ public void sendGateSetDemo(int num) throws COPSPdpException {
+ final IPCMMGate gate = new PCMMGateReq();
+ final ITransactionID trID = new TransactionID();
+ final IAMID amid = new AMID();
+ final ISubscriberID subscriberID = new SubscriberID();
+ final IGateSpec gateSpec = new GateSpec();
+ final IClassifier classifier = new Classifier();
+ final IExtendedClassifier eclassifier = new ExtendedClassifier();
final int trafficRate;
-
if (num == 1)
trafficRate = PCMMGlobalConfig.DefaultBestEffortTrafficRate;
else
trafficRate = PCMMGlobalConfig.DefaultLowBestEffortTrafficRate;
- ITrafficProfile trafficProfile = new BestEffortService(
+ final ITrafficProfile trafficProfile = new BestEffortService(
(byte) 7); //BestEffortService.DEFAULT_ENVELOP);
((BestEffortService) trafficProfile).getAuthorizedEnvelop()
.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- // new pcmm specific clientsi
- COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
-
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());
-
// set transaction ID to gate set
trID.setGateCommandType(ITransactionID.GateSet);
_transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
gateSpec.setTimerT4(PCMMGlobalConfig.GateT4);
// XXX - if the version major is less than 4 we need to use Classifier
+ // TODO - Use some variable here or remove...
if (true) {
//eclassifier.setProtocol(IClassifier.Protocol.NONE);
eclassifier.setProtocol(IClassifier.Protocol.TCP);
gate.setTrafficProfile(trafficProfile);
gate.setClassifier(eclassifier);
- byte[] data = gate.getData();
+ final byte[] data = gate.getData();
- // new pcmm specific clientsi
- clientSD.setData(new COPSData(data, 0, data.length));
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(handle);
- // Decisions (no flags supplied)
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- COPSDecision install = new COPSDecision();
- install.setCmdCode(COPSDecision.DEC_INSTALL);
- install.setFlags(COPSDecision.F_REQERROR);
- decisionMsg.addDecision(install, cntxt);
- decisionMsg.add(clientSD); // setting up the gate
- /*
- try {
- decisionMsg.dump(System.out);
- } catch (IOException unae) {
- System.out.println("Error dumping " + unae.getMessage());
- }
- */
-
- } catch (COPSException e) {
- logger.error("Error making Msg", e);
- }
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR,
+ new COPSData(data, 0, data.length)));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(),
+ new COPSHandle(getClientHandle().getId()), decisionMap, null);
+// new COPSClientSI(CSIType.SIGNALED, new COPSData(data, 0, data.length)), decisionMap);
+ // new COPSClientSI(CNum.DEC, (byte) 4, new COPSData(data, 0, data.length))); TODO - what does the value of 4 mean here???
// ** Send the GateSet Decision
// **
try {
decisionMsg.writeData(_sock);
} catch (IOException e) {
- logger.error("Failed to send the decision, reason: ", e);
+ logger.error("Failed to send the decision", e);
}
}
/**
* Sends a PCMM GateSet COPS Decision message
- *
- * @param
* @throws COPSPdpException
*/
- public void sendGateSetBestEffortWithExtendedClassifier()
- throws COPSPdpException {
- // Common Header with the same ClientType as the request
-
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
-
- IPCMMGate gate = new PCMMGateReq();
- ITransactionID trID = new TransactionID();
-
- IAMID amid = new AMID();
- ISubscriberID subscriberID = new SubscriberID();
- IGateSpec gateSpec = new GateSpec();
- IClassifier classifier = new Classifier();
- IExtendedClassifier eclassifier = new ExtendedClassifier();
+ public void sendGateSetBestEffortWithExtendedClassifier() throws COPSPdpException {
+ final IPCMMGate gate = new PCMMGateReq();
+ final ITransactionID trID = new TransactionID();
+ final IAMID amid = new AMID();
+ final ISubscriberID subscriberID = new SubscriberID();
+ final IGateSpec gateSpec = new GateSpec();
+ final IClassifier classifier = new Classifier();
+ final IExtendedClassifier eclassifier = new ExtendedClassifier();
// XXX check if other values should be provided
//
- ITrafficProfile trafficProfile = new BestEffortService(
+ final ITrafficProfile trafficProfile = new BestEffortService(
(byte) 7); //BestEffortService.DEFAULT_ENVELOP);
((BestEffortService) trafficProfile).getAuthorizedEnvelop()
.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
- // new pcmm specific clientsi
- COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
-
- // Client Handle with the same clientHandle as the request
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());
-
// set transaction ID to gate set
trID.setGateCommandType(ITransactionID.GateSet);
_transactionID = (_transactionID == 0 ? (short) (Math.random() * hashCode()) : _transactionID);
byte[] data = gate.getData();
- // new pcmm specific clientsi
- clientSD.setData(new COPSData(data, 0, data.length));
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(handle);
- // Decisions (no flags supplied)
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- COPSDecision install = new COPSDecision();
- install.setCmdCode(COPSDecision.DEC_INSTALL);
- install.setFlags(COPSDecision.F_REQERROR);
- decisionMsg.addDecision(install, cntxt);
- decisionMsg.add(clientSD); // setting up the gate
- /*
- try {
- decisionMsg.dump(System.out);
- } catch (IOException unae) {
- System.out.println("Error dumping " + unae.getMessage());
- }
- */
-
- } catch (COPSException e) {
- logger.error("Error making Msg", e);
- }
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData(data, 0, data.length)));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
+ decisionMap, null);
+// new COPSClientSI(CSIType.SIGNALED, new COPSData(data, 0, data.length)), decisionMap);
+ // new COPSClientSI(CNum.DEC, (byte) 4, new COPSData(data, 0, data.length), null)); TODO - what does the value of 4 mean here???
// ** Send the GateSet Decision
// **
}
- public boolean handleGateReport(Socket socket) throws COPSPdpException {
+ public boolean handleGateReport(final Socket socket) throws COPSPdpException {
try {
// waits for the gate-set-ack or error
- COPSMsg responseMsg = COPSTransceiver.receiveMsg(socket);
- if (responseMsg.getHeader().isAReport()) {
+ final COPSMsg responseMsg = COPSTransceiver.receiveMsg(socket);
+ if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
logger.info("processing received report from CMTS");
- COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
- if (reportMsg.getClientSI().size() == 0) {
+ final COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
+ if (reportMsg.getClientSI() == null) {
return false;
}
- COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI()
- .elementAt(0);
- IPCMMGate responseGate = new PCMMGateReq(clientSI.getData()
- .getData());
+ final IPCMMGate responseGate = new PCMMGateReq(reportMsg.getClientSI().getData().getData());
if (responseGate.getTransactionID() != null
&& responseGate.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
logger.info("the CMTS has sent a Gate-Set-Ack response");
/**
* Sends a PCMM GateSet COPS Decision message
*
- * @param
* @throws COPSPdpException
*/
public void sendGateSet() throws COPSPdpException {
// Common Header with the same ClientType as the request
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
-
- IPCMMGate gate = new PCMMGateReq();
- ITransactionID trID = new TransactionID();
+ final IPCMMGate gate = new PCMMGateReq();
+ final ITransactionID trID = new TransactionID();
- IAMID amid = new AMID();
- ISubscriberID subscriberID = new SubscriberID();
- IGateSpec gateSpec = new GateSpec();
- IClassifier classifier = new Classifier();
+ final IAMID amid = new AMID();
+ final ISubscriberID subscriberID = new SubscriberID();
+ final IGateSpec gateSpec = new GateSpec();
+ final IClassifier classifier = new Classifier();
// XXX check if other values should be provided
- ITrafficProfile trafficProfile = new BestEffortService(
+ final ITrafficProfile trafficProfile = new BestEffortService(
BestEffortService.DEFAULT_ENVELOP);
((BestEffortService) trafficProfile).getAuthorizedEnvelop()
.setTrafficPriority(BestEffortService.DEFAULT_TRAFFIC_PRIORITY);
.setRequestTransmissionPolicy(
PCMMGlobalConfig.BETransmissionPolicy);
- // new pcmm specific clientsi
- COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
-
- // Client Handle with the same clientHandle as the request
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());
// byte[] content = "1234".getBytes();
// handle.setId(new COPSData(content, 0, content.length));
gate.setTrafficProfile(trafficProfile);
gate.setClassifier(classifier);
- byte[] data = gate.getData();
+ final byte[] data = gate.getData();
- // new pcmm specific clientsi
- clientSD.setData(new COPSData(data, 0, data.length));
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL,
+ DecisionFlag.REQERROR, new COPSData(data, 0, data.length)));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(handle);
- // Decisions (no flags supplied)
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- COPSDecision install = new COPSDecision();
- install.setCmdCode(COPSDecision.DEC_INSTALL);
- install.setFlags(COPSDecision.F_REQERROR);
- decisionMsg.addDecision(install, cntxt);
- decisionMsg.add(clientSD); // setting up the gate
- /*
- try {
- decisionMsg.dump(System.out);
- } catch (IOException unae) {
- System.out.println("Error dumping " + unae.getMessage());
- }
- */
-
- } catch (COPSException e) {
- logger.error("Error making Msg", e);
- }
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(),
+ new COPSHandle(getClientHandle().getId()), decisionMap, null);
+// new COPSClientSI(CSIType.SIGNALED, new COPSData(data, 0, data.length)), decisionMap);
+ // new COPSClientSI(CNum.DEC, (byte) 4, new COPSData(data, 0, data.length), null));
// ** Send the GateSet Decision
// **
* <Decision Header> <TransactionID> <AMID> <SubscriberID> <GateID>
*/
// Common Header with the same ClientType as the request
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- // Client Handle with the same clientHandle as the request
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
-
- IPCMMGate gate = new PCMMGateReq();
- ITransactionID trID = new TransactionID();
+ final IPCMMGate gate = new PCMMGateReq();
+ final ITransactionID trID = new TransactionID();
- IAMID amid = new AMID();
- ISubscriberID subscriberID = new SubscriberID();
- IGateID gateID = new GateID();
-
- // new pcmm specific clientsi
- COPSClientSI clientSD = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
-
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());
+ final IAMID amid = new AMID();
+ final ISubscriberID subscriberID = new SubscriberID();
+ final IGateSpec gateSpec = new GateSpec();
+ final IGateID gateID = new GateID();
// set transaction ID to gate set
trID.setGateCommandType(ITransactionID.GateDelete);
gate.setGateID(gateID);
// XXX - GateID
- byte[] data = gate.getData();
+ final byte[] data = gate.getData();
- // new pcmm specific clientsi
- clientSD.setData(new COPSData(data, 0, data.length));
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR,
+ new COPSData(data, 0, data.length)));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short) 0), decisionSet);
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(handle);
- // Decisions (no flags supplied)
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- COPSDecision install = new COPSDecision();
- install.setCmdCode(COPSDecision.DEC_INSTALL);
- install.setFlags(COPSDecision.F_REQERROR);
- decisionMsg.addDecision(install, cntxt);
- decisionMsg.add(clientSD); // setting up the gate
- /*
- try {
- decisionMsg.dump(System.out);
- } catch (IOException unae) {
- System.out.println("Error dumping " + unae.getMessage());
- }
- */
-
- } catch (COPSException e) {
- logger.error("Error making Msg", e);
- }
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(),
+ new COPSHandle(getClientHandle().getId()), decisionMap, null);
+// new COPSClientSI(CSIType.SIGNALED, new COPSData(data, 0, data.length)), decisionMap);
+ // new COPSClientSI(CNum.DEC, (byte) 4, new COPSData(data, 0, data.length), null));
// ** Send the GateDelete Decision
// **
* <Decision: Flags> <Decision: Flags> ::= Install Request-State
*/
- // Common Header with the same ClientType as the request (default
- // UNSOLICITED)
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, getClientType());
-
- // Client Handle with the same clientHandle as the request
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
- // Decisions
- // <Context>
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);
- // <Decision: Flags>
- COPSDecision dec = new COPSDecision();
- dec.setCmdCode(COPSDecision.DEC_INSTALL);
- dec.setFlags(COPSDecision.F_REQSTATE);
-
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();
- try {
- decisionMsg.add(hdr);
- decisionMsg.add(clienthandle);
- decisionMsg.addDecision(dec, cntxt);
- } catch (COPSException e) {
- throw new COPSPdpException("Error making Msg");
- }
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), new COPSHandle(_handle.getId()),
+ decisionMap, null);
try {
decisionMsg.writeData(_sock);
/*
* <Gate-Info> ::= <Common Header> [<Client Handle>] [<Integrity>]
*/
-
- // Common Header with the same ClientType as the request
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_SSQ, getClientType());
-
- // Client Handle with the same clientHandle as the request
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());
-
- COPSSyncStateMsg msg = new COPSSyncStateMsg();
- try {
- msg.add(hdr);
- msg.add(clienthandle);
- } catch (Exception e) {
- throw new COPSPdpException("Error making Msg");
- }
-
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), new COPSHandle(_handle.getId()), null);
try {
msg.writeData(_sock);
} catch (IOException e) {
* [<Integrity>]
*/
- // Common Header with the same ClientType as the request
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_SSQ, getClientType());
-
// Client Handle with the same clientHandle as the request
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());
-
- COPSSyncStateMsg msg = new COPSSyncStateMsg();
- try {
- msg.add(hdr);
- msg.add(clienthandle);
- } catch (Exception e) {
- throw new COPSPdpException("Error making Msg");
- }
-
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), new COPSHandle(_handle.getId()), null);
try {
msg.writeData(_sock);
} catch (IOException e) {
-/**\r
- @header@\r
- */\r
-\r
-package org.pcmm;\r
-\r
-import org.pcmm.gates.ITransactionID;\r
-import org.pcmm.gates.impl.PCMMGateReq;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.prpdp.COPSPdpException;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.*;\r
-\r
-/**\r
- * State manager class for provisioning requests, at the PDP side.\r
- */\r
-public class PCMMPdpReqStateMan {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);\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
- logger.info("PCMMGateReq Parse Gate Message");\r
- PCMMGateReq gateMsg = new PCMMGateReq(data);\r
-\r
- // TODO - Determine why this Map is being populated but never used???\r
- Map<String, String> repSIs = new HashMap<>();\r
- String strobjprid = "";\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
- logger.info("COPSPrObjBase.PR_PRID");\r
- strobjprid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- logger.info("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
- logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());\r
- logger.error("PRID: " + strobjprid);\r
- logger.error("EPD: " + obj.getData().str());\r
- break;\r
- }\r
- }\r
-\r
- logger.info("rtypemsg process");\r
- //** Here we must act in accordance with\r
- //** the report received\r
- if (rtypemsg.isSuccess()) {\r
- logger.info("rtypemsg success");\r
- _status = ST_REPORT;\r
- if (_process != null)\r
- _process.successReport(this, gateMsg);\r
- else {\r
- if ( gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck ) {\r
- logger.info("GateDeleteAck: 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
- logger.info("GateSetAck: 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
- } else if (rtypemsg.isFailure()) {\r
- logger.info("rtypemsg failure");\r
- _status = ST_REPORT;\r
- if (_process != null)\r
- _process.failReport(this, gateMsg);\r
- else\r
- logger.info("Gate message error - " + gateMsg.getError().toString());\r
- } else if (rtypemsg.isAccounting()) {\r
- logger.info("rtypemsg account");\r
- _status = ST_ACCT;\r
- if (_process != null)\r
- _process.acctReport(this, gateMsg);\r
- }\r
- logger.info("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
+/**
+ @header@
+ */
+
+package org.pcmm;
+
+import org.pcmm.gates.ITransactionID;
+import org.pcmm.gates.impl.PCMMGateReq;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.prpdp.COPSPdpException;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 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(final short clientType, final String clientHandle) {
+ _handle = new COPSHandle(new COPSData(clientHandle));
+ _clientType = clientType;
+ _status = ST_CREATE;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public int 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
+ //**
+
+ /* <Request> ::= <Common Header>
+ * <Client Handle>
+ * <Context>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>
+ *
+ * Very important, this is actually being treated like this:
+ * <Named ClientSI> ::= <PRID> | <EPD>
+ *
+
+ // 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 {
+ // 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");
+ PCMMGateReq gateMsg = new PCMMGateReq(data);
+
+ 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");
+ strobjprid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ logger.info("COPSPrObjBase.PR_EPD");
+ repSIs.put(strobjprid, obj.getData().str());
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
+ break;
+ default:
+ logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());
+ logger.error("PRID: " + strobjprid);
+ logger.error("EPD: " + obj.getData().str());
+ break;
+ }
+
+ logger.info("rtypemsg process");
+ //** Here we must act in accordance with
+ //** the report received
+ if (rtypemsg.getReportType().equals(ReportType.SUCCESS)) {
+ logger.info("rtypemsg success");
+ _status = ST_REPORT;
+ if (_process != null)
+ _process.successReport(this, gateMsg);
+ } else {
+ if (gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateDeleteAck) {
+ logger.info("GateDeleteAck: GateID = " + gateMsg.getGateID().getGateID());
+ if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID1())
+ PCMMGlobalConfig.setGateID1(0);
+ if (gateMsg.getGateID().getGateID() == PCMMGlobalConfig.getGateID2())
+ PCMMGlobalConfig.setGateID2(0);
+
+ }
+ if (gateMsg.getTransactionID().getGateCommandType() == ITransactionID.GateSetAck) {
+ logger.info("GateSetAck: GateID = " + gateMsg.getGateID().getGateID());
+ if (0 == PCMMGlobalConfig.getGateID1())
+ PCMMGlobalConfig.setGateID1(gateMsg.getGateID().getGateID());
+ if (0 == PCMMGlobalConfig.getGateID2())
+ PCMMGlobalConfig.setGateID2(gateMsg.getGateID().getGateID());
+ }
+ }
+ if (rtypemsg.getReportType().equals(ReportType.FAILURE)) {
+ logger.info("rtypemsg failure");
+ _status = ST_REPORT;
+ if (_process != null)
+ _process.failReport(this, gateMsg);
+ else
+ logger.info("Gate message error - " + gateMsg.getError().toString());
+ } else
+ if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) {
+ logger.info("rtypemsg account");
+ _status = ST_ACCT;
+ if (_process != null)
+ _process.acctReport(this, gateMsg);
+ }
+ }
+ }
+
+ /**
+ * 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 <tt>COPSDeleteMsg</tt> received from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)
+ throws COPSPdpException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = ST_DEL;
+ }
+
+}
import org.umu.cops.prpep.COPSPepConnection;
import org.umu.cops.prpep.COPSPepException;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.ServerSocket;
* @param clientType
* Client-type
*/
- public PCMMPepAgent(String pepID, short clientType) {
+ public PCMMPepAgent(final String pepID, final short clientType) {
super(pepID, clientType);
serverPort = WELL_KNOWN_CMTS_PORT;
}
* @param clientType
* Client-type
*/
- public PCMMPepAgent(short clientType) {
+ public PCMMPepAgent(final short clientType) {
super(clientType);
serverPort = WELL_KNOWN_CMTS_PORT;
}
*/
private COPSPepConnection processConnection(Socket socket) throws IOException, COPSException, COPSPepException {
// Build OPN
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, getClientType());
-
- COPSPepId pepId = new COPSPepId();
- COPSData d = new COPSData(getPepID());
- pepId.setData(d);
-
- COPSClientOpenMsg msg = new COPSClientOpenMsg();
- msg.add(hdr);
- msg.add(pepId);
+ final COPSPepId pepId = new COPSPepId(new COPSData(getPepID()));
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(getClientType(), pepId, null, null, null);
// Create Socket and send OPN
/*
logger.info("Receive the resposne from PDP");
COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
- if (recvmsg.getHeader().isAClientAccept()) {
+ if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
logger.info("isAClientAccept from PDP");
COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
new Thread(conn).start();
return conn;
- } else if (recvmsg.getHeader().isAClientClose()) {
+ } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
logger.info("isAClientClose from PDP");
COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
error = cMsg.getError();
*/
package org.pcmm.messages;
-import java.util.Properties;
-
+import org.umu.cops.stack.COPSHeader.OPCode;
import org.umu.cops.stack.COPSMsg;
+import java.util.Properties;
+
/**
*
* Factory used to create {@code COPSMsg} based on message type input and a list
* message type
* @return new message.
*/
- COPSMsg create(byte messageType);
+ COPSMsg create(OPCode messageType);
/**
* creates a new message with the specified message type and content
* message content.
* @return new message.
*/
- COPSMsg create(byte messageType, Properties properties);
+ COPSMsg create(OPCode messageType, Properties properties);
}
package org.pcmm.messages.impl;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* COPS Decision Message
public class COPSDecisionMsgEX extends COPSMsg {
/* COPSHeader coming from base class */
- private COPSHandle _clientHandle;
- private COPSError _error;
- private Hashtable _decisions;
- private COPSIntegrity _integrity;
- private COPSContext _decContext;
- private COPSClientSI clientSI;
-
- // /
- public COPSDecisionMsgEX() {
- _clientHandle = null;
- _error = null;
- _decisions = new Hashtable(20);
- _integrity = null;
- _decContext = null;
- clientSI = null;
- }
-
- /**
- * Checks the sanity of COPS message and throw an COPSBadDataException when
- * data is bad.
- */
- public void checkSanity() throws COPSException {
- if ((_hdr == null) || (_clientHandle == null)
- || ((_error == null) && (_decisions.size() == 0))) {
- throw new COPSException("Bad message format");
- }
- }
-
- // /
- protected COPSDecisionMsgEX(byte[] data) throws COPSException {
- _decisions = new Hashtable(20);
- _clientHandle = null;
- _error = null;
- _integrity = null;
- _decContext = null;
- clientSI = null;
- parse(data);
- }
-
- /**
- * Parses the data and fills COPSDecisionMsg with its constituents
- *
- * @param data
- * a byte[]
- *
- * @throws COPSException
- *
- */
- protected void parse(byte[] data) throws COPSException {
- super.parseHeader(data);
-
- while (_dataStart < _dataLength) {
- byte[] buf = new byte[data.length - _dataStart];
- System.arraycopy(data, _dataStart, buf, 0, data.length - _dataStart);
-
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);
- switch (objHdr.getCNum()) {
- case HANDLE:
- _clientHandle = new COPSHandle(buf) {
- };
- _dataStart += _clientHandle.getDataLength();
- break;
- case CONTEXT:
- // dec context
- _decContext = new COPSContext(buf) {
- };
- _dataStart += _decContext.getDataLength();
- break;
- case ERROR:
- _error = new COPSError(buf) {
- };
- _dataStart += _error.getDataLength();
- break;
- case DEC:
- COPSDecision decs = new COPSDecision(buf) {
- };
- _dataStart += decs.getDataLength();
- addDecision(decs, _decContext);
- break;
- case MSG_INTEGRITY:
- _integrity = new COPSIntegrity(buf);
- _dataStart += _integrity.getDataLength();
- break;
- case CSI:
- clientSI = new COPSClientSI(buf) {
- };
- _dataStart += clientSI.getDataLength();
- break;
- default:
- throw new COPSException(
- "Bad Message format, unknown object type");
- }
- }
- checkSanity();
- }
-
- /**
- * Parses the data and fills that follows the header hdr and fills
- * COPSDecisionMsg
- *
- * @param hdr
- * a COPSHeader
- * @param data
- * a byte[]
- *
- * @throws COPSException
- *
- */
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {
- _hdr = hdr;
- parse(data);
- setMsgLength();
- }
-
- /**
- * Add message header
- *
- * @param hdr
- * a COPSHeader
- *
- * @throws COPSException
- *
- */
- public void add(COPSHeader hdr) throws COPSException {
- if (hdr == null)
- throw new COPSException("Null Header");
- if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC)
- throw new COPSException("Error Header (no COPS_OP_DEC)");
- _hdr = hdr;
- setMsgLength();
- }
-
- /**
- * Add client handle to the message
- *
- * @param handle
- * a COPSHandle
- *
- * @throws COPSException
- *
- */
- public void add(COPSHandle handle) throws COPSException {
- if (handle == null)
- throw new COPSException("Null Handle");
- _clientHandle = handle;
- setMsgLength();
- }
-
- /**
- * Add an Error object
- *
- * @param error
- * a COPSError
- *
- * @throws COPSException
- *
- */
- public void add(COPSError error) throws COPSException {
- if (_decisions.size() != 0)
- throw new COPSException("No null decisions");
- if (_error != null)
- throw new COPSException("No null error");
- // Message integrity object should be the very last one
- // If it is already added
- if (_integrity != null)
- throw new COPSException("No null integrity");
- _error = error;
- setMsgLength();
+ private final COPSHandle _clientHandle;
+ private final COPSError _error;
+ private final COPSIntegrity _integrity;
+// private COPSContext _decContext;
+ private final COPSClientSI clientSI;
+ private final Map<COPSContext, List<COPSDecision>> _decisions;
+
+ public COPSDecisionMsgEX(final short clientType, final COPSHandle _clientHandle, final COPSError _error,
+ final COPSIntegrity _integrity, final COPSClientSI clientSI,
+ final Map<COPSContext, List<COPSDecision>> _decisions) {
+ super(new COPSHeader(OPCode.DEC, clientType));
+ this._clientHandle = _clientHandle;
+ this._error = _error;
+ this._integrity = _integrity;
+ this.clientSI = clientSI;
+ this._decisions = new ConcurrentHashMap<>(_decisions);
}
- /**
- * Add one or more local decision object for a given decision context the
- * context is optional, if null all decision object are tided to message
- * context
- *
- * @param decision
- * a COPSDecision
- * @param context
- * a COPSContext
- *
- * @throws COPSException
- *
- */
- public void addDecision(COPSDecision decision, COPSContext context)
- throws COPSException {
- // Either error or decision can be added
- // If error is aleady there assert
- if (_error != null)
- throw new COPSException("No null error");
-
- if (decision.isLocalDecision())
- throw new COPSException("Is local decision");
+ @Override
+ protected int getDataLength() {
+ int out = 0;
+ if (_clientHandle != null) out += _clientHandle.getDataLength();
+ if (_error != null) out += _error.getDataLength();
- Vector v = (Vector) _decisions.get(context);
- if (v == null)
- v = new Vector();
-
- if (decision.isFlagSet()) {// Commented out as advised by Felix
- // if (v.size() != 0)
- // {
- // Only one set of decision flags is allowed
- // for each context
- // throw new COPSException
- // ("Bad Message format, only one set of decision flags is allowed.");
- // }
- } else {
- if (v.size() == 0) {
- // The flags decision must precede any other
- // decision message, since the decision is not
- // flags throw exception
- throw new COPSException(
- "Bad Message format, flags decision must precede any other decision object.");
+ // Display decisions
+ // Display any local decisions
+ for (final Map.Entry<COPSContext, List<COPSDecision>> entry : _decisions.entrySet()) {
+ out += entry.getKey().getDataLength();
+ for (final COPSDecision decision : entry.getValue()) {
+ out += decision.getDataLength();
}
}
- v.add(decision);
- _decisions.put(context, v);
-
- setMsgLength();
+ if (clientSI != null) out += clientSI.getDataLength();
+ if (_integrity != null) out += _integrity.getDataLength();
+ return out;
}
- /**
- * Add integrity object
- *
- * @param integrity
- * a COPSIntegrity
- *
- * @throws COPSException
- *
- */
- public void add(COPSIntegrity integrity) throws COPSException {
- if (integrity == null)
- throw new COPSException("Null Integrity");
- if (!integrity.isMessageIntegrity())
- throw new COPSException("Error Integrity");
- _integrity = integrity;
- setMsgLength();
- }
-
- /**
- * Add a client specific informations
- *
- * @param clientSI
- * a COPSClientSI
- *
- * @throws COPSException
- *
- */
- public void add(COPSClientSI clientSI) throws COPSException {
- if (clientSI == null)
- throw new COPSException("Null ClientSI");
- this.clientSI = clientSI;
- setMsgLength();
- }
-
- /**
- * Writes data to given socket
- *
- * @param id
- * a Socket
- *
- * @throws IOException
- *
- */
- public void writeData(Socket id) throws IOException {
- // checkSanity();
- if (_hdr != null)
- _hdr.writeData(id);
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
if (_clientHandle != null)
- _clientHandle.writeData(id);
+ _clientHandle.writeData(socket);
if (_error != null)
- _error.writeData(id);
+ _error.writeData(socket);
// Display decisions
// Display any local decisions
- for (Enumeration e = _decisions.keys(); e.hasMoreElements();) {
+ for (final Map.Entry<COPSContext, List<COPSDecision>> entry : _decisions.entrySet()) {
- COPSContext context = (COPSContext) e.nextElement();
- Vector v = (Vector) _decisions.get(context);
- context.writeData(id);
+ final COPSContext context = entry.getKey();
+ final List<COPSDecision> decisions = entry.getValue();
+ context.writeData(socket);
- for (Enumeration ee = v.elements(); ee.hasMoreElements();) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
- decision.writeData(id);
+ for (final COPSDecision decision : decisions) {
+ decision.writeData(socket);
}
}
if (clientSI != null)
- clientSI.writeData(id);
+ clientSI.writeData(socket);
if (_integrity != null)
- _integrity.writeData(id);
- }
-
- /**
- * Method getHeader
- *
- * @return a COPSHeader
- *
- */
- public COPSHeader getHeader() {
- return _hdr;
+ _integrity.writeData(socket);
}
/**
return clientSI;
}
- /**
- * Returns true if it has error object
- *
- * @return a boolean
- *
- */
- public boolean hasError() {
- return (_error != null);
- };
-
- /**
- * Should check hasError() before calling
- *
- * @return a COPSError
- *
- */
- public COPSError getError() {
- return _error;
- };
-
- /**
- * Returns a map of decision for which is an arry of context and vector of
- * associated decision object.
- *
- * @return a Hashtable
- *
- */
- public Hashtable getDecisions() {
- return _decisions;
- };
-
- /**
- * Returns true if it has integrity object
- *
- * @return a boolean
- *
- */
- public boolean hasIntegrity() {
- return (_integrity != null);
- };
-
- /**
- * Should check hasIntegrity() before calling
- *
- * @return a COPSIntegrity
- *
- */
- public COPSIntegrity getIntegrity() {
- return _integrity;
- };
-
- /**
- * Method setMsgLength
- *
- * @throws COPSException
- *
- */
- protected void setMsgLength() throws COPSException {
- short len = 0;
- if (_clientHandle != null)
- len += _clientHandle.getDataLength();
- if (_error != null)
- len += _error.getDataLength();
-
- // Display any local decisions
- for (Enumeration e = _decisions.keys(); e.hasMoreElements();) {
-
- COPSContext context = (COPSContext) e.nextElement();
- Vector v = (Vector) _decisions.get(context);
- len += context.getDataLength();
-
- for (Enumeration ee = v.elements(); ee.hasMoreElements();) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
- len += decision.getDataLength();
- }
- }
- if (clientSI != null)
- len += clientSI.getDataLength();
- if (_integrity != null) {
- len += _integrity.getDataLength();
- }
-
- _hdr.setMsgLength((int) len);
- }
-
- /**
- * Write an object textual description in the output stream
- *
- * @param os
- * an OutputStream
- *
- * @throws IOException
- *
- */
- public void dump(OutputStream os) throws IOException {
- _hdr.dump(os);
-
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
if (_clientHandle != null)
_clientHandle.dump(os);
if (_error != null)
_error.dump(os);
// Display any local decisions
- for (Enumeration e = _decisions.keys(); e.hasMoreElements();) {
-
- COPSContext context = (COPSContext) e.nextElement();
- Vector v = (Vector) _decisions.get(context);
+ for (final Map.Entry<COPSContext, List<COPSDecision>> entry : _decisions.entrySet()) {
+ final COPSContext context = entry.getKey();
+ final List<COPSDecision> v = entry.getValue();
context.dump(os);
- for (Enumeration ee = v.elements(); ee.hasMoreElements();) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
+ for (final COPSDecision decision : v) {
decision.dump(os);
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.stack.*;
-import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.OPCode;
import org.umu.cops.stack.COPSObjHeader.CType;
import java.net.InetAddress;
-import java.util.Properties;
+import java.util.*;
/**
*
*
* @see pcmm.messages.IMessageFactory#create(pcmm.messages.MessageType)
*/
- public COPSMsg create(final byte messageType) {
+ public COPSMsg create(final OPCode messageType) {
return create(messageType, new Properties());
}
* @see org.pcmm.messages.IMessageFactory#create(org.pcmm.messages.IMessage.
* MessageType, java.util.Properties)
*/
- public COPSMsg create(final byte messageType, final Properties properties) {
+ public COPSMsg create(final OPCode messageType, final Properties properties) {
logger.info("Creating message of type - " + messageType);
// return new PCMMMessage(messageType, content);
switch (messageType) {
- case COPSHeader.COPS_OP_OPN:
+ case OPN:
return createOPNMessage(properties);
- case COPSHeader.COPS_OP_REQ:
+ case REQ:
return createREQMessage(properties);
- case COPSHeader.COPS_OP_CAT:
+ case CAT:
return createCATMessage(properties);
- case COPSHeader.COPS_OP_CC:
+ case CC:
return createCCMessage(properties);
- case COPSHeader.COPS_OP_DEC:
+ case DEC:
return createDECMessage(properties);
- case COPSHeader.COPS_OP_DRQ:
+ case DRQ:
break;
- case COPSHeader.COPS_OP_KA:
+ case KA:
return createKAMessage(properties);
- case COPSHeader.COPS_OP_RPT:
+ case RPT:
break;
- case COPSHeader.COPS_OP_SSC:
+ case SSC:
break;
- case COPSHeader.COPS_OP_SSQ:
+ case SSQ:
break;
}
return null;
* @return - the message
*/
protected COPSMsg createDECMessage(final Properties prop) {
- final COPSDecisionMsg msg = new COPSDecisionMsg();
+
// ===common part between all gate control messages
- final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, IPCMMClient.CLIENT_TYPE);
+ // final COPSHeader hdr = new COPSHeader(OPCode.DEC, IPCMMClient.CLIENT_TYPE);
// handle
// context
- final COPSContext context = new COPSContext(COPSContext.CONFIG, (short) 0);
// decision
- final COPSDecision decision = new COPSDecision();
+ // TODO - the old command and flag codes are not congruent with the ones described in COPSDecision
+ // TODO - what is the correct client type to be using here???
+/*
if (prop.get(MessageProperties.DECISION_CMD_CODE) != null)
decision.setCmdCode((byte) prop.get(MessageProperties.DECISION_CMD_CODE));
if (prop.get(MessageProperties.DECISION_FLAG) != null)
decision.setFlags((short) prop.get(MessageProperties.DECISION_FLAG));
+*/
- final COPSClientSI si = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
+ final COPSData data;
if (prop.get(MessageProperties.GATE_CONTROL) != null)
- si.setData((COPSData) prop.get(MessageProperties.GATE_CONTROL));
- try {
- msg.add(hdr);
- final COPSHandle handle;
- if (prop.get(MessageProperties.CLIENT_HANDLE) != null) {
- handle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
- }
- else {
- // TODO - This smells wrong to have a null handle ID
- handle = new COPSHandle(null);
- }
- msg.add(handle);
- msg.addDecision(decision, context);
- msg.add(si);
+ data = (COPSData) prop.get(MessageProperties.GATE_CONTROL);
+ else
+ data = null;
- // TODO - determine why this block has been commented out
- // try {
- // msg.dump(System.out);
- // } catch (IOException unae) {
- // }
+ // TODO - Need to determine is SIGNALED is the correct default CSIType
+ // Decided that CSI object is not what should be encapsulated by the COPSDecisionMsg, therefore placing
+ // data into the COPSDecision object located in the decisionMap
+ // final COPSClientSI si = new COPSClientSI(CSIType.SIGNALED, data);
- } catch (final COPSException e) {
- logger.error(e.getMessage());
+ final COPSHandle handle;
+ if (prop.get(MessageProperties.CLIENT_HANDLE) != null) {
+ handle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
}
+ else {
+ // TODO - This smells wrong to have a null handle ID
+ handle = new COPSHandle(null);
+ }
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(CType.DEF, Command.NULL, DecisionFlag.NA, data));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ final COPSDecisionMsg msg = new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, handle, decisionMap, null);
+
+ // TODO - determine why this block has been commented out
+ // try {
+ // msg.dump(System.out);
+ // } catch (IOException unae) {
+ // }
return msg;
}
* @return COPS message
*/
protected COPSMsg createOPNMessage(final Properties prop) {
- final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, IPCMMClient.CLIENT_TYPE);
- final COPSPepId pepId = new COPSPepId();
// version infor object
short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO;
short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO;
if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null)
minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO);
// Mandatory MM version.
- final COPSClientSI clientSI = new COPSClientSI((byte) 1);
byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray();
- clientSI.setData(new COPSData(versionInfo, 0, versionInfo.length));
- final COPSClientOpenMsg msg = new COPSClientOpenMsg();
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData(versionInfo, 0, versionInfo.length));
try {
final COPSData d;
if (prop.get(MessageProperties.PEP_ID) != null)
d = new COPSData((String) prop.get(MessageProperties.PEP_ID));
else
d = new COPSData(InetAddress.getLocalHost().getHostName());
- pepId.setData(d);
- msg.add(hdr);
- msg.add(pepId);
- msg.add(clientSI);
+ final COPSPepId pepId = new COPSPepId(d);
+ return new COPSClientOpenMsg(IPCMMClient.CLIENT_TYPE, pepId, clientSI, null, null);
} catch (Exception e) {
logger.error("Error creating OPN message", e);
}
- return msg;
+
+ // TODO - this probably should not return null and throw an exception instead
+ return null;
}
/**
* @return COPS message
*/
protected COPSMsg createCATMessage(final Properties prop) {
- final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_CAT, IPCMMClient.CLIENT_TYPE);
+ // TODO - determine what the first constructor parameter really should be???
final COPSKATimer katimer;
if (prop.get(MessageProperties.KA_TIMER) != null)
- katimer = new COPSKATimer((short) prop.get(MessageProperties.KA_TIMER));
+ katimer = new COPSKATimer((short)prop.get(MessageProperties.KA_TIMER));
else
katimer = new COPSKATimer(KA_TIMER_VALUE);
+ // TODO - determine what the first constructor parameter really should be???
final COPSAcctTimer acctTimer;
if (prop.get(MessageProperties.ACCEPT_TIMER) != null)
acctTimer = new COPSAcctTimer((short) prop.get(MessageProperties.ACCEPT_TIMER));
else
acctTimer = new COPSAcctTimer(ACCT_TIMER_VALUE);
- final COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
- try {
- acceptMsg.add(hdr);
- acceptMsg.add(katimer);
- if (acctTimer.getTimerVal() != 0)
- acceptMsg.add(acctTimer);
- } catch (COPSException e) {
- logger.error(e.getMessage());
- }
- return acceptMsg;
+ if (acctTimer.getTimerVal() != 0)
+ return new COPSClientAcceptMsg(IPCMMClient.CLIENT_TYPE, katimer, acctTimer, null);
+ else return new COPSClientAcceptMsg(IPCMMClient.CLIENT_TYPE, katimer, null, null);
}
/**
* @return COPS message
*/
protected COPSMsg createCCMessage(final Properties prop) {
- final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, IPCMMClient.CLIENT_TYPE);
final COPSError err;
if (prop.get(MessageProperties.ERR_MESSAGE) != null) {
- short code = (short) 0;
- final short error = (short) prop.get(MessageProperties.ERR_MESSAGE);
+ ErrorTypes code = ErrorTypes.NA;
+ final ErrorTypes error = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE);
if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null)
- code = (short) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
- err = new COPSError(error, code);
+ code = (ErrorTypes) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
+ err = new COPSError(COPSError.ERROR_CODE_TO_TYPE.get(error.ordinal()),
+ COPSError.ERROR_CODE_TO_TYPE.get(code.ordinal()));
} else
- err = new COPSError(COPSError.COPS_ERR_UNKNOWN, (short) 0);
+ err = new COPSError(ErrorTypes.UNKNOWN, ErrorTypes.NA);
- final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
- try {
- closeMsg.add(cHdr);
- closeMsg.add(err);
- } catch (COPSException e) {
- logger.error(e.getMessage());
- }
- return closeMsg;
+ return new COPSClientCloseMsg(IPCMMClient.CLIENT_TYPE, err, null, null);
}
/**
* @return Request message
*/
protected COPSMsg createREQMessage(final Properties prop) {
- final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_REQ, IPCMMClient.CLIENT_TYPE);
- final COPSReqMsg req = new COPSReqMsg();
-
final short rType;
if (prop.get(MessageProperties.R_TYPE) != null)
rType = (Short) prop.get(MessageProperties.R_TYPE);
mType = (Short) prop.get(MessageProperties.M_TYPE);
else mType = ICMTS.DEFAULT_M_TYPE;
- final COPSContext copsContext = new COPSContext(rType, mType);
+ final COPSContext copsContext = new COPSContext(COPSContext.VAL_TO_RTYPE.get((int)rType), mType);
final COPSHandle copsHandle;
if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
copsHandle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
else
// just a random handle
copsHandle = new COPSHandle(new COPSData("" + Math.random() * 82730));
- try {
- req.add(cHdr);
- req.add(copsContext);
- req.add(copsHandle);
- } catch (COPSException e) {
- logger.error(e.getMessage());
- }
- return req;
+
+ return new COPSReqMsg(IPCMMClient.CLIENT_TYPE, copsHandle, copsContext, null, null, null, null, null);
}
/**
* TODO - Why is there a timer being instantiated but never used?
*/
protected COPSMsg createKAMessage(final Properties prop) {
- final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_KA, (short) 0);
- final COPSKAMsg kaMsg = new COPSKAMsg();
+ // TODO - determine why this isn't really doing anything
+ return new COPSKAMsg(null);
+/*
final COPSKATimer timer;
if (prop.get(MessageProperties.KA_TIMER) != null)
- timer = new COPSKATimer((Short) prop.get(MessageProperties.KA_TIMER));
+ timer = new COPSKATimer((short)0, (Short) prop.get(MessageProperties.KA_TIMER));
else
timer = new COPSKATimer();
- try {
- kaMsg.add(cHdr);
- } catch (COPSException e) {
- logger.error(e.getMessage());
- }
- return kaMsg;
+*/
}
}
*/
package org.pcmm.nio;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import java.nio.ByteBuffer;
-import java.util.Date;
-
import org.pcmm.PCMMProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.stack.COPSException;
-import org.umu.cops.stack.COPSHeader;
import org.umu.cops.stack.COPSMsg;
import org.umu.cops.stack.COPSMsgParser;
+import java.io.IOException;
+import java.net.Socket;
+
/**
* this class provides a set of utilities to efficiently read/write data from a
* stream, it could parameterized with a reading timeout or -1 for blocking
public class PCMMChannel {
private Logger logger = LoggerFactory.getLogger(getClass().getName());
- private ByteBuffer dataBuffer;
- private Socket socket;
+ private final Socket socket;
private int timeout;
public static final int DEFAULT_BYTE_BUFFER_SIZE = 2048;
public static final int DEFAULT_READ_TIMEOUT = -1;
- public PCMMChannel(Socket socket) {
+ public PCMMChannel(final Socket socket) {
this(socket, PCMMProperties.get(PCMMProperties.DEFAULT_TIEMOUT,
Integer.class, DEFAULT_READ_TIMEOUT));
}
- public PCMMChannel(Socket socket, int timeout) {
+ public PCMMChannel(final Socket socket, int timeout) {
this.socket = socket;
- dataBuffer = ByteBuffer.allocateDirect(DEFAULT_BYTE_BUFFER_SIZE);
logger.info("Allocated byte buffer with size = "
+ DEFAULT_BYTE_BUFFER_SIZE);
this.timeout = timeout;
}
- public int readData(byte[] dataRead, int nchar) throws IOException {
- InputStream input;
- input = getSocket().getInputStream();
- int nread = 0;
- int startTime = (int) (new Date().getTime());
- do {
- if (timeout == -1 || input.available() != 0) {
- nread += input.read(dataRead, nread, nchar - nread);
- startTime = (int) (new Date().getTime());
- } else {
- int nowTime = (int) (new Date().getTime());
- if ((nowTime - startTime) > timeout)
- break;
- }
- } while (nread != nchar);
- return nread;
- }
-
/**
* Method sendMsg
- *
- * @param msg
- * a COPSMsg
- *
+ * @param msg - a COPSMsg
* @throws IOException
* @throws COPSException
- *
*/
- public void sendMsg(COPSMsg msg) throws IOException, COPSException {
+ public void sendMsg(final COPSMsg msg) throws IOException, COPSException {
logger.debug("sendMsg({})==>{}", getSocket(), msg);
- msg.checkSanity();
msg.writeData(getSocket());
}
/**
* Method receiveMessage
- *
* @return a COPSMsg
- *
* @throws IOException
* @throws COPSException
- *
*/
public COPSMsg receiveMessage() throws IOException, COPSException {
- int nread = 0;
- byte[] hBuf = new byte[8];
-
- logger.debug("receiveMessage({})", getSocket());
-
- nread = readData(hBuf, 8);
-
- if (nread == 0) {
- throw new COPSException("Error reading connection");
- }
-
- if (nread != 8) {
- throw new COPSException("Bad COPS message");
- }
-
- COPSHeader hdr = new COPSHeader(hBuf);
- int dataLen = hdr.getMsgLength() - hdr.getHdrLength();
- logger.debug("COPS Msg length :[" + dataLen + "]\n");
- byte[] buf = new byte[dataLen + 1];
- nread = 0;
-
- nread = readData(buf, dataLen);
- buf[dataLen] = (byte) '\0';
- logger.debug("Data read length:[" + nread + "]\n");
-
- if (nread != dataLen) {
- throw new COPSException("Bad COPS message");
- }
- COPSMsgParser prser = new COPSMsgParser();
- COPSMsg msg = prser.parse(hdr, buf);
- return msg;
- }
-
- /**
- * @return the dataBuffer
- */
- public ByteBuffer getDataBuffer() {
- return dataBuffer;
- }
-
- /**
- * @param dataBuffer
- * the dataBuffer to set
- */
- public void setDataBuffer(ByteBuffer dataBuffer) {
- this.dataBuffer = dataBuffer;
+ return COPSMsgParser.parseMessage(socket);
}
/**
return socket;
}
- /**
- * @param socket
- * the socket to set
- */
- public void setSocket(Socket socket) {
- this.socket = socket;
- }
-
/**
* @return the timeout
*/
package org.pcmm.rcd;
-import java.net.InetAddress;
-
import org.umu.cops.stack.COPSMsg;
+import java.net.InetAddress;
+
/**
* <p>
* This is a Client Type 1, which represents existing "legacy" endpoints (e.g.,
*/
package org.pcmm.rcd.impl;
-import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.util.concurrent.Executors;
-
import org.pcmm.PCMMConstants;
import org.pcmm.PCMMProperties;
import org.pcmm.concurrent.IWorkerPool;
import org.pcmm.concurrent.impl.WorkerPool;
-// import org.junit.Assert;
import org.pcmm.messages.impl.MessageFactory;
import org.pcmm.rcd.IPCMMServer;
import org.pcmm.state.IState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.umu.cops.stack.COPSHeader;
+import org.umu.cops.stack.COPSHeader.OPCode;
import org.umu.cops.stack.COPSMsg;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.concurrent.Executors;
+
+// import org.junit.Assert;
+
/*
* (non-Javadoc)
*
* This client is used to handle requests from within the Application
* Manager
*
- * @param socket
+ * @param socket - the connection to the PCMM server
* @return client handler
*/
protected abstract IPCMMClientHandler getPCMMClientHandler(Socket socket);
*/
// if (getSocket() != null)
// handlersPool.remove(getSocket());
- COPSMsg message = MessageFactory.getInstance().create(COPSHeader.COPS_OP_CC);
+ COPSMsg message = MessageFactory.getInstance().create(OPCode.CC);
sendRequest(message);
return super.disconnect();
}
*/
package org.pcmm.rcd.impl;
-import java.net.Socket;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.Vector;
-import java.util.concurrent.Callable;
-
import org.pcmm.gates.IPCMMGate;
import org.pcmm.gates.ITransactionID;
import org.pcmm.gates.impl.PCMMGateReq;
import org.umu.cops.prpep.COPSPepDataProcess;
import org.umu.cops.prpep.COPSPepException;
import org.umu.cops.prpep.COPSPepReqStateMan;
-import org.umu.cops.stack.COPSAcctTimer;
-import org.umu.cops.stack.COPSClientAcceptMsg;
-import org.umu.cops.stack.COPSClientCloseMsg;
-import org.umu.cops.stack.COPSContext;
-import org.umu.cops.stack.COPSData;
-import org.umu.cops.stack.COPSDecision;
-import org.umu.cops.stack.COPSDecisionMsg;
-import org.umu.cops.stack.COPSError;
-import org.umu.cops.stack.COPSException;
-import org.umu.cops.stack.COPSHeader;
-import org.umu.cops.stack.COPSKATimer;
-import org.umu.cops.stack.COPSMsg;
-import org.umu.cops.stack.COPSPrObjBase;
-import org.umu.cops.stack.COPSReqMsg;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.net.Socket;
+import java.util.*;
+import java.util.concurrent.Callable;
/**
*
// set the major version info and minor version info to
// default (5,0)
logger.info("Send OPN message to the PS");
- sendRequest(MessageFactory.getInstance().create(COPSHeader.COPS_OP_OPN, new Properties()));
+ sendRequest(MessageFactory.getInstance().create(OPCode.OPN, new Properties()));
// wait for CAT
COPSMsg recvMsg = readMessage();
- if (recvMsg.getHeader().isAClientClose()) {
+ if (recvMsg.getHeader().getOpCode().equals(OPCode.CC)) {
COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvMsg;
logger.info("PS requested Client-Close" + cMsg.getError().getDescription());
// send a CC message and close the socket
disconnect();
return;
}
- if (recvMsg.getHeader().isAClientAccept()) {
+ if (recvMsg.getHeader().getOpCode().equals(OPCode.CAT)) {
logger.info("received Client-Accept from PS");
COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvMsg;
// Support
logger.info("Send a REQ message to the PS");
{
Properties prop = new Properties();
- COPSMsg reqMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_REQ, prop);
+ COPSMsg reqMsg = MessageFactory.getInstance().create(OPCode.REQ, prop);
handle = ((COPSReqMsg) reqMsg).getClientHandle().getId().str();
sendRequest(reqMsg);
}
/* public */class PCMMCmtsConnection extends COPSPepConnection {
- public PCMMCmtsConnection(short clientType, Socket sock) {
+ public PCMMCmtsConnection(final short clientType, final Socket sock) {
super(clientType, sock);
}
@SuppressWarnings("rawtypes")
class PCMMPSReqStateMan extends COPSPepReqStateMan {
- public PCMMPSReqStateMan(short clientType, String clientHandle) {
+ public PCMMPSReqStateMan(final short clientType, final String clientHandle) {
super(clientType, clientHandle);
_process = new CmtsDataProcessor();
throws COPSPepException {
// COPSHandle handle = dMsg.getClientHandle();
- Hashtable decisions = dMsg.getDecisions();
+ Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
- Hashtable<String, String> removeDecs = new Hashtable<String, String>(10);
- Hashtable<String, String> installDecs = new Hashtable<String, String>(10);
- Hashtable<String, String> errorDecs = new Hashtable<String, String>(10);
- for (Enumeration e = decisions.keys(); e.hasMoreElements();) {
+ Map<String, String> removeDecs = new HashMap<>();
+ Map<String, String> installDecs = new HashMap<>();
+ Map<String, String> errorDecs = new HashMap<>();
- COPSContext context = (COPSContext) e.nextElement();
- Vector v = (Vector) decisions.get(context);
- Enumeration ee = v.elements();
- COPSDecision cmddecision = (COPSDecision) ee.nextElement();
+ for (final Set<COPSDecision> copsDecisions : dMsg.getDecisions().values()) {
+ final COPSDecision cmddecision = copsDecisions.iterator().next();
// cmddecision --> we must check whether it is an error!
+ String prid = "";
+ switch (cmddecision.getCommand()) {
+ case INSTALL:
+ for (final COPSDecision decision : copsDecisions) {
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ // TODO when there is install request only the PR_PRID
+ // is git but the ClientSI object containing the PR_EPD
+ // is null??? this is why the tests fail and so I set
+ // the assertion to NOT true....
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ installDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ case REMOVE:
+ for (final COPSDecision decision : copsDecisions) {
+ COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ // TODO when there is install request only the PR_PRID
+ // is git but the ClientSI object containing the PR_EPD
+ // is null??? this is why the tests fail and so I set
+ // the assertion to NOT true....
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ removeDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
- if (cmddecision.isInstallDecision()) {
- String prid = new String();
- for (; ee.hasMoreElements();) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
- COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
- switch (obj.getSNum()) {
- // TODO when there is install request only the PR_PRID
- // is git but the ClientSI object containing the PR_EPD
- // is null??? this is why the tests fail and so I set
- // the assertion to NOT true....
- case COPSPrObjBase.PR_PRID:
- prid = obj.getData().str();
- break;
- case COPSPrObjBase.PR_EPD:
- installDecs.put(prid, obj.getData().str());
- break;
- default:
- break;
- }
- }
- }
- if (cmddecision.isRemoveDecision()) {
- String prid = new String();
- for (; ee.hasMoreElements();) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
- COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
- switch (obj.getSNum()) {
- case COPSPrObjBase.PR_PRID:
- prid = obj.getData().str();
- break;
- case COPSPrObjBase.PR_EPD:
- removeDecs.put(prid, obj.getData().str());
- break;
- default:
- break;
- }
- }
- }
- }
if (_process != null) {
// ** Apply decisions to the configuration
_process.setDecisions(this, removeDecs, installDecs, errorDecs);
@SuppressWarnings("rawtypes")
class CmtsDataProcessor extends COPSPepDataProcess {
- private Hashtable<String, String> removeDecs;
- private Hashtable<String, String> installDecs;
- private Hashtable<String, String> errorDecs;
+ private Map<String, String> removeDecs;
+ private Map<String, String> installDecs;
+ private Map<String, String> errorDecs;
private COPSPepReqStateMan stateManager;
public CmtsDataProcessor() {
- setRemoveDecs(new Hashtable<String, String>(10));
- setInstallDecs(new Hashtable<String, String>(10));
- setErrorDecs(new Hashtable<String, String>(10));
+ setRemoveDecs(new HashMap<String, String>());
+ setInstallDecs(new HashMap<String, String>());
+ setErrorDecs(new HashMap<String, String>());
}
@SuppressWarnings("unchecked")
@Override
- public void setDecisions(COPSPepReqStateMan man, Hashtable removeDecs, Hashtable installDecs, Hashtable errorDecs) {
+ public void setDecisions(final COPSPepReqStateMan man, final Map<String, String> removeDecs,
+ final Map<String, String> installDecs, final Map<String, String> errorDecs) {
setRemoveDecs(removeDecs);
setInstallDecs(installDecs);
setErrorDecs(errorDecs);
}
@Override
- public Hashtable getReportData(COPSPepReqStateMan man) {
+ public Map<String, String> getReportData(COPSPepReqStateMan man) {
if (isFailReport(man)) {
return errorDecs;
} else {
- ITransactionID transactionID = null;
- String key = null;
- Hashtable<String, String> siDataHashTable = new Hashtable<String, String>();
+ Map<String, String> siDataHashTable = new HashMap<>();
if (installDecs.size() > 0) {
String data = "";
for (String k : installDecs.keySet()) {
data = installDecs.get(k);
break;
}
- transactionID = new PCMMGateReq(new COPSData(data).getData()).getTransactionID();
+ final ITransactionID transactionID = new PCMMGateReq(new COPSData(data).getData()).getTransactionID();
IPCMMGate responseGate = new PCMMGateReq();
responseGate.setTransactionID(transactionID);
+
+ // TODO FIXME - Why is the key always null??? What value should be used here???
+ final String key = null;
siDataHashTable.put(key, new String(responseGate.getData()));
}
return siDataHashTable;
}
- public Hashtable<String, String> getRemoveDecs() {
- return removeDecs;
+ public Map<String, String> getRemoveDecs() {
+ return new HashMap<>(removeDecs);
}
- public void setRemoveDecs(Hashtable<String, String> removeDecs) {
- this.removeDecs = removeDecs;
+ public void setRemoveDecs(final Map<String, String> removeDecs) {
+ this.removeDecs = new HashMap<>(removeDecs);
}
- public Hashtable<String, String> getInstallDecs() {
- return installDecs;
+ public Map<String, String> getInstallDecs() {
+ return new HashMap<>(installDecs);
}
- public void setInstallDecs(Hashtable<String, String> installDecs) {
- this.installDecs = installDecs;
+ public void setInstallDecs(final Map<String, String> installDecs) {
+ this.installDecs = new HashMap<>(installDecs);
}
- public Hashtable<String, String> getErrorDecs() {
+ public Map<String, String> getErrorDecs() {
return errorDecs;
}
- public void setErrorDecs(Hashtable<String, String> errorDecs) {
- this.errorDecs = errorDecs;
+ public void setErrorDecs(final Map<String, String> errorDecs) {
+ this.errorDecs = new HashMap<>(errorDecs);
}
public COPSPepReqStateMan getStateManager() {
import org.umu.cops.prpdp.COPSPdpConnection;
import org.umu.cops.prpdp.COPSPdpDataProcess;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.InetAddress;
logger.debug("waiting for OPN message from CMTS");
COPSMsg opnMessage = client.readMessage();
// Client-Close
- if (opnMessage.getHeader().isAClientClose()) {
+ if (opnMessage.getHeader().getOpCode().equals(OPCode.CC)) {
COPSError error = ((COPSClientCloseMsg) opnMessage).getError();
logger.debug("CMTS requetsed Client-Close");
- throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode()));
+ throw new PCMMException(new PCMMError((short)error.getErrCode().ordinal(),
+ (short)error.getErrSubCode().ordinal()));
} else // Client-Open
{
- if (opnMessage.getHeader().isAClientOpen()) {
+ if (opnMessage.getHeader().getOpCode().equals(OPCode.OPN)) {
logger.debug("OPN message received from CMTS");
COPSClientOpenMsg opn = (COPSClientOpenMsg) opnMessage;
if (opn.getClientSI() == null) {
// send CAT response
Properties prop = new Properties();
logger.debug("send CAT to the CMTS ");
- COPSMsg catMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_CAT, prop);
+ COPSMsg catMsg = MessageFactory.getInstance().create(OPCode.CAT, prop);
client.sendRequest(catMsg);
// wait for REQ msg
COPSMsg reqMsg = client.readMessage();
// Client-Close
- if (reqMsg.getHeader().isAClientClose()) {
+ if (reqMsg.getHeader().getOpCode().equals(OPCode.CC)) {
COPSError error = ((COPSClientCloseMsg) opnMessage).getError();
logger.debug("CMTS requetsed Client-Close");
- throw new PCMMException(new PCMMError(error.getErrCode(), error.getErrSubCode()));
+ throw new PCMMException(new PCMMError((short)error.getErrCode().ordinal(),
+ (short)error.getErrSubCode().ordinal()));
} else // Request
{
- if (reqMsg.getHeader().isARequest()) {
+ if (reqMsg.getHeader().getOpCode().equals(OPCode.REQ)) {
logger.debug("Received REQ message form CMTS");
// end connection attempts
COPSReqMsg req = (COPSReqMsg) reqMsg;
// configure message properties
Properties prop = new Properties();
prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle());
- prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL);
- prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL);
+ prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL);
+ prop.put(MessageProperties.DECISION_FLAG, Command.NULL);
prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length));
- COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop);
+ COPSMsg decisionMsg = MessageFactory.getInstance().create(OPCode.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()) {
+ if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
logger.info("processing received report from CMTS");
COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
- if (reportMsg.getClientSI().size() == 0) {
+ if (reportMsg.getClientSI() == null) {
logger.debug("CMTS responded with an empty SI");
return false;
}
- COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ COPSClientSI clientSI = reportMsg.getClientSI();
IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
IPCMMError error = responseGate.getError();
if (error != null) {
// configure message properties
Properties prop = new Properties();
prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle());
- prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL);
- prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL);
+ prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL);
+ prop.put(MessageProperties.DECISION_FLAG, Command.NULL);
byte[] data = gate.getData();
prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length));
- COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop);
+ COPSMsg decisionMsg = MessageFactory.getInstance().create(OPCode.DEC, prop);
// ** Send the GateSet Decision
// **
try {
}
// waits for the gate-delete-ack or error
COPSMsg responseMsg = readMessage();
- if (responseMsg.getHeader().isAReport()) {
+ if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
logger.info("processing received report from CMTS");
COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
- if (reportMsg.getClientSI().size() == 0) {
+ if (reportMsg.getClientSI() == null) {
return false;
}
- COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ COPSClientSI clientSI = reportMsg.getClientSI();
IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
IPCMMError error = responseGate.getError();
if (error != null) {
// configure message properties
Properties prop = new Properties();
prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle());
- prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL);
- prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL);
+ prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL);
+ prop.put(MessageProperties.DECISION_FLAG, Command.NULL);
byte[] data = gate.getData();
prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length));
- COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop);
+ COPSMsg decisionMsg = MessageFactory.getInstance().create(OPCode.DEC, prop);
// ** Send the GateSet Decision
// **
try {
}
// waits for the gate-Info-ack or error
COPSMsg responseMsg = readMessage();
- if (responseMsg.getHeader().isAReport()) {
+ if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
logger.info("processing received report from CMTS");
COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
- if (reportMsg.getClientSI().size() == 0) {
+ if (reportMsg.getClientSI() == null) {
return false;
}
- COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ COPSClientSI clientSI = reportMsg.getClientSI();
IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
IPCMMError error = responseGate.getError();
ITransactionID responseTransactionID = responseGate.getTransactionID();
// configure message properties
Properties prop = new Properties();
prop.put(MessageProperties.CLIENT_HANDLE, getClientHandle());
- prop.put(MessageProperties.DECISION_CMD_CODE, COPSDecision.DEC_INSTALL);
- prop.put(MessageProperties.DECISION_FLAG, (short) COPSDecision.DEC_NULL);
+ prop.put(MessageProperties.DECISION_CMD_CODE, Command.INSTALL);
+ prop.put(MessageProperties.DECISION_FLAG, Command.NULL);
byte[] data = gate.getData();
prop.put(MessageProperties.GATE_CONTROL, new COPSData(data, 0, data.length));
- COPSMsg decisionMsg = MessageFactory.getInstance().create(COPSHeader.COPS_OP_DEC, prop);
+ COPSMsg decisionMsg = MessageFactory.getInstance().create(OPCode.DEC, prop);
// ** Send the GateSet Decision
// **
try {
}
// waits for the gate-Info-ack or error
COPSMsg responseMsg = readMessage();
- if (responseMsg.getHeader().isAReport()) {
+ if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
logger.info("processing received report from CMTS");
COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
- if (reportMsg.getClientSI().size() == 0) {
+ if (reportMsg.getClientSI() == null) {
return false;
}
- COPSClientSI clientSI = (COPSClientSI) reportMsg.getClientSI().elementAt(0);
+ COPSClientSI clientSI = reportMsg.getClientSI();
IPCMMGate responseGate = new PCMMGateReq(clientSI.getData().getData());
IPCMMError error = responseGate.getError();
ITransactionID responseTransactionID = responseGate.getTransactionID();
-package org.umu.cops.ospdp;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.ServerSocket;\r
-import java.net.Socket;\r
-import java.util.Map;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * Core PDP agent for outsourcing.\r
- */\r
-public class COPSPdpOSAgent extends Thread {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSAgent.class);\r
-\r
- /** Well-known port for COPS */\r
- public static final int WELL_KNOWN_PDP_PORT = 3288;\r
- /** Default keep-alive timer value (secs) */\r
- public static final short KA_TIMER_VALUE = 30;\r
- /** Default accounting timer value (secs) */\r
- public static final short ACCT_TIMER_VALUE = 0;\r
-\r
- /**\r
- PDP host port\r
- */\r
- private int _serverPort;\r
-\r
- /**\r
- Client-type of connecting PEP\r
- */\r
- private short _clientType;\r
-\r
- /**\r
- Accounting timer (secs)\r
- */\r
- private short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer (secs)\r
- */\r
- private short _kaTimer;\r
-\r
- /**\r
- Maps a PEP-ID to a connection\r
- */\r
- private final Map<String, COPSPdpOSConnection> _connectionMap;\r
- // map < String(PEPID), COPSPdpOSConnection > ConnectionMap;\r
-\r
- /**\r
- * Policy data processing object\r
- */\r
- private COPSPdpOSDataProcess _process;\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpOSAgent(short clientType, COPSPdpOSDataProcess process) {\r
- _serverPort = WELL_KNOWN_PDP_PORT;\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param port Port to listen to\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpOSAgent(int port, short clientType, COPSPdpOSDataProcess process) {\r
- _serverPort = port;\r
-\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Sets the keep-alive timer value\r
- * @param kaTimer Keep alive timer value (secs)\r
- */\r
- public void setKaTimer (short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Sets the accounting timer value\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAcctTimer (short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the value of the keep-alive timer\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer () {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Gets the accounting timer value\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer () {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return The client-type\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Disconnects a PEP\r
- * @param pepID PEP-ID of the PEP to be disconnected\r
- * @param error COPS Error to be reported as a reason\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- public void disconnect (String pepID, COPSError error) throws COPSException, IOException {\r
- COPSPdpOSConnection pdpConn = _connectionMap.get(pepID);\r
-\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- if (error != null)\r
- closeMsg.add(error);\r
-\r
- closeMsg.writeData(pdpConn.getSocket());\r
- pdpConn.close();\r
- }\r
-\r
- /**\r
- * Requests a COPS sync for a PEP\r
- * @param pepID PEP-ID of the PEP to be synced\r
- * @throws COPSException\r
- * @throws COPSPdpException\r
- */\r
- public void sync(String pepID) throws COPSException, COPSPdpException {\r
- COPSPdpOSConnection pdpConn = _connectionMap.get(pepID);\r
- pdpConn.syncAllRequestState();\r
- }\r
-\r
- /**\r
- * Removes a PEP from the connection map\r
- * @param pepID PEP-ID of the PEP to be removed\r
- */\r
- public void delete (String pepID) {\r
- _connectionMap.remove(pepID);\r
- }\r
-\r
- /**\r
- * Runs the PDP process\r
- */\r
- public void run() {\r
- try {\r
- final ServerSocket serverSocket = new ServerSocket (_serverPort);\r
-\r
- //Loop through for Incoming messages\r
-\r
- // server infinite loop\r
- while (true) {\r
- // Wait for an incoming connection from a PEP\r
- Socket socket = serverSocket.accept();\r
-\r
- // COPSDebug.out(getClass().getName(),"New connection accepted " +\r
- // socket.getInetAddress() +\r
- // ":" + socket.getPort());\r
-\r
- // We're waiting for an OPN message\r
- try {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(socket);\r
- if (msg.getHeader().isAClientOpen()) {\r
- handleClientOpenMsg(socket, msg);\r
- } else {\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- } catch (Exception e) { // COPSException, IOException\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,\r
- // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- }\r
- } catch (IOException e) {\r
- logger.error("Error processing socket messages", e);\r
- }\r
- }\r
-\r
- /**\r
- * Handles a COPS client-open message\r
- * @param conn Socket to the PEP\r
- * @param msg <tt>COPSMsg</tt> holding the client-open message\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException {\r
- COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;\r
- COPSPepId pepId = cMsg.getPepId();\r
-\r
- // Validate Client Type\r
- if (msg.getHeader().getClientType() != _clientType) {\r
- // Unsupported client type\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing data", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported client type");\r
- }\r
-\r
- // PEPId is mandatory\r
- if (pepId == null) {\r
- // Mandatory COPS object missing\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing data", unae);\r
- }\r
-\r
- throw new COPSException("Mandatory COPS object missing (PEPId)");\r
- }\r
-\r
- // Support\r
- if ( (cMsg.getClientSI() != null) ||\r
- (cMsg.getPdpAddress() != null) ||\r
- (cMsg.getIntegrity() != null)) {\r
-\r
- // Unsupported objects\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing data", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");\r
- }\r
-\r
- // Connection accepted\r
- COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());\r
- COPSKATimer katimer = new COPSKATimer(_kaTimer);\r
- COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);\r
- COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();\r
- acceptMsg.add(ahdr);\r
- acceptMsg.add(katimer) ;\r
- if (_acctTimer != 0) acceptMsg.add(acctTimer);\r
- acceptMsg.writeData(conn);\r
-\r
- COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process);\r
- pdpConn.setKaTimer(_kaTimer);\r
- if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);\r
- new Thread(pdpConn).start();\r
- _connectionMap.put(pepId.getData().str(),pdpConn);\r
- }\r
-}\r
+package org.umu.cops.ospdp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Core PDP agent for outsourcing.
+ */
+public class COPSPdpOSAgent extends Thread {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSAgent.class);
+
+ /** Well-known port for COPS */
+ public static final int WELL_KNOWN_PDP_PORT = 3288;
+ /** Default keep-alive timer value (secs) */
+ public static final short KA_TIMER_VALUE = 30;
+ /** Default accounting timer value (secs) */
+ public static final short ACCT_TIMER_VALUE = 0;
+
+ /**
+ PDP host port
+ */
+ private int _serverPort;
+
+ /**
+ Client-type of connecting PEP
+ */
+ private short _clientType;
+
+ /**
+ Accounting timer (secs)
+ */
+ private short _acctTimer;
+
+ /**
+ Keep-alive timer (secs)
+ */
+ private short _kaTimer;
+
+ /**
+ Maps a PEP-ID to a connection
+ */
+ private final Map<String, COPSPdpOSConnection> _connectionMap;
+ // map < String(PEPID), COPSPdpOSConnection > ConnectionMap;
+
+ /**
+ * Policy data processing object
+ */
+ private COPSPdpOSDataProcess _process;
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param clientType COPS Client-type
+ * @param process Object to perform policy data processing
+ */
+ public COPSPdpOSAgent(final short clientType, final COPSPdpOSDataProcess process) {
+ _serverPort = WELL_KNOWN_PDP_PORT;
+ _kaTimer = KA_TIMER_VALUE;
+ _acctTimer = ACCT_TIMER_VALUE;
+
+ _clientType = clientType;
+ _connectionMap = new ConcurrentHashMap<>();
+ _process = process;
+ }
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param port Port to listen to
+ * @param clientType COPS Client-type
+ * @param process Object to perform policy data processing
+ */
+ public COPSPdpOSAgent(final int port, final short clientType, final COPSPdpOSDataProcess process) {
+ _serverPort = port;
+
+ _kaTimer = KA_TIMER_VALUE;
+ _acctTimer = ACCT_TIMER_VALUE;
+
+ _clientType = clientType;
+ _connectionMap = new ConcurrentHashMap<>();
+ _process = process;
+ }
+
+ /**
+ * Sets the keep-alive timer value
+ * @param kaTimer Keep alive timer value (secs)
+ */
+ public void setKaTimer (short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Sets the accounting timer value
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAcctTimer (short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Gets the value of the keep-alive timer
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer () {
+ return _kaTimer;
+ }
+
+ /**
+ * Gets the accounting timer value
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer () {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets the client-type
+ * @return The client-type
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Disconnects a PEP
+ * @param pepID PEP-ID of the PEP to be disconnected
+ * @param error COPS Error to be reported as a reason
+ * @throws COPSException
+ * @throws IOException
+ */
+ public void disconnect(final String pepID, final COPSError error) throws COPSException, IOException {
+ final COPSPdpOSConnection pdpConn = _connectionMap.get(pepID);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
+ closeMsg.writeData(pdpConn.getSocket());
+ pdpConn.close();
+ }
+
+ /**
+ * Requests a COPS sync for a PEP
+ * @param pepID PEP-ID of the PEP to be synced
+ * @throws COPSException
+ * @throws COPSPdpException
+ */
+ public void sync(String pepID) throws COPSException, COPSPdpException {
+ COPSPdpOSConnection pdpConn = _connectionMap.get(pepID);
+ pdpConn.syncAllRequestState();
+ }
+
+ /**
+ * Removes a PEP from the connection map
+ * @param pepID PEP-ID of the PEP to be removed
+ */
+ public void delete (String pepID) {
+ _connectionMap.remove(pepID);
+ }
+
+ /**
+ * Runs the PDP process
+ */
+ public void run() {
+ try {
+ final ServerSocket serverSocket = new ServerSocket (_serverPort);
+
+ //Loop through for Incoming messages
+
+ // server infinite loop
+ while (true) {
+ // Wait for an incoming connection from a PEP
+ Socket socket = serverSocket.accept();
+
+ // COPSDebug.out(getClass().getName(),"New connection accepted " +
+ // socket.getInetAddress() +
+ // ":" + socket.getPort());
+
+ // We're waiting for an OPN message
+ try {
+ COPSMsg msg = COPSTransceiver.receiveMsg(socket);
+ if (msg.getHeader().getOpCode().equals(OPCode.OPN)) {
+ handleClientOpenMsg(socket, msg);
+ } else {
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Error closing socket", ex);
+ }
+ }
+ } catch (Exception e) { // COPSException, IOException
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Error closing socket", ex);
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error("Error processing socket messages", e);
+ }
+ }
+
+ /**
+ * Handles a COPS client-open message
+ * @param conn Socket to the PEP
+ * @param msg <tt>COPSMsg</tt> holding the client-open message
+ * @throws COPSException
+ * @throws IOException
+ */
+ private void handleClientOpenMsg(Socket conn, COPSMsg msg) throws COPSException, IOException {
+ COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
+ COPSPepId pepId = cMsg.getPepId();
+
+ // Validate Client Type
+ if (msg.getHeader().getClientType() != _clientType) {
+ // Unsupported client type
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing data", unae);
+ }
+
+ throw new COPSException("Unsupported client type");
+ }
+
+ // PEPId is mandatory
+ if (pepId == null) {
+ // Mandatory COPS object missing
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing data", unae);
+ }
+
+ throw new COPSException("Mandatory COPS object missing (PEPId)");
+ }
+
+ // Support
+ if ( (cMsg.getClientSI() != null) || (cMsg.getPdpAddress() != null) || (cMsg.getIntegrity() != null)) {
+
+ // Unsupported objects
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType,
+ new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing data", unae);
+ }
+
+ throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");
+ }
+
+ // Connection accepted
+ final COPSKATimer katimer = new COPSKATimer(_kaTimer);
+ final COPSClientAcceptMsg acceptMsg;
+ if (_acctTimer != 0)
+ acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer, new COPSAcctTimer(_acctTimer),
+ null);
+ else
+ acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer, null, null);
+
+ acceptMsg.writeData(conn);
+
+ final COPSPdpOSConnection pdpConn = new COPSPdpOSConnection(pepId, conn, _process);
+ pdpConn.setKaTimer(_kaTimer);
+ if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);
+ new Thread(pdpConn).start();
+ _connectionMap.put(pepId.getData().str(),pdpConn);
+ }
+}
-package org.umu.cops.ospdp;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Date;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-\r
-/**\r
- * Class for managing an outsourcing connection at the PDP side.\r
- */\r
-public class COPSPdpOSConnection implements Runnable {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSConnection.class);\r
-\r
- /**\r
- Socket connected to PEP\r
- */\r
- private Socket _sock;\r
-\r
- /**\r
- PEP identifier\r
- */\r
- private COPSPepId _pepId;\r
-\r
- /**\r
- Time of the latest keep-alive sent\r
- */\r
- private Date _lastKa;\r
-\r
- /**\r
- Opcode of the latest message sent\r
- */\r
- private byte _lastmessage;\r
-\r
- /**\r
- * Time of the latest keep-alive received\r
- */\r
- protected Date _lastRecKa;\r
-\r
- /**\r
- Maps a Client Handle to a Handler\r
- */\r
- protected Hashtable _managerMap;\r
- // map < String(COPSHandle), COPSPdpHandler> HandlerMap;\r
-\r
- /**\r
- * PDP policy data processor class\r
- */\r
- protected COPSPdpOSDataProcess _process;\r
-\r
- /**\r
- Accounting timer value (secs)\r
- */\r
- protected short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer value (secs)\r
- */\r
- protected short _kaTimer;\r
-\r
- /**\r
- COPS error returned by PEP\r
- */\r
- protected COPSError _error;\r
-\r
- /**\r
- * Creates a new PDP connection\r
- *\r
- * @param pepId PEP-ID of the connected PEP\r
- * @param sock Socket connected to PEP\r
- * @param process Object for processing policy data\r
- */\r
- public COPSPdpOSConnection(COPSPepId pepId, Socket sock, COPSPdpOSDataProcess process) {\r
- _sock = sock;\r
- _pepId = pepId;\r
-\r
- _lastKa = new Date();\r
- _lastmessage = COPSHeader.COPS_OP_OPN;\r
- _managerMap = new Hashtable(20);\r
-\r
- _kaTimer = 0;\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Gets the time of that latest keep-alive sent\r
- * @return Time of that latest keep-alive sent\r
- */\r
- public Date getLastKAlive() {\r
- return _lastKa;\r
- }\r
-\r
- /**\r
- * Sets the keep-alive timer value\r
- * @param kaTimer Keep-alive timer value (secs)\r
- */\r
- public void setKaTimer(short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Gets the keep-alive timer value\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer() {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Sets the accounting timer value\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAccTimer(short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the accounting timer value\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer() {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the latest COPS message\r
- * @return Code of the latest message sent\r
- */\r
- public byte getLastMessage() {\r
- return _lastmessage;\r
- }\r
-\r
- /**\r
- * Gets active handles\r
- * @return An <tt>Enumeration</tt> holding all active handles\r
- */\r
- public Enumeration getHandles() {\r
- return _managerMap.keys();\r
- }\r
-\r
- /**\r
- * Gets the handle map\r
- * @return A <tt>Hashtable</tt> holding the handle map\r
- */\r
- public Hashtable getReqStateMans() {\r
- return _managerMap;\r
- }\r
-\r
- /**\r
- * Gets the PEP-ID\r
- * @return The ID of the PEP, as a <tt>String</tt>\r
- */\r
- public String getPepId() {\r
- return _pepId.getData().str();\r
- }\r
-\r
- /**\r
- * Checks whether the socket to the PEP is closed or not\r
- * @return <tt>true</tt> if closed, <tt>false</tt> otherwise\r
- */\r
- public boolean isClosed() {\r
- return _sock.isClosed();\r
- }\r
-\r
- /**\r
- * Closes the socket to the PEP\r
- * @throws IOException\r
- */\r
- protected void close()\r
- throws IOException {\r
- _sock.close();\r
- }\r
-\r
- /**\r
- * Gets the socket to the PEP\r
- * @return Socket connected to the PEP\r
- */\r
- public Socket getSocket() {\r
- return _sock;\r
- }\r
-\r
- /**\r
- * Main loop\r
- */\r
- public void run () {\r
- Date _lastSendKa = new Date();\r
- _lastRecKa = new Date();\r
- try {\r
- while (!_sock.isClosed()) {\r
- if (_sock.getInputStream().available() != 0) {\r
- _lastmessage = processMessage(_sock);\r
- _lastRecKa = new Date();\r
- }\r
-\r
- // Keep Alive\r
- if (_kaTimer > 0) {\r
- // Timeout at PDP\r
- int _startTime = (int) (_lastRecKa.getTime());\r
- int cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > _kaTimer*1000) {\r
- _sock.close();\r
- // Notify all Request State Managers\r
- notifyNoKAAllReqStateMan();\r
- }\r
-\r
- // Send to PEP\r
- _startTime = (int) (_lastSendKa.getTime());\r
- cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > ((_kaTimer*3/4)*1000)) {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
- COPSKAMsg msg = new COPSKAMsg();\r
-\r
- msg.add(hdr);\r
-\r
- COPSTransceiver.sendMsg(msg, _sock);\r
- _lastSendKa = new Date();\r
- }\r
- }\r
-\r
- try {\r
- Thread.sleep(500);\r
- } catch (Exception e) {\r
- logger.error("Exception caught while sleeping", e);\r
- }\r
-\r
- }\r
- } catch (Exception e) {\r
- logger.error("Error processing COPS message from socket", e);\r
- }\r
-\r
- // connection closed by server\r
- // COPSDebug.out(getClass().getName(),"Connection closed by client");\r
- try {\r
- _sock.close();\r
- } catch (IOException e) {\r
- logger.error("Error closing socket", e);\r
- }\r
-\r
- // Notify all Request State Managers\r
- try {\r
- notifyCloseAllReqStateMan();\r
- } catch (COPSPdpException e) {\r
- logger.error("Error closing state managers", e);\r
- }\r
- }\r
-\r
- /**\r
- * Gets a COPS message from the socket and processes it\r
- * @param conn Socket connected to the PEP\r
- * @return Type of COPS message\r
- */\r
- private byte processMessage(Socket conn)\r
- throws COPSPdpException, COPSException, IOException {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
-\r
- if (msg.getHeader().isAClientClose()) {\r
- handleClientCloseMsg(conn, msg);\r
- return COPSHeader.COPS_OP_CC;\r
- } else if (msg.getHeader().isAKeepAlive()) {\r
- handleKeepAliveMsg(conn, msg);\r
- return COPSHeader.COPS_OP_KA;\r
- } else if (msg.getHeader().isARequest()) {\r
- handleRequestMsg(conn, msg);\r
- return COPSHeader.COPS_OP_REQ;\r
- } else if (msg.getHeader().isAReport()) {\r
- handleReportMsg(conn, msg);\r
- return COPSHeader.COPS_OP_RPT;\r
- } else if (msg.getHeader().isADeleteReq()) {\r
- handleDeleteRequestMsg(conn, msg);\r
- return COPSHeader.COPS_OP_DRQ;\r
- } else if (msg.getHeader().isASyncComplete()) {\r
- handleSyncComplete(conn, msg);\r
- return COPSHeader.COPS_OP_SSC;\r
- } else {\r
- throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
- }\r
- }\r
-\r
- /**\r
- * Handle Client Close Message, close the passed connection\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- *\r
- * <Client-Close> ::= <Common Header>\r
- * <Error>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- */\r
- private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
- COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
- _error = cMsg.getError();\r
-\r
- // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
-\r
- try {\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- conn.close();\r
- } catch (Exception unae) {\r
- logger.error("Unexpected exception while closing the connection", unae);\r
- }\r
- }\r
-\r
- /**\r
- * Gets the occurred COPS Error\r
- * @return <tt>COPSError</tt> object\r
- */\r
- protected COPSError getError() {\r
- return _error;\r
- }\r
-\r
- /**\r
- * Handle Keep Alive Message\r
- *\r
- * <Keep-Alive> ::= <Common Header>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
- COPSKAMsg cMsg = (COPSKAMsg) msg;\r
-\r
- COPSKAMsg kaMsg = (COPSKAMsg) msg;\r
- try {\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- kaMsg.writeData(conn);\r
- } catch (Exception unae) {\r
- logger.error("Unexpected exception writing COPS data", unae);\r
- }\r
- }\r
-\r
- /**\r
- * Handle Delete Request Message\r
- *\r
- * <Delete Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Reason>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
- COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;\r
- // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +\r
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- // Delete clientHandler\r
- if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {\r
- // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +\r
- // cMsg.getClientHandle().getId().getData());\r
- }\r
-\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("State manager not found for ID - " + cMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processDeleteRequestState(cMsg);\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Handle Request Message\r
- *\r
- * <Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Context>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {\r
- COPSReqMsg reqMsg = (COPSReqMsg) msg;\r
- COPSContext cntxt = reqMsg.getContext();\r
- COPSHeader header = reqMsg.getHeader();\r
- //short reqType = cntxt.getRequestType();\r
- short cType = header.getClientType();\r
-\r
- // Support\r
- if (reqMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpOSReqStateMan man;\r
- man = (COPSPdpOSReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- man = new COPSPdpOSReqStateMan(cType, reqMsg.getClientHandle().getId().str());\r
- _managerMap.put(reqMsg.getClientHandle().getId().str(),man);\r
- man.setDataProcess(_process);\r
- man.initRequestState(_sock);\r
-\r
- // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +\r
- // header.getClientType() + " msgType=" +\r
- // cntxt.getMessageType() + ", connId=" + conn.toString());\r
- }\r
-\r
- man.processRequest(reqMsg);\r
- }\r
-\r
- /**\r
- * Handle Report Message\r
- *\r
- * <Report State> ::= <Common Header>\r
- * <Client Handle>\r
- * <Report Type>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleReportMsg(Socket conn, COPSMsg msg) throws COPSPdpException {\r
- COPSReportMsg repMsg = (COPSReportMsg) msg;\r
- // COPSHandle handle = repMsg.getClientHandle();\r
- // COPSHeader header = repMsg.getHeader();\r
-\r
- // Support\r
- if (repMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("State manager not found for ID - " + repMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processReport(repMsg);\r
- }\r
- }\r
-\r
- /**\r
- * Method handleSyncComplete\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleSyncComplete(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
- COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
- // COPSHandle handle = cMsg.getClientHandle();\r
- // COPSHeader header = cMsg.getHeader();\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("State manager not found for ID - " + cMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processSyncComplete(cMsg);\r
- }\r
- }\r
-\r
- /**\r
- * Requests a COPS sync from the PEP\r
- * @throws COPSException\r
- * @throws COPSPdpException\r
- */\r
- protected void syncAllRequestState()\r
- throws COPSException, COPSPdpException {\r
- if (_managerMap.size() > 0) {\r
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
- String handle = (String) e.nextElement();\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
-\r
- man.syncRequestState();\r
- }\r
- }\r
- }\r
-\r
- private void notifyCloseAllReqStateMan()\r
- throws COPSPdpException {\r
- if (_managerMap.size() > 0) {\r
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
- String handle = (String) e.nextElement();\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
-\r
- man.processClosedConnection(_error);\r
- }\r
- }\r
- }\r
-\r
- private void notifyNoKAAllReqStateMan()\r
- throws COPSPdpException {\r
- if (_managerMap.size() > 0) {\r
- for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
- String handle = (String) e.nextElement();\r
- COPSPdpOSReqStateMan man = (COPSPdpOSReqStateMan) _managerMap.get(handle);\r
-\r
- man.processNoKAConnection();\r
- }\r
- }\r
- }\r
-\r
-}\r
+package org.umu.cops.ospdp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Class for managing an outsourcing connection at the PDP side.
+ */
+public class COPSPdpOSConnection implements Runnable {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSPdpOSConnection.class);
+
+ /**
+ Socket connected to PEP
+ */
+ private Socket _sock;
+
+ /**
+ PEP identifier
+ */
+ private COPSPepId _pepId;
+
+ /**
+ Time of the latest keep-alive sent
+ */
+ private Date _lastKa;
+
+ /**
+ * Time of the latest keep-alive received
+ */
+ protected Date _lastRecKa;
+
+ /**
+ Maps a Client Handle to a Handler
+ */
+ protected final Map<String, COPSPdpOSReqStateMan> _managerMap;
+
+ /**
+ * PDP policy data processor class
+ */
+ protected COPSPdpOSDataProcess _process;
+
+ /**
+ Accounting timer value (secs)
+ */
+ protected short _acctTimer;
+
+ /**
+ Keep-alive timer value (secs)
+ */
+ protected short _kaTimer;
+
+ /**
+ COPS error returned by PEP
+ */
+ protected COPSError _error;
+
+ /**
+ * Creates a new PDP connection
+ *
+ * @param pepId PEP-ID of the connected PEP
+ * @param sock Socket connected to PEP
+ * @param process Object for processing policy data
+ */
+ public COPSPdpOSConnection(COPSPepId pepId, Socket sock, COPSPdpOSDataProcess process) {
+ _sock = sock;
+ _pepId = pepId;
+
+ _lastKa = new Date();
+ _managerMap = new ConcurrentHashMap<>();
+
+ _kaTimer = 0;
+ _process = process;
+ }
+
+ /**
+ * Gets the time of that latest keep-alive sent
+ * @return Time of that latest keep-alive sent
+ */
+ public Date getLastKAlive() {
+ return _lastKa;
+ }
+
+ /**
+ * Sets the keep-alive timer value
+ * @param kaTimer Keep-alive timer value (secs)
+ */
+ public void setKaTimer(short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Gets the keep-alive timer value
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer() {
+ return _kaTimer;
+ }
+
+ /**
+ * Sets the accounting timer value
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAccTimer(short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Gets the accounting timer value
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer() {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets the PEP-ID
+ * @return The ID of the PEP, as a <tt>String</tt>
+ */
+ public String getPepId() {
+ return _pepId.getData().str();
+ }
+
+ /**
+ * Checks whether the socket to the PEP is closed or not
+ * @return <tt>true</tt> if closed, <tt>false</tt> otherwise
+ */
+ public boolean isClosed() {
+ return _sock.isClosed();
+ }
+
+ /**
+ * Closes the socket to the PEP
+ * @throws IOException
+ */
+ protected void close()
+ throws IOException {
+ _sock.close();
+ }
+
+ /**
+ * Gets the socket to the PEP
+ * @return Socket connected to the PEP
+ */
+ public Socket getSocket() {
+ return _sock;
+ }
+
+ /**
+ * Main loop
+ */
+ public void run() {
+ Date _lastSendKa = new Date();
+ _lastRecKa = new Date();
+ try {
+ while (!_sock.isClosed()) {
+ if (_sock.getInputStream().available() != 0) {
+// _lastmessage = processMessage(_sock);
+ processMessage(_sock);
+ _lastRecKa = new Date();
+ }
+
+ // Keep Alive
+ if (_kaTimer > 0) {
+ // Timeout at PDP
+ int _startTime = (int) (_lastRecKa.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > _kaTimer*1000) {
+ _sock.close();
+ // Notify all Request State Managers
+ notifyNoKAAllReqStateMan();
+ }
+
+ // Send to PEP
+ _startTime = (int) (_lastSendKa.getTime());
+ cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > ((_kaTimer*3/4)*1000)) {
+ // TODO - is 0 ok for a clientType here???
+ final COPSKAMsg msg = new COPSKAMsg(null);
+ COPSTransceiver.sendMsg(msg, _sock);
+ _lastSendKa = new Date();
+ }
+ }
+
+ try {
+ Thread.sleep(500);
+ } catch (Exception e) {
+ logger.error("Exception caught while sleeping", e);
+ }
+
+ }
+ } catch (Exception e) {
+ logger.error("Error processing COPS message from socket", e);
+ }
+
+ // connection closed by server
+ // COPSDebug.out(getClass().getName(),"Connection closed by client");
+ try {
+ _sock.close();
+ } catch (IOException e) {
+ logger.error("Error closing socket", e);
+ }
+
+ // Notify all Request State Managers
+ try {
+ notifyCloseAllReqStateMan();
+ } catch (COPSPdpException e) {
+ logger.error("Error closing state managers", e);
+ }
+ }
+
+ /**
+ * Gets a COPS message from the socket and processes it
+ * @param conn Socket connected to the PEP
+ */
+ private void processMessage(Socket conn) throws COPSPdpException, COPSException, IOException {
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+
+ if (msg.getHeader().getOpCode().equals(OPCode.CC)) {
+ handleClientCloseMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.KA)) {
+ handleKeepAliveMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.REQ)) {
+ handleRequestMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.RPT)) {
+ handleReportMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.DRQ)) {
+ handleDeleteRequestMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.SSC)) {
+ handleSyncComplete(conn, msg);
+ } else {
+ throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
+ }
+ }
+
+ /**
+ * Handle Client Close Message, close the passed connection
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ */
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
+ _error = cMsg.getError();
+
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
+
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ conn.close();
+ } catch (Exception unae) {
+ logger.error("Unexpected exception while closing the connection", unae);
+ }
+ }
+
+ /**
+ * Gets the occurred COPS Error
+ * @return <tt>COPSError</tt> object
+ */
+ protected COPSError getError() {
+ return _error;
+ }
+
+ /**
+ * Handle Keep Alive Message
+ *
+ * <Keep-Alive> ::= <Common Header>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
+ COPSKAMsg cMsg = (COPSKAMsg) msg;
+
+ COPSKAMsg kaMsg = (COPSKAMsg) msg;
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ kaMsg.writeData(conn);
+ } catch (Exception unae) {
+ logger.error("Unexpected exception writing COPS data", unae);
+ }
+ }
+
+ /**
+ * Handle Delete Request Message
+ *
+ * <Delete Request> ::= <Common Header>
+ * <Client Handle>
+ * <Reason>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)
+ throws COPSPdpException {
+ COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;
+ // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ // Delete clientHandler
+ if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {
+ // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +
+ // cMsg.getClientHandle().getId().getData());
+ }
+
+ final COPSPdpOSReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("State manager not found for ID - " + cMsg.getClientHandle().getId().str());
+ } else {
+ man.processDeleteRequestState(cMsg);
+ }
+
+ }
+
+ /**
+ * Handle Request Message
+ *
+ * <Request> ::= <Common Header>
+ * <Client Handle>
+ * <Context>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {
+ final COPSReqMsg reqMsg = (COPSReqMsg) msg;
+ final COPSHeader header = reqMsg.getHeader();
+ final short cType = header.getClientType();
+
+ // Support
+ if (reqMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ final COPSPdpOSReqStateMan man;
+ if (_managerMap.get(reqMsg.getClientHandle().getId().str()) == null) {
+ man = new COPSPdpOSReqStateMan(cType, reqMsg.getClientHandle().getId().str());
+ _managerMap.put(reqMsg.getClientHandle().getId().str(),man);
+ man.setDataProcess(_process);
+ man.initRequestState(_sock);
+ } else {
+ man = _managerMap.get(reqMsg.getClientHandle().getId().str());
+ }
+ man.processRequest(reqMsg);
+ }
+
+ /**
+ * Handle Report Message
+ *
+ * <Report State> ::= <Common Header>
+ * <Client Handle>
+ * <Report Type>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleReportMsg(Socket conn, COPSMsg msg) throws COPSPdpException {
+ COPSReportMsg repMsg = (COPSReportMsg) msg;
+ // COPSHandle handle = repMsg.getClientHandle();
+ // COPSHeader header = repMsg.getHeader();
+
+ // Support
+ if (repMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ COPSPdpOSReqStateMan man = _managerMap.get(repMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("State manager not found for ID - " + repMsg.getClientHandle().getId().str());
+ } else {
+ man.processReport(repMsg);
+ }
+ }
+
+ /**
+ * Method handleSyncComplete
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleSyncComplete(Socket conn, COPSMsg msg) throws COPSPdpException {
+ final COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ final COPSPdpOSReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("State manager not found for ID - " + cMsg.getClientHandle().getId().str());
+ } else {
+ man.processSyncComplete(cMsg);
+ }
+ }
+
+ /**
+ * Requests a COPS sync from the PEP
+ * @throws COPSException
+ * @throws COPSPdpException
+ */
+ protected void syncAllRequestState() throws COPSException, COPSPdpException {
+ for (final COPSPdpOSReqStateMan man : _managerMap.values()) {
+ man.syncRequestState();
+ }
+ }
+
+ private void notifyCloseAllReqStateMan() throws COPSPdpException {
+ for (final COPSPdpOSReqStateMan man : _managerMap.values()) {
+ man.processClosedConnection(_error);
+ }
+ }
+
+ private void notifyNoKAAllReqStateMan() throws COPSPdpException {
+ for (final COPSPdpOSReqStateMan man : _managerMap.values()) {
+ man.processNoKAConnection();
+ }
+ }
+
+}
-package org.umu.cops.ospdp;\r
-\r
-import java.util.Vector;\r
-\r
-import org.umu.cops.stack.COPSError;\r
-\r
-/**\r
- * Abstract class for implementing policy data processing classes for outsourcing PDPs.\r
- */\r
-abstract public class COPSPdpOSDataProcess {\r
- /**\r
- * Gets the policies to be uninstalled\r
- * @param man The associated request state manager\r
- * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
- */\r
- abstract public Vector getRemovePolicy(COPSPdpOSReqStateMan man);\r
- /**\r
- * Gets the policies to be installed\r
- * @param man The associated request state manager\r
- * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
- */\r
- abstract public Vector getInstallPolicy(COPSPdpOSReqStateMan man);\r
- /**\r
- * Makes a decision from the supplied request data\r
- * @param man The associated request state manager\r
- * @param reqSIs Client specific data suppplied in the COPS request\r
- */\r
- abstract public void setClientData(COPSPdpOSReqStateMan man, Vector reqSIs);\r
- /**\r
- * Builds a failure report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void failReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
- /**\r
- * Builds a success report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void successReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
- /**\r
- * Builds an accounting report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void acctReport (COPSPdpOSReqStateMan man, Vector reportSIs);\r
- /**\r
- * Notifies that no accounting report has been received\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyNoAcctReport (COPSPdpOSReqStateMan man);\r
-\r
- /**\r
- * Notifies a keep-alive timeout\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyNoKAliveReceived (COPSPdpOSReqStateMan man);\r
-\r
- /**\r
- * Notifies that the connection has been closed\r
- * @param man The associated request state manager\r
- * @param error Reason\r
- */\r
- public abstract void notifyClosedConnection (COPSPdpOSReqStateMan man, COPSError error);\r
-\r
- /**\r
- * Notifies that a request state has been deleted\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyDeleteRequestState (COPSPdpOSReqStateMan man);\r
-\r
- /**\r
- * Notifies that a request state has been closed\r
- * @param man The associated request state manager\r
- */\r
- public abstract void closeRequestState(COPSPdpOSReqStateMan man);\r
-\r
-}\r
+package org.umu.cops.ospdp;
+
+import org.umu.cops.stack.COPSClientSI;
+import org.umu.cops.stack.COPSError;
+
+import java.util.Vector;
+
+/**
+ * Abstract class for implementing policy data processing classes for outsourcing PDPs.
+ */
+public interface COPSPdpOSDataProcess {
+ /**
+ * Gets the policies to be uninstalled
+ * @param man The associated request state manager
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled
+ */
+ public Vector getRemovePolicy(COPSPdpOSReqStateMan man);
+ /**
+ * Gets the policies to be installed
+ * @param man The associated request state manager
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled
+ */
+ public Vector getInstallPolicy(COPSPdpOSReqStateMan man);
+ /**
+ * Makes a decision from the supplied request data
+ * @param man The associated request state manager
+ * @param reqSIs Client specific data suppplied in the COPS request
+ */
+ public void setClientData(COPSPdpOSReqStateMan man, COPSClientSI... reqSIs);
+ /**
+ * Builds a failure report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void failReport (COPSPdpOSReqStateMan man, COPSClientSI... reportSIs);
+ /**
+ * Builds a success report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void successReport (COPSPdpOSReqStateMan man, COPSClientSI... reportSIs);
+ /**
+ * Builds an accounting report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void acctReport (COPSPdpOSReqStateMan man, COPSClientSI... reportSIs);
+ /**
+ * Notifies that no accounting report has been received
+ * @param man The associated request state manager
+ */
+ abstract void notifyNoAcctReport (COPSPdpOSReqStateMan man);
+
+ /**
+ * Notifies a keep-alive timeout
+ * @param man The associated request state manager
+ */
+ abstract void notifyNoKAliveReceived (COPSPdpOSReqStateMan man);
+
+ /**
+ * Notifies that the connection has been closed
+ * @param man The associated request state manager
+ * @param error Reason
+ */
+ abstract void notifyClosedConnection (COPSPdpOSReqStateMan man, COPSError error);
+
+ /**
+ * Notifies that a request state has been deleted
+ * @param man The associated request state manager
+ */
+ abstract void notifyDeleteRequestState (COPSPdpOSReqStateMan man);
+
+ /**
+ * Notifies that a request state has been closed
+ * @param man The associated request state manager
+ */
+ abstract void closeRequestState(COPSPdpOSReqStateMan man);
+
+}
-package org.umu.cops.ospdp;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Vector;\r
-\r
-/**\r
- * COPS message transceiver class for outsourcing connections at the PDP side.\r
- *\r
- * TODO - change all references of Vector to List<>\r
- */\r
-public class COPSPdpOSMsgSender {\r
- /**\r
- * Socket connected to PEP\r
- */\r
- protected Socket _sock;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Creates a COPSPepMsgSender\r
- *\r
- * @param clientType COPS client-type\r
- * @param clientHandle Client handle\r
- * @param sock Socket to the PEP\r
- */\r
- public COPSPdpOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
- // COPS Handle\r
- _handle = clientHandle;\r
- _clientType = clientType;\r
-\r
- _sock = sock;\r
- }\r
-\r
- /**\r
- * Gets the client handle\r
- * @return Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return Client-type value\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Sends a decision message which was requested by the PEP\r
- * @param removeDecs Decisions to be removed\r
- * @param installDecs Decisions to be installed\r
- * @throws COPSPdpException\r
- */\r
- public void sendSolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {\r
- sendDecision(removeDecs, installDecs, true);\r
- }\r
-\r
- /**\r
- * Sends a decision message which was not requested by the PEP\r
- * @param removeDecs Decisions to be removed\r
- * @param installDecs Decisions to be installed\r
- * @throws COPSPdpException\r
- */\r
- public void sendUnsolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {\r
- sendDecision(removeDecs, installDecs, false);\r
- }\r
-\r
- /**\r
- * Sends a decision message to the PEP\r
- * @param removeDecs Decisions to be removed\r
- * @param installDecs Decisions to be installed\r
- * @param solicited <tt>true</tt> if the PEP requested this decision, <tt>false</tt> otherwise\r
- * @throws COPSPdpException\r
- */\r
- public void sendDecision(Vector removeDecs, Vector installDecs, boolean solicited) throws COPSPdpException {\r
- // Common Header holding the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- if (solicited)\r
- hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED);\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(handle);\r
-\r
- // Decisions (no flags supplied)\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
-\r
- // Remove Decisions\r
- // <Decision: Flags>\r
- if (removeDecs.size() > 0) {\r
- COPSDecision rdec1 = new COPSDecision();\r
- rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
-\r
- decisionMsg.addDecision(rdec1, cntxt);\r
-\r
- Enumeration removeDecsEnum = removeDecs.elements();\r
- while (removeDecsEnum.hasMoreElements())\r
- decisionMsg.addDecision((COPSDecision) removeDecsEnum.nextElement(), cntxt);\r
- }\r
-\r
- // Install Decisions\r
- // <Decision: Flags>\r
- if (installDecs.size() > 0) {\r
- COPSDecision idec1 = new COPSDecision();\r
- idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
-\r
- decisionMsg.addDecision(idec1, cntxt);\r
-\r
- Enumeration installDecsEnum = installDecs.elements();\r
- while (installDecsEnum.hasMoreElements())\r
- decisionMsg.addDecision((COPSDecision) installDecsEnum.nextElement(), cntxt);\r
- /**\r
- COPSIntegrity intr = new COPSIntegrity();\r
- intr.setKeyId(19);\r
- intr.setSeqNum(9);\r
- intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
- decisionMsg.add(intr);\r
- /**/\r
- }\r
- } catch (COPSException e) {\r
- e.printStackTrace();\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- //** Send decision\r
- //**\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**FIXME: unused?\r
- * Sends a message asking that the request state be deleted\r
- * @throws COPSPdpException\r
- */\r
- public void sendDeleteRequestState() throws COPSPdpException {\r
- /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>)\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * <Decision: Flags> ::= Remove Request-State\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request (default UNSOLICITED)\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- // Decisions\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
- // <Decision: Flags>\r
- COPSDecision dec = new COPSDecision();\r
- dec.setCmdCode(COPSDecision.DEC_REMOVE);\r
- dec.setFlags(COPSDecision.F_REQSTATE);\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(clienthandle);\r
- decisionMsg.addDecision(dec, cntxt);\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Method sendOpenNewRequestState\r
- *\r
- * @throws COPSPdpException\r
- *\r
- */\r
- //FIXME: Unused?\r
- public void sendOpenNewRequestState() throws COPSPdpException {\r
- /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>)\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * <Decision: Flags> ::= Install Request-State\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request (default UNSOLICITED)\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- // Decisions\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
- // <Decision: Flags>\r
- COPSDecision dec = new COPSDecision();\r
- dec.setCmdCode(COPSDecision.DEC_INSTALL);\r
- dec.setFlags(COPSDecision.F_REQSTATE);\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(clienthandle);\r
- decisionMsg.addDecision(dec, cntxt);\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a message asking for a COPS sync operation\r
- * @throws COPSPdpException\r
- */\r
- public void sendSyncRequestState()\r
- throws COPSPdpException {\r
- /* <Synchronize State Request> ::= <Common Header>\r
- * [<Client Handle>]\r
- * [<Integrity>]\r
- */\r
-\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(clienthandle);\r
- } catch (Exception e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
-}\r
+package org.umu.cops.ospdp;
+
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSHeader.Flag;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.*;
+
+/**
+ * COPS message transceiver class for outsourcing connections at the PDP side.
+ *
+ * TODO - change all references of Vector to List<>
+ */
+public class COPSPdpOSMsgSender {
+ /**
+ * Socket connected to PEP
+ */
+ protected final Socket _sock;
+
+ /**
+ * COPS client-type that identifies the policy client
+ */
+ protected final short _clientType;
+
+ /**
+ * COPS client handle used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected final COPSHandle _handle;
+
+ /**
+ * Creates a COPSPepMsgSender
+ *
+ * @param clientType COPS client-type
+ * @param clientHandle Client handle
+ * @param sock Socket to the PEP
+ */
+ public COPSPdpOSMsgSender (final short clientType, final COPSHandle clientHandle, final Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+
+ _sock = sock;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Sends a decision message which was requested by the PEP
+ * @param removeDecs Decisions to be removed
+ * @param installDecs Decisions to be installed
+ * @throws COPSPdpException
+ */
+ public void sendSolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {
+ sendDecision(removeDecs, installDecs, true);
+ }
+
+ /**
+ * Sends a decision message which was not requested by the PEP
+ * @param removeDecs Decisions to be removed
+ * @param installDecs Decisions to be installed
+ * @throws COPSPdpException
+ */
+ public void sendUnsolicitedDecision(Vector removeDecs, Vector installDecs) throws COPSPdpException {
+ sendDecision(removeDecs, installDecs, false);
+ }
+
+ /**
+ * Sends a decision message to the PEP
+ * @param removeDecs Decisions to be removed
+ * @param installDecs Decisions to be installed
+ * @param solicited <tt>true</tt> if the PEP requested this decision, <tt>false</tt> otherwise
+ * @throws COPSPdpException
+ */
+ public void sendDecision(Vector removeDecs, Vector installDecs, boolean solicited) throws COPSPdpException {
+ // Common Header holding the same ClientType as the request
+ final Flag flag;
+ if (solicited)
+ flag= Flag.SOLICITED;
+ else
+ flag = Flag.UNSOLICITED;
+
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+
+ // Decisions (no flags supplied)
+ // <Context>
+ final COPSContext cntxt = new COPSContext(RType.CONFIG, (short)0);
+
+ // Remove Decisions
+ // <Decision: Flags>
+ final COPSDecision rdec1;
+ if (installDecs.size() == 0)
+ rdec1 = new COPSDecision(Command.REMOVE);
+ else
+ rdec1 = new COPSDecision(Command.INSTALL);
+
+ if (decisions.get(cntxt) == null) {
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(rdec1);
+ decisions.put(cntxt, decisionSet);
+ } else {
+ decisions.get(cntxt).add(rdec1);
+ }
+
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(1, flag, getClientType(),
+ new COPSHandle(getClientHandle().getId()), decisions, null);
+
+ //** Send decision
+ //**
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a message asking that the request state be deleted
+ * @throws COPSPdpException
+ */
+ public void sendDeleteRequestState() throws COPSPdpException {
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(Command.REMOVE, DecisionFlag.REQSTATE));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ // Common Header with the same ClientType as the request (default UNSOLICITED)
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), new COPSHandle(_handle.getId()),
+ decisionMap, null);
+
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Method sendOpenNewRequestState
+ *
+ * @throws COPSPdpException
+ *
+ */
+ //FIXME: Unused?
+ public void sendOpenNewRequestState() throws COPSPdpException {
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
+ * <Client Handle>
+ * *(<Decision>)
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * <Decision: Flags> ::= Install Request-State
+ *
+ */
+
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE));
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ // Common Header with the same ClientType as the request (default UNSOLICITED)
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), new COPSHandle(_handle.getId()),
+ decisionMap, null);
+
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a message asking for a COPS sync operation
+ * @throws COPSPdpException
+ */
+ public void sendSyncRequestState() throws COPSPdpException {
+ /* <Synchronize State Request> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ */
+
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(_clientType, new COPSHandle(_handle.getId()), null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());
+ }
+ }
+
+}
-package org.umu.cops.ospdp;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Vector;\r
-\r
-/**\r
- * State manager class for outsourcing requests, at the PDP side.\r
- */\r
-public class COPSPdpOSReqStateMan {\r
- /**\r
- * Request State created\r
- */\r
- public final static short ST_CREATE = 1;\r
- /**\r
- * Request received\r
- */\r
- public final static short ST_INIT = 2;\r
- /**\r
- * Decisions sent\r
- */\r
- public final static short ST_DECS = 3;\r
- /**\r
- * Report received\r
- */\r
- public final static short ST_REPORT = 4;\r
- /**\r
- * Request state finalized\r
- */\r
- public final static short ST_FINAL = 5;\r
- /**\r
- * New request state solicited\r
- */\r
- public final static short ST_NEW = 6;\r
- /**\r
- * Delete request state solicited\r
- */\r
- public final static short ST_DEL = 7;\r
- /**\r
- * SYNC request sent\r
- */\r
- public final static short ST_SYNC = 8;\r
- /**\r
- * SYNC completed\r
- */\r
- public final static short ST_SYNCALL = 9;\r
- /**\r
- * Close connection received\r
- */\r
- public final static short ST_CCONN = 10;\r
- /**\r
- * Keep-alive timeout\r
- */\r
- public final static short ST_NOKA = 11;\r
- /**\r
- * Accounting timeout\r
- */\r
- public final static short ST_ACCT = 12;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Object for performing policy data processing\r
- */\r
- protected COPSPdpOSDataProcess _process;\r
-\r
- /**\r
- * Current state of the request being managed\r
- */\r
- protected short _status;\r
-\r
- /** COPS message transceiver used to send COPS messages */\r
- protected COPSPdpOSMsgSender _sender;\r
-\r
- /**\r
- * Creates a request state manager\r
- * @param clientType Client-type\r
- * @param clientHandle Client handle\r
- */\r
- public COPSPdpOSReqStateMan(short clientType, String clientHandle) {\r
- _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 COPSPdpOSDataProcess getDataProcess() {\r
- return _process;\r
- }\r
-\r
- /**\r
- * Sets the policy data processing object\r
- * @param process Policy data processing object\r
- */\r
- public void setDataProcess(COPSPdpOSDataProcess process) {\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Called when COPS sync is completed\r
- * @param repMsg COPS sync message\r
- * @throws COPSPdpException\r
- */\r
- protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
- throws COPSPdpException {\r
-\r
- _status = ST_SYNCALL;\r
-\r
- // maybe we should notifySyncComplete ...\r
- }\r
-\r
- /**\r
- * Initializes a new request state over a socket\r
- * @param sock Socket to the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void initRequestState(Socket sock)\r
- throws COPSPdpException {\r
- // Inits an object for sending COPS messages to the PDP\r
- _sender = new COPSPdpOSMsgSender(_clientType, _handle, sock);\r
-\r
- // Initial state\r
- _status = ST_INIT;\r
- }\r
-\r
- /**\r
- * Processes a COPS request\r
- * @param msg COPS request received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processRequest(COPSReqMsg msg) throws COPSPdpException {\r
- Vector clientSIs = msg.getClientSI();\r
-\r
- //** Here we must retrieve a decision depending on the\r
- //** supplied ClientSIs\r
- /*Vector removeDecs = new Vector();\r
- Vector installDecs = new Vector();*/\r
- _process.setClientData(this, clientSIs);\r
-\r
- Vector removeDecs = _process.getRemovePolicy(this);\r
- Vector installDecs = _process.getInstallPolicy(this);\r
-\r
- //** We create a SOLICITED decision\r
- //**\r
- _sender.sendSolicitedDecision(removeDecs, installDecs);\r
- _status = ST_DECS;\r
- }\r
-\r
- /**\r
- * Processes a report\r
- * @param msg Report message from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processReport(COPSReportMsg msg) throws COPSPdpException {\r
- //** Analyze the report\r
- //**\r
-\r
- /*\r
- * <Report State> ::= <Common Header>\r
- * <Client Handle>\r
- * <Report Type>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
- * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
- *\r
- * Important, <Named ClientSI> is not parsed\r
- */\r
-\r
- // COPSHeader hdrmsg = msg.getHeader();\r
- // COPSHandle handlemsg = msg.getClientHandle();\r
-\r
- // Report Type\r
- COPSReportType rtypemsg = msg.getReport();\r
-\r
- // Named ClientSI\r
- Vector clientSIs = msg.getClientSI();\r
-\r
- //** We should act here in accordance with\r
- //** the received report\r
- if (rtypemsg.isSuccess()) {\r
- _status = ST_REPORT;\r
- _process.successReport(this, clientSIs);\r
- } else if (rtypemsg.isFailure()) {\r
- _status = ST_REPORT;\r
- _process.failReport(this, clientSIs);\r
- } else if (rtypemsg.isAccounting()) {\r
- _status = ST_ACCT;\r
- _process.acctReport(this, clientSIs);\r
- }\r
- }\r
-\r
- /**\r
- * Called when connection is closed\r
- * @param error Reason\r
- * @throws COPSPdpException\r
- */\r
- protected void processClosedConnection(COPSError error)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyClosedConnection(this, error);\r
-\r
- _status = ST_CCONN;\r
- }\r
-\r
- /**\r
- * Called when no keep-alive is received\r
- * @throws COPSPdpException\r
- */\r
- protected void processNoKAConnection()\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyNoKAliveReceived(this);\r
-\r
- _status = ST_NOKA;\r
- }\r
-\r
- /**\r
- * Deletes the request state\r
- * @throws COPSPdpException\r
- */\r
- protected void finalizeRequestState()\r
- throws COPSPdpException {\r
- _sender.sendDeleteRequestState();\r
- _status = ST_FINAL;\r
- }\r
-\r
- /**\r
- * Asks for a COPS sync\r
- * @throws COPSPdpException\r
- */\r
- protected void syncRequestState()\r
- throws COPSPdpException {\r
- _sender.sendSyncRequestState();\r
- _status = ST_SYNC;\r
- }\r
-\r
- /**\r
- * Opens a new request state\r
- * @throws COPSPdpException\r
- */\r
- protected void openNewRequestState()//FIXME: unused?\r
- throws COPSPdpException {\r
- _sender.sendOpenNewRequestState();\r
- _status = ST_NEW;\r
- }\r
-\r
- /**\r
- * Processes a COPS delete message\r
- * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.closeRequestState(this);\r
-\r
- _status = ST_DEL;\r
- }\r
-\r
-}\r
+package org.umu.cops.ospdp;
+
+import org.umu.cops.stack.*;
+
+import java.net.Socket;
+import java.util.Vector;
+
+/**
+ * State manager class for outsourcing requests, at the PDP side.
+ */
+public class COPSPdpOSReqStateMan {
+ /**
+ * Request State created
+ */
+ public final static short ST_CREATE = 1;
+ /**
+ * Request received
+ */
+ public final static short ST_INIT = 2;
+ /**
+ * Decisions sent
+ */
+ public final static short ST_DECS = 3;
+ /**
+ * Report received
+ */
+ public final static short ST_REPORT = 4;
+ /**
+ * Request state finalized
+ */
+ public final static short ST_FINAL = 5;
+ /**
+ * New request state solicited
+ */
+ public final static short ST_NEW = 6;
+ /**
+ * Delete request state solicited
+ */
+ public final static short ST_DEL = 7;
+ /**
+ * SYNC request sent
+ */
+ public final static short ST_SYNC = 8;
+ /**
+ * SYNC completed
+ */
+ public final static short ST_SYNCALL = 9;
+ /**
+ * Close connection received
+ */
+ public final static short ST_CCONN = 10;
+ /**
+ * Keep-alive timeout
+ */
+ public final static short ST_NOKA = 11;
+ /**
+ * Accounting timeout
+ */
+ public final static short ST_ACCT = 12;
+
+ /**
+ * COPS client-type that identifies the policy client
+ */
+ protected short _clientType;
+
+ /**
+ * COPS client handle used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected COPSHandle _handle;
+
+ /**
+ * Object for performing policy data processing
+ */
+ protected COPSPdpOSDataProcess _process;
+
+ /**
+ * Current state of the request being managed
+ */
+ protected short _status;
+
+ /** COPS message transceiver used to send COPS messages */
+ protected COPSPdpOSMsgSender _sender;
+
+ /**
+ * Creates a request state manager
+ * @param clientType Client-type
+ * @param clientHandle Client handle
+ */
+ public COPSPdpOSReqStateMan(final short clientType, final String clientHandle) {
+ _handle = new COPSHandle(new COPSData(clientHandle));
+ _clientType = clientType;
+ _status = ST_CREATE;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Gets the status of the request
+ * @return Request state value
+ */
+ public short getStatus() {
+ return _status;
+ }
+
+ /**
+ * Gets the policy data processing object
+ * @return Policy data processing object
+ */
+ public COPSPdpOSDataProcess getDataProcess() {
+ return _process;
+ }
+
+ /**
+ * Sets the policy data processing object
+ * @param process Policy data processing object
+ */
+ public void setDataProcess(COPSPdpOSDataProcess process) {
+ _process = process;
+ }
+
+ /**
+ * Called when COPS sync is completed
+ * @param repMsg COPS sync message
+ * @throws COPSPdpException
+ */
+ protected void processSyncComplete(COPSSyncStateMsg repMsg)
+ throws COPSPdpException {
+
+ _status = ST_SYNCALL;
+
+ // maybe we should notifySyncComplete ...
+ }
+
+ /**
+ * Initializes a new request state over a socket
+ * @param sock Socket to the PEP
+ * @throws COPSPdpException
+ */
+ protected void initRequestState(Socket sock)
+ throws COPSPdpException {
+ // Inits an object for sending COPS messages to the PDP
+ _sender = new COPSPdpOSMsgSender(_clientType, _handle, sock);
+
+ // Initial state
+ _status = ST_INIT;
+ }
+
+ /**
+ * Processes a COPS request
+ * @param msg COPS request received from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processRequest(COPSReqMsg msg) throws COPSPdpException {
+ //** Here we must retrieve a decision depending on the
+ //** supplied ClientSIs
+ /*Vector removeDecs = new Vector();
+ Vector installDecs = new Vector();*/
+ if (msg.getClientSI() != null)
+ _process.setClientData(this, msg.getClientSI().toArray(new COPSClientSI[msg.getClientSI().size()]));
+
+ Vector removeDecs = _process.getRemovePolicy(this);
+ Vector installDecs = _process.getInstallPolicy(this);
+
+ //** We create a SOLICITED decision
+ //**
+ _sender.sendSolicitedDecision(removeDecs, installDecs);
+ _status = ST_DECS;
+ }
+
+ /**
+ * Processes a report
+ * @param msg Report message from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processReport(final COPSReportMsg msg) throws COPSPdpException {
+ //** Analyze the report
+ //**
+
+ /*
+ * <Report State> ::= <Common Header>
+ * <Client Handle>
+ * <Report Type>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>
+ * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)
+ *
+ * Important, <Named ClientSI> is not parsed
+ */
+
+ // COPSHeader hdrmsg = msg.getHeader();
+ // COPSHandle handlemsg = msg.getClientHandle();
+
+ // Report Type
+ final COPSReportType rtypemsg = msg.getReport();
+
+ // Named ClientSI
+ if (msg.getClientSI() != null) {
+ //** Here we must act in accordance with
+ //** the report received
+ switch (rtypemsg.getReportType()) {
+ case SUCCESS:
+ _status = ST_REPORT;
+ _process.successReport(this, msg.getClientSI());
+ break;
+ case FAILURE:
+ _status = ST_REPORT;
+ _process.failReport(this, msg.getClientSI());
+ break;
+ case ACCOUNTING:
+ _status = ST_ACCT;
+ _process.acctReport(this, msg.getClientSI());
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Called when connection is closed
+ * @param error Reason
+ * @throws COPSPdpException
+ */
+ protected void processClosedConnection(COPSError error)
+ throws COPSPdpException {
+ if (_process != null)
+ _process.notifyClosedConnection(this, error);
+
+ _status = ST_CCONN;
+ }
+
+ /**
+ * Called when no keep-alive is received
+ * @throws COPSPdpException
+ */
+ protected void processNoKAConnection()
+ throws COPSPdpException {
+ if (_process != null)
+ _process.notifyNoKAliveReceived(this);
+
+ _status = ST_NOKA;
+ }
+
+ /**
+ * Deletes the request state
+ * @throws COPSPdpException
+ */
+ protected void finalizeRequestState()
+ throws COPSPdpException {
+ _sender.sendDeleteRequestState();
+ _status = ST_FINAL;
+ }
+
+ /**
+ * Asks for a COPS sync
+ * @throws COPSPdpException
+ */
+ protected void syncRequestState()
+ throws COPSPdpException {
+ _sender.sendSyncRequestState();
+ _status = ST_SYNC;
+ }
+
+ /**
+ * Opens a new request state
+ * @throws COPSPdpException
+ */
+ protected void openNewRequestState()//FIXME: unused?
+ throws COPSPdpException {
+ _sender.sendOpenNewRequestState();
+ _status = ST_NEW;
+ }
+
+ /**
+ * Processes a COPS delete message
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)
+ throws COPSPdpException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = ST_DEL;
+ }
+
+}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
-import java.net.UnknownHostException;
import java.util.Hashtable;
-import java.util.Vector;
+import java.util.List;
/**
* This is a outsourcing COPS PEP. Responsible for making
* @param pepID PEP-ID
* @param clientType Client-type
*/
- public COPSPepOSAgent(String pepID, short clientType) {
+ public COPSPepOSAgent(final String pepID, final 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) {
+ public COPSPepOSAgent(final short clientType) {
// PEPId
try {
_pepID = InetAddress.getLocalHost().getHostName();
* Gets the COPS client-type
* @return PEP's client-type
*/
- public short getClientType() {
+ public int getClientType() {
return _clientType;
}
* @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);
-
+ public void disconnect(final COPSError error) throws COPSException, IOException {
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
closeMsg.writeData(_conn.getSocket());
_conn.close();
_conn = null;
* @throws COPSPepException
* @throws COPSException
*/
- public COPSPepOSReqStateMan addRequestState(COPSHandle handle, Vector clientSIs) throws COPSPepException, COPSException {
+ public COPSPepOSReqStateMan addRequestState(final COPSHandle handle, List<COPSClientSI> clientSIs) throws COPSPepException, COPSException {
if (_conn != null)
return _conn.addRequestState(handle.getId().str(), _process, clientSIs);
*
* Not send [<PDPRedirAddr>], [<Integrity>]
*
- * @throws UnknownHostException
* @throws IOException
* @throws COPSException
* @throws COPSPepException
*
*/
- private COPSPepOSConnection processConnection(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException {
+ private COPSPepOSConnection processConnection(final String psHost, final int psPort)
+ throws IOException, COPSException, COPSPepException {
// Build OPN
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);
-
- COPSPepId pepId = new COPSPepId();
- COPSData d = new COPSData(_pepID);
- pepId.setData(d);
-
- COPSClientOpenMsg msg = new COPSClientOpenMsg();
- msg.add(hdr);
- msg.add(pepId);
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(_clientType, new COPSPepId(new COPSData(_pepID)),
+ null, null, null);
// Create socket and send OPN
- InetAddress addr = InetAddress.getByName(psHost);
- Socket socket = new Socket(addr,psPort);
+ final InetAddress addr = InetAddress.getByName(psHost);
+ final Socket socket = new Socket(addr,psPort);
msg.writeData(socket);
// Get response
- COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
+ final COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
- if (recvmsg.getHeader().isAClientAccept()) {
- COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
+ if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
+ final COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
// Support
if (cMsg.getIntegrity() != null) {
}
// Mandatory KATimer
- COPSKATimer kt = cMsg.getKATimer();
+ final 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();
+ final COPSAcctTimer at = cMsg.getAcctTimer();
+ short _acctTimer;
+ if (at != null) _acctTimer = at.getTimerVal();
+ else _acctTimer = 0;
// Create connection manager
- COPSPepOSConnection conn = new COPSPepOSConnection(_clientType, socket);
+ final 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;
+ } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
+ final COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
_error = cMsg.getError();
socket.close();
return null;
* @param handle The COPS handle for this request
* @param clientSIs The client specific data for this request
*/
- public void dispatchEvent(COPSHandle handle, Vector clientSIs) {
+ public void dispatchEvent(COPSHandle handle, final List<COPSClientSI> clientSIs) {
try {
addRequestState(handle, clientSIs);
} catch (Exception e) {
-package org.umu.cops.ospep;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.*;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * COPSPepConnection represents a PEP-PDP Connection Manager.\r
- * Responsible for processing messages received from PDP.\r
- */\r
-public class COPSPepOSConnection implements Runnable {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPepOSConnection.class);\r
-\r
- /** Socket connected to PDP */\r
- protected Socket _sock;\r
-\r
- /** Time to wait responses (milliseconds), default is 10 seconds */\r
- protected final int _responseTime;\r
-\r
- /** COPS Client-type */\r
- protected final short _clientType;\r
-\r
- /**\r
- Accounting timer value (secs)\r
- */\r
- protected transient short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer value (secs)\r
- */\r
- protected transient short _kaTimer;\r
-\r
- /**\r
- * Time of the latest keep-alive received\r
- */\r
- protected Date _lastRecKa;\r
-\r
- /**\r
- Opcode of the latest message sent\r
- */\r
- protected byte _lastmessage;\r
-\r
- /**\r
- Maps a COPS Client Handle to a Request State Manager\r
- */\r
- protected final Map<String, COPSPepOSReqStateMan> _managerMap;\r
- // map < String(COPSHandle), COPSPepOSReqStateMan>;\r
-\r
- /**\r
- COPS error returned by PDP\r
- */\r
- protected COPSError _error;\r
-\r
- /**\r
- * Creates a new PEP connection\r
- * @param clientType PEP's client-type\r
- * @param sock Socket connected to PDP\r
- */\r
- public COPSPepOSConnection(short clientType, Socket sock) {\r
- _clientType = clientType;\r
- _sock = sock;\r
-\r
- // Timers\r
- _acctTimer = 0;\r
- _kaTimer = 0;\r
- _responseTime = 10000;\r
- _lastmessage = COPSHeader.COPS_OP_CAT;\r
-\r
- _managerMap = new ConcurrentHashMap<>();\r
- }\r
-\r
- /**\r
- * Gets the response time\r
- * @return Response time value (msecs)\r
- */\r
- public int getResponseTime() {\r
- return _responseTime;\r
- }\r
-\r
- /**\r
- * Gets the socket connected to the PDP\r
- * @return Socket connected to PDP\r
- */\r
- public Socket getSocket() {\r
- return _sock;\r
- }\r
-\r
- /**\r
- * Gets keep-alive timer\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer () {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Gets accounting timer\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer () {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets all request state managers\r
- * @return A <tt>Hashatable</tt> holding all request state managers\r
- * TODO - change the return to Map\r
- */\r
- protected Hashtable getReqStateMans() {\r
- return new Hashtable(_managerMap);\r
- }\r
-\r
- /**\r
- * Checks whether the socket to the PDP is closed or not\r
- * @return <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise\r
- */\r
- public boolean isClosed() {\r
- return _sock.isClosed();\r
- }\r
-\r
- /**\r
- * Closes the socket\r
- *\r
- * @throws java.io.IOException\r
- */\r
- protected void close() throws IOException {\r
- _sock.close();\r
- }\r
-\r
- /**\r
- * Gets the opcode of the lastest message sent\r
- * @return Message opcode\r
- */\r
- public byte getLastmessage() {\r
- return _lastmessage;\r
- }\r
-\r
- /**\r
- * Sets keep-alive timer\r
- * @param kaTimer Keep-alive timer value (secs)\r
- */\r
- public void setKaTimer(short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Sets accounting timer\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAcctTimer(short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Message-processing loop\r
- */\r
- public void run () {\r
- Date _lastSendKa = new Date();\r
- Date _lastSendAcc = new Date();\r
- _lastRecKa = new Date();\r
-\r
- try {\r
- while (!_sock.isClosed()) {\r
- if (_sock.getInputStream().available() != 0) {\r
- _lastmessage = processMessage(_sock);\r
- _lastRecKa = new Date();\r
- }\r
-\r
- // Keep Alive\r
- if (_kaTimer > 0) {\r
- // Timeout del PDP\r
- int _startTime = (int) (_lastRecKa.getTime());\r
- int cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > _kaTimer*1000) {\r
- _sock.close();\r
- // Notify all Request State Managers\r
- notifyNoKAAllReqStateMan();\r
- }\r
-\r
- // Send to PEP\r
- _startTime = (int) (_lastSendKa.getTime());\r
- cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
- COPSKAMsg msg = new COPSKAMsg();\r
-\r
- msg.add(hdr);\r
-\r
- COPSTransceiver.sendMsg(msg, _sock);\r
- _lastSendKa = new Date();\r
- }\r
- }\r
-\r
- // Accounting\r
- if (_acctTimer > 0) {\r
- int _startTime = (int) (_lastSendAcc.getTime());\r
- int cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > ((_acctTimer*3/4)*1000)) {\r
- // Notify all Request State Managers\r
- notifyAcctAllReqStateMan();\r
- _lastSendAcc = new Date();\r
- }\r
- }\r
-\r
- try {\r
- Thread.sleep(500);\r
- } catch (Exception e) {\r
- logger.error("Exception thrown while sleeping", e);\r
- }\r
- }\r
- } catch (Exception e) {\r
- logger.error("Error while processing socket messages", e);\r
- }\r
-\r
- // connection closed by server\r
- // COPSDebug.out(getClass().getName(),"Connection closed by server");\r
- try {\r
- _sock.close();\r
- } catch (IOException e) {\r
- logger.error("Unexpected exception closing the socket", e);\r
- }\r
-\r
- // Notify all Request State Managers\r
- try {\r
- notifyCloseAllReqStateMan();\r
- } catch (COPSPepException e) {\r
- logger.error("Error closing state managers", e);\r
- }\r
- }\r
-\r
- /**\r
- * Gets a COPS message from the socket and processes it\r
- * @param conn Socket connected to the PDP\r
- * @return COPS message type\r
- * @throws COPSPepException\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- protected byte processMessage(Socket conn) throws COPSPepException, COPSException, IOException {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
-\r
- if (msg.getHeader().isAClientClose()) {\r
- handleClientCloseMsg(conn, msg);\r
- return COPSHeader.COPS_OP_CC;\r
- } else if (msg.getHeader().isADecision()) {\r
- handleDecisionMsg(/*OJO conn, */msg);\r
- return COPSHeader.COPS_OP_DEC;\r
- } else if (msg.getHeader().isASyncStateReq()) {\r
- handleSyncStateReqMsg(conn, msg);\r
- return COPSHeader.COPS_OP_SSQ;\r
- } else if (msg.getHeader().isAKeepAlive()) {\r
- handleKeepAliveMsg(conn, msg);\r
- return COPSHeader.COPS_OP_KA;\r
- } else {\r
- throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
- }\r
- }\r
-\r
- /**\r
- * Handle Client Close Message, close the passed connection\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- *\r
- * <Client-Close> ::= <Common Header>\r
- * <Error>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- */\r
- private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
- COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
- _error = cMsg.getError();\r
-\r
- // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
-\r
- try {\r
- // Support\r
- if (cMsg.getIntegrity() != null)\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
-\r
- conn.close();\r
- } catch (Exception unae) {\r
- logger.error("Unexpected exception closing connection", unae);\r
- }\r
- }\r
-\r
- /**\r
- * Gets the COPS error\r
- * @return <tt>COPSError</tt> returned by PDP\r
- */\r
- protected COPSError getError() {\r
- return _error;\r
- }\r
-\r
- /**\r
- * Handle Keep Alive Message\r
- *\r
- * <Keep-Alive> ::= <Common Header>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
- COPSKAMsg cMsg = (COPSKAMsg) msg;\r
-\r
- // COPSDebug.out(getClass().getName(),"Get KAlive Msg");\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null)\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
-\r
- // must we do anything else?\r
- }\r
-\r
- /**\r
- * Method handleDecisionMsg\r
- *\r
- * <Decision Message> ::= <Common Header: Flag SOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>) | <Error>\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * [<ClientSI Decision Data: Outsourcing>]\r
- * <Decision: Flags> ::= <Command-Code> NULLFlag\r
- * <Command-Code> ::= NULLDecision | Install | Remove\r
- * <ClientSI Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
- * <Install Decision> ::= *(<PRID> <EPD>)\r
- * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
- *\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleDecisionMsg(/*OJO Socket conn, */COPSMsg msg) throws COPSPepException {\r
- COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;\r
- COPSHandle handle = dMsg.getClientHandle();\r
- COPSPepOSReqStateMan manager = (COPSPepOSReqStateMan) _managerMap.get(handle.getId().str());\r
- manager.processDecision(dMsg);\r
- }\r
-\r
- /**\r
- * Method handleSyncStateReqMsg\r
- *\r
- * <Synchronize State> ::= <Common Header>\r
- * [<Client Handle>]\r
- * [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleSyncStateReqMsg(Socket conn, COPSMsg msg) throws COPSPepException {\r
- COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
- // COPSHandle handle = cMsg.getClientHandle();\r
- // COPSHeader header = cMsg.getHeader();\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null)\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
-\r
- COPSPepOSReqStateMan manager = _managerMap.get(cMsg.getClientHandle().getId().str());\r
-\r
- if (manager == null)\r
- logger.warn("Unable to find state manager with ID - " + cMsg.getClientHandle().getId().str());\r
- else\r
- manager.processSyncStateRequest(cMsg);\r
- }\r
-\r
- /**\r
- * Adds a new request state\r
- * @param clientHandle Client's handle\r
- * @param process Policy data processing object\r
- * @param clientSIs Client data from the outsourcing event\r
- * @return The newly created request state manager\r
- * @throws COPSException\r
- * @throws COPSPepException\r
- */\r
- protected COPSPepOSReqStateMan addRequestState(String clientHandle, COPSPepOSDataProcess process, Vector clientSIs) throws COPSException, COPSPepException {\r
- COPSPepOSReqStateMan manager = new COPSPepOSReqStateMan(_clientType, clientHandle);\r
- if (_managerMap.get(clientHandle) != null)\r
- throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);\r
-\r
- manager.setDataProcess(process);\r
- manager.setClientSI(clientSIs);\r
- _managerMap.put(clientHandle, manager);\r
- manager.initRequestState(_sock);\r
- return manager;\r
- }\r
-\r
- /**\r
- * Deletes a request state\r
- * @param manager Request state manager\r
- * @throws COPSException\r
- * @throws COPSPepException\r
- */\r
- protected void deleteRequestState(COPSPepOSReqStateMan manager) throws COPSException, COPSPepException {\r
- manager.finalizeRequestState();\r
- }\r
-\r
- private void notifyCloseAllReqStateMan() throws COPSPepException {\r
- for (final COPSPepOSReqStateMan man : _managerMap.values()) {\r
- man.processClosedConnection(_error);\r
- }\r
- }\r
-\r
- private void notifyNoKAAllReqStateMan() throws COPSPepException {\r
- for (final COPSPepOSReqStateMan man : _managerMap.values()) {\r
- man.processNoKAConnection();\r
- }\r
- }\r
-\r
- private void notifyAcctAllReqStateMan() throws COPSPepException {\r
- for (final COPSPepOSReqStateMan man : _managerMap.values()) {\r
- man.processAcctReport();\r
- }\r
- }\r
-\r
-}\r
+package org.umu.cops.ospep;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Date;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPSPepConnection represents a PEP-PDP Connection Manager.
+ * Responsible for processing messages received from PDP.
+ */
+public class COPSPepOSConnection implements Runnable {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSPepOSConnection.class);
+
+ /** Socket connected to PDP */
+ protected Socket _sock;
+
+ /** Time to wait responses (milliseconds), default is 10 seconds */
+ protected final int _responseTime;
+
+ /** COPS Client-type */
+ protected short _clientType;
+
+ /**
+ Accounting timer value (secs)
+ */
+ protected transient short _acctTimer;
+
+ /**
+ Keep-alive timer value (secs)
+ */
+ protected transient short _kaTimer;
+
+ /**
+ * Time of the latest keep-alive received
+ */
+ protected Date _lastRecKa;
+
+ /**
+ Maps a COPS Client Handle to a Request State Manager
+ */
+ protected final Map<String, COPSPepOSReqStateMan> _managerMap;
+
+ /**
+ COPS error returned by PDP
+ */
+ protected COPSError _error;
+
+ /**
+ * Creates a new PEP connection
+ * @param clientType PEP's client-type
+ * @param sock Socket connected to PDP
+ */
+ public COPSPepOSConnection(final short clientType, final Socket sock) {
+ _clientType = clientType;
+ _sock = sock;
+
+ // Timers
+ _acctTimer = 0;
+ _kaTimer = 0;
+ _responseTime = 10000;
+ _managerMap = new ConcurrentHashMap<>();
+ }
+
+ /**
+ * Gets the response time
+ * @return Response time value (msecs)
+ */
+ public int getResponseTime() {
+ return _responseTime;
+ }
+
+ /**
+ * Gets the socket connected to the PDP
+ * @return Socket connected to PDP
+ */
+ public Socket getSocket() {
+ return _sock;
+ }
+
+ /**
+ * Gets keep-alive timer
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer () {
+ return _kaTimer;
+ }
+
+ /**
+ * Gets accounting timer
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer () {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets all request state managers
+ * @return A <tt>Hashatable</tt> holding all request state managers
+ * TODO - change the return to Map
+ */
+ protected Hashtable getReqStateMans() {
+ return new Hashtable(_managerMap);
+ }
+
+ /**
+ * Checks whether the socket to the PDP is closed or not
+ * @return <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise
+ */
+ public boolean isClosed() {
+ return _sock.isClosed();
+ }
+
+ /**
+ * Closes the socket
+ *
+ * @throws java.io.IOException
+ */
+ protected void close() throws IOException {
+ _sock.close();
+ }
+
+ /**
+ * Sets keep-alive timer
+ * @param kaTimer Keep-alive timer value (secs)
+ */
+ public void setKaTimer(short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Sets accounting timer
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAcctTimer(short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Message-processing loop
+ */
+ public void run () {
+ Date _lastSendKa = new Date();
+ Date _lastSendAcc = new Date();
+ _lastRecKa = new Date();
+
+ try {
+ while (!_sock.isClosed()) {
+ if (_sock.getInputStream().available() != 0) {
+ processMessage(_sock);
+ _lastRecKa = new Date();
+ }
+
+ // Keep Alive
+ if (_kaTimer > 0) {
+ // Timeout del PDP
+ int _startTime = (int) (_lastRecKa.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > _kaTimer*1000) {
+ _sock.close();
+ // Notify all Request State Managers
+ notifyNoKAAllReqStateMan();
+ }
+
+ // Send to PEP
+ _startTime = (int) (_lastSendKa.getTime());
+ cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {
+ final COPSKAMsg msg = new COPSKAMsg(null);
+ COPSTransceiver.sendMsg(msg, _sock);
+ _lastSendKa = new Date();
+ }
+ }
+
+ // Accounting
+ if (_acctTimer > 0) {
+ int _startTime = (int) (_lastSendAcc.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > ((_acctTimer*3/4)*1000)) {
+ // Notify all Request State Managers
+ notifyAcctAllReqStateMan();
+ _lastSendAcc = new Date();
+ }
+ }
+
+ try {
+ Thread.sleep(500);
+ } catch (Exception e) {
+ logger.error("Exception thrown while sleeping", e);
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Error while processing socket messages", e);
+ }
+
+ // connection closed by server
+ // COPSDebug.out(getClass().getName(),"Connection closed by server");
+ try {
+ _sock.close();
+ } catch (IOException e) {
+ logger.error("Unexpected exception closing the socket", e);
+ }
+
+ // Notify all Request State Managers
+ try {
+ notifyCloseAllReqStateMan();
+ } catch (COPSPepException e) {
+ logger.error("Error closing state managers", e);
+ }
+ }
+
+ /**
+ * Gets a COPS message from the socket and processes it
+ * @param conn Socket connected to the PDP
+ * @throws COPSPepException
+ * @throws COPSException
+ * @throws IOException
+ */
+ protected void processMessage(Socket conn) throws COPSPepException, COPSException, IOException {
+ COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+
+ if (msg.getHeader().getOpCode().equals(OPCode.CC)) {
+ handleClientCloseMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.DEC)) {
+ handleDecisionMsg(/*OJO conn, */msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.SSQ)) {
+ handleSyncStateReqMsg(conn, msg);
+ } else if (msg.getHeader().getOpCode().equals(OPCode.KA)) {
+ handleKeepAliveMsg(conn, msg);
+ } else {
+ throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");
+ }
+ }
+
+ /**
+ * Handle Client Close Message, close the passed connection
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ */
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
+ _error = cMsg.getError();
+
+ // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
+ // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
+
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null)
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+
+ conn.close();
+ } catch (Exception unae) {
+ logger.error("Unexpected exception closing connection", unae);
+ }
+ }
+
+ /**
+ * Gets the COPS error
+ * @return <tt>COPSError</tt> returned by PDP
+ */
+ protected COPSError getError() {
+ return _error;
+ }
+
+ /**
+ * Handle Keep Alive Message
+ *
+ * <Keep-Alive> ::= <Common Header>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
+ COPSKAMsg cMsg = (COPSKAMsg) msg;
+
+ // COPSDebug.out(getClass().getName(),"Get KAlive Msg");
+
+ // Support
+ if (cMsg.getIntegrity() != null)
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+
+ // must we do anything else?
+ }
+
+ /**
+ * Method handleDecisionMsg
+ *
+ * <Decision Message> ::= <Common Header: Flag SOLICITED>
+ * <Client Handle>
+ * *(<Decision>) | <Error>
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * [<ClientSI Decision Data: Outsourcing>]
+ * <Decision: Flags> ::= <Command-Code> NULLFlag
+ * <Command-Code> ::= NULLDecision | Install | Remove
+ * <ClientSI Decision Data> ::= <<Install Decision> | <Remove Decision>>
+ * <Install Decision> ::= *(<PRID> <EPD>)
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)
+ *
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleDecisionMsg(/*OJO Socket conn, */COPSMsg msg) throws COPSPepException {
+ COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;
+ COPSHandle handle = dMsg.getClientHandle();
+ COPSPepOSReqStateMan manager = _managerMap.get(handle.getId().str());
+ manager.processDecision(dMsg);
+ }
+
+ /**
+ * Method handleSyncStateReqMsg
+ *
+ * <Synchronize State> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleSyncStateReqMsg(Socket conn, COPSMsg msg) throws COPSPepException {
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
+ // COPSHandle handle = cMsg.getClientHandle();
+ // COPSHeader header = cMsg.getHeader();
+
+ // Support
+ if (cMsg.getIntegrity() != null)
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+
+ COPSPepOSReqStateMan manager = _managerMap.get(cMsg.getClientHandle().getId().str());
+
+ if (manager == null)
+ logger.warn("Unable to find state manager with ID - " + cMsg.getClientHandle().getId().str());
+ else
+ manager.processSyncStateRequest(cMsg);
+ }
+
+ /**
+ * Adds a new request state
+ * @param clientHandle Client's handle
+ * @param process Policy data processing object
+ * @param clientSIs Client data from the outsourcing event
+ * @return The newly created request state manager
+ * @throws COPSException
+ * @throws COPSPepException
+ */
+ protected COPSPepOSReqStateMan addRequestState(final String clientHandle, final COPSPepOSDataProcess process,
+ final List<COPSClientSI> clientSIs)
+ throws COPSException, COPSPepException {
+ COPSPepOSReqStateMan manager = new COPSPepOSReqStateMan(_clientType, clientHandle);
+ if (_managerMap.get(clientHandle) != null)
+ throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);
+
+ manager.setDataProcess(process);
+ manager.setClientSI(clientSIs);
+ _managerMap.put(clientHandle, manager);
+ manager.initRequestState(_sock);
+ return manager;
+ }
+
+ /**
+ * Deletes a request state
+ * @param manager Request state manager
+ * @throws COPSException
+ * @throws COPSPepException
+ */
+ protected void deleteRequestState(COPSPepOSReqStateMan manager) throws COPSException, COPSPepException {
+ manager.finalizeRequestState();
+ }
+
+ private void notifyCloseAllReqStateMan() throws COPSPepException {
+ for (final COPSPepOSReqStateMan man : _managerMap.values()) {
+ man.processClosedConnection(_error);
+ }
+ }
+
+ private void notifyNoKAAllReqStateMan() throws COPSPepException {
+ for (final COPSPepOSReqStateMan man : _managerMap.values()) {
+ man.processNoKAConnection();
+ }
+ }
+
+ private void notifyAcctAllReqStateMan() throws COPSPepException {
+ for (final COPSPepOSReqStateMan man : _managerMap.values()) {
+ man.processAcctReport();
+ }
+ }
+
+}
-package org.umu.cops.ospep;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Vector;\r
-\r
-import org.umu.cops.stack.COPSClientSI;\r
-import org.umu.cops.stack.COPSContext;\r
-import org.umu.cops.stack.COPSDeleteMsg;\r
-import org.umu.cops.stack.COPSException;\r
-import org.umu.cops.stack.COPSHandle;\r
-import org.umu.cops.stack.COPSHeader;\r
-import org.umu.cops.stack.COPSReason;\r
-import org.umu.cops.stack.COPSReportMsg;\r
-import org.umu.cops.stack.COPSReportType;\r
-import org.umu.cops.stack.COPSReqMsg;\r
-import org.umu.cops.stack.COPSSyncStateMsg;\r
-\r
-/**\r
- * COPS message transceiver class for outsourcing connections at the PEP side.\r
- */\r
-public class COPSPepOSMsgSender {\r
- /**\r
- * Socket connection to PDP\r
- */\r
- protected Socket _sock;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Creates a COPSPepMsgSender\r
- *\r
- * @param clientType Client-type\r
- * @param clientHandle Client handle\r
- * @param sock Socket connected to the PDP\r
- */\r
- public COPSPepOSMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
- // COPS Handle\r
- _handle = clientHandle;\r
- _clientType = clientType;\r
-\r
- _sock = sock;\r
- }\r
-\r
- /**\r
- * Gets the client handle\r
- * @return Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return Client-type value\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Sends a request to the PDP.\r
- * The PEP establishes a request state client handle for which the\r
- * remote PDP may maintain state.\r
- * @param clientSIs Client data\r
- * @throws COPSPepException\r
- */\r
- public void sendRequest(Vector clientSIs) throws COPSPepException {\r
- // Create COPS Message\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType);\r
-\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0);\r
-\r
- COPSHandle handle = _handle;\r
-\r
- COPSReqMsg msg = new COPSReqMsg();\r
- try {\r
- msg.add(hdr) ;\r
- msg.add(handle) ;\r
- msg.add(cntxt) ;\r
-\r
- Enumeration clientSIEnum = clientSIs.elements();\r
- while (clientSIEnum.hasMoreElements())\r
- msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
- } catch (COPSException e) {\r
- throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage());\r
- }\r
-\r
- // Send message\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a failure report to the PDP. This report message notifies the PDP\r
- * of failure when carrying out the PDP's decision, or when reporting\r
- * an accounting related state change.\r
- * @param clientSIs Report data\r
- * @throws COPSPepException\r
- */\r
- public void sendFailReport(Vector clientSIs) throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report FAIL\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.FAILURE);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
-\r
- Enumeration clientSIEnum = clientSIs.elements();\r
- while (clientSIEnum.hasMoreElements())\r
- msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a success report to the PDP. This report message notifies the PDP\r
- * of success when carrying out the PDP's decision, or when reporting\r
- * an accounting related state change.\r
- * @param clientSIs Report data\r
- * @throws COPSPepException\r
- */\r
- public void sendSuccessReport(Vector clientSIs) throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report SUCESS\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.SUCCESS);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
-\r
- Enumeration clientSIEnum = clientSIs.elements();\r
- while (clientSIEnum.hasMoreElements())\r
- msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends an accounting report to the PDP\r
- * @param clientSIs Report data\r
- * @throws COPSPepException\r
- */\r
- public void sendAcctReport(Vector clientSIs) throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report SUCCESS\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.ACCT);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
-\r
- Enumeration clientSIEnum = clientSIs.elements();\r
- while (clientSIEnum.hasMoreElements())\r
- msg.add( (COPSClientSI) clientSIEnum.nextElement());\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a sync-complete message to the PDP. This indicates the\r
- * end of a synchronization requested by the PDP.\r
- * @throws COPSPepException\r
- */\r
- public void sendSyncComplete() throws COPSPepException {\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType);\r
-\r
- // Client Handle with the same clientHandle as the request\r
- COPSHandle clienthandle = _handle;\r
-\r
- COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(clienthandle);\r
- } catch (Exception e) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a delete request to the PDP.\r
- * When sent from the PEP this message indicates to the remote PDP that\r
- * the state identified by the client handle is no longer\r
- * available/relevant.\r
- * @throws COPSPepException\r
- */\r
- public void sendDeleteRequest() throws COPSPepException {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType);\r
- COPSHandle handle = _handle;\r
-\r
- // *** TODO: use real reason codes\r
- COPSReason reason = new COPSReason((short) 234, (short) 345);\r
-\r
- COPSDeleteMsg msg = new COPSDeleteMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(handle);\r
- msg.add(reason);\r
- msg.writeData(_sock);\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
-}\r
+package org.umu.cops.ospep;
+
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSReason.ReasonCode;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * COPS message transceiver class for outsourcing connections at the PEP side.
+ */
+public class COPSPepOSMsgSender {
+ /**
+ * Socket connection to PDP
+ */
+ protected Socket _sock;
+
+ /**
+ * COPS client-type that identifies the policy client
+ */
+ protected short _clientType;
+
+ /**
+ * COPS client handle used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected COPSHandle _handle;
+
+ /**
+ * Creates a COPSPepMsgSender
+ *
+ * @param clientType Client-type
+ * @param clientHandle Client handle
+ * @param sock Socket connected to the PDP
+ */
+ public COPSPepOSMsgSender (final short clientType, final COPSHandle clientHandle, final Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+
+ _sock = sock;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Sends a request to the PDP.
+ * The PEP establishes a request state client handle for which the
+ * remote PDP may maintain state.
+ * @param clientSIs Client data
+ * @throws COPSPepException
+ */
+ public void sendRequest(final Set<COPSClientSI> clientSIs) throws COPSPepException {
+ // Create COPS Message
+ final COPSReqMsg msg = new COPSReqMsg(_clientType, _handle, new COPSContext(RType.CONFIG, (short)0), null,
+ null, null, clientSIs, null);
+
+ // Send message
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a failure report to the PDP. This report message notifies the PDP
+ * of failure when carrying out the PDP's decision, or when reporting
+ * an accounting related state change.
+ * @param clientSIs Report data
+ * @throws COPSPepException
+ */
+ public void sendFailReport(final List<COPSClientSI> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.FAILURE));
+ }
+
+ /**
+ * Sends a success report to the PDP. This report message notifies the PDP
+ * of success when carrying out the PDP's decision, or when reporting
+ * an accounting related state change.
+ * @param clientSIs Report data
+ * @throws COPSPepException
+ */
+ public void sendSuccessReport(final List<COPSClientSI> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.SUCCESS));
+ }
+
+ /**
+ * Sends an accounting report to the PDP
+ * @param clientSIs Report data
+ * @throws COPSPepException
+ */
+ public void sendAcctReport(final List<COPSClientSI> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.ACCOUNTING));
+ }
+
+ private void sendReport(final List<COPSClientSI> clientSIs, final COPSReportType type) throws COPSPepException {
+ // Change back to old way if it is ultimately determined that a report may contain more than one COPSClientSI
+ final COPSReportMsg msg = new COPSReportMsg(_clientType, _handle, type, null, null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a sync-complete message to the PDP. This indicates the
+ * end of a synchronization requested by the PDP.
+ * @throws COPSPepException
+ */
+ public void sendSyncComplete() throws COPSPepException {
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(_clientType, _handle, null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a delete request to the PDP.
+ * When sent from the PEP this message indicates to the remote PDP that
+ * the state identified by the client handle is no longer
+ * available/relevant.
+ * @throws COPSPepException
+ */
+ public void sendDeleteRequest() throws COPSPepException {
+ // *** TODO: use real reason codes
+ COPSReason reason = new COPSReason(ReasonCode.UNSPECIFIED, ReasonCode.NA);
+
+ final COPSDeleteMsg msg = new COPSDeleteMsg(_clientType, _handle, reason, null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());
+ }
+ }
+
+}
-package org.umu.cops.ospep;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Vector;\r
-\r
-/**\r
- * State manager class for outsourcing requests, at the PEP side.\r
- */\r
-public class COPSPepOSReqStateMan {\r
- /**\r
- * Request State created\r
- */\r
- public final static short ST_CREATE = 1;\r
- /**\r
- * Request sent\r
- */\r
- public final static short ST_INIT = 2;\r
- /**\r
- * Decisions received\r
- */\r
- public final static short ST_DECS = 3;\r
- /**\r
- * Report sent\r
- */\r
- public final static short ST_REPORT = 4;\r
- /**\r
- * Request State finalized\r
- */\r
- public final static short ST_FINAL = 5;\r
- /**\r
- * New Request State solicited\r
- */\r
- public final static short ST_NEW = 6;\r
- /**\r
- * Delete Request State solicited\r
- */\r
- public final static short ST_DEL = 7;\r
- /**\r
- * SYNC request received\r
- */\r
- public final static short ST_SYNC = 8;\r
- /**\r
- * Sync completed\r
- */\r
- public final static short ST_SYNCALL = 9;\r
- /**\r
- * Close connection received\r
- */\r
- public final static short ST_CCONN = 10;\r
- /**\r
- * Keep-alive timeout\r
- */\r
- public final static short ST_NOKA = 11;\r
- /**\r
- * Accounting timeout\r
- */\r
- public final static short ST_ACCT = 12;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- Object for performing policy data processing\r
- */\r
- protected COPSPepOSDataProcess _process;\r
-\r
- /**\r
- * ClientSI data from signaling.\r
- */\r
- protected Vector _clientSIs;\r
-\r
- /**\r
- * Current state of the request being managed\r
- */\r
- protected short _status;\r
-\r
- /**\r
- COPS message transceiver used to send COPS messages\r
- */\r
- protected COPSPepOSMsgSender _sender;\r
-\r
- /**\r
- * Sync state\r
- */\r
- protected boolean _syncState;\r
-\r
- /**\r
- * Creates a state request manager\r
- * @param clientType Client-type\r
- * @param clientHandle Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSPepOSReqStateMan(short clientType, String clientHandle) {\r
- // COPS Handle\r
- _handle = new COPSHandle(new COPSData(clientHandle));\r
- _clientType = clientType;\r
- _syncState = true;\r
- _status = ST_CREATE;\r
- _clientSIs = null;\r
- }\r
-\r
- /**\r
- * Gets the client handle\r
- * @return Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Sets the client SI data.\r
- * @param someClientSIs Client SI data built by the event listener\r
- */\r
- public void setClientSI(Vector someClientSIs) {\r
- _clientSIs = someClientSIs;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return Client-type value\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Gets the request status\r
- * @return Request status value\r
- */\r
- public short getStatus() {\r
- return _status;\r
- }\r
-\r
- /**\r
- * Gets the policy data processing object\r
- *\r
- * @return Policy data processing object\r
- *\r
- */\r
- public COPSPepOSDataProcess getDataProcess() {\r
- return _process;\r
- }\r
-\r
- /**\r
- * Sets the policy data processing object\r
- *\r
- * @param process Policy data processing object\r
- *\r
- */\r
- public void setDataProcess(COPSPepOSDataProcess process) {\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Initializes a new request state over a socket\r
- * @param sock Socket to the PDP\r
- * @throws COPSPepException\r
- */\r
- protected void initRequestState(Socket sock) throws COPSPepException {\r
- // Inits an object for sending COPS messages to the PDP\r
- _sender = new COPSPepOSMsgSender(_clientType, _handle, sock);\r
-\r
- // If an object exists for retrieving the PEP features,\r
- // use it for retrieving them.\r
- /* Hashtable clientSIs;\r
- if (_process != null)\r
- clientSIs = _process.getClientData(this);\r
- else\r
- clientSIs = null;*/\r
-\r
- // Semd the request\r
- _sender.sendRequest(_clientSIs);\r
-\r
- // Initial state\r
- _status = ST_INIT;\r
- }\r
-\r
- /**\r
- * Deletes the request state\r
- * @throws COPSPepException\r
- */\r
- protected void finalizeRequestState() throws COPSPepException {\r
- _sender.sendDeleteRequest();\r
- _status = ST_FINAL;\r
- }\r
-\r
- /**\r
- * Processes the decision message\r
- * @param dMsg Decision message from the PDP\r
- * @throws COPSPepException\r
- */\r
- protected void processDecision(COPSDecisionMsg dMsg) throws COPSPepException {\r
- // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
-\r
- //Hashtable decisionsPerContext = dMsg.getDecisions();\r
-\r
- //** Applies decisions to the configuration\r
- //_process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
- // second param changed to dMsg so that the data processor\r
- // can check the 'solicited' flag\r
- boolean isFailReport = _process.setDecisions(this, dMsg /*decisionsPerContext*/);\r
- _status = ST_DECS;\r
-\r
- if (isFailReport) {\r
- // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
- _sender.sendFailReport(_process.getReportData(this));\r
- } else {\r
- // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
- _sender.sendSuccessReport(_process.getReportData(this));\r
- }\r
- _status = ST_REPORT;\r
-\r
- if (!_syncState) {\r
- _sender.sendSyncComplete();\r
- _syncState = true;\r
- _status = ST_SYNCALL;\r
- }\r
- }\r
-\r
-\r
- /**\r
- * Processes a COPS delete message\r
- * @param dMsg <tt>COPSDeleteMsg</tt> received from the PDP\r
- * @throws COPSPepException\r
- */\r
- protected void processDeleteRequestState(COPSDecisionMsg dMsg) throws COPSPepException {\r
- if (_process != null)\r
- _process.closeRequestState(this);\r
-\r
- _status = ST_DEL;\r
- }\r
-\r
- /**\r
- * Processes the message SycnStateRequest.\r
- * The message SycnStateRequest indicates that the remote PDP\r
- * wishes the client (which appears in the common header)\r
- * to re-send its state.\r
- *\r
- * @param ssMsg The sync request from the PDP\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void processSyncStateRequest(COPSSyncStateMsg ssMsg) throws COPSPepException {\r
- _syncState = false;\r
- // If an object exists for retrieving the PEP features,\r
- // use it for retrieving them.\r
-\r
- // Send the request\r
- _sender.sendRequest(_clientSIs);\r
-\r
- _status = ST_SYNC;\r
- }\r
-\r
- /**\r
- * Called when connection is closed\r
- * @param error Reason\r
- * @throws COPSPepException\r
- */\r
- protected void processClosedConnection(COPSError error) throws COPSPepException {\r
- if (_process != null)\r
- _process.notifyClosedConnection(this, error);\r
-\r
- _status = ST_CCONN;\r
- }\r
-\r
- /**\r
- * Called when no keep-alive is received\r
- * @throws COPSPepException\r
- */\r
- protected void processNoKAConnection() throws COPSPepException {\r
- if (_process != null)\r
- _process.notifyNoKAliveReceived(this);\r
-\r
- _status = ST_NOKA;\r
- }\r
-\r
- /**\r
- * Processes the accounting report\r
- * @throws COPSPepException\r
- */\r
- protected void processAcctReport() throws COPSPepException {\r
- Vector report = new Vector();\r
-\r
- if (_process != null)\r
- report = _process.getAcctData(this);\r
-\r
- _sender.sendAcctReport(report);\r
-\r
- _status = ST_ACCT;\r
- }\r
-}\r
+package org.umu.cops.ospep;
+
+import org.umu.cops.stack.*;
+
+import java.net.Socket;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * State manager class for outsourcing requests, at the PEP side.
+ */
+public class COPSPepOSReqStateMan {
+ /**
+ * Request State created
+ */
+ public final static short ST_CREATE = 1;
+ /**
+ * Request sent
+ */
+ public final static short ST_INIT = 2;
+ /**
+ * Decisions received
+ */
+ public final static short ST_DECS = 3;
+ /**
+ * Report sent
+ */
+ public final static short ST_REPORT = 4;
+ /**
+ * Request State finalized
+ */
+ public final static short ST_FINAL = 5;
+ /**
+ * New Request State solicited
+ */
+ public final static short ST_NEW = 6;
+ /**
+ * Delete Request State solicited
+ */
+ public final static short ST_DEL = 7;
+ /**
+ * SYNC request received
+ */
+ public final static short ST_SYNC = 8;
+ /**
+ * Sync completed
+ */
+ public final static short ST_SYNCALL = 9;
+ /**
+ * Close connection received
+ */
+ public final static short ST_CCONN = 10;
+ /**
+ * 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 COPSPepOSDataProcess _process;
+
+ /**
+ * ClientSI data from signaling.
+ */
+ protected final Set<COPSClientSI> _clientSIs;
+
+ /**
+ * Current state of the request being managed
+ */
+ protected short _status;
+
+ /**
+ COPS message transceiver used to send COPS messages
+ */
+ protected COPSPepOSMsgSender _sender;
+
+ /**
+ * Sync state
+ */
+ protected boolean _syncState;
+
+ /**
+ * Creates a state request manager
+ * @param clientType Client-type
+ * @param clientHandle Client's <tt>COPSHandle</tt>
+ */
+ public COPSPepOSReqStateMan(final short clientType, final String clientHandle) {
+ // COPS Handle
+ _handle = new COPSHandle(new COPSData(clientHandle));
+ _clientType = clientType;
+ _syncState = true;
+ _status = ST_CREATE;
+ _clientSIs = null;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Sets the client SI data.
+ * @param someClientSIs Client SI data built by the event listener
+ */
+ public void setClientSI(final List<COPSClientSI> someClientSIs) {
+ _clientSIs.addAll(someClientSIs);
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Gets the request status
+ * @return Request status value
+ */
+ public short getStatus() {
+ return _status;
+ }
+
+ /**
+ * Gets the policy data processing object
+ *
+ * @return Policy data processing object
+ *
+ */
+ public COPSPepOSDataProcess getDataProcess() {
+ return _process;
+ }
+
+ /**
+ * Sets the policy data processing object
+ *
+ * @param process Policy data processing object
+ *
+ */
+ public void setDataProcess(COPSPepOSDataProcess process) {
+ _process = process;
+ }
+
+ /**
+ * Initializes a new request state over a socket
+ * @param sock Socket to the PDP
+ * @throws COPSPepException
+ */
+ protected void initRequestState(Socket sock) throws COPSPepException {
+ // Inits an object for sending COPS messages to the PDP
+ _sender = new COPSPepOSMsgSender(_clientType, _handle, sock);
+
+ // If an object exists for retrieving the PEP features,
+ // use it for retrieving them.
+ /* Hashtable clientSIs;
+ if (_process != null)
+ clientSIs = _process.getClientData(this);
+ else
+ clientSIs = null;*/
+
+ // Semd the request
+ _sender.sendRequest(_clientSIs);
+
+ // Initial state
+ _status = ST_INIT;
+ }
+
+ /**
+ * Deletes the request state
+ * @throws COPSPepException
+ */
+ protected void finalizeRequestState() throws COPSPepException {
+ _sender.sendDeleteRequest();
+ _status = ST_FINAL;
+ }
+
+ /**
+ * Processes the decision message
+ * @param dMsg Decision message from the PDP
+ * @throws COPSPepException
+ */
+ protected void processDecision(COPSDecisionMsg dMsg) throws COPSPepException {
+ // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
+
+ //Hashtable decisionsPerContext = dMsg.getDecisions();
+
+ //** Applies decisions to the configuration
+ //_process.setDecisions(this, removeDecs, installDecs, errorDecs);
+ // second param changed to dMsg so that the data processor
+ // can check the 'solicited' flag
+ boolean isFailReport = _process.setDecisions(this, dMsg /*decisionsPerContext*/);
+ _status = ST_DECS;
+
+ if (isFailReport) {
+ // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
+ _sender.sendFailReport(_process.getReportData(this));
+ } else {
+ // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
+ _sender.sendSuccessReport(_process.getReportData(this));
+ }
+ _status = ST_REPORT;
+
+ if (!_syncState) {
+ _sender.sendSyncComplete();
+ _syncState = true;
+ _status = ST_SYNCALL;
+ }
+ }
+
+
+ /**
+ * Processes a COPS delete message
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PDP
+ * @throws COPSPepException
+ */
+ protected void processDeleteRequestState(COPSDecisionMsg dMsg) throws COPSPepException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = ST_DEL;
+ }
+
+ /**
+ * Processes the message SycnStateRequest.
+ * The message SycnStateRequest indicates that the remote PDP
+ * wishes the client (which appears in the common header)
+ * to re-send its state.
+ *
+ * @param ssMsg The sync request from the PDP
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void processSyncStateRequest(COPSSyncStateMsg ssMsg) throws COPSPepException {
+ _syncState = false;
+ // If an object exists for retrieving the PEP features,
+ // use it for retrieving them.
+
+ // Send the request
+ _sender.sendRequest(_clientSIs);
+
+ _status = ST_SYNC;
+ }
+
+ /**
+ * Called when connection is closed
+ * @param error Reason
+ * @throws COPSPepException
+ */
+ protected void processClosedConnection(COPSError error) throws COPSPepException {
+ if (_process != null)
+ _process.notifyClosedConnection(this, error);
+
+ _status = ST_CCONN;
+ }
+
+ /**
+ * Called when no keep-alive is received
+ * @throws COPSPepException
+ */
+ protected void processNoKAConnection() throws COPSPepException {
+ if (_process != null)
+ _process.notifyNoKAliveReceived(this);
+
+ _status = ST_NOKA;
+ }
+
+ /**
+ * Processes the accounting report
+ * @throws COPSPepException
+ */
+ protected void processAcctReport() throws COPSPepException {
+ Vector report = new Vector();
+
+ if (_process != null)
+ report = _process.getAcctData(this);
+
+ _sender.sendAcctReport(report);
+
+ _status = ST_ACCT;
+ }
+}
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.ServerSocket;\r
-import java.net.Socket;\r
-import java.util.Hashtable;\r
-import java.util.Map;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * Core PDP agent for provisioning\r
- */\r
-public class COPSPdpAgent extends Thread {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class);\r
-\r
- /** Well-known port for COPS */\r
- public static final int WELL_KNOWN_PDP_PORT = 3288;\r
- /** Default keep-alive timer value (secs) */\r
- public static final short KA_TIMER_VALUE = 30;\r
- /** Default accounting timer value (secs) */\r
- public static final short ACCT_TIMER_VALUE = 0;\r
-\r
- /**\r
- PDP host port\r
- */\r
- private int _serverPort;\r
-\r
- /**\r
- Client-type of connecting PEP\r
- */\r
- private short _clientType;\r
-\r
- /**\r
- Accounting timer (secs)\r
- */\r
- private short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer (secs)\r
- */\r
- private short _kaTimer;\r
-\r
- /**\r
- Maps a PEP-ID to a connection\r
- */\r
- private final Map<String, COPSPdpConnection> _connectionMap;\r
- // map < String(PEPID), COPSPdpConnection > ConnectionMap;\r
-\r
- /**\r
- * Policy data processing object\r
- */\r
- private COPSPdpDataProcess _process;\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpAgent(short clientType, COPSPdpDataProcess process) {\r
- _serverPort = WELL_KNOWN_PDP_PORT;\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Creates a PDP Agent\r
- *\r
- * @param port Port to listen to\r
- * @param clientType COPS Client-type\r
- * @param process Object to perform policy data processing\r
- */\r
- public COPSPdpAgent(int port, short clientType, COPSPdpDataProcess process) {\r
- _serverPort = port;\r
-\r
- _kaTimer = KA_TIMER_VALUE;\r
- _acctTimer = ACCT_TIMER_VALUE;\r
-\r
- _clientType = clientType;\r
- _connectionMap = new ConcurrentHashMap<>();\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Sets the keep-alive timer value\r
- * @param kaTimer Keep alive timer value (secs)\r
- */\r
- public void setKaTimer (short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Sets the accounting timer value\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAcctTimer (short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the value of the keep-alive timer\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer () {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Gets the accounting timer value\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer () {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the connection map\r
- * @return A <tt>Hashtable</tt> holding the connection map\r
- */\r
- public Hashtable getConnectionMap() {\r
- return new Hashtable(_connectionMap);\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return The client-type\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Disconnects a PEP\r
- * @param pepID PEP-ID of the PEP to be disconnected\r
- * @param error COPS Error to be reported as a reason\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- public void disconnect (String pepID, COPSError error)\r
- throws COPSException, IOException {\r
-\r
- COPSPdpConnection pdpConn = _connectionMap.get(pepID);\r
-\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- if (error != null)\r
- closeMsg.add(error);\r
-\r
- closeMsg.writeData(pdpConn.getSocket());\r
- pdpConn.close();\r
- }\r
-\r
- /**\r
- * Requests a COPS sync for a PEP\r
- * @param pepID PEP-ID of the PEP to be synced\r
- * @throws COPSException\r
- * @throws COPSPdpException\r
- */\r
- public void sync (String pepID)\r
- throws COPSException, COPSPdpException {\r
-\r
- COPSPdpConnection pdpConn = _connectionMap.get(pepID);\r
- pdpConn.syncAllRequestState();\r
- }\r
-\r
- /**\r
- * Removes a PEP from the connection map\r
- * @param pepID PEP-ID of the PEP to be removed\r
- */\r
- public void delete (String pepID) {\r
- _connectionMap.remove(pepID);\r
- }\r
-\r
-\r
- /**\r
- * Runs the PDP process\r
- */\r
- public void run() {\r
- try {\r
- final ServerSocket serverSocket = new ServerSocket (_serverPort);\r
-\r
- //Loop through for Incoming messages\r
-\r
- // server infinite loop\r
- while (true) {\r
-\r
- // Wait for an incoming connection from a PEP\r
- Socket socket = serverSocket.accept();\r
-\r
- // COPSDebug.out(getClass().getName(),"New connection accepted " +\r
- // socket.getInetAddress() +\r
- // ":" + socket.getPort());\r
-\r
- // We're waiting for an OPN message\r
- try {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(socket);\r
- if (msg.getHeader().isAClientOpen()) {\r
- handleClientOpenMsg(socket, msg);\r
- } else {\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- } catch (Exception e) { // COPSException, IOException\r
- // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,\r
- // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);\r
- try {\r
- socket.close();\r
- } catch (Exception ex) {\r
- logger.error("Error closing socket", ex);\r
- }\r
- }\r
- }\r
- } catch (IOException e) {\r
- logger.error("Error caught while processing socket messages", e);\r
- }\r
- }\r
-\r
- /**\r
- * Handles a COPS client-open message\r
- * @param conn Socket to the PEP\r
- * @param msg <tt>COPSMsg</tt> holding the client-open message\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- private void handleClientOpenMsg(Socket conn, COPSMsg msg)\r
- throws COPSException, IOException {\r
- COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;\r
- COPSPepId pepId = cMsg.getPepId();\r
-\r
- // Validate Client Type\r
- if (msg.getHeader().getClientType() != _clientType) {\r
- // Unsupported client type\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNSUPPORTED_CLIENT_TYPE, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing COPS data", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported client type");\r
- }\r
-\r
- // PEPId is mandatory\r
- if (pepId == null) {\r
- // Mandatory COPS object missing\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_MANDATORY_OBJECT_MISSING, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing close message", unae);\r
- }\r
-\r
- throw new COPSException("Mandatory COPS object missing (PEPId)");\r
- }\r
-\r
- // Support\r
- if ( (cMsg.getClientSI() != null) ||\r
- (cMsg.getPdpAddress() != null) ||\r
- (cMsg.getIntegrity() != null)) {\r
-\r
- // Unsupported objects\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, msg.getHeader().getClientType());\r
- COPSError err = new COPSError(COPSError.COPS_ERR_UNKNOWN_OBJECT, (short) 0);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- closeMsg.add(err);\r
- try {\r
- closeMsg.writeData(conn);\r
- } catch (IOException unae) {\r
- logger.error("Error writing close message", unae);\r
- }\r
-\r
- throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");\r
- }\r
-\r
- // Connection accepted\r
- COPSHeader ahdr = new COPSHeader(COPSHeader.COPS_OP_CAT, msg.getHeader().getClientType());\r
- COPSKATimer katimer = new COPSKATimer(_kaTimer);\r
- COPSAcctTimer acctTimer = new COPSAcctTimer(_acctTimer);\r
- COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();\r
- acceptMsg.add(ahdr);\r
- acceptMsg.add(katimer) ;\r
- if (_acctTimer != 0) acceptMsg.add(acctTimer);\r
- acceptMsg.writeData(conn);\r
-\r
- COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process);\r
- pdpConn.setKaTimer(_kaTimer);\r
- if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);\r
- new Thread(pdpConn).start();\r
- _connectionMap.put(pepId.getData().str(),pdpConn);\r
- }\r
-\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Core PDP agent for provisioning
+ */
+public class COPSPdpAgent extends Thread {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSPdpAgent.class);
+
+ /** Well-known port for COPS */
+ public static final int WELL_KNOWN_PDP_PORT = 3288;
+ /** Default keep-alive timer value (secs) */
+ public static final short KA_TIMER_VALUE = 30;
+ /** Default accounting timer value (secs) */
+ public static final short ACCT_TIMER_VALUE = 0;
+
+ /**
+ PDP host port
+ */
+ private int _serverPort;
+
+ /**
+ Client-type of connecting PEP
+ */
+ private short _clientType;
+
+ /**
+ Accounting timer (secs)
+ */
+ private short _acctTimer;
+
+ /**
+ Keep-alive timer (secs)
+ */
+ private short _kaTimer;
+
+ /**
+ Maps a PEP-ID to a connection
+ */
+ private final Map<String, COPSPdpConnection> _connectionMap;
+ // map < String(PEPID), COPSPdpConnection > ConnectionMap;
+
+ /**
+ * Policy data processing object
+ */
+ private COPSPdpDataProcess _process;
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param clientType COPS Client-type
+ * @param process Object to perform policy data processing
+ */
+ public COPSPdpAgent(final short clientType, final COPSPdpDataProcess process) {
+ _serverPort = WELL_KNOWN_PDP_PORT;
+ _kaTimer = KA_TIMER_VALUE;
+ _acctTimer = ACCT_TIMER_VALUE;
+
+ _clientType = clientType;
+ _connectionMap = new ConcurrentHashMap<>();
+ _process = process;
+ }
+
+ /**
+ * Creates a PDP Agent
+ *
+ * @param port Port to listen to
+ * @param clientType COPS Client-type
+ * @param process Object to perform policy data processing
+ */
+ public COPSPdpAgent(final int port, final short clientType, final COPSPdpDataProcess process) {
+ _serverPort = port;
+
+ _kaTimer = KA_TIMER_VALUE;
+ _acctTimer = ACCT_TIMER_VALUE;
+
+ _clientType = clientType;
+ _connectionMap = new ConcurrentHashMap<>();
+ _process = process;
+ }
+
+ /**
+ * Sets the keep-alive timer value
+ * @param kaTimer Keep alive timer value (secs)
+ */
+ public void setKaTimer (short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Sets the accounting timer value
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAcctTimer (short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Gets the value of the keep-alive timer
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer () {
+ return _kaTimer;
+ }
+
+ /**
+ * Gets the accounting timer value
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer () {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets the client-type
+ * @return The client-type
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Disconnects a PEP
+ * @param pepID PEP-ID of the PEP to be disconnected
+ * @param error COPS Error to be reported as a reason
+ * @throws COPSException
+ * @throws IOException
+ */
+ public void disconnect(final String pepID, final COPSError error) throws COPSException, IOException {
+ final COPSPdpConnection pdpConn = _connectionMap.get(pepID);
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
+ closeMsg.writeData(pdpConn.getSocket());
+ pdpConn.close();
+ }
+
+ /**
+ * Requests a COPS sync for a PEP
+ * @param pepID PEP-ID of the PEP to be synced
+ * @throws COPSException
+ * @throws COPSPdpException
+ */
+ public void sync (String pepID)
+ throws COPSException, COPSPdpException {
+
+ COPSPdpConnection pdpConn = _connectionMap.get(pepID);
+ pdpConn.syncAllRequestState();
+ }
+
+ /**
+ * Removes a PEP from the connection map
+ * @param pepID PEP-ID of the PEP to be removed
+ */
+ public void delete (String pepID) {
+ _connectionMap.remove(pepID);
+ }
+
+
+ /**
+ * Runs the PDP process
+ */
+ public void run() {
+ try {
+ final ServerSocket serverSocket = new ServerSocket (_serverPort);
+
+ //Loop through for Incoming messages
+
+ // server infinite loop
+ while (true) {
+
+ // Wait for an incoming connection from a PEP
+ Socket socket = serverSocket.accept();
+
+ // COPSDebug.out(getClass().getName(),"New connection accepted " +
+ // socket.getInetAddress() +
+ // ":" + socket.getPort());
+
+ // We're waiting for an OPN message
+ try {
+ final COPSMsg msg = COPSTransceiver.receiveMsg(socket);
+ if (msg.getHeader().getOpCode().equals(OPCode.OPN)) {
+ handleClientOpenMsg(socket, msg);
+ } else {
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Error closing socket", ex);
+ }
+ }
+ } catch (Exception e) { // COPSException, IOException
+ // COPSDebug.err(getClass().getName(), COPSDebug.ERROR_EXCEPTION,
+ // "(" + socket.getInetAddress() + ":" + socket.getPort() + ")", e);
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ logger.error("Error closing socket", ex);
+ }
+ }
+ }
+ } catch (IOException e) {
+ logger.error("Error caught while processing socket messages", e);
+ }
+ }
+
+ /**
+ * Handles a COPS client-open message
+ * @param conn Socket to the PEP
+ * @param msg <tt>COPSMsg</tt> holding the client-open message
+ * @throws COPSException
+ * @throws IOException
+ */
+ private void handleClientOpenMsg(final Socket conn, final COPSMsg msg) throws COPSException, IOException {
+ final COPSClientOpenMsg cMsg = (COPSClientOpenMsg) msg;
+ final COPSPepId pepId = cMsg.getPepId();
+
+ // Validate Client Type
+ if (msg.getHeader().getClientType() == _clientType) {
+ // Unsupported client type
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing COPS data", unae);
+ }
+
+ throw new COPSException("Unsupported client type");
+ }
+
+ // PEPId is mandatory
+ if (pepId == null) {
+ // Mandatory COPS object missing
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.MANDATORY_OBJECT_MISSING, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing close message", unae);
+ }
+
+ throw new COPSException("Mandatory COPS object missing (PEPId)");
+ }
+
+ // Support
+ if ( (cMsg.getClientSI() != null) ||
+ (cMsg.getPdpAddress() != null) ||
+ (cMsg.getIntegrity() != null)) {
+
+ // Unsupported objects
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(msg.getHeader().getClientType(),
+ new COPSError(ErrorTypes.UNKNOWN_OBJECT, ErrorTypes.NA), null, null);
+ try {
+ closeMsg.writeData(conn);
+ } catch (IOException unae) {
+ logger.error("Error writing close message", unae);
+ }
+
+ throw new COPSException("Unsupported objects (ClientSI, PdpAddress, Integrity)");
+ }
+
+ // Connection accepted
+ final COPSKATimer katimer = new COPSKATimer(_kaTimer);
+ final COPSClientAcceptMsg acceptMsg;
+ if (_acctTimer != 0) acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer, null, null);
+ else acceptMsg = new COPSClientAcceptMsg(msg.getHeader().getClientType(), katimer,
+ new COPSAcctTimer(_acctTimer), null);
+ acceptMsg.writeData(conn);
+
+ final COPSPdpConnection pdpConn = new COPSPdpConnection(pepId,conn,_process);
+ pdpConn.setKaTimer(_kaTimer);
+ if (_acctTimer != 0) pdpConn.setAccTimer(_acctTimer);
+ new Thread(pdpConn).start();
+ _connectionMap.put(pepId.getData().str(),pdpConn);
+ }
+
+}
+
+
+
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Date;\r
-import java.util.Map;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * Class for managing an provisioning connection at the PDP side.\r
- */\r
-public class COPSPdpConnection implements Runnable {\r
-\r
- public final static Logger logger = LoggerFactory.getLogger(COPSPdpConnection.class);\r
-\r
- /**\r
- Socket connected to PEP\r
- */\r
- private Socket _sock;\r
-\r
- /**\r
- PEP identifier\r
- */\r
- private COPSPepId _pepId;\r
-\r
- /**\r
- Time of the latest keep-alive sent\r
- */\r
- private Date _lastKa;\r
-\r
- /**\r
- Opcode of the latest message sent\r
- */\r
- private byte _lastmessage;\r
-\r
- /**\r
- * Time of the latest keep-alive received\r
- */\r
- protected Date _lastRecKa;\r
-\r
- /**\r
- Maps a Client Handle to a Handler\r
- */\r
- protected final Map<String, COPSPdpReqStateMan> _managerMap;\r
- // map < String(COPSHandle), COPSPdpHandler> HandlerMap;\r
-\r
- /**\r
- * PDP policy data processor class\r
- */\r
- protected COPSPdpDataProcess _process;\r
-\r
- /**\r
- Accounting timer value (secs)\r
- */\r
- protected short _acctTimer;\r
-\r
- /**\r
- Keep-alive timer value (secs)\r
- */\r
- protected short _kaTimer;\r
-\r
- /**\r
- COPS error returned by PEP\r
- */\r
- protected COPSError _error;\r
-\r
- /**\r
- * Creates a new PDP connection\r
- *\r
- * @param pepId PEP-ID of the connected PEP\r
- * @param sock Socket connected to PEP\r
- * @param process Object for processing policy data\r
- */\r
- public COPSPdpConnection(COPSPepId pepId, Socket sock, COPSPdpDataProcess process) {\r
- _sock = sock;\r
- _pepId = pepId;\r
-\r
- _lastKa = new Date();\r
- _lastmessage = COPSHeader.COPS_OP_OPN;\r
- _managerMap = new ConcurrentHashMap<>();\r
-\r
- _kaTimer = 0;\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Gets the time of that latest keep-alive sent\r
- * @return Time of that latest keep-alive sent\r
- */\r
- public Date getLastKAlive() {\r
- return _lastKa;\r
- }\r
-\r
- /**\r
- * Sets the keep-alive timer value\r
- * @param kaTimer Keep-alive timer value (secs)\r
- */\r
- public void setKaTimer(short kaTimer) {\r
- _kaTimer = kaTimer;\r
- }\r
-\r
- /**\r
- * Gets the keep-alive timer value\r
- * @return Keep-alive timer value (secs)\r
- */\r
- public short getKaTimer() {\r
- return _kaTimer;\r
- }\r
-\r
- /**\r
- * Sets the accounting timer value\r
- * @param acctTimer Accounting timer value (secs)\r
- */\r
- public void setAccTimer(short acctTimer) {\r
- _acctTimer = acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the accounting timer value\r
- * @return Accounting timer value (secs)\r
- */\r
- public short getAcctTimer() {\r
- return _acctTimer;\r
- }\r
-\r
- /**\r
- * Gets the latest COPS message\r
- * @return Code of the latest message sent\r
- */\r
- public byte getLastMessage() {\r
- return _lastmessage;\r
- }\r
-\r
- /**\r
- * Gets the PEP-ID\r
- * @return The ID of the PEP, as a <tt>String</tt>\r
- */\r
- public String getPepId() {\r
- return _pepId.getData().str();\r
- }\r
-\r
- /**\r
- * Checks whether the socket to the PEP is closed or not\r
- * @return <tt>true</tt> if closed, <tt>false</tt> otherwise\r
- */\r
- public boolean isClosed() {\r
- return _sock.isClosed();\r
- }\r
-\r
- /**\r
- * Closes the socket to the PEP\r
- * @throws IOException\r
- */\r
- protected void close()\r
- throws IOException {\r
- _sock.close();\r
- }\r
-\r
- /**\r
- * Gets the socket to the PEP\r
- * @return Socket connected to the PEP\r
- */\r
- public Socket getSocket() {\r
- return _sock;\r
- }\r
-\r
- /**\r
- * Main loop\r
- */\r
- public void run () {\r
- Date _lastSendKa = new Date();\r
- _lastRecKa = new Date();\r
- try {\r
- while (!_sock.isClosed()) {\r
- if (_sock.getInputStream().available() != 0) {\r
- _lastmessage = processMessage(_sock);\r
- _lastRecKa = new Date();\r
- }\r
-\r
- // Keep Alive\r
- if (_kaTimer > 0) {\r
- // Timeout at PDP\r
- int _startTime = (int) (_lastRecKa.getTime());\r
- int cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > _kaTimer * 1000) {\r
- _sock.close();\r
- // Notify all Request State Managers\r
- notifyNoKAAllReqStateMan();\r
- }\r
-\r
- // Send to PEP\r
- _startTime = (int) (_lastSendKa.getTime());\r
- cTime = (int) (new Date().getTime());\r
-\r
- if ((cTime - _startTime) > ((_kaTimer * 3/4) * 1000)) {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
- COPSKAMsg msg = new COPSKAMsg();\r
-\r
- msg.add(hdr);\r
-\r
- COPSTransceiver.sendMsg(msg, _sock);\r
- _lastSendKa = new Date();\r
- }\r
- }\r
-\r
- try {\r
- Thread.sleep(500);\r
- } catch (Exception e) {\r
- logger.error("Exception thrown while sleeping", e);\r
- }\r
-\r
- }\r
- } catch (Exception e) {\r
- logger.error("Error while processing socket messages", e);\r
- }\r
-\r
- // connection closed by server\r
- // COPSDebug.out(getClass().getName(),"Connection closed by client");\r
- try {\r
- _sock.close();\r
- } catch (IOException e) {\r
- logger.error("Error closing socket", e);\r
- }\r
-\r
- // Notify all Request State Managers\r
- try {\r
- notifyCloseAllReqStateMan();\r
- } catch (COPSPdpException e) {\r
- logger.error("Error closing state managers");\r
- }\r
- }\r
-\r
- /**\r
- * Gets a COPS message from the socket and processes it\r
- * @param conn Socket connected to the PEP\r
- * @return Type of COPS message\r
- */\r
- private byte processMessage(Socket conn)\r
- throws COPSPdpException, COPSException, IOException {\r
- COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
-\r
- if (msg.getHeader().isAClientClose()) {\r
- handleClientCloseMsg(conn, msg);\r
- return COPSHeader.COPS_OP_CC;\r
- } else if (msg.getHeader().isAKeepAlive()) {\r
- handleKeepAliveMsg(conn, msg);\r
- return COPSHeader.COPS_OP_KA;\r
- } else if (msg.getHeader().isARequest()) {\r
- handleRequestMsg(conn, msg);\r
- return COPSHeader.COPS_OP_REQ;\r
- } else if (msg.getHeader().isAReport()) {\r
- handleReportMsg(conn, msg);\r
- return COPSHeader.COPS_OP_RPT;\r
- } else if (msg.getHeader().isADeleteReq()) {\r
- handleDeleteRequestMsg(conn, msg);\r
- return COPSHeader.COPS_OP_DRQ;\r
- } else if (msg.getHeader().isASyncComplete()) {\r
- handleSyncComplete(conn, msg);\r
- return COPSHeader.COPS_OP_SSC;\r
- } else {\r
- throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
- }\r
- }\r
-\r
- /**\r
- * Handle Client Close Message, close the passed connection\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- *\r
- * <Client-Close> ::= <Common Header>\r
- * <Error>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- */\r
- private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
- COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
- _error = cMsg.getError();\r
-\r
- // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
-\r
- try {\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- conn.close();\r
- } catch (Exception unae) {\r
- logger.error("Unexpected exception closing connection", unae);\r
- }\r
- }\r
-\r
- /**\r
- * Gets the occurred COPS Error\r
- * @return <tt>COPSError</tt> object\r
- */\r
- protected COPSError getError() {\r
- return _error;\r
- }\r
-\r
- /**\r
- * Handle Keep Alive Message\r
- *\r
- * <Keep-Alive> ::= <Common Header>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
- COPSKAMsg cMsg = (COPSKAMsg) msg;\r
-\r
- COPSKAMsg kaMsg = (COPSKAMsg) msg;\r
- try {\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
- kaMsg.writeData(conn);\r
- } catch (Exception unae) {\r
- logger.error("Unexpected exception while writing COPS data", unae);\r
- }\r
- }\r
-\r
- /**\r
- * Handle Delete Request Message\r
- *\r
- * <Delete Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Reason>\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
- COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;\r
- // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +\r
- // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- // Delete clientHandler\r
- if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {\r
- // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +\r
- // cMsg.getClientHandle().getId().getData());\r
- }\r
-\r
- COPSPdpReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processDeleteRequestState(cMsg);\r
- }\r
-\r
- }\r
-\r
- /**\r
- * Handle Request Message\r
- *\r
- * <Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Context>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleRequestMsg(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
-\r
- COPSReqMsg reqMsg = (COPSReqMsg) msg;\r
- COPSContext cntxt = reqMsg.getContext();\r
- COPSHeader header = reqMsg.getHeader();\r
- //short reqType = cntxt.getRequestType();\r
- short cType = header.getClientType();\r
-\r
- // Support\r
- if (reqMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpReqStateMan man;\r
- man = (COPSPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
-\r
- man = new COPSPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());\r
- _managerMap.put(reqMsg.getClientHandle().getId().str(),man);\r
- man.setDataProcess(_process);\r
- man.initRequestState(_sock);\r
-\r
- // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +\r
- // header.getClientType() + " msgType=" +\r
- // cntxt.getMessageType() + ", connId=" + conn.toString());\r
- }\r
-\r
- man.processRequest(reqMsg);\r
- }\r
-\r
- /**\r
- * Handle Report Message\r
- *\r
- * <Report State> ::= <Common Header>\r
- * <Client Handle>\r
- * <Report Type>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- *\r
- * Not support [<Integrity>]\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleReportMsg(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
- COPSReportMsg repMsg = (COPSReportMsg) msg;\r
- // COPSHandle handle = repMsg.getClientHandle();\r
- // COPSHeader header = repMsg.getHeader();\r
-\r
- // Support\r
- if (repMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("No state manager found with ID - " + repMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processReport(repMsg);\r
- }\r
- }\r
-\r
- /**\r
- * Method handleSyncComplete\r
- *\r
- * @param conn a Socket\r
- * @param msg a COPSMsg\r
- *\r
- */\r
- private void handleSyncComplete(Socket conn, COPSMsg msg)\r
- throws COPSPdpException {\r
- COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
- // COPSHandle handle = cMsg.getClientHandle();\r
- // COPSHeader header = cMsg.getHeader();\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
- }\r
-\r
- COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
- if (man == null) {\r
- logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());\r
- } else {\r
- man.processSyncComplete(cMsg);\r
- }\r
- }\r
-\r
- /**\r
- * Requests a COPS sync from the PEP\r
- * @throws COPSException\r
- * @throws COPSPdpException\r
- */\r
- protected void syncAllRequestState() throws COPSException, COPSPdpException {\r
- for (final COPSPdpReqStateMan man : _managerMap.values()) {\r
- man.syncRequestState();\r
- }\r
- }\r
-\r
- private void notifyCloseAllReqStateMan() throws COPSPdpException {\r
- for (final COPSPdpReqStateMan man : _managerMap.values()) {\r
- man.processClosedConnection(_error);\r
- }\r
- }\r
-\r
- private void notifyNoKAAllReqStateMan() throws COPSPdpException {\r
- for (final COPSPdpReqStateMan man : _managerMap.values()) {\r
- man.processNoKAConnection();\r
- }\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.*;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Class for managing an provisioning connection at the PDP side.
+ */
+public class COPSPdpConnection implements Runnable {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSPdpConnection.class);
+
+ /**
+ Socket connected to PEP
+ */
+ private Socket _sock;
+
+ /**
+ PEP identifier
+ */
+ private COPSPepId _pepId;
+
+ /**
+ Time of the latest keep-alive sent
+ */
+ private Date _lastKa;
+
+ /**
+ * Time of the latest keep-alive received
+ */
+ protected Date _lastRecKa;
+
+ /**
+ Maps a Client Handle to a Handler
+ */
+ protected final Map<String, COPSPdpReqStateMan> _managerMap;
+
+ /**
+ * PDP policy data processor class
+ */
+ protected COPSPdpDataProcess _process;
+
+ /**
+ Accounting timer value (secs)
+ */
+ protected short _acctTimer;
+
+ /**
+ Keep-alive timer value (secs)
+ */
+ protected short _kaTimer;
+
+ /**
+ COPS error returned by PEP
+ */
+ protected COPSError _error;
+
+ /**
+ * Creates a new PDP connection
+ *
+ * @param pepId PEP-ID of the connected PEP
+ * @param sock Socket connected to PEP
+ * @param process Object for processing policy data
+ */
+ public COPSPdpConnection(COPSPepId pepId, Socket sock, COPSPdpDataProcess process) {
+ _sock = sock;
+ _pepId = pepId;
+
+ _lastKa = new Date();
+ _managerMap = new ConcurrentHashMap<>();
+
+ _kaTimer = 0;
+ _process = process;
+ }
+
+ /**
+ * Gets the time of that latest keep-alive sent
+ * @return Time of that latest keep-alive sent
+ */
+ public Date getLastKAlive() {
+ return _lastKa;
+ }
+
+ /**
+ * Sets the keep-alive timer value
+ * @param kaTimer Keep-alive timer value (secs)
+ */
+ public void setKaTimer(short kaTimer) {
+ _kaTimer = kaTimer;
+ }
+
+ /**
+ * Gets the keep-alive timer value
+ * @return Keep-alive timer value (secs)
+ */
+ public short getKaTimer() {
+ return _kaTimer;
+ }
+
+ /**
+ * Sets the accounting timer value
+ * @param acctTimer Accounting timer value (secs)
+ */
+ public void setAccTimer(short acctTimer) {
+ _acctTimer = acctTimer;
+ }
+
+ /**
+ * Gets the accounting timer value
+ * @return Accounting timer value (secs)
+ */
+ public short getAcctTimer() {
+ return _acctTimer;
+ }
+
+ /**
+ * Gets the PEP-ID
+ * @return The ID of the PEP, as a <tt>String</tt>
+ */
+ public String getPepId() {
+ return _pepId.getData().str();
+ }
+
+ /**
+ * Checks whether the socket to the PEP is closed or not
+ * @return <tt>true</tt> if closed, <tt>false</tt> otherwise
+ */
+ public boolean isClosed() {
+ return _sock.isClosed();
+ }
+
+ /**
+ * Closes the socket to the PEP
+ * @throws IOException
+ */
+ protected void close()
+ throws IOException {
+ _sock.close();
+ }
+
+ /**
+ * Gets the socket to the PEP
+ * @return Socket connected to the PEP
+ */
+ public Socket getSocket() {
+ return _sock;
+ }
+
+ /**
+ * Main loop
+ */
+ public void run () {
+ Date _lastSendKa = new Date();
+ _lastRecKa = new Date();
+ try {
+ while (!_sock.isClosed()) {
+ if (_sock.getInputStream().available() != 0) {
+ processMessage(_sock);
+ _lastRecKa = new Date();
+ }
+
+ // Keep Alive
+ if (_kaTimer > 0) {
+ // Timeout at PDP
+ int _startTime = (int) (_lastRecKa.getTime());
+ int cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > _kaTimer*1000) {
+ _sock.close();
+ // Notify all Request State Managers
+ notifyNoKAAllReqStateMan();
+ }
+
+ // Send to PEP
+ _startTime = (int) (_lastSendKa.getTime());
+ cTime = (int) (new Date().getTime());
+
+ if ((cTime - _startTime) > ((_kaTimer*3/4)*1000)) {
+ // TODO - what should the real clientType be here???
+ final COPSKAMsg msg = new COPSKAMsg(null);
+ COPSTransceiver.sendMsg(msg, _sock);
+ _lastSendKa = new Date();
+ }
+ }
+
+ try {
+ Thread.sleep(500);
+ } catch (Exception e) {
+ logger.error("Exception thrown while sleeping", e);
+ }
+
+ }
+ } catch (Exception e) {
+ logger.error("Error while processing socket messages", e);
+ }
+
+ // connection closed by server
+ try {
+ _sock.close();
+ } catch (IOException e) {
+ logger.error("Error closing socket", e);
+ }
+
+ // Notify all Request State Managers
+ try {
+ notifyCloseAllReqStateMan();
+ } catch (COPSPdpException e) {
+ logger.error("Error closing state managers");
+ }
+ }
+
+ /**
+ * Gets a COPS message from the socket and processes it
+ * @param conn Socket connected to the PEP
+ */
+ private void processMessage(final Socket conn) throws COPSPdpException, COPSException, IOException {
+ final COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+ switch (msg.getHeader().getOpCode()) {
+ case CC:
+ handleClientCloseMsg(conn, msg);
+ break;
+ case KA:
+ handleKeepAliveMsg(conn, msg);
+ break;
+ case REQ:
+ handleRequestMsg(conn, msg);
+ break;
+ case RPT:
+ handleReportMsg(conn, msg);
+ break;
+ case DRQ:
+ handleDeleteRequestMsg(conn, msg);
+ break;
+ case SSC:
+ handleSyncComplete(conn, msg);
+ break;
+ default:
+ throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
+ }
+ }
+
+ /**
+ * Handle Client Close Message, close the passed connection
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ */
+ private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
+ COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
+ _error = cMsg.getError();
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+ conn.close();
+ } catch (Exception unae) {
+ logger.error("Unexpected exception closing connection", unae);
+ }
+ }
+
+ /**
+ * Gets the occurred COPS Error
+ * @return <tt>COPSError</tt> object
+ */
+ protected COPSError getError() {
+ return _error;
+ }
+
+ /**
+ * Handle Keep Alive Message
+ *
+ * <Keep-Alive> ::= <Common Header>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
+ COPSKAMsg cMsg = (COPSKAMsg) msg;
+
+ COPSKAMsg kaMsg = (COPSKAMsg) msg;
+ try {
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+ kaMsg.writeData(conn);
+ } catch (Exception unae) {
+ logger.error("Unexpected exception while writing COPS data", unae);
+ }
+ }
+
+ /**
+ * Handle Delete Request Message
+ *
+ * <Delete Request> ::= <Common Header>
+ * <Client Handle>
+ * <Reason>
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)
+ throws COPSPdpException {
+ COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ // Delete clientHandler
+ if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {
+ // TODO - Do something here
+ }
+
+ COPSPdpReqStateMan man = _managerMap.get(cMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());
+ } else {
+ man.processDeleteRequestState(cMsg);
+ }
+
+ }
+
+ /**
+ * Handle Request Message
+ *
+ * <Request> ::= <Common Header>
+ * <Client Handle>
+ * <Context>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleRequestMsg(Socket conn, COPSMsg msg) throws COPSPdpException {
+
+ final COPSReqMsg reqMsg = (COPSReqMsg) msg;
+// final COPSContext cntxt = reqMsg.getContext();
+ final COPSHeader header = reqMsg.getHeader();
+ //short reqType = cntxt.getRequestType();
+ final short cType = header.getClientType();
+
+ // Support
+ if (reqMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ COPSPdpReqStateMan man = _managerMap.get(reqMsg.getClientHandle().getId().str());
+ if (man == null) {
+
+ man = new COPSPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());
+ _managerMap.put(reqMsg.getClientHandle().getId().str(),man);
+ man.setDataProcess(_process);
+ man.initRequestState(_sock);
+
+ // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +
+ // header.getClientType() + " msgType=" +
+ // cntxt.getMessageType() + ", connId=" + conn.toString());
+ }
+
+ man.processRequest(reqMsg);
+ }
+
+ /**
+ * Handle Report Message
+ *
+ * <Report State> ::= <Common Header>
+ * <Client Handle>
+ * <Report Type>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ *
+ * Not support [<Integrity>]
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleReportMsg(Socket conn, COPSMsg msg)
+ throws COPSPdpException {
+ COPSReportMsg repMsg = (COPSReportMsg) msg;
+ // COPSHandle handle = repMsg.getClientHandle();
+ // COPSHeader header = repMsg.getHeader();
+
+ // Support
+ if (repMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ final COPSPdpReqStateMan man = _managerMap.get(repMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("No state manager found with ID - " + repMsg.getClientHandle().getId().str());
+ } else {
+ man.processReport(repMsg);
+ }
+ }
+
+ /**
+ * Method handleSyncComplete
+ *
+ * @param conn a Socket
+ * @param msg a COPSMsg
+ *
+ */
+ private void handleSyncComplete(Socket conn, COPSMsg msg)
+ throws COPSPdpException {
+ COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
+ // COPSHandle handle = cMsg.getClientHandle();
+ // COPSHeader header = cMsg.getHeader();
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
+ }
+
+ COPSPdpReqStateMan man = (COPSPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
+ if (man == null) {
+ logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());
+ } else {
+ man.processSyncComplete(cMsg);
+ }
+ }
+
+ /**
+ * Requests a COPS sync from the PEP
+ * @throws COPSException
+ * @throws COPSPdpException
+ */
+ protected void syncAllRequestState() throws COPSException, COPSPdpException {
+ for (final COPSPdpReqStateMan man : _managerMap.values()) {
+ man.syncRequestState();
+ }
+ }
+
+ private void notifyCloseAllReqStateMan() throws COPSPdpException {
+ for (final COPSPdpReqStateMan man : _managerMap.values()) {
+ man.processClosedConnection(_error);
+ }
+ }
+
+ private void notifyNoKAAllReqStateMan() throws COPSPdpException {
+ for (final COPSPdpReqStateMan man : _managerMap.values()) {
+ man.processNoKAConnection();
+ }
+ }
+
+}
+
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import java.util.Hashtable;\r
-\r
-import org.umu.cops.stack.COPSError;\r
-\r
-/**\r
- * Abstract class for implementing policy data processing classes for provisioning PDPs.\r
- */\r
-abstract public class COPSPdpDataProcess {\r
- /**\r
- * Gets the policies to be uninstalled\r
- * @param man The associated request state manager\r
- * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
- */\r
- abstract public Hashtable getRemovePolicy(COPSPdpReqStateMan man);\r
- /**\r
- * Gets the policies to be installed\r
- * @param man The associated request state manager\r
- * @return A <tt>Vector</tt> holding the policies to be uninstalled\r
- */\r
- abstract public Hashtable getInstallPolicy(COPSPdpReqStateMan man);\r
- /**\r
- * Makes a decision from the supplied request data\r
- * @param man The associated request state manager\r
- * @param reqSIs Client specific data suppplied in the COPS request\r
- */\r
- abstract public void setClientData(COPSPdpReqStateMan man, Hashtable reqSIs);\r
- /**\r
- * Builds a failure report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void failReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
- /**\r
- * Builds a success report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void successReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
- /**\r
- * Builds an accounting report\r
- * @param man The associated request state manager\r
- * @param reportSIs Report data\r
- */\r
- abstract public void acctReport (COPSPdpReqStateMan man, Hashtable reportSIs);\r
- /**\r
- * Notifies that no accounting report has been received\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyNoAcctReport (COPSPdpReqStateMan man);\r
-\r
- /**\r
- * Notifies a keep-alive timeout\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyNoKAliveReceived (COPSPdpReqStateMan man);\r
-\r
- /**\r
- * Notifies that the connection has been closed\r
- * @param man The associated request state manager\r
- * @param error Reason\r
- */\r
- public abstract void notifyClosedConnection (COPSPdpReqStateMan man, COPSError error);\r
-\r
- /**\r
- * Notifies that a request state has been deleted\r
- * @param man The associated request state manager\r
- */\r
- public abstract void notifyDeleteRequestState (COPSPdpReqStateMan man);\r
-\r
- /**\r
- * Notifies that a request state has been closed\r
- * @param man The associated request state manager\r
- */\r
- public abstract void closeRequestState(COPSPdpReqStateMan man);\r
-}\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.umu.cops.stack.COPSError;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+ * Abstract class for implementing policy data processing classes for provisioning PDPs.
+ */
+public interface COPSPdpDataProcess {
+ /**
+ * Gets the policies to be uninstalled
+ * @param man The associated request state manager
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled
+ */
+ public Hashtable getRemovePolicy(COPSPdpReqStateMan man);
+ /**
+ * Gets the policies to be installed
+ * @param man The associated request state manager
+ * @return A <tt>Vector</tt> holding the policies to be uninstalled
+ */
+ public Hashtable getInstallPolicy(COPSPdpReqStateMan man);
+ /**
+ * Makes a decision from the supplied request data
+ * @param man The associated request state manager
+ * @param reqSIs Client specific data suppplied in the COPS request
+ */
+ public void setClientData(COPSPdpReqStateMan man, Map<String, String> reqSIs);
+ /**
+ * Builds a failure report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void failReport(COPSPdpReqStateMan man, Map<String, String> reportSIs);
+ /**
+ * Builds a success report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void successReport(COPSPdpReqStateMan man, Map<String, String> reportSIs);
+ /**
+ * Builds an accounting report
+ * @param man The associated request state manager
+ * @param reportSIs Report data
+ */
+ public void acctReport(COPSPdpReqStateMan man, Map<String, String> reportSIs);
+ /**
+ * Notifies that no accounting report has been received
+ * @param man The associated request state manager
+ */
+ public void notifyNoAcctReport (COPSPdpReqStateMan man);
+
+ /**
+ * Notifies a keep-alive timeout
+ * @param man The associated request state manager
+ */
+ public void notifyNoKAliveReceived (COPSPdpReqStateMan man);
+
+ /**
+ * Notifies that the connection has been closed
+ * @param man The associated request state manager
+ * @param error Reason
+ */
+ public void notifyClosedConnection (COPSPdpReqStateMan man, COPSError error);
+
+ /**
+ * Notifies that a request state has been deleted
+ * @param man The associated request state manager
+ */
+ public void notifyDeleteRequestState (COPSPdpReqStateMan man);
+
+ /**
+ * Notifies that a request state has been closed
+ * @param man The associated request state manager
+ */
+ public void closeRequestState(COPSPdpReqStateMan man);
+}
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-\r
-/**\r
- * COPS message transceiver class for provisioning connections at the PDP side.\r
- *\r
- * TODO - Need to continue refactoring by removing all instances of Hashtable (change to Map<>)\r
- */\r
-public class COPSPdpMsgSender {\r
-\r
- /**\r
- * Socket connected to PEP\r
- */\r
- protected Socket _sock;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Creates a COPSPepMsgSender\r
- *\r
- * @param clientType COPS client-type\r
- * @param clientHandle Client handle\r
- * @param sock Socket to the PEP\r
- */\r
- public COPSPdpMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
- // COPS Handle\r
- _handle = clientHandle;\r
- _clientType = clientType;\r
-\r
- _sock = sock;\r
- }\r
-\r
- /**\r
- * Gets the client handle\r
- * @return Client's <tt>COPSHandle</tt>\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Gets the client-type\r
- * @return Client-type value\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Sends a decision message\r
- * @param removeDecs Decisions to be removed\r
- * @param installDecs Decisions to be installed\r
- * @throws COPSPdpException\r
- */\r
- public void sendDecision(Hashtable removeDecs, Hashtable installDecs)\r
- throws COPSPdpException {\r
- /* <Decision Message> ::= <Common Header: Flag SOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>) | <Error>\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * [<Named Decision Data: Provisioning>]\r
- * <Decision: Flags> ::= <Command-Code> NULLFlag\r
- * <Command-Code> ::= NULLDecision | Install | Remove\r
- * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
- * <Install Decision> ::= *(<PRID> <EPD>)\r
- * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
- *\r
- * Very important, this is actually being treated like this:\r
- * <Install Decision> ::= <PRID> | <EPD>\r
- * <Remove Decision> ::= <PRID> | <PPRID>\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
- hdr.setFlag(COPSHeader.COPS_FLAG_SOLICITED);\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(handle);\r
-\r
- // Decisions (no flags supplied)\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
-\r
- // Remove Decisions\r
- // <Decision: Flags>\r
- if (removeDecs.size() > 0) {\r
- COPSDecision rdec1 = new COPSDecision();\r
- rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
-\r
- decisionMsg.addDecision(rdec1, cntxt);\r
-\r
- for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) removeDecs.get(strprid);\r
-\r
- // <Named Decision Data: Provisioning> (PRID)\r
- COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
- // <Named Decision Data: Provisioning> (EPD)\r
- COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- decisionMsg.addDecision(dec2, cntxt);\r
- decisionMsg.addDecision(dec3, cntxt);\r
- }\r
- }\r
-\r
- // Install Decisions\r
- // <Decision: Flags>\r
- if (installDecs.size() > 0) {\r
- COPSDecision idec1 = new COPSDecision();\r
- idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
-\r
- decisionMsg.addDecision(idec1, cntxt);\r
-\r
- for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) installDecs.get(strprid);\r
-\r
- // <Named Decision Data: Provisioning> (PRID)\r
- COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
- // <Named Decision Data: Provisioning> (EPD)\r
- COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- decisionMsg.addDecision(dec2, cntxt);\r
- decisionMsg.addDecision(dec3, cntxt);\r
- }\r
-\r
- /**\r
- COPSIntegrity intr = new COPSIntegrity();\r
- intr.setKeyId(19);\r
- intr.setSeqNum(9);\r
- intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
- decisionMsg.add(intr);\r
- /**/\r
- }\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- //** Send the decision\r
- //**\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a decision message which was not requested by the PEP\r
- * @param removeDecs Decisions to be removed\r
- * @param installDecs Decisions to be installed\r
- * @throws COPSPdpException\r
- */\r
- public void sendUnsolicitedDecision(Hashtable removeDecs, Hashtable installDecs)\r
- throws COPSPdpException {\r
- //** Example of an UNSOLICITED decision\r
- //**\r
-\r
- /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>) | <Error>\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * [<Named Decision Data: Provisioning>]\r
- * <Decision: Flags> ::= <Command-Code> NULLFlag\r
- * <Command-Code> ::= NULLDecision | Install | Remove\r
- * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
- * <Install Decision> ::= *(<PRID> <EPD>)\r
- * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
- *\r
- * Very important, this is actually being treated like this:\r
- * <Install Decision> ::= <PRID> | <EPD>\r
- * <Remove Decision> ::= <PRID> | <PPRID>\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle handle = new COPSHandle(getClientHandle().getId());\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(handle);\r
-\r
- // Decisions (no flags supplied)\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
-\r
- // Remove Decisions\r
- // <Decision: Flags>\r
- COPSDecision rdec1 = new COPSDecision();\r
- rdec1.setCmdCode(COPSDecision.DEC_REMOVE);\r
-\r
- decisionMsg.addDecision(rdec1, cntxt);\r
-\r
- for (Enumeration e = removeDecs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) removeDecs.get(strprid);\r
-\r
- // <Named Decision Data: Provisioning> (PRID)\r
- COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
- // <Named Decision Data: Provisioning> (EPD)\r
- COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- decisionMsg.addDecision(dec2, cntxt);\r
- decisionMsg.addDecision(dec3, cntxt);\r
- }\r
-\r
- // Install Decisions\r
- // <Decision: Flags>\r
- COPSDecision idec1 = new COPSDecision();\r
- idec1.setCmdCode(COPSDecision.DEC_INSTALL);\r
-\r
- decisionMsg.addDecision(idec1, cntxt);\r
-\r
- for (Enumeration e = installDecs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) installDecs.get(strprid);\r
-\r
- // <Named Decision Data: Provisioning> (PRID)\r
- COPSDecision dec2 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- dec2.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
- // <Named Decision Data: Provisioning> (EPD)\r
- COPSDecision dec3 = new COPSDecision(COPSDecision.DEC_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- dec3.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- decisionMsg.addDecision(dec2, cntxt);\r
- decisionMsg.addDecision(dec3, cntxt);\r
- }\r
-\r
- /**\r
- COPSIntegrity intr = new COPSIntegrity();\r
- intr.setKeyId(19);\r
- intr.setSeqNum(9);\r
- intr.setKeyDigest(new COPSData("KEY DIGEST"));\r
- decisionMsg.add(intr);\r
- /**/\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- //** Send the decision\r
- //**\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a message asking that the request state be deleted\r
- * @throws COPSPdpException\r
- */\r
- public void sendDeleteRequestState()\r
- throws COPSPdpException {\r
- /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>)\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * <Decision: Flags> ::= Remove Request-State\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request (default UNSOLICITED)\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- // Decisions\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
- // <Decision: Flags>\r
- COPSDecision dec = new COPSDecision();\r
- dec.setCmdCode(COPSDecision.DEC_REMOVE);\r
- dec.setFlags(COPSDecision.F_REQSTATE);\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(clienthandle);\r
- decisionMsg.addDecision(dec, cntxt);\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a request asking that a new request state be created\r
- * @throws COPSPdpException\r
- */\r
- public void sendOpenNewRequestState()\r
- throws COPSPdpException {\r
- /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>\r
- * <Client Handle>\r
- * *(<Decision>)\r
- * [<Integrity>]\r
- * <Decision> ::= <Context>\r
- * <Decision: Flags>\r
- * <Decision: Flags> ::= Install Request-State\r
- *\r
- */\r
-\r
- // Common Header with the same ClientType as the request (default UNSOLICITED)\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_DEC, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- // Decisions\r
- // <Context>\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG, (short) 0);\r
- // <Decision: Flags>\r
- COPSDecision dec = new COPSDecision();\r
- dec.setCmdCode(COPSDecision.DEC_INSTALL);\r
- dec.setFlags(COPSDecision.F_REQSTATE);\r
-\r
- COPSDecisionMsg decisionMsg = new COPSDecisionMsg();\r
- try {\r
- decisionMsg.add(hdr);\r
- decisionMsg.add(clienthandle);\r
- decisionMsg.addDecision(dec, cntxt);\r
- } catch (COPSException e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- decisionMsg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Sends a message asking for a COPS sync operation\r
- * @throws COPSPdpException\r
- */\r
- public void sendSyncRequestState()\r
- throws COPSPdpException {\r
- /* <Synchronize State Request> ::= <Common Header>\r
- * [<Client Handle>]\r
- * [<Integrity>]\r
- */\r
-\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSQ, getClientType());\r
-\r
- // Client Handle with the same clientHandle as the request\r
- final COPSHandle clienthandle = new COPSHandle(_handle.getId());\r
-\r
- COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(clienthandle);\r
- } catch (Exception e) {\r
- throw new COPSPdpException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());\r
- }\r
- }\r
-}\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * COPS message transceiver class for provisioning connections at the PDP side.
+ *
+ * TODO - Need to continue refactoring by removing all instances of Hashtable (change to Map<>)
+ */
+public class COPSPdpMsgSender {
+
+ /**
+ * Socket connected to PEP
+ */
+ protected final Socket _sock;
+
+ /**
+ * COPS client-type that identifies the policy client
+ */
+ protected final short _clientType;
+
+ /**
+ * COPS client handle used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected final COPSHandle _handle;
+
+ /**
+ * Creates a COPSPepMsgSender
+ *
+ * @param clientType COPS client-type
+ * @param clientHandle Client handle
+ * @param sock Socket to the PEP
+ */
+ public COPSPdpMsgSender (final short clientType, final COPSHandle clientHandle, final Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+
+ _sock = sock;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Sends a decision message
+ * @param removeDecs Decisions to be removed
+ * @param installDecs Decisions to be installed
+ * @throws COPSPdpException
+ */
+ public void sendDecision(final Map<String, String> removeDecs, Map<String, String> installDecs)
+ throws COPSPdpException {
+ /* <Decision Message> ::= <Common Header: Flag SOLICITED>
+ * <Client Handle>
+ * *(<Decision>) | <Error>
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * [<Named Decision Data: Provisioning>]
+ * <Decision: Flags> ::= <Command-Code> NULLFlag
+ * <Command-Code> ::= NULLDecision | Install | Remove
+ * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>
+ * <Install Decision> ::= *(<PRID> <EPD>)
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)
+ *
+ * Very important, this is actually being treated like this:
+ * <Install Decision> ::= <PRID> | <EPD>
+ * <Remove Decision> ::= <PRID> | <PPRID>
+ *
+ */
+
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+
+ // Decisions (no flags supplied)
+ // <Context>
+ final COPSContext cntxt = new COPSContext(RType.CONFIG, (short)0);
+
+ // Remove Decisions
+ // <Decision: Flags>
+ final COPSDecision rdec1 = new COPSDecision(Command.REMOVE);
+
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(rdec1);
+ decisionMap.put(cntxt, decisionSet);
+
+ for (final Map.Entry<String, String> entry : removeDecs.entrySet()) {
+ // <Named Decision Data: Provisioning> (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+ final COPSDecision decisionPrid = new COPSDecision(CType.NAMED,
+ new COPSData(prid.getDataRep(), 0, prid.getDataLength()));
+
+ decisionMap.get(cntxt).add(decisionPrid);
+
+ final COPSPrEPD epd = new COPSPrEPD();
+ final COPSDecision decisionPrepd = new COPSDecision(CType.NAMED,
+ new COPSData(epd.getDataRep(), 0, epd.getDataLength()));
+
+ decisionMap.get(cntxt).add(decisionPrepd);
+ }
+
+ // Install Decisions
+ // <Decision: Flags>
+ final COPSDecision idec1 = new COPSDecision(Command.INSTALL);
+ decisionMap.get(cntxt).add(idec1);
+
+ for (final Map.Entry<String, String> entry : installDecs.entrySet()) {
+ // <Named Decision Data: Provisioning> (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+ final COPSDecision decisionPrid2 = new COPSDecision(CType.NAMED,
+ new COPSData(prid.getDataRep(), 0, prid.getDataLength()));
+
+ decisionMap.get(cntxt).add(decisionPrid2);
+ }
+
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
+ decisionMap, null);
+
+ //** Send the decision
+ //**
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a decision message which was not requested by the PEP
+ * @param removeDecs Decisions to be removed
+ * @param installDecs Decisions to be installed
+ * @throws COPSPdpException
+ */
+ public void sendUnsolicitedDecision(final Map<String, String> removeDecs, final Map<String, String> installDecs)
+ throws COPSPdpException {
+ //** Example of an UNSOLICITED decision
+ //**
+
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
+ * <Client Handle>
+ * *(<Decision>) | <Error>
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * [<Named Decision Data: Provisioning>]
+ * <Decision: Flags> ::= <Command-Code> NULLFlag
+ * <Command-Code> ::= NULLDecision | Install | Remove
+ * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>
+ * <Install Decision> ::= *(<PRID> <EPD>)
+ * <Remove Decision> ::= *(<PRID> | <PPRID>)
+ *
+ * Very important, this is actually being treated like this:
+ * <Install Decision> ::= <PRID> | <EPD>
+ * <Remove Decision> ::= <PRID> | <PPRID>
+ *
+ */
+
+ // Common Header with the same ClientType as the request
+ // Client Handle with the same clientHandle as the request
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ // Decisions (no flags supplied)
+ // <Context>
+ final COPSContext cntxt = new COPSContext(RType.CONFIG, (short)0);
+
+ // Remove Decisions
+ // <Decision: Flags>
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(new COPSDecision(Command.REMOVE));
+ decisionMap.put(cntxt, decisionSet);
+
+ for (final Map.Entry<String, String> entry : removeDecs.entrySet()) {
+ // <Named Decision Data: Provisioning> (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+ decisionMap.get(cntxt).add(new COPSDecision(CType.NAMED,
+ new COPSData(prid.getDataRep(), 0, prid.getDataLength())));
+
+ // <Named Decision Data: Provisioning> (EPD)
+ final COPSPrEPD epd = new COPSPrEPD();
+ epd.setData(new COPSData(entry.getValue()));
+ decisionMap.get(cntxt).add(
+ new COPSDecision(CType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())));
+ }
+
+ // Install Decisions
+ // <Decision: Flags>
+ decisionMap.get(cntxt).add(new COPSDecision(Command.INSTALL));
+
+ for (final Map.Entry<String, String> entry : installDecs.entrySet()) {
+ // <Named Decision Data: Provisioning> (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+ decisionMap.get(cntxt).add(new COPSDecision(CType.NAMED,
+ new COPSData(prid.getDataRep(), 0, prid.getDataLength())));
+
+ final COPSPrEPD epd = new COPSPrEPD();
+ epd.setData(new COPSData(entry.getValue()));
+ decisionMap.get(cntxt).add(
+ new COPSDecision(CType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())));
+ }
+
+ /**
+ COPSIntegrity intr = new COPSIntegrity();
+ intr.setKeyId(19);
+ intr.setSeqNum(9);
+ intr.setKeyDigest(new COPSData("KEY DIGEST"));
+ decisionMsg.add(intr);
+ /**/
+
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
+ decisionMap, null);
+
+ //** Send the decision
+ //**
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a message asking that the request state be deleted
+ * @throws COPSPdpException
+ */
+ public void sendDeleteRequestState() throws COPSPdpException {
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
+ * <Client Handle>
+ * *(<Decision>)
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * <Decision: Flags> ::= Remove Request-State
+ *
+ */
+
+ // Decisions
+ // <Context>
+ // <Decision: Flags>
+ final COPSDecision dec = new COPSDecision(Command.REMOVE, DecisionFlag.REQSTATE);
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(dec);
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), new COPSHandle(_handle.getId()),
+ decisionMap, null);
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a request asking that a new request state be created
+ * @throws COPSPdpException
+ */
+ public void sendOpenNewRequestState()
+ throws COPSPdpException {
+ /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
+ * <Client Handle>
+ * *(<Decision>)
+ * [<Integrity>]
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * <Decision: Flags> ::= Install Request-State
+ *
+ */
+
+ // <Decision: Flags>
+ final COPSDecision dec = new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE);
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+ final Set<COPSDecision> decisionSet = new HashSet<>();
+ decisionSet.add(dec);
+ decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
+
+ final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(_handle.getId()),
+ decisionMap, null);
+
+ try {
+ decisionMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Sends a message asking for a COPS sync operation
+ * @throws COPSPdpException
+ */
+ public void sendSyncRequestState()
+ throws COPSPdpException {
+ /* <Synchronize State Request> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ */
+
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(_clientType, new COPSHandle(_handle.getId()), null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());
+ }
+ }
+}
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpdp;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-\r
-/**\r
- * State manager class for provisioning requests, at the PDP side.\r
- */\r
-public class COPSPdpReqStateMan {\r
-\r
- /**\r
- * Request State created\r
- */\r
- public final static short ST_CREATE = 1;\r
- /**\r
- * Request received\r
- */\r
- public final static short ST_INIT = 2;\r
- /**\r
- * Decisions sent\r
- */\r
- public final static short ST_DECS = 3;\r
- /**\r
- * Report received\r
- */\r
- public final static short ST_REPORT = 4;\r
- /**\r
- * Request State finalized\r
- */\r
- public final static short ST_FINAL = 5;\r
- /**\r
- * New Request State solicited\r
- */\r
- public final static short ST_NEW = 6;\r
- /**\r
- * Delete Request State solicited\r
- */\r
- public final static short ST_DEL = 7;\r
- /**\r
- * SYNC request sent\r
- */\r
- public final static short ST_SYNC = 8;\r
- /**\r
- * SYNC completed\r
- */\r
- public final static short ST_SYNCALL = 9;\r
- /**\r
- * Close connection received\r
- */\r
- public final static short ST_CCONN = 10;\r
- /**\r
- * Keep-alive timeout\r
- */\r
- public final static short ST_NOKA = 11;\r
- /**\r
- * Accounting timeout\r
- */\r
- public final static short ST_ACCT = 12;\r
-\r
- /**\r
- * COPS client-type that identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * COPS client handle used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Object for performing policy data processing\r
- */\r
- protected COPSPdpDataProcess _process;\r
-\r
- /**\r
- * Current state of the request being managed\r
- */\r
- protected short _status;\r
-\r
- /** COPS message transceiver used to send COPS messages */\r
- protected COPSPdpMsgSender _sender;\r
-\r
- /**\r
- * Creates a request state manager\r
- * @param clientType Client-type\r
- * @param clientHandle Client handle\r
- */\r
- public COPSPdpReqStateMan(short clientType, String clientHandle) {\r
- _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 COPSPdpDataProcess getDataProcess() {\r
- return _process;\r
- }\r
-\r
- /**\r
- * Sets the policy data processing object\r
- * @param process Policy data processing object\r
- */\r
- public void setDataProcess(COPSPdpDataProcess process) {\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Called when COPS sync is completed\r
- * @param repMsg COPS sync message\r
- * @throws COPSPdpException\r
- */\r
- protected void processSyncComplete(COPSSyncStateMsg repMsg)\r
- throws COPSPdpException {\r
-\r
- _status = ST_SYNCALL;\r
-\r
- // maybe we should notifySyncComplete ...\r
- }\r
-\r
- /**\r
- * Initializes a new request state over a socket\r
- * @param sock Socket to the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void initRequestState(Socket sock)\r
- throws COPSPdpException {\r
- // Inits an object for sending COPS messages to the PEP\r
- _sender = new COPSPdpMsgSender(_clientType, _handle, sock);\r
-\r
- // Initial state\r
- _status = ST_INIT;\r
- }\r
-\r
- /**\r
- * Processes a COPS request\r
- * @param msg COPS request received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processRequest(COPSReqMsg msg)\r
- throws COPSPdpException {\r
-\r
- COPSHeader hdrmsg = msg.getHeader();\r
- COPSHandle handlemsg = msg.getClientHandle();\r
- COPSContext contextmsg = msg.getContext();\r
-\r
- //** Analyze the request\r
- //**\r
-\r
- /* <Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Context>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI> ::= <*(<PRID> <EPD>)>\r
- *\r
- * Very important, this is actually being treated like this:\r
- * <Named ClientSI> ::= <PRID> | <EPD>\r
- *\r
-\r
- // Named ClientSI\r
- Vector clientSIs = msg.getClientSI();\r
- Hashtable reqSIs = new Hashtable(40);\r
- String strobjprid = new String();\r
- for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
- switch (obj.getSNum())\r
- {\r
- case COPSPrObjBase.PR_PRID:\r
- strobjprid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- reqSIs.put(strobjprid, obj.getData().str());\r
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- //** Here we must retrieve a decision depending on\r
- //** the supplied ClientSIs\r
- // reqSIs is a hashtable with the prid and epds\r
-\r
- // ................\r
- //\r
- Hashtable removeDecs = new Hashtable();\r
- Hashtable installDecs = new Hashtable();\r
- _process.setClientData(this, reqSIs);\r
-\r
- removeDecs = _process.getRemovePolicy(this);\r
- installDecs = _process.getInstallPolicy(this);\r
-\r
- //** We create the SOLICITED decision\r
- //**\r
- _sender.sendDecision(removeDecs, installDecs);\r
- _status = ST_DECS;\r
- */\r
- }\r
-\r
- /**\r
- * Processes a report\r
- * @param msg Report message from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processReport(COPSReportMsg msg)\r
- throws COPSPdpException {\r
-\r
- //** Analyze the report\r
- //**\r
-\r
- /*\r
- * <Report State> ::= <Common Header>\r
- * <Client Handle>\r
- * <Report Type>\r
- * *(<Named ClientSI>)\r
- * [<Integrity>]\r
- * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>\r
- * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)\r
- *\r
- * Important, <Named ClientSI> is not parsed\r
- */\r
-\r
- // COPSHeader hdrmsg = msg.getHeader();\r
- // COPSHandle handlemsg = msg.getClientHandle();\r
-\r
- // Report Type\r
- COPSReportType rtypemsg = msg.getReport();\r
-\r
- // Named ClientSI\r
- Vector clientSIs = msg.getClientSI();\r
- Hashtable repSIs = new Hashtable(40);\r
- String strobjprid = new String();\r
- for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());\r
- switch (obj.getSNum()) {\r
- case COPSPrObjBase.PR_PRID:\r
- strobjprid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- repSIs.put(strobjprid, obj.getData().str());\r
- // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);\r
- // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- //** Here we must act in accordance with\r
- //** the report received\r
- if (rtypemsg.isSuccess()) {\r
- _status = ST_REPORT;\r
- _process.successReport(this, repSIs);\r
- } else if (rtypemsg.isFailure()) {\r
- _status = ST_REPORT;\r
- _process.failReport(this, repSIs);\r
- } else if (rtypemsg.isAccounting()) {\r
- _status = ST_ACCT;\r
- _process.acctReport(this, repSIs);\r
- }\r
- }\r
-\r
- /**\r
- * Called when connection is closed\r
- * @param error Reason\r
- * @throws COPSPdpException\r
- */\r
- protected void processClosedConnection(COPSError error)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyClosedConnection(this, error);\r
-\r
- _status = ST_CCONN;\r
- }\r
-\r
- /**\r
- * Called when no keep-alive is received\r
- * @throws COPSPdpException\r
- */\r
- protected void processNoKAConnection()\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.notifyNoKAliveReceived(this);\r
-\r
- _status = ST_NOKA;\r
- }\r
-\r
- /**\r
- * Deletes the request state\r
- * @throws COPSPdpException\r
- */\r
- protected void finalizeRequestState()\r
- throws COPSPdpException {\r
- _sender.sendDeleteRequestState();\r
- _status = ST_FINAL;\r
- }\r
-\r
- /**\r
- * Asks for a COPS sync\r
- * @throws COPSPdpException\r
- */\r
- protected void syncRequestState()\r
- throws COPSPdpException {\r
- _sender.sendSyncRequestState();\r
- _status = ST_SYNC;\r
- }\r
-\r
- /**\r
- * Opens a new request state\r
- * @throws COPSPdpException\r
- */\r
- protected void openNewRequestState()\r
- throws COPSPdpException {\r
- _sender.sendOpenNewRequestState();\r
- _status = ST_NEW;\r
- }\r
-\r
- /**\r
- * Processes a COPS delete message\r
- * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP\r
- * @throws COPSPdpException\r
- */\r
- protected void processDeleteRequestState(COPSDeleteMsg dMsg)\r
- throws COPSPdpException {\r
- if (_process != null)\r
- _process.closeRequestState(this);\r
-\r
- _status = ST_DEL;\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpdp;
+
+import org.umu.cops.stack.*;
+
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * State manager class for provisioning requests, at the PDP side.
+ */
+public class COPSPdpReqStateMan {
+
+ /**
+ * Request State created
+ */
+ public final static short ST_CREATE = 1;
+ /**
+ * Request received
+ */
+ public final static short ST_INIT = 2;
+ /**
+ * Decisions sent
+ */
+ public final static short ST_DECS = 3;
+ /**
+ * Report received
+ */
+ public final static short ST_REPORT = 4;
+ /**
+ * Request State finalized
+ */
+ public final static short ST_FINAL = 5;
+ /**
+ * New Request State solicited
+ */
+ public final static short ST_NEW = 6;
+ /**
+ * Delete Request State solicited
+ */
+ public final static short ST_DEL = 7;
+ /**
+ * SYNC request sent
+ */
+ public final static short ST_SYNC = 8;
+ /**
+ * SYNC completed
+ */
+ public final static short ST_SYNCALL = 9;
+ /**
+ * Close connection received
+ */
+ public final static short ST_CCONN = 10;
+ /**
+ * Keep-alive timeout
+ */
+ public final static short ST_NOKA = 11;
+ /**
+ * Accounting timeout
+ */
+ public final static short ST_ACCT = 12;
+
+ /**
+ * COPS client-type that identifies the policy client
+ */
+ protected short _clientType;
+
+ /**
+ * COPS client handle used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected COPSHandle _handle;
+
+ /**
+ * Object for performing policy data processing
+ */
+ protected COPSPdpDataProcess _process;
+
+ /**
+ * Current state of the request being managed
+ */
+ protected short _status;
+
+ /** COPS message transceiver used to send COPS messages */
+ protected COPSPdpMsgSender _sender;
+
+ /**
+ * Creates a request state manager
+ * @param clientType Client-type
+ * @param clientHandle Client handle
+ */
+ public COPSPdpReqStateMan(short clientType, String clientHandle) {
+ _handle = new COPSHandle(new COPSData(clientHandle));
+ _clientType = clientType;
+ _status = ST_CREATE;
+ }
+
+ /**
+ * Gets the client handle
+ * @return Client's <tt>COPSHandle</tt>
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Gets the client-type
+ * @return Client-type value
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Gets the status of the request
+ * @return Request state value
+ */
+ public short getStatus() {
+ return _status;
+ }
+
+ /**
+ * Gets the policy data processing object
+ * @return Policy data processing object
+ */
+ public COPSPdpDataProcess getDataProcess() {
+ return _process;
+ }
+
+ /**
+ * Sets the policy data processing object
+ * @param process Policy data processing object
+ */
+ public void setDataProcess(COPSPdpDataProcess process) {
+ _process = process;
+ }
+
+ /**
+ * Called when COPS sync is completed
+ * @param repMsg COPS sync message
+ * @throws COPSPdpException
+ */
+ protected void processSyncComplete(COPSSyncStateMsg repMsg)
+ throws COPSPdpException {
+
+ _status = ST_SYNCALL;
+
+ // maybe we should notifySyncComplete ...
+ }
+
+ /**
+ * Initializes a new request state over a socket
+ * @param sock Socket to the PEP
+ * @throws COPSPdpException
+ */
+ protected void initRequestState(Socket sock)
+ throws COPSPdpException {
+ // Inits an object for sending COPS messages to the PEP
+ _sender = new COPSPdpMsgSender(_clientType, _handle, sock);
+
+ // Initial state
+ _status = ST_INIT;
+ }
+
+ /**
+ * Processes a COPS request
+ * @param msg COPS request received from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processRequest(COPSReqMsg msg)
+ throws COPSPdpException {
+
+ COPSHeader hdrmsg = msg.getHeader();
+ COPSHandle handlemsg = msg.getClientHandle();
+ COPSContext contextmsg = msg.getContext();
+
+ //** Analyze the request
+ //**
+
+ /* <Request> ::= <Common Header>
+ * <Client Handle>
+ * <Context>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI> ::= <*(<PRID> <EPD>)>
+ *
+ * Very important, this is actually being treated like this:
+ * <Named ClientSI> ::= <PRID> | <EPD>
+ *
+
+ // 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(final COPSReportMsg msg) throws COPSPdpException {
+
+ //** Analyze the report
+ //**
+
+ /*
+ * <Report State> ::= <Common Header>
+ * <Client Handle>
+ * <Report Type>
+ * *(<Named ClientSI>)
+ * [<Integrity>]
+ * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>
+ * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)
+ *
+ * Important, <Named ClientSI> is not parsed
+ */
+
+ // COPSHeader hdrmsg = msg.getHeader();
+ // COPSHandle handlemsg = msg.getClientHandle();
+
+ if (msg.getClientSI() != null) {
+ // Report Type
+ final COPSReportType rtypemsg = msg.getReport();
+
+ // Named ClientSI
+ // final Set<COPSClientSI> clientSIs = msg.getClientSI();
+ final Map<String, String> repSIs = new HashMap<>();
+ String strobjprid = "";
+ // for (final COPSClientSI clientSI : clientSIs) {
+ final COPSPrObjBase obj = new COPSPrObjBase(msg.getClientSI().getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ strobjprid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ repSIs.put(strobjprid, obj.getData().str());
+ // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
+ // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ // }
+
+ //** Here we must act in accordance with
+ //** the report received
+ switch (rtypemsg.getReportType()) {
+ case SUCCESS:
+ _status = ST_REPORT;
+ _process.successReport(this, repSIs);
+ break;
+ case FAILURE:
+ _status = ST_REPORT;
+ _process.failReport(this, repSIs);
+ break;
+ case ACCOUNTING:
+ _status = ST_ACCT;
+ _process.acctReport(this, repSIs);
+ break;
+ }
+ }
+
+
+ }
+
+ /**
+ * Called when connection is closed
+ * @param error Reason
+ * @throws COPSPdpException
+ */
+ protected void processClosedConnection(COPSError error)
+ throws COPSPdpException {
+ if (_process != null)
+ _process.notifyClosedConnection(this, error);
+
+ _status = ST_CCONN;
+ }
+
+ /**
+ * Called when no keep-alive is received
+ * @throws COPSPdpException
+ */
+ protected void processNoKAConnection()
+ throws COPSPdpException {
+ if (_process != null)
+ _process.notifyNoKAliveReceived(this);
+
+ _status = ST_NOKA;
+ }
+
+ /**
+ * Deletes the request state
+ * @throws COPSPdpException
+ */
+ protected void finalizeRequestState()
+ throws COPSPdpException {
+ _sender.sendDeleteRequestState();
+ _status = ST_FINAL;
+ }
+
+ /**
+ * Asks for a COPS sync
+ * @throws COPSPdpException
+ */
+ protected void syncRequestState()
+ throws COPSPdpException {
+ _sender.sendSyncRequestState();
+ _status = ST_SYNC;
+ }
+
+ /**
+ * Opens a new request state
+ * @throws COPSPdpException
+ */
+ protected void openNewRequestState()
+ throws COPSPdpException {
+ _sender.sendOpenNewRequestState();
+ _status = ST_NEW;
+ }
+
+ /**
+ * Processes a COPS delete message
+ * @param dMsg <tt>COPSDeleteMsg</tt> received from the PEP
+ * @throws COPSPdpException
+ */
+ protected void processDeleteRequestState(COPSDeleteMsg dMsg)
+ throws COPSPdpException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = ST_DEL;
+ }
+
+}
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpep;\r
-\r
-import java.io.IOException;\r
-import java.net.InetAddress;\r
-import java.net.Socket;\r
-import java.net.UnknownHostException;\r
-import java.util.Hashtable;\r
-\r
-import org.umu.cops.stack.COPSAcctTimer;\r
-import org.umu.cops.stack.COPSClientAcceptMsg;\r
-import org.umu.cops.stack.COPSClientCloseMsg;\r
-import org.umu.cops.stack.COPSClientOpenMsg;\r
-import org.umu.cops.stack.COPSData;\r
-import org.umu.cops.stack.COPSError;\r
-import org.umu.cops.stack.COPSException;\r
-import org.umu.cops.stack.COPSHeader;\r
-import org.umu.cops.stack.COPSKATimer;\r
-import org.umu.cops.stack.COPSMsg;\r
-import org.umu.cops.stack.COPSPepId;\r
-import org.umu.cops.stack.COPSTransceiver;\r
-\r
-/**\r
- * This is a provisioning COPS PEP. Responsible for making\r
- * connection to the PDP and maintaining it\r
- */\r
-public class COPSPepAgent {\r
-\r
- /**\r
- PEP's Identifier\r
- */\r
- private String _pepID;\r
-\r
- /**\r
- PEP's client-type\r
- */\r
- private short _clientType;\r
-\r
- /**\r
- PDP host name\r
- */\r
- private String _psHost;\r
-\r
- /**\r
- PDP port\r
- */\r
- private int _psPort;\r
-\r
- /**\r
- PEP-PDP connection manager\r
- */\r
- private COPSPepConnection _conn;\r
-\r
- /**\r
- COPS error returned by PDP\r
- */\r
- private COPSError _error;\r
-\r
- /**\r
- * Creates a PEP agent\r
- * @param pepID PEP-ID\r
- * @param clientType Client-type\r
- */\r
- public COPSPepAgent(String pepID, short clientType) {\r
- _pepID = pepID;\r
- _clientType = clientType;\r
- }\r
-\r
- /**\r
- * Creates a PEP agent with a PEP-ID equal to "noname"\r
- * @param clientType Client-type\r
- */\r
- public COPSPepAgent(short clientType) {\r
-\r
- // PEPId\r
- try {\r
- _pepID = InetAddress.getLocalHost().getHostName();\r
- } catch (Exception e) {\r
- _pepID = "noname";\r
- }\r
-\r
- _clientType = clientType;\r
- }\r
-\r
- /**\r
- * Gets the identifier of the PEP\r
- * @return PEP-ID\r
- */\r
- public String getPepID() {\r
- return _pepID;\r
- }\r
-\r
- /**\r
- * Gets the COPS client-type\r
- * @return PEP's client-type\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Gets PDP host name\r
- * @return PDP host name\r
- */\r
- public String getPDPName() {\r
- return _psHost;\r
- }\r
-\r
- /**\r
- * Gets the port of the PDP\r
- * @return PDP port\r
- */\r
- public int getPDPPort() {\r
- return _psPort;\r
- }\r
-\r
- /**\r
- * Connects to a PDP\r
- * @param psHost PDP host name\r
- * @param psPort PDP port\r
- * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise\r
- * @throws java.net.UnknownHostException\r
- * @throws java.io.IOException\r
- * @throws COPSException\r
- * @throws COPSPepException\r
- */\r
- public boolean connect(String psHost, int psPort)\r
- throws UnknownHostException, IOException, COPSException, COPSPepException {\r
-\r
- // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");\r
- _psHost = psHost;\r
- _psPort = psPort;\r
-\r
- // Check whether it already exists\r
- if (_conn == null)\r
- _conn = processConnection(psHost,psPort);\r
- else {\r
- // Check if it's closed\r
- if (_conn.isClosed()) {\r
- _conn = processConnection(psHost,psPort);\r
- } else {\r
- disconnect(null);\r
- _conn = processConnection(psHost,psPort);\r
- }\r
- }\r
-\r
- return (_conn != null);\r
- }\r
-\r
- /**\r
- * Gets the connection manager\r
- * @return PEP-PDP connection manager object\r
- */\r
- public COPSPepConnection getConnection () {\r
- return (_conn);\r
- }\r
-\r
- /**\r
- * Gets the COPS error returned by the PDP\r
- * @return <tt>COPSError</tt> returned by PDP\r
- */\r
- public COPSError getConnectionError() {\r
- return _error;\r
- }\r
-\r
- /**\r
- * Disconnects from the PDP\r
- * @param error Reason\r
- * @throws COPSException\r
- * @throws IOException\r
- */\r
- public void disconnect(COPSError error)\r
- throws COPSException, IOException {\r
-\r
- COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
- COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
- closeMsg.add(cHdr);\r
- if (error != null)\r
- closeMsg.add(error);\r
-\r
- closeMsg.writeData(_conn.getSocket());\r
- _conn.close();\r
- _conn = null;\r
- }\r
-\r
- /**\r
- * Adds a request state to the connection manager.\r
- * @return The newly created connection manager\r
- * @throws COPSPepException\r
- * @throws COPSException\r
- */\r
- public COPSPepReqStateMan addRequestState (String handle, COPSPepDataProcess process)\r
- throws COPSPepException, COPSException {\r
- if (_conn != null) {\r
- return _conn.addRequestState(handle, process);\r
- }\r
- return null;\r
- }\r
-\r
-\r
- /**\r
- * Queries the connection manager to delete a request state\r
- * @param man Request state manager\r
- * @throws COPSPepException\r
- * @throws COPSException\r
- */\r
- public void deleteRequestState (COPSPepReqStateMan man)\r
- throws COPSPepException, COPSException {\r
- if (_conn != null)\r
- _conn.deleteRequestState(man);\r
- }\r
-\r
- /**\r
- * Gets all the request state managers\r
- * @return A <tt>Hashtable</tt> holding all active request state managers\r
- */\r
- public Hashtable getReqStateMans() {\r
- if (_conn != null)\r
- return _conn.getReqStateMans();\r
- return null;\r
- }\r
-\r
- /**\r
- * Establish connection to PDP's IP address\r
- *\r
- * <Client-Open> ::= <Common Header>\r
- * <PEPID>\r
- * [<ClientSI>]\r
- * [<LastPDPAddr>]\r
- * [<Integrity>]\r
- *\r
- * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]\r
- *\r
- * <Client-Accept> ::= <Common Header>\r
- * <KA Timer>\r
- * [<ACCT Timer>]\r
- * [<Integrity>]\r
- *\r
- * Not send [<Integrity>]\r
- *\r
- * <Client-Close> ::= <Common Header>\r
- * <Error>\r
- * [<PDPRedirAddr>]\r
- * [<Integrity>]\r
- *\r
- * Not send [<PDPRedirAddr>], [<Integrity>]\r
- *\r
- * @throws UnknownHostException\r
- * @throws IOException\r
- * @throws COPSException\r
- * @throws COPSPepException\r
- *\r
- */\r
- private COPSPepConnection processConnection(String psHost, int psPort)\r
- throws UnknownHostException, IOException, COPSException, COPSPepException {\r
- // Build OPN\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);\r
-\r
- COPSPepId pepId = new COPSPepId();\r
- COPSData d = new COPSData(_pepID);\r
- pepId.setData(d);\r
-\r
- COPSClientOpenMsg msg = new COPSClientOpenMsg();\r
- msg.add(hdr);\r
- msg.add(pepId);\r
-\r
- // Create Socket and send OPN\r
- InetAddress addr = InetAddress.getByName(psHost);\r
- Socket socket = new Socket(addr,psPort);\r
- msg.writeData(socket);\r
-\r
- // Receive the response\r
- COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);\r
-\r
- if (recvmsg.getHeader().isAClientAccept()) {\r
- COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;\r
-\r
- // Support\r
- if (cMsg.getIntegrity() != null) {\r
- throw new COPSPepException("Unsupported object (Integrity)");\r
- }\r
-\r
- // Mandatory KATimer\r
- COPSKATimer kt = cMsg.getKATimer();\r
- if (kt == null)\r
- throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");\r
- short _kaTimeVal = kt.getTimerVal();\r
-\r
- // ACTimer\r
- COPSAcctTimer at = cMsg.getAcctTimer();\r
- short _acctTimer = 0;\r
- if (at != null)\r
- _acctTimer = at.getTimerVal();\r
-\r
- // Create the connection manager\r
- COPSPepConnection conn = new COPSPepConnection(_clientType, socket);\r
- conn.setKaTimer(_kaTimeVal);\r
- conn.setAcctTimer(_acctTimer);\r
- new Thread(conn).start();\r
-\r
- return conn;\r
- } else if (recvmsg.getHeader().isAClientClose()) {\r
- COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;\r
- _error = cMsg.getError();\r
- socket.close();\r
- return null;\r
- } else { // messages of other types are not expected\r
- throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+/**
+ * This is a provisioning COPS PEP. Responsible for making
+ * connection to the PDP and maintaining it
+ */
+public class COPSPepAgent {
+
+ /**
+ PEP's Identifier
+ */
+ private String _pepID;
+
+ /**
+ PEP's client-type
+ */
+ private short _clientType;
+
+ /**
+ PDP host name
+ */
+ private String _psHost;
+
+ /**
+ PDP port
+ */
+ private int _psPort;
+
+ /**
+ PEP-PDP connection manager
+ */
+ private COPSPepConnection _conn;
+
+ /**
+ COPS error returned by PDP
+ */
+ private COPSError _error;
+
+ /**
+ * Creates a PEP agent
+ * @param pepID PEP-ID
+ * @param clientType Client-type
+ */
+ public COPSPepAgent(final String pepID, final short clientType) {
+ _pepID = pepID;
+ _clientType = clientType;
+ }
+
+ /**
+ * Creates a PEP agent with a PEP-ID equal to "noname"
+ * @param clientType Client-type
+ */
+ public COPSPepAgent(final short clientType) {
+
+ // PEPId
+ try {
+ _pepID = InetAddress.getLocalHost().getHostName();
+ } catch (Exception e) {
+ _pepID = "noname";
+ }
+
+ _clientType = clientType;
+ }
+
+ /**
+ * Gets the identifier of the PEP
+ * @return PEP-ID
+ */
+ public String getPepID() {
+ return _pepID;
+ }
+
+ /**
+ * Gets the COPS client-type
+ * @return PEP's client-type
+ */
+ public short getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Gets PDP host name
+ * @return PDP host name
+ */
+ public String getPDPName() {
+ return _psHost;
+ }
+
+ /**
+ * Gets the port of the PDP
+ * @return PDP port
+ */
+ public int getPDPPort() {
+ return _psPort;
+ }
+
+ /**
+ * Connects to a PDP
+ * @param psHost PDP host name
+ * @param psPort PDP port
+ * @return <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise
+ * @throws java.io.IOException
+ * @throws COPSException
+ * @throws COPSPepException
+ */
+ public boolean connect(String psHost, int psPort) throws IOException, COPSException, COPSPepException {
+
+ // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");
+ _psHost = psHost;
+ _psPort = psPort;
+
+ // Check whether it already exists
+ if (_conn == null)
+ _conn = processConnection(psHost,psPort);
+ else {
+ // Check if it's closed
+ if (_conn.isClosed()) {
+ _conn = processConnection(psHost,psPort);
+ } else {
+ disconnect(null);
+ _conn = processConnection(psHost,psPort);
+ }
+ }
+
+ return (_conn != null);
+ }
+
+ /**
+ * Gets the connection manager
+ * @return PEP-PDP connection manager object
+ */
+ public COPSPepConnection getConnection () {
+ return (_conn);
+ }
+
+ /**
+ * Gets the COPS error returned by the PDP
+ * @return <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(final COPSError error) throws COPSException, IOException {
+ final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
+ closeMsg.writeData(_conn.getSocket());
+ _conn.close();
+ }
+
+ /**
+ * Adds a request state to the connection manager.
+ * @return The newly created connection manager
+ * @throws COPSPepException
+ * @throws COPSException
+ */
+ public COPSPepReqStateMan addRequestState(final String handle, final COPSPepDataProcess process)
+ throws COPSPepException, COPSException {
+ if (_conn != null) {
+ return _conn.addRequestState(handle, process);
+ }
+ return null;
+ }
+
+
+ /**
+ * Queries the connection manager to delete a request state
+ * @param man Request state manager
+ * @throws COPSPepException
+ * @throws COPSException
+ */
+ public void deleteRequestState(final COPSPepReqStateMan man)
+ throws COPSPepException, COPSException {
+ if (_conn != null)
+ _conn.deleteRequestState(man);
+ }
+
+ /**
+ * Establish connection to PDP's IP address
+ *
+ * <Client-Open> ::= <Common Header>
+ * <PEPID>
+ * [<ClientSI>]
+ * [<LastPDPAddr>]
+ * [<Integrity>]
+ *
+ * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]
+ *
+ * <Client-Accept> ::= <Common Header>
+ * <KA Timer>
+ * [<ACCT Timer>]
+ * [<Integrity>]
+ *
+ * Not send [<Integrity>]
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<PDPRedirAddr>]
+ * [<Integrity>]
+ *
+ * Not send [<PDPRedirAddr>], [<Integrity>]
+ *
+ * @throws UnknownHostException
+ * @throws IOException
+ * @throws COPSException
+ * @throws COPSPepException
+ *
+ */
+ private COPSPepConnection processConnection(String psHost, int psPort)
+ throws IOException, COPSException, COPSPepException {
+ // Build OPN
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(_clientType, new COPSPepId(new COPSData(_pepID)),
+ null, null, null);
+
+ // Create Socket and send OPN
+ final InetAddress addr = InetAddress.getByName(psHost);
+ final Socket socket = new Socket(addr,psPort);
+ msg.writeData(socket);
+
+ // Receive the response
+ final COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
+
+ if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
+ final COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
+
+ // Support
+ if (cMsg.getIntegrity() != null) {
+ throw new COPSPepException("Unsupported object (Integrity)");
+ }
+
+ // Mandatory KATimer
+ final COPSKATimer kt = cMsg.getKATimer();
+ if (kt == null)
+ throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");
+ short _kaTimeVal = kt.getTimerVal();
+
+ // ACTimer
+ final COPSAcctTimer at = cMsg.getAcctTimer();
+ short _acctTimer = 0;
+ if (at != null)
+ _acctTimer = at.getTimerVal();
+
+ // Create the connection manager
+ final COPSPepConnection conn = new COPSPepConnection(_clientType, socket);
+ conn.setKaTimer(_kaTimeVal);
+ conn.setAcctTimer(_acctTimer);
+ new Thread(conn).start();
+
+ return conn;
+ } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
+ final COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
+ _error = cMsg.getError();
+ socket.close();
+ return null;
+ } else { // messages of other types are not expected
+ throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
+ }
+ }
+}
+
+
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSHeader.OPCode;
import java.io.IOException;
import java.net.Socket;
-import java.util.*;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
*/
protected Date _lastRecKa;
- /**
- Opcode of the latest message sent
- */
- protected byte _lastmessage;
-
/**
Maps a COPS Client Handle to a Request State Manager
*/
protected final Map<String, COPSPepReqStateMan> _managerMap;
- // map < String(COPSHandle), COPSPepReqStateMan>;
/**
COPS error returned by PDP
* @param clientType PEP's client-type
* @param sock Socket connected to PDP
*/
- public COPSPepConnection(short clientType, Socket sock) {
+ public COPSPepConnection(final short clientType, final Socket sock) {
_clientType = clientType;
_sock = sock;
_acctTimer = 0;
_kaTimer = 0;
_responseTime = 10000;
- _lastmessage = COPSHeader.COPS_OP_CAT;
-
_managerMap = new ConcurrentHashMap<>();
}
return _acctTimer;
}
- /**
- * Gets all request state managers
- * @return A <tt>Hashatable</tt> holding all request state managers
- */
- protected Hashtable getReqStateMans() {
- return new Hashtable(_managerMap);
- }
-
/**
* Checks whether the socket to the PDP is closed or not
* @return <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise
_sock.close();
}
- /**
- * Gets the opcode of the lastest message sent
- * @return Message opcode
- */
- public byte getLastmessage() {
- return _lastmessage;
- }
-
/**
* Sets response time
* @param respTime Response time value (msecs)
try {
while (!_sock.isClosed()) {
if (_sock.getInputStream().available() != 0) {
- _lastmessage = processMessage(_sock);
+ processMessage(_sock);
_lastRecKa = new Date();
}
cTime = (int) (new Date().getTime());
if ((cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);
- COPSKAMsg msg = new COPSKAMsg();
-
- msg.add(hdr);
-
+ final COPSKAMsg msg = new COPSKAMsg(null);
COPSTransceiver.sendMsg(msg, _sock);
_lastSendKa = new Date();
}
* @throws COPSException
* @throws IOException
*/
- protected byte processMessage(Socket conn)
- throws COPSPepException, COPSException, IOException {
- COPSMsg msg = COPSTransceiver.receiveMsg(conn);
-
- if (msg.getHeader().isAClientClose()) {
- handleClientCloseMsg(conn, msg);
- return COPSHeader.COPS_OP_CC;
- } else if (msg.getHeader().isADecision()) {
- handleDecisionMsg(conn, msg);
- return COPSHeader.COPS_OP_DEC;
- } else if (msg.getHeader().isASyncStateReq()) {
- handleSyncStateReqMsg(conn, msg);
- return COPSHeader.COPS_OP_SSQ;
- } else if (msg.getHeader().isAKeepAlive()) {
- handleKeepAliveMsg(conn, msg);
- return COPSHeader.COPS_OP_KA;
- } else {
- throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");
+ protected byte processMessage(final Socket conn) throws COPSPepException, COPSException, IOException {
+ final COPSMsg msg = COPSTransceiver.receiveMsg(conn);
+
+ switch (msg.getHeader().getOpCode()) {
+ case CC:
+ handleClientCloseMsg(conn, msg);
+ return (byte)OPCode.CC.ordinal();
+ case DEC:
+ handleDecisionMsg(conn, msg);
+ return (byte)OPCode.DEC.ordinal();
+ case SSQ:
+ handleSyncStateReqMsg(conn, msg);
+ return (byte)OPCode.SSQ.ordinal();
+ case KA:
+ handleKeepAliveMsg(conn, msg);
+ return (byte)OPCode.KA.ordinal();
+ default:
+ throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");
}
}
* @param msg a COPSMsg
*
*/
- private void handleDecisionMsg(Socket conn, COPSMsg msg)
- throws COPSPepException {
- COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;
- COPSHandle handle = dMsg.getClientHandle();
- Hashtable decisions = dMsg.getDecisions();
-
- for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {
-
- COPSContext context = (COPSContext) e.nextElement();
- Vector v = (Vector) decisions.get(context);
-
- Enumeration ee = v.elements();
- if (ee.hasMoreElements()) {
- COPSDecision decision = (COPSDecision) ee.nextElement();
+ private void handleDecisionMsg(final Socket conn, final COPSMsg msg) throws COPSPepException {
+ final COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;
+ final COPSHandle handle = dMsg.getClientHandle();
+ final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
+ for (final Set<COPSDecision> copsDecisions: decisions.values()) {
+ for (final COPSDecision decision : copsDecisions) {
// Get the associated manager
- COPSPepReqStateMan manager = _managerMap.get(handle.getId().str());
+ final COPSPepReqStateMan manager = _managerMap.get(handle.getId().str());
if (manager == null)
logger.warn("Unable to find state manager with key - " + handle.getId().str());
// Check message type
- if (decision.getFlags() == COPSDecision.F_REQSTATE) {
- if (decision.isRemoveDecision())
+ // TODO FIXME - Use of manager object could result in a NPE
+ if (decision.getFlag().equals(DecisionFlag.REQSTATE)) {
+ if (decision.getCommand().equals(Command.REMOVE))
// Delete Request State
manager.processDeleteRequestState(dMsg);
else
* @param handle a COPSHandle
*
*/
- private void handleOpenNewRequestStateMsg(Socket conn, COPSHandle handle)
- throws COPSPepException {
+ private void handleOpenNewRequestStateMsg(Socket conn, COPSHandle handle) throws COPSPepException {
COPSPepReqStateMan manager = _managerMap.get(handle.getId().str());
if (manager == null)
logger.warn("Unable to find state manager with key - " + handle.getId().str());
+ // TODO FIXME - Use of manager object could result in a NPE
manager.processOpenNewRequestState();
}
* @param msg a COPSMsg
*
*/
- private void handleSyncStateReqMsg(Socket conn, COPSMsg msg)
- throws COPSPepException {
+ private void handleSyncStateReqMsg(Socket conn, COPSMsg msg) throws COPSPepException {
COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
- // COPSHandle handle = cMsg.getClientHandle();
- // COPSHeader header = cMsg.getHeader();
// Support
if (cMsg.getIntegrity() != null) {
logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
}
- COPSPepReqStateMan manager = (COPSPepReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
+ COPSPepReqStateMan manager = _managerMap.get(cMsg.getClientHandle().getId().str());
if (manager == null) {
logger.warn("Unable to find state manager with key - " + cMsg.getClientHandle().getId().str());
} else {
* @throws COPSPepException
*
*/
- protected COPSPepReqStateMan addRequestState(String clientHandle, COPSPepDataProcess process)
- throws COPSException, COPSPepException {
- COPSPepReqStateMan manager = new COPSPepReqStateMan(_clientType,clientHandle);
+ protected COPSPepReqStateMan addRequestState(String clientHandle, COPSPepDataProcess process) throws COPSException,
+ COPSPepException {
+ COPSPepReqStateMan manager = new COPSPepReqStateMan(_clientType, clientHandle);
if (_managerMap.get(clientHandle) != null)
throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);
* @throws COPSPepException
*
*/
- protected void deleteRequestState(COPSPepReqStateMan manager)
- throws COPSException, COPSPepException {
+ protected void deleteRequestState(COPSPepReqStateMan manager) throws COPSException, COPSPepException {
manager.finalizeRequestState();
}
package org.umu.cops.prpep;
-import java.util.Hashtable;
-
import org.umu.cops.stack.COPSError;
+import java.util.Map;
+
/**
* COPSPepDataProcess process policy data and events.
*
/**
* Establish PDP decisions
*
- * @param removeDecs
- * @param installDecs
- * @param errorDecs
+ * @param man - the state manager
+ * @param removeDecs - the remove decisions
+ * @param installDecs - the install decisions
+ * @param errorDecs - the error decisions
*/
- public abstract void setDecisions(COPSPepReqStateMan man, Hashtable removeDecs, Hashtable installDecs, Hashtable errorDecs);
+ public abstract void setDecisions(COPSPepReqStateMan man, Map<String, String> removeDecs,
+ Map<String, String> installDecs, Map<String, String> errorDecs);
/**
* If the report is fail, return true
*
- * @return
+ * @return - t/f
*/
public abstract boolean isFailReport(COPSPepReqStateMan man);
/**
* Return Report Data
*
- * @return
+ * @return - the report data
*/
- public abstract Hashtable getReportData(COPSPepReqStateMan man);
+ public abstract Map<String, String> getReportData(COPSPepReqStateMan man);
/**
* Return Client Data
*
- * @return
+ * @return - the client data
*/
- public abstract Hashtable getClientData(COPSPepReqStateMan man);
+ public abstract Map<String, String> getClientData(COPSPepReqStateMan man);
/**
- * Return Accouting Data
+ * Return Accounting Data
*
- * @return
+ * @return - the accounting data
*/
- public abstract Hashtable getAcctData(COPSPepReqStateMan man);
+ public abstract Map<String, String> getAcctData(COPSPepReqStateMan man);
/**
* Notify the connection closed
- *
- * @param error
*/
- public abstract void notifyClosedConnection (COPSPepReqStateMan man, COPSError error);
+ public abstract void notifyClosedConnection(COPSPepReqStateMan man, COPSError error);
/**
* Notify the KAlive timeout
*/
- public abstract void notifyNoKAliveReceived (COPSPepReqStateMan man);
+ public abstract void notifyNoKAliveReceived(COPSPepReqStateMan man);
/**
* Process a PDP request to close a Request State
/**
* Process a PDP request to open a new Request State
*
- * @param man
+ * @param man Request State Manager
*/
public abstract void newRequestState(COPSPepReqStateMan man);
}
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpep;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-\r
-import org.umu.cops.stack.COPSClientSI;\r
-import org.umu.cops.stack.COPSContext;\r
-import org.umu.cops.stack.COPSData;\r
-import org.umu.cops.stack.COPSDeleteMsg;\r
-import org.umu.cops.stack.COPSException;\r
-import org.umu.cops.stack.COPSHandle;\r
-import org.umu.cops.stack.COPSHeader;\r
-import org.umu.cops.stack.COPSPrEPD;\r
-import org.umu.cops.stack.COPSPrID;\r
-import org.umu.cops.stack.COPSReason;\r
-import org.umu.cops.stack.COPSReportMsg;\r
-import org.umu.cops.stack.COPSReportType;\r
-import org.umu.cops.stack.COPSReqMsg;\r
-import org.umu.cops.stack.COPSSyncStateMsg;\r
-\r
-/**\r
- * COPSPepMsgSender sends COPS messages to PDP.\r
- *\r
- * @version COPSPepMsgSender.java, v 2.00 2004\r
- *\r
- */\r
-public class COPSPepMsgSender {\r
-\r
- /**\r
- * Socket connection to PDP\r
- */\r
- protected Socket _sock;\r
-\r
- /**\r
- * The client-type identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * The client handle is used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- * Create a COPSPepMsgSender\r
- *\r
- * @param clientType client-type\r
- * @param clientHandle client handle\r
- * @param sock socket of PDP connection\r
- */\r
- public COPSPepMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {\r
- // COPS Handle\r
- _handle = clientHandle;\r
- _clientType = clientType;\r
-\r
- _sock = sock;\r
- }\r
-\r
- /**\r
- * Return client handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Return client-type\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Send Request to PDP.\r
- * The PEP establishes a request state client handle for which the\r
- * remote PDP may maintain state.\r
- *\r
- * @param clientSIs a Hashtable\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- public void sendRequest(Hashtable clientSIs)\r
- throws COPSPepException {\r
- // Create COPS Message\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_REQ, _clientType);\r
- COPSContext cntxt = new COPSContext(COPSContext.CONFIG , (short) 0);\r
-\r
- COPSHandle handle = _handle;\r
-\r
- // Add the clientSIs\r
- COPSReqMsg msg = new COPSReqMsg();\r
- try {\r
- msg.add(hdr) ;\r
- msg.add(handle) ;\r
- msg.add(cntxt) ;\r
-\r
- if (clientSIs.size() > 0) {\r
- for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) clientSIs.get(strprid);\r
-\r
- // (PRID)\r
- COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
-\r
- // (EPD)\r
- COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- msg.add(cSi);\r
- msg.add(cSi2);\r
- }\r
- }\r
-\r
- } catch (COPSException e) {\r
- throw new COPSPepException("Error making Request Msg, reason: " + e.getMessage());\r
- }\r
-\r
- // Send message\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Send Fail Report to PDP.\r
- * The RPT message is used by the PEP to communicate to the PDP its\r
- * success or failure in carrying out the PDP's decision, or to report\r
- * an accounting related change in state.\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- public void sendFailReport(Hashtable clientSIs)\r
- throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report FAIL\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.FAILURE);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
- if (clientSIs.size() > 0) {\r
- for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) clientSIs.get(strprid);\r
-\r
- // (PRID)\r
- COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
-\r
- // (EPD)\r
- COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- msg.add(cSi);\r
- msg.add(cSi2);\r
- }\r
- }\r
-\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Send Succes Report to PDP.\r
- * The RPT message is used by the PEP to communicate to the PDP its\r
- * success or failure in carrying out the PDP's decision, or to report\r
- * an accounting related change in state.\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- public void sendSuccessReport(Hashtable clientSIs)\r
- throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report SUCESS\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.SUCCESS);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
-\r
- if (clientSIs.size() > 0) {\r
- for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) clientSIs.get(strprid);\r
-\r
- // (PRID)\r
- COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
-\r
- // (EPD)\r
- COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- msg.add(cSi);\r
- msg.add(cSi2);\r
- }\r
- }\r
-\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- public void sendAcctReport(Hashtable clientSIs)\r
- throws COPSPepException {\r
- COPSReportMsg msg = new COPSReportMsg();\r
- // Report SUCESS\r
- try {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_RPT, _clientType);\r
- COPSHandle hnd = _handle;\r
-\r
- COPSReportType report = new COPSReportType(COPSReportType.ACCT);\r
-\r
- msg.add(hdr);\r
- msg.add(hnd);\r
- msg.add(report);\r
-\r
- if (clientSIs.size() > 0) {\r
- for (Enumeration e = clientSIs.keys() ; e.hasMoreElements() ;) {\r
- String strprid = (String) e.nextElement();\r
- String strepd = (String) clientSIs.get(strprid);\r
-\r
- // (PRID)\r
- COPSClientSI cSi = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrID prid = new COPSPrID();\r
- prid.setData(new COPSData(strprid));\r
- cSi.setData(new COPSData(prid.getDataRep(), 0, prid.getDataLength()));\r
-\r
- // (EPD)\r
- COPSClientSI cSi2 = new COPSClientSI(COPSClientSI.CSI_NAMED);\r
- COPSPrEPD epd = new COPSPrEPD();\r
- epd.setData(new COPSData(strepd));\r
- cSi2.setData(new COPSData(epd.getDataRep(), 0, epd.getDataLength()));\r
-\r
- msg.add(cSi);\r
- msg.add(cSi2);\r
- }\r
- }\r
-\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Send Sync State Complete to PDP.\r
- * The Synchronize State Complete is sent by the PEP to the PDP after\r
- * the PDP sends a synchronize state request to the PEP and the PEP has\r
- * finished synchronization.\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- public void sendSyncComplete()\r
- throws COPSPepException {\r
- // Common Header with the same ClientType as the request\r
- COPSHeader hdr = new COPSHeader (COPSHeader.COPS_OP_SSC, _clientType);\r
-\r
- // Client Handle with the same clientHandle as the request\r
- COPSHandle clienthandle = _handle;\r
-\r
- COPSSyncStateMsg msg = new COPSSyncStateMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(clienthandle);\r
- } catch (Exception e) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
-\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());\r
- }\r
- }\r
-\r
- /**\r
- * Send Delete Request to PDP.\r
- * When sent from the PEP this message indicates to the remote PDP that\r
- * the state identified by the client handle is no longer\r
- * available/relevant.\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- public void sendDeleteRequest()\r
- throws COPSPepException {\r
- COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DRQ, _clientType);\r
- COPSHandle handle = _handle;\r
-\r
- // *** TODO: send a real reason\r
- COPSReason reason = new COPSReason((short) 234, (short) 345);\r
-\r
- COPSDeleteMsg msg = new COPSDeleteMsg();\r
- try {\r
- msg.add(hdr);\r
- msg.add(handle);\r
- msg.add(reason);\r
- } catch (COPSException ex) {\r
- throw new COPSPepException("Error making Msg");\r
- }\r
- try {\r
- msg.writeData(_sock);\r
- } catch (IOException e) {\r
- throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import org.umu.cops.stack.*;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSReason.ReasonCode;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * COPSPepMsgSender sends COPS messages to PDP.
+ *
+ * @version COPSPepMsgSender.java, v 2.00 2004
+ *
+ */
+public class COPSPepMsgSender {
+
+ /**
+ * Socket connection to PDP
+ */
+ protected Socket _sock;
+
+ /**
+ * The client-type identifies the policy client
+ */
+ protected short _clientType;
+
+ /**
+ * The client handle is used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected COPSHandle _handle;
+
+ /**
+ * Create a COPSPepMsgSender
+ *
+ * @param clientType client-type
+ * @param clientHandle client handle
+ * @param sock socket of PDP connection
+ */
+ public COPSPepMsgSender (short clientType, COPSHandle clientHandle, Socket sock) {
+ // COPS Handle
+ _handle = clientHandle;
+ _clientType = clientType;
+
+ _sock = sock;
+ }
+
+ /**
+ * Return client handle
+ *
+ * @return a COPSHandle
+ *
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Return client-type
+ *
+ * @return a short
+ *
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Send Request to PDP.
+ * The PEP establishes a request state client handle for which the
+ * remote PDP may maintain state.
+ *
+ * @param clientSIs a Hashtable
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void sendRequest(final Map<String, String> clientSIs) throws COPSPepException {
+ final Set<COPSClientSI> clientSISet = new HashSet<>();
+ // Add the clientSIs
+ for (final Map.Entry<String, String> entry : clientSIs.entrySet()) {
+ // (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+ clientSISet.add(new COPSClientSI(CSIType.NAMED, new COPSData(prid.getDataRep(), 0, prid.getDataLength())));
+
+ // (EPD)
+ final COPSPrEPD epd = new COPSPrEPD();
+ epd.setData(new COPSData(entry.getValue()));
+ clientSISet.add(new COPSClientSI(CSIType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())));
+ }
+ final COPSReqMsg msg = new COPSReqMsg(_clientType, _handle, new COPSContext(RType.CONFIG, (short)0),
+ null, null, null, clientSISet, null);
+
+ // Send message
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the request, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Send Fail Report to PDP.
+ * The RPT message is used by the PEP to communicate to the PDP its
+ * success or failure in carrying out the PDP's decision, or to report
+ * an accounting related change in state.
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void sendFailReport(final Map<String, String> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.FAILURE));
+ }
+
+ /**
+ * Send Succes Report to PDP.
+ * The RPT message is used by the PEP to communicate to the PDP its
+ * success or failure in carrying out the PDP's decision, or to report
+ * an accounting related change in state.
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void sendSuccessReport(final Map<String, String> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.SUCCESS));
+ }
+
+ public void sendAcctReport(final Map<String, String> clientSIs) throws COPSPepException {
+ sendReport(clientSIs, new COPSReportType(ReportType.ACCOUNTING));
+ }
+
+ private void sendReport(final Map<String, String> clientSIs, final COPSReportType reportType)
+ throws COPSPepException {
+ // Report SUCESS
+ for (final Map.Entry<String, String> entry : clientSIs.entrySet()) {
+ // (PRID)
+ final COPSPrID prid = new COPSPrID();
+ prid.setData(new COPSData(entry.getKey()));
+
+ final COPSReportMsg pridMsg = new COPSReportMsg(_clientType, _handle, reportType,
+ new COPSClientSI(CSIType.NAMED, new COPSData(prid.getDataRep(), 0, prid.getDataLength())), null);
+ try {
+ pridMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());
+ }
+
+ // (EPD)
+ final COPSPrEPD epd = new COPSPrEPD();
+ epd.setData(new COPSData(entry.getValue()));
+ final COPSReportMsg epdMsg = new COPSReportMsg(_clientType, _handle, reportType,
+ new COPSClientSI(CSIType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())), null);
+ try {
+ pridMsg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the report, reason: " + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Send Sync State Complete to PDP.
+ * The Synchronize State Complete is sent by the PEP to the PDP after
+ * the PDP sends a synchronize state request to the PEP and the PEP has
+ * finished synchronization.
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void sendSyncComplete() throws COPSPepException {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(_clientType, _handle, null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the sync state request, reason: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Send Delete Request to PDP.
+ * When sent from the PEP this message indicates to the remote PDP that
+ * the state identified by the client handle is no longer
+ * available/relevant.
+ *
+ * @throws COPSPepException
+ *
+ */
+ public void sendDeleteRequest() throws COPSPepException {
+ // *** TODO: send a real reason
+ final COPSReason reason = new COPSReason(ReasonCode.UNSPECIFIED, ReasonCode.NA);
+ final COPSDeleteMsg msg = new COPSDeleteMsg(_clientType, _handle, reason, null);
+ try {
+ msg.writeData(_sock);
+ } catch (IOException e) {
+ throw new COPSPepException("Failed to send the delete request, reason: " + e.getMessage());
+ }
+ }
+}
+
+
+
+
-/*\r
- * Copyright (c) 2004 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.prpep;\r
-\r
-import org.umu.cops.stack.*;\r
-\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-\r
-/**\r
- * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)\r
- * in PEP.\r
- *\r
- * The client handle is used to identify a unique request state for a\r
- * single PEP per client-type. Client handles are chosen by the PEP and\r
- * are opaque to the PDP. The PDP simply uses the request handle to\r
- * uniquely identify the request state for a particular Client-Type over\r
- * a particular TCP connection and generically tie its decisions to a\r
- * corresponding request. Client handles are initiated in request\r
- * messages and are then used by subsequent request, decision, and\r
- * report messages to reference the same request state. When the PEP is\r
- * ready to remove a local request state, it will issue a delete message\r
- * to the PDP for the corresponding client handle. A handle MUST be\r
- * explicitly deleted by the PEP before it can be used by the PEP to\r
- * identify a new request state. Handles referring to different request\r
- * states MUST be unique within the context of a particular TCP\r
- * connection and client-type.\r
- *\r
- * @version COPSPepReqStateMan.java, v 2.00 2004\r
- *\r
- */\r
-public class COPSPepReqStateMan {\r
-\r
- /**\r
- * Request State created\r
- */\r
- public final static short ST_CREATE = 1;\r
- /**\r
- * Request sent\r
- */\r
- public final static short ST_INIT = 2;\r
- /**\r
- * Decisions received\r
- */\r
- public final static short ST_DECS = 3;\r
- /**\r
- * Report sent\r
- */\r
- public final static short ST_REPORT = 4;\r
- /**\r
- * Request State finalized\r
- */\r
- public final static short ST_FINAL = 5;\r
- /**\r
- * New Request State solicited\r
- */\r
- public final static short ST_NEW = 6;\r
- /**\r
- * Delete Request State solicited\r
- */\r
- public final static short ST_DEL = 7;\r
- /**\r
- * SYNC Request received\r
- */\r
- public final static short ST_SYNC = 8;\r
- /**\r
- * SYNC Completed\r
- */\r
- public final static short ST_SYNCALL = 9;\r
- /**\r
- * Close Connection received\r
- */\r
- public final static short ST_CCONN = 10;\r
- /**\r
- * KAlive Time out\r
- */\r
- public final static short ST_NOKA = 11;\r
- /**\r
- * ACCT Time out\r
- */\r
- public final static short ST_ACCT = 12;\r
-\r
- /**\r
- * The client-type identifies the policy client\r
- */\r
- protected short _clientType;\r
-\r
- /**\r
- * The client handle is used to uniquely identify a particular\r
- * PEP's request for a client-type\r
- */\r
- protected COPSHandle _handle;\r
-\r
- /**\r
- The PolicyDataProcess is used to process policy data in the PEP\r
- */\r
- protected COPSPepDataProcess _process;\r
-\r
- /**\r
- * State Request State\r
- */\r
- protected short _status;\r
-\r
- /**\r
- The Msg Sender is used to send COPS messages\r
- */\r
- protected COPSPepMsgSender _sender;\r
-\r
- /**\r
- * Sync State\r
- */\r
- protected boolean _syncState;\r
-\r
- /**\r
- * Create a State Request Manager\r
- *\r
- * @param clientHandle a Client Handle\r
- *\r
- */\r
- public COPSPepReqStateMan(short clientType, String clientHandle) {\r
- _handle = new COPSHandle(new COPSData(clientHandle));\r
- _clientType = clientType;\r
- _syncState = true;\r
- _status = ST_CREATE;\r
- }\r
-\r
- /**\r
- * Return client handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _handle;\r
- }\r
-\r
- /**\r
- * Return client-type\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getClientType() {\r
- return _clientType;\r
- }\r
-\r
- /**\r
- * Return Request State status\r
- *\r
- * @return s short\r
- */\r
- public short getStatus() {\r
- return _status;\r
- }\r
-\r
- /**\r
- * Return the Policy Data Process\r
- *\r
- * @return a PolicyConfigure\r
- *\r
- */\r
- public COPSPepDataProcess getDataProcess() {\r
- return _process;\r
- }\r
-\r
- /**\r
- * Establish the Policy Data Process\r
- *\r
- * @param process a PolicyConfigure\r
- *\r
- */\r
- public void setDataProcess(COPSPepDataProcess process) {\r
- _process = process;\r
- }\r
-\r
- /**\r
- * Init Request State\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void initRequestState(Socket sock)\r
- throws COPSPepException {\r
- // Inits an object for sending COPS messages to the PDP\r
- _sender = new COPSPepMsgSender(_clientType, _handle, sock);\r
-\r
- // If an object for retrieving PEP features exists,\r
- // use it for retrieving them\r
- Hashtable clientSIs;\r
- if (_process != null)\r
- clientSIs = _process.getClientData(this);\r
- else\r
- clientSIs = null;\r
-\r
- // Send the request\r
- _sender.sendRequest(clientSIs);\r
-\r
- // Initial state\r
- _status = ST_INIT;\r
- }\r
-\r
- /**\r
- * Finalize Request State\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void finalizeRequestState()\r
- throws COPSPepException {\r
- _sender.sendDeleteRequest();\r
- _status = ST_FINAL;\r
- }\r
-\r
- /**\r
- * Process the message Decision\r
- *\r
- * @param dMsg a COPSDecisionMsg\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void processDecision(COPSDecisionMsg dMsg)\r
- throws COPSPepException {\r
- // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
-\r
- // COPSHandle handle = dMsg.getClientHandle();\r
- Hashtable decisions = dMsg.getDecisions();\r
-\r
- Hashtable removeDecs = new Hashtable(40);\r
- Hashtable installDecs = new Hashtable(40);\r
- Hashtable errorDecs = new Hashtable(40);\r
- for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) decisions.get(context);\r
- Enumeration ee = v.elements();\r
- COPSDecision cmddecision = (COPSDecision) ee.nextElement();\r
-\r
- // cmddecision --> we must check whether it is an error!\r
-\r
- if (cmddecision.isInstallDecision()) {\r
- String prid = new String();\r
- for (; ee.hasMoreElements() ;) {\r
- COPSDecision decision = (COPSDecision) ee.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
- switch (obj.getSNum()) {\r
- case COPSPrObjBase.PR_PRID:\r
- prid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- installDecs.put(prid, obj.getData().str());\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
-\r
- if (cmddecision.isRemoveDecision()) {\r
-\r
- String prid = new String();\r
- for (; ee.hasMoreElements() ;) {\r
- COPSDecision decision = (COPSDecision) ee.nextElement();\r
-\r
- COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
- switch (obj.getSNum()) {\r
- case COPSPrObjBase.PR_PRID:\r
- prid = obj.getData().str();\r
- break;\r
- case COPSPrObjBase.PR_EPD:\r
- removeDecs.put(prid, obj.getData().str());\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- //** Apply decisions to the configuration\r
- _process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
- _status = ST_DECS;\r
-\r
-\r
- if (_process.isFailReport(this)) {\r
- // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
- _sender.sendFailReport(_process.getReportData(this));\r
- } else {\r
- // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
- _sender.sendSuccessReport(_process.getReportData(this));\r
- }\r
- _status = ST_REPORT;\r
-\r
- if (!_syncState) {\r
- _sender.sendSyncComplete();\r
- _syncState = true;\r
- _status = ST_SYNCALL;\r
- }\r
- }\r
-\r
- /**\r
- * Process the message NewRequestState\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void processOpenNewRequestState()\r
- throws COPSPepException {\r
-\r
- if (_process != null)\r
- _process.newRequestState(this);\r
-\r
- _status = ST_NEW;\r
- }\r
-\r
- /**\r
- * Process the message DeleteRequestState\r
- *\r
- * @param dMsg a COPSDecisionMsg\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void processDeleteRequestState(COPSDecisionMsg dMsg)\r
- throws COPSPepException {\r
- if (_process != null)\r
- _process.closeRequestState(this);\r
-\r
- _status = ST_DEL;\r
- }\r
-\r
- /**\r
- * Process the message SycnStateRequest.\r
- * The message SycnStateRequest indicates that the remote PDP\r
- * wishes the client (which appears in the common header)\r
- * to re-send its state.\r
- *\r
- * @param ssMsg a COPSSyncStateMsg\r
- *\r
- * @throws COPSPepException\r
- *\r
- */\r
- protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)\r
- throws COPSPepException {\r
- _syncState = false;\r
- // If an object for retrieving PEP features exists,\r
- // use it for retrieving them\r
- Hashtable clientSIs;\r
- if (_process != null)\r
- clientSIs = _process.getClientData(this);\r
- else\r
- clientSIs = null;\r
-\r
- // Send request\r
- _sender.sendRequest(clientSIs);\r
-\r
- _status = ST_SYNC;\r
- }\r
-\r
- protected void processClosedConnection(COPSError error)\r
- throws COPSPepException {\r
- if (_process != null)\r
- _process.notifyClosedConnection(this, error);\r
-\r
- _status = ST_CCONN;\r
- }\r
-\r
- protected void processNoKAConnection()\r
- throws COPSPepException {\r
- if (_process != null)\r
- _process.notifyNoKAliveReceived(this);\r
-\r
- _status = ST_NOKA;\r
- }\r
-\r
- protected void processAcctReport()\r
- throws COPSPepException {\r
-\r
- Hashtable report = new Hashtable();\r
- if (_process != null)\r
- report = _process.getAcctData(this);\r
-\r
- _sender.sendAcctReport(report);\r
-\r
- _status = ST_ACCT;\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2004 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.prpep;
+
+import org.umu.cops.stack.*;
+
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)
+ * in PEP.
+ *
+ * The client handle is used to identify a unique request state for a
+ * single PEP per client-type. Client handles are chosen by the PEP and
+ * are opaque to the PDP. The PDP simply uses the request handle to
+ * uniquely identify the request state for a particular Client-Type over
+ * a particular TCP connection and generically tie its decisions to a
+ * corresponding request. Client handles are initiated in request
+ * messages and are then used by subsequent request, decision, and
+ * report messages to reference the same request state. When the PEP is
+ * ready to remove a local request state, it will issue a delete message
+ * to the PDP for the corresponding client handle. A handle MUST be
+ * explicitly deleted by the PEP before it can be used by the PEP to
+ * identify a new request state. Handles referring to different request
+ * states MUST be unique within the context of a particular TCP
+ * connection and client-type.
+ *
+ * @version COPSPepReqStateMan.java, v 2.00 2004
+ *
+ */
+public class COPSPepReqStateMan {
+
+ /**
+ * Request State created
+ */
+ public final static short ST_CREATE = 1;
+ /**
+ * Request sent
+ */
+ public final static short ST_INIT = 2;
+ /**
+ * Decisions received
+ */
+ public final static short ST_DECS = 3;
+ /**
+ * Report sent
+ */
+ public final static short ST_REPORT = 4;
+ /**
+ * Request State finalized
+ */
+ public final static short ST_FINAL = 5;
+ /**
+ * New Request State solicited
+ */
+ public final static short ST_NEW = 6;
+ /**
+ * Delete Request State solicited
+ */
+ public final static short ST_DEL = 7;
+ /**
+ * SYNC Request received
+ */
+ public final static short ST_SYNC = 8;
+ /**
+ * SYNC Completed
+ */
+ public final static short ST_SYNCALL = 9;
+ /**
+ * Close Connection received
+ */
+ public final static short ST_CCONN = 10;
+ /**
+ * KAlive Time out
+ */
+ public final static short ST_NOKA = 11;
+ /**
+ * ACCT Time out
+ */
+ public final static short ST_ACCT = 12;
+
+ /**
+ * The client-type identifies the policy client
+ */
+ protected short _clientType;
+
+ /**
+ * The client handle is used to uniquely identify a particular
+ * PEP's request for a client-type
+ */
+ protected COPSHandle _handle;
+
+ /**
+ The PolicyDataProcess is used to process policy data in the PEP
+ */
+ protected COPSPepDataProcess _process;
+
+ /**
+ * State Request State
+ */
+ protected short _status;
+
+ /**
+ The Msg Sender is used to send COPS messages
+ */
+ protected COPSPepMsgSender _sender;
+
+ /**
+ * Sync State
+ */
+ protected boolean _syncState;
+
+ /**
+ * Create a State Request Manager
+ *
+ * @param clientHandle a Client Handle
+ *
+ */
+ public COPSPepReqStateMan(final short clientType, final String clientHandle) {
+ _handle = new COPSHandle(new COPSData(clientHandle));
+ _clientType = clientType;
+ _syncState = true;
+ _status = ST_CREATE;
+ }
+
+ /**
+ * Return client handle
+ *
+ * @return a COPSHandle
+ *
+ */
+ public COPSHandle getClientHandle() {
+ return _handle;
+ }
+
+ /**
+ * Return client-type
+ *
+ * @return a short
+ *
+ */
+ public int getClientType() {
+ return _clientType;
+ }
+
+ /**
+ * Return Request State status
+ *
+ * @return s short
+ */
+ public short getStatus() {
+ return _status;
+ }
+
+ /**
+ * Return the Policy Data Process
+ *
+ * @return a PolicyConfigure
+ *
+ */
+ public COPSPepDataProcess getDataProcess() {
+ return _process;
+ }
+
+ /**
+ * Establish the Policy Data Process
+ *
+ * @param process a PolicyConfigure
+ *
+ */
+ public void setDataProcess(COPSPepDataProcess process) {
+ _process = process;
+ }
+
+ /**
+ * Init Request State
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void initRequestState(Socket sock)
+ throws COPSPepException {
+ // Inits an object for sending COPS messages to the PDP
+ _sender = new COPSPepMsgSender(_clientType, _handle, sock);
+
+ // If an object for retrieving PEP features exists,
+ // use it for retrieving them
+ final Map<String, String> clientSIs;
+ if (_process != null)
+ clientSIs = _process.getClientData(this);
+ else
+ clientSIs = new HashMap<>();
+
+ // Send the request
+ // TODO - do we really want to send when this is empty???
+ _sender.sendRequest(clientSIs);
+
+ // Initial state
+ _status = ST_INIT;
+ }
+
+ /**
+ * Finalize Request State
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void finalizeRequestState()
+ throws COPSPepException {
+ _sender.sendDeleteRequest();
+ _status = ST_FINAL;
+ }
+
+ /**
+ * Process the message Decision
+ *
+ * @param dMsg a COPSDecisionMsg
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void processDecision(COPSDecisionMsg dMsg)
+ throws COPSPepException {
+ // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());
+
+ // COPSHandle handle = dMsg.getClientHandle();
+ final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
+
+ final Map<String, String> removeDecs = new HashMap<>();
+ final Map<String, String> installDecs = new HashMap<>();
+
+ for (Set<COPSDecision> copsDecisions: decisions.values()) {
+ final COPSDecision cmddecision = copsDecisions.iterator().next();
+ String prid = "";
+ switch (cmddecision.getCommand()) {
+ case INSTALL:
+ for (final COPSDecision decision : copsDecisions) {
+ final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ installDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case REMOVE:
+ for (final COPSDecision decision : copsDecisions) {
+ final COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());
+ switch (obj.getSNum()) {
+ case COPSPrObjBase.PR_PRID:
+ prid = obj.getData().str();
+ break;
+ case COPSPrObjBase.PR_EPD:
+ removeDecs.put(prid, obj.getData().str());
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ }
+
+ //** Apply decisions to the configuration
+ // TODO - why is this collection never getting populated???
+ final Map<String, String> errorDecs = new HashMap<>();
+ _process.setDecisions(this, removeDecs, installDecs, errorDecs);
+ _status = ST_DECS;
+
+
+ if (_process.isFailReport(this)) {
+ // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
+ _sender.sendFailReport(_process.getReportData(this));
+ } else {
+ // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
+ _sender.sendSuccessReport(_process.getReportData(this));
+ }
+ _status = ST_REPORT;
+
+ if (!_syncState) {
+ _sender.sendSyncComplete();
+ _syncState = true;
+ _status = ST_SYNCALL;
+ }
+ }
+
+ /**
+ * Process the message NewRequestState
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void processOpenNewRequestState()
+ throws COPSPepException {
+
+ if (_process != null)
+ _process.newRequestState(this);
+
+ _status = ST_NEW;
+ }
+
+ /**
+ * Process the message DeleteRequestState
+ *
+ * @param dMsg a COPSDecisionMsg
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void processDeleteRequestState(COPSDecisionMsg dMsg)
+ throws COPSPepException {
+ if (_process != null)
+ _process.closeRequestState(this);
+
+ _status = ST_DEL;
+ }
+
+ /**
+ * Process the message SycnStateRequest.
+ * The message SycnStateRequest indicates that the remote PDP
+ * wishes the client (which appears in the common header)
+ * to re-send its state.
+ *
+ * @param ssMsg a COPSSyncStateMsg
+ *
+ * @throws COPSPepException
+ *
+ */
+ protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)
+ throws COPSPepException {
+ _syncState = false;
+ // If an object for retrieving PEP features exists,
+ // use it for retrieving them
+ final Map<String, String> clientSIs;
+ if (_process != null)
+ clientSIs = _process.getClientData(this);
+ else
+ clientSIs = new HashMap<>();
+
+ // Send request
+ // TODO - do we really want to send the request when the map is empty???
+ _sender.sendRequest(clientSIs);
+
+ _status = ST_SYNC;
+ }
+
+ protected void processClosedConnection(COPSError error)
+ throws COPSPepException {
+ if (_process != null)
+ _process.notifyClosedConnection(this, error);
+
+ _status = ST_CCONN;
+ }
+
+ protected void processNoKAConnection()
+ throws COPSPepException {
+ if (_process != null)
+ _process.notifyNoKAliveReceived(this);
+
+ _status = ST_NOKA;
+ }
+
+ protected void processAcctReport()
+ throws COPSPepException {
+
+ final Map<String, String> report;
+ if (_process != null) report = _process.getAcctData(this);
+ else report = new HashMap<>();
+
+ // TODO - do we really want to send when the map is empty???
+ _sender.sendAcctReport(report);
+
+ _status = ST_ACCT;
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-/**\r
- * COPS Accounting Timer Object\r
- *\r
- * @version COPSAcctTimer.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSAcctTimer extends COPSTimer {\r
-\r
- public COPSAcctTimer() {\r
- super(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), (short) 1);\r
- }\r
-\r
- ///\r
- public COPSAcctTimer(short timeVal) {\r
- super(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), timeVal);\r
- }\r
-\r
- ///\r
- /**\r
- * Method isAcctTimer\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAcctTimer() {\r
- return true;\r
- }\r
-\r
- ///\r
- protected COPSAcctTimer(byte[] dataPtr) {\r
- super (dataPtr);\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS Accounting Timer Object (RFC 2748)
+ *
+ * Times are encoded as 2 octet integer values and are in units of
+ * seconds. The timer value is treated as a delta.
+ *
+ * C-Num = 15,
+ * C-Type = 1, Accounting timer value
+ *
+ * Optional timer value used to determine the minimum interval between
+ * periodic accounting type reports. It is used by the PDP to describe
+ * to the PEP an acceptable interval between unsolicited accounting
+ * updates via Report messages where applicable. It provides a method
+ * for the PDP to control the amount of accounting traffic seen by the
+ * network. The range of finite time values is 1 to 65535 seconds
+ * represented as an unsigned two-octet integer. A value of zero means
+ * there SHOULD be no unsolicited accounting updates.
+ */
+public class COPSAcctTimer extends COPSTimer {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param timeVal - the timer value
+ * @throws java.lang.IllegalArgumentException when the id parameter is null
+ */
+ public COPSAcctTimer(final short timeVal) {
+ this((short)0, timeVal);
+ }
+
+ /**
+ * Constructor generally used for sending messages with some reserved value
+ * @param reserved - ???
+ * @param timeVal - the timer value
+ * @throws java.lang.IllegalArgumentException when the id parameter is null
+ */
+ protected COPSAcctTimer(final short reserved, final short timeVal) {
+ this(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), reserved, timeVal);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param header - the object header
+ * @param reserved - ???
+ * @param timeVal - the timer value
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSAcctTimer(final COPSObjHeader header, final short reserved, final short timeVal) {
+ super(header, reserved, timeVal);
+ if (!header.getCNum().equals(CNum.ACCT_TIMER))
+ throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.ACCT_TIMER);
+ if (!header.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSAcctTimer parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ short reserved = 0;
+ reserved |= ((short) dataPtr[4]) << 8;
+ reserved |= ((short) dataPtr[5]) & 0xFF;
+
+ short timerValue = 0;
+ timerValue |= ((short) dataPtr[6]) << 8;
+ timerValue |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSAcctTimer(objHdrData.header, reserved, timerValue);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Client Accept Message\r
- *\r
- * @version COPSClientAcceptMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSClientAcceptMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSKATimer _kaTimer;\r
- private COPSAcctTimer _acctTimer;\r
- private COPSIntegrity _integrity;\r
-\r
- ///Constructor\r
- public COPSClientAcceptMsg() {\r
- _kaTimer = null;\r
- _acctTimer = null;\r
- _integrity = null;\r
- }\r
-\r
- ///Create object from data\r
- protected COPSClientAcceptMsg(byte[] data) throws COPSException {\r
- parse(data);\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_kaTimer == null))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT)\r
- throw new COPSException ("Error Header (no COPS_OP_CAT)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Timer object to the message\r
- *\r
- * @param timer a COPSTimer\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSTimer timer) throws COPSException {\r
- if (timer.isKATimer()) {\r
- _kaTimer = (COPSKATimer) timer;\r
- } else {\r
- _acctTimer = (COPSAcctTimer) timer;\r
- }\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Integrity objects\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Method getKATimer\r
- *\r
- * @return a COPSKATimer\r
- *\r
- */\r
- public COPSKATimer getKATimer() {\r
- return _kaTimer;\r
- };\r
-\r
- /**\r
- * Returns true if has a account timer object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasAcctTimer() {\r
- return (_acctTimer != null);\r
- };\r
-\r
- /**\r
- * Should check hasAcctTimer() before calling\r
- *\r
- * @return a COPSAcctTimer\r
- *\r
- */\r
- public COPSAcctTimer getAcctTimer() {\r
- return (_acctTimer);\r
- }\r
-\r
- /**\r
- * Returns true if has a Integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- };\r
-\r
- /**\r
- * Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Writes data to a given socket id\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_kaTimer != null) _kaTimer.writeData(id);\r
- if (_acctTimer != null) _acctTimer.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case KA:\r
- _kaTimer = new COPSKATimer(buf);\r
- _dataStart += _kaTimer.getDataLength();\r
- break;\r
- case ACCT_TIMER:\r
- _acctTimer = new COPSAcctTimer(buf);\r
- _dataStart += _acctTimer.getDataLength();\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_CAT)\r
- throw new COPSException("Error Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_kaTimer != null) len += _kaTimer.getDataLength();\r
- if (_acctTimer != null) len += _acctTimer.getDataLength();\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_kaTimer != null)\r
- _kaTimer.dump(os);\r
-\r
- if (_acctTimer != null)\r
- _acctTimer.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Client-Accept (CAT) PDP -> PEP (RFC 2748 pag. 26)
+ *
+ * The Client-Accept message is used to positively respond to the
+ * Client-Open message. This message will return to the PEP a timer
+ * object indicating the maximum time interval between keep-alive
+ * messages. Optionally, a timer specifying the minimum allowed interval
+ * between accounting report messages may be included when applicable.
+ *
+ * <Client-Accept> ::= <Common Header>
+ * <KA Timer>
+ * [<ACCT Timer>]
+ * [<Integrity>]
+ *
+ * If the PDP refuses the client, it will instead issue a Client-Close
+ * message.
+ *
+ * The KA Timer corresponds to maximum acceptable intermediate time
+ * between the generation of messages by the PDP and PEP. The timer
+ * value is determined by the PDP and is specified in seconds. A timer
+ * value of 0 implies no secondary connection verification is necessary.
+ *
+ * The optional ACCT Timer allows the PDP to indicate to the PEP that
+ * periodic accounting reports SHOULD NOT exceed the specified timer
+ * interval per client handle. This allows the PDP to control the rate
+ * at which accounting reports are sent by the PEP (when applicable).
+ *
+ * In general, accounting type Report messages are sent to the PDP when
+ * determined appropriate by the PEP. The accounting timer merely is
+ * used by the PDP to keep the rate of such updates in check (i.e.
+ * Preventing the PEP from blasting the PDP with accounting reports).
+ * Not including this object implies there are no PDP restrictions on
+ * the rate at which accounting updates are generated.
+ *
+ * If the PEP receives a malformed Client-Accept message it MUST
+ * generate a Client-Close message specifying the appropriate error
+ * code.
+ */
+public class COPSClientAcceptMsg extends COPSMsg {
+
+ // Required
+ private final COPSKATimer _kaTimer;
+
+ // Optional
+ private final COPSAcctTimer _acctTimer;
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param kaTimer - the Keep alive timer (required)
+ * @param acctTimer - the account timer (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSClientAcceptMsg(final short clientType, final COPSKATimer kaTimer, final COPSAcctTimer acctTimer,
+ final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.CAT, clientType), kaTimer, acctTimer, integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param clientType - the type of client that created the message (required)
+ * @param kaTimer - the Keep alive timer (required)
+ * @param acctTimer - the account timer (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSClientAcceptMsg(final int version, final Flag flag, final short clientType,
+ final COPSKATimer kaTimer, final COPSAcctTimer acctTimer, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.CAT, clientType), kaTimer, acctTimer, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param kaTimer - the Keep alive timer (required)
+ * @param acctTimer - the account timer (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSClientAcceptMsg(final COPSHeader hdr, final COPSKATimer kaTimer, final COPSAcctTimer acctTimer,
+ final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.CAT))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.CAT);
+ if (kaTimer == null) throw new IllegalArgumentException("Keep alive timer must not be null");
+ _kaTimer = kaTimer;
+ _acctTimer = acctTimer;
+ _integrity = integrity;
+ }
+
+ // Getters
+ public COPSKATimer getKATimer() {
+ return _kaTimer;
+ }
+ public COPSAcctTimer getAcctTimer() {
+ return (_acctTimer);
+ }
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _kaTimer.writeData(socket);
+ if (_acctTimer != null) _acctTimer.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _kaTimer.getDataLength() + _kaTimer.getHeader().getHdrLength();
+ if (_acctTimer != null) out += _acctTimer.getDataLength() + _acctTimer.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ _kaTimer.dump(os);
+ if (_acctTimer != null) _acctTimer.dump(os);
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSClientAcceptMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSClientAcceptMsg acceptMsg = (COPSClientAcceptMsg) o;
+
+ return !(_acctTimer != null ? !_acctTimer.equals(acceptMsg._acctTimer) : acceptMsg._acctTimer != null) &&
+ !(_integrity != null ? !_integrity.equals(acceptMsg._integrity) : acceptMsg._integrity != null) &&
+ _kaTimer.equals(acceptMsg._kaTimer);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _kaTimer.hashCode();
+ result = 31 * result + (_acctTimer != null ? _acctTimer.hashCode() : 0);
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSClientAcceptMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSKATimer kaTimer = null;
+ COPSAcctTimer acctTimer = null;
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case KA:
+ kaTimer = COPSKATimer.parse(objHdrData, buf);
+ break;
+ case ACCT_TIMER:
+ acctTimer = COPSAcctTimer.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSClientAcceptMsg(hdrData.header, kaTimer, acctTimer, integrity);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Client Close Message\r
- *\r
- * @version COPSClientCloseMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSClientCloseMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSError _error;\r
- private COPSIntegrity _integrity;\r
-\r
-\r
- public COPSClientCloseMsg() {\r
- _error = null;\r
- _integrity = null;\r
- }\r
-\r
- protected COPSClientCloseMsg(byte[] data) throws COPSException {\r
- parse (data);\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_error == null))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_CC)\r
- throw new COPSException ("Error Header (no COPS_OP_CC)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Error object\r
- *\r
- * @param error a COPSError\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSError error) throws COPSException {\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_error != null)\r
- throw new COPSException ("No null Error");\r
- _error = error;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Integrity objects\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Method getError\r
- *\r
- * @return a COPSError\r
- *\r
- */\r
- public COPSError getError() {\r
- return (_error);\r
- }\r
-\r
- /**\r
- * Returns true If it has integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- };\r
-\r
- /**\r
- * Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Write object data to given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_error != null) _error.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case ERROR:\r
- _error = new COPSError(buf);\r
- _dataStart += _error.getDataLength();\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_CC)\r
- throw new COPSException("Error Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- int len = 0;\r
- if (_error != null) len += _error.getDataLength();\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_error != null)\r
- _error.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Client Close Message (RFC 2748 pg. 27)
+ *
+ * The Client-Close message can be issued by either the PDP or PEP to
+ * notify the other that a particular type of client is no longer being
+ * supported.
+ *
+ * <Client-Close> ::= <Common Header>
+ * <Error>
+ * [<PDPRedirAddr>]
+ * [<Integrity>]
+ *
+ * The Error object is included to describe the reason for the close
+ * (e.g. the requested client-type is not supported by the remote PDP or
+ * client failure).
+ *
+ * A PDP MAY optionally include a PDP Redirect Address object in order
+ * to inform the PEP of the alternate PDP it SHOULD use for the client-
+ * type specified in the common header.
+ */
+public class COPSClientCloseMsg extends COPSMsg {
+
+ // Required
+ private final COPSError _error;
+
+ // Optional
+ private final COPSPdpAddress _redirAddr;
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param error - the error (required)
+ * @param redirAddr - the redirect address (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSClientCloseMsg(final short clientType, final COPSError error, final COPSPdpAddress redirAddr,
+ final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.CC, clientType), error, redirAddr, integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param clientType - the type of client that created the message (required)
+ * @param error - the error (required)
+ * @param redirAddr - the redirect address (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSClientCloseMsg(final int version, final Flag flag, final short clientType, final COPSError error,
+ final COPSPdpAddress redirAddr, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.CC, clientType), error, redirAddr, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param error - the error (required)
+ * @param redirAddr - the redirect address (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSClientCloseMsg(final COPSHeader hdr, final COPSError error, final COPSPdpAddress redirAddr,
+ final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.CC))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.CAT);
+ if (error == null) throw new IllegalArgumentException("Error object must not be null");
+ this._error = error;
+ this._redirAddr = redirAddr;
+ this._integrity = integrity;
+ }
+
+ // Getters
+ public COPSError getError() {
+ return (_error);
+ }
+ public COPSPdpAddress getRedirAddr() {
+ return (_redirAddr);
+ }
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _error.writeData(socket);
+ if (_redirAddr != null) _redirAddr.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _error.getDataLength() + _error.getHeader().getHdrLength();
+ if (_redirAddr != null) out += _redirAddr.getDataLength() + _redirAddr.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ @Override
+ protected void dumpBody(OutputStream os) throws IOException {
+ _error.dump(os);
+ if (_redirAddr != null) _redirAddr.dump(os);
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSClientCloseMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSClientCloseMsg closeMsg = (COPSClientCloseMsg) o;
+
+ return _error.equals(closeMsg._error) &&
+ !(_integrity != null ? !_integrity.equals(closeMsg._integrity) : closeMsg._integrity != null) &&
+ !(_redirAddr != null ? !_redirAddr.equals(closeMsg._redirAddr) : closeMsg._redirAddr != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _error.hashCode();
+ result = 31 * result + (_redirAddr != null ? _redirAddr.hashCode() : 0);
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSClientCloseMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSError error = null;
+ COPSPdpAddress redirAddr = null;
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case ERROR:
+ error = COPSError.parse(objHdrData, buf);
+ break;
+ case PDP_REDIR:
+ redirAddr = COPSPdpAddress.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSClientCloseMsg(hdrData.header, error, redirAddr, integrity);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Client Open Message\r
- *\r
- * @version COPSClientOpenMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSClientOpenMsg extends COPSMsg {\r
-\r
- private COPSPepId _pepId;\r
- private COPSClientSI _clientSI;\r
- private COPSPdpAddress _pdpAddress;\r
- private COPSIntegrity _integrity;\r
-\r
- public COPSClientOpenMsg() {\r
- _pepId = null;\r
- _clientSI = null;\r
- _pdpAddress = null;\r
- _integrity = null;\r
- _hdr = null;\r
- }\r
-\r
- protected COPSClientOpenMsg(byte[] data) throws COPSException {\r
- _pepId = null;\r
- _clientSI = null;\r
- _pdpAddress = null;\r
- _integrity = null;\r
- _hdr = null;\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Method writeData\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null)_hdr.writeData(id);\r
- if (_pepId != null) _pepId.writeData(id);\r
- if (_clientSI != null) _clientSI.writeData(id);\r
- if (_pdpAddress != null) _pdpAddress.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN)\r
- throw new COPSException ("Error Header (no COPS_OP_OPN)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add PEP Identification Object\r
- *\r
- * @param pepid a COPSPepId\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSPepId pepid) throws COPSException {\r
- if (pepid == null)\r
- throw new COPSException ("Null COPSPepId");\r
- if (!pepid.isPepId())\r
- throw new COPSException ("Error COPSPepId");\r
- _pepId = pepid;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Client Specific Information Object\r
- *\r
- * @param clientSI a COPSClientSI\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSClientSI clientSI) throws COPSException {\r
- if (clientSI == null)\r
- throw new COPSException ("Null COPSClientSI");\r
- if (!clientSI.isClientSI())\r
- throw new COPSException ("Error COPSClientSI");\r
- _clientSI = clientSI;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add PDP Address\r
- *\r
- * @param pdpAddr a COPSPdpAddress\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSPdpAddress pdpAddr) throws COPSException {\r
- if (pdpAddr == null)\r
- throw new COPSException ("Null COPSPdpAddress");\r
- if (!pdpAddr.isLastPdpAddress())\r
- throw new COPSException ("Error COPSPdpAddress");\r
- _pdpAddress = pdpAddr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_pepId == null))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Method getPepId\r
- *\r
- * @return a COPSPepId\r
- *\r
- */\r
- public COPSPepId getPepId() {\r
- return _pepId;\r
- }\r
-\r
- /**\r
- * Method hasClientSI\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasClientSI() {\r
- return (_clientSI != null);\r
- }\r
-\r
- /**\r
- * Method getClientSI\r
- *\r
- * @return a COPSClientSI\r
- *\r
- */\r
- public COPSClientSI getClientSI() {\r
- return (_clientSI);\r
- }\r
-\r
- /**\r
- * Method hasPdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasPdpAddress() {\r
- return (_pdpAddress != null);\r
- }\r
-\r
- /**\r
- * Method getPdpAddress\r
- *\r
- * @return a COPSPdpAddress\r
- *\r
- */\r
- public COPSPdpAddress getPdpAddress() {\r
- return _pdpAddress;\r
- }\r
-\r
- /**\r
- * Method hasIntegrity\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- }\r
-\r
- /**\r
- * Method getIntegrity\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return _integrity;\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- private void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_pepId != null) len += _pepId.getDataLength();\r
- if (_clientSI != null) len += _clientSI.getDataLength();\r
- if (_pdpAddress != null) len += _pdpAddress.getDataLength();\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- parseHeader(data);\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case PEPID:\r
- _pepId = new COPSPepId(buf);\r
- _dataStart += _pepId.getDataLength();\r
- break;\r
- case LAST_PDP_ADDR:\r
- if (objHdr.getCType().ordinal() == 1) {\r
- _pdpAddress = new COPSIpv4LastPdpAddr(buf);\r
- } else if (objHdr.getCType().ordinal() == 2) {\r
- _pdpAddress = new COPSIpv6LastPdpAddr(buf);\r
- }\r
- _dataStart += _pdpAddress.getDataLength();\r
- break;\r
- case CSI:\r
- _clientSI = new COPSClientSI(buf);\r
- _dataStart += _clientSI.getDataLength();\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_OPN)\r
- throw new COPSException("Error Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_pepId != null)\r
- _pepId.dump(os);\r
-\r
- if (_clientSI != null)\r
- _clientSI.dump(os);\r
-\r
- if (_pdpAddress != null)\r
- _pdpAddress.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Client Open Message (RFC 2748 page. 26)
+ *
+ * The Client-Open message can be used by the PEP to specify to the PDP
+ * the client-types the PEP can support, the last PDP to which the PEP
+ * connected for the given client-type, and/or client specific feature
+ * negotiation. A Client-Open message can be sent to the PDP at any time
+ * and multiple Client-Open messages for the same client-type are
+ * allowed (in case of global state changes).
+ *
+ * <Client-Open> ::= <Common Header>
+ * <PEPID>
+ * [<ClientSI>]
+ * [<LastPDPAddr>]
+ * [<Integrity>]
+ *
+ * The PEPID is a symbolic, variable length name that uniquely
+ * identifies the specific client to the PDP (see Section 2.2.11).
+ *
+ * A named ClientSI object can be included for relaying additional
+ * global information about the PEP to the PDP when required (as
+ * specified in the appropriate extensions document for the client-
+ * type).
+ *
+ * The PEP may also provide a Last PDP Address object in its Client-Open
+ * message specifying the last PDP (for the given client-type) for which
+ * it is still caching decisions since its last reboot. A PDP can use
+ * this information to determine the appropriate synchronization
+ * behavior (See section 2.5).
+ *
+ * If the PDP receives a malformed Client-Open message it MUST generate
+ * a Client-Close message specifying the appropriate error code.
+ */
+public class COPSClientOpenMsg extends COPSMsg {
+
+ private final COPSPepId _pepId;
+ private final COPSClientSI _clientSI;
+ private final COPSPdpAddress _pdpAddress;
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param pepId - the PEP ID (required)
+ * @param clientSI - the COPS Client SI (optional)
+ * @param pdpAddress - the COPS PDP Address (optional)
+ * @param integrity - the COPS Integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSClientOpenMsg(final short clientType, final COPSPepId pepId, final COPSClientSI clientSI,
+ final COPSPdpAddress pdpAddress, final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.OPN, clientType), pepId, clientSI, pdpAddress, integrity);
+ }
+
+ /**
+ * Recommended constructor generally for use by a client sending messages.
+ * @param version - the supported PCMM Version (required)
+ * @param flag - the flag... (required)
+ * @param clientType - the type of client that created the message (required)
+ * @param pepId - the PEP ID (required)
+ * @param clientSI - the COPS Client SI (optional)
+ * @param pdpAddress - the COPS PDP Address (optional)
+ * @param integrity - the COPS Integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSClientOpenMsg(final int version, final Flag flag, final short clientType, final COPSPepId pepId,
+ final COPSClientSI clientSI, final COPSPdpAddress pdpAddress,
+ final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.OPN, clientType), pepId, clientSI, pdpAddress, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header (required)
+ * @param pepId - the PEP ID (required)
+ * @param clientSI - the COPS Client SI (optional)
+ * @param pdpAddress - the COPS PDP Address (optional)
+ * @param integrity - the COPS Integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSClientOpenMsg(final COPSHeader hdr, final COPSPepId pepId, final COPSClientSI clientSI,
+ final COPSPdpAddress pdpAddress, final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.OPN))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.OPN);
+ if (pepId == null) throw new IllegalArgumentException("Pep ID must not be null");
+ // TODO - considering adding some validation on the PDP Address and the client type
+ this._pepId = pepId;
+ this._clientSI = clientSI;
+ this._pdpAddress = pdpAddress;
+ this._integrity = integrity;
+ }
+
+ // Getters
+ public COPSPepId getPepId() {
+ return _pepId;
+ }
+ public COPSClientSI getClientSI() {
+ return (_clientSI);
+ }
+ public COPSPdpAddress getPdpAddress() {
+ return _pdpAddress;
+ }
+ public COPSIntegrity getIntegrity() {
+ return _integrity;
+ }
+
+ /**
+ * Method writeData
+ * @param socket a Socket
+ * @throws IOException
+ */
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _pepId.writeData(socket);
+ if (_clientSI != null) _clientSI.writeData(socket);
+ if (_pdpAddress != null) _pdpAddress.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _pepId.getDataLength() + _pepId.getHeader().getHdrLength();
+ if (_clientSI != null) out += _clientSI.getDataLength() + _clientSI.getHeader().getHdrLength();
+ if (_pdpAddress != null) out += _pdpAddress.getDataLength() + _pdpAddress.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ _pepId.dump(os);
+ if (_clientSI != null) _clientSI.dump(os);
+ if (_pdpAddress != null) _pdpAddress.dump(os);
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSClientOpenMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSClientOpenMsg that = (COPSClientOpenMsg) o;
+
+ return !(_clientSI != null ? !_clientSI.equals(that._clientSI) : that._clientSI != null) &&
+ !(_integrity != null ? !_integrity.equals(that._integrity) : that._integrity != null) &&
+ !(_pdpAddress != null ? !_pdpAddress.equals(that._pdpAddress) : that._pdpAddress != null) &&
+ _pepId.equals(that._pepId);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _pepId.hashCode();
+ result = 31 * result + (_clientSI != null ? _clientSI.hashCode() : 0);
+ result = 31 * result + (_pdpAddress != null ? _pdpAddress.hashCode() : 0);
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSReqMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSClientOpenMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSPepId pepId = null;
+ COPSClientSI clientSI = null;
+ COPSPdpAddress pdpAddress = null;
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case PEPID:
+ pepId = COPSPepId.parse(objHdrData, buf);
+ break;
+ case CSI:
+ clientSI = COPSClientSI.parse(objHdrData, buf);
+ break;
+ case LAST_PDP_ADDR:
+ pdpAddress = COPSPdpAddress.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSClientOpenMsg(hdrData.header, pepId, clientSI, pdpAddress, integrity);
+ }
+
+}
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Client Specific Information Object\r
- *\r
- * @version COPSClientSI.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSClientSI extends COPSObjBase {\r
- public final static byte CSI_SIGNALED = 1;\r
- public final static byte CSI_NAMED = 2;\r
-\r
- private COPSObjHeader _objHdr;\r
- private COPSData _data;\r
- private COPSData _padding;\r
-\r
- ///\r
- public COPSClientSI(byte type) {\r
- _objHdr = new COPSObjHeader(CNum.CSI, COPSObjHeader.VAL_TO_CTYPE.get((int)type));\r
- }\r
-\r
- public COPSClientSI(byte cnum, byte ctype) {\r
- _objHdr = new COPSObjHeader(COPSObjHeader.VAL_TO_CNUM.get((int)cnum), COPSObjHeader.VAL_TO_CTYPE.get((int)ctype));\r
- }\r
-\r
- /**\r
- Parse the data and create a ClientSI object\r
- */\r
- protected COPSClientSI(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- //Get the length of data following the obj header\r
- short dLen = (short) (_objHdr.getDataLength() - 4);\r
- COPSData d = new COPSData(dataPtr, 4, dLen);\r
- setData(d);\r
- }\r
-\r
- /**\r
- * Method setData\r
- *\r
- * @param data a COPSData\r
- *\r
- */\r
- public void setData(COPSData data) {\r
- _data = data;\r
- if (_data.length() % 4 != 0) {\r
- int padLen = 4 - _data.length() % 4;\r
- _padding = getPadding(padLen);\r
- }\r
- _objHdr.setDataLength((short) _data.length());\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- int lpadding = 0;\r
- if (_padding != null) lpadding = _padding.length();\r
- return (short) (_objHdr.getDataLength() + lpadding);\r
- }\r
-\r
- /**\r
- * Method getData\r
- *\r
- * @return a COPSData\r
- *\r
- */\r
- public COPSData getData() {\r
- return _data;\r
- };\r
-\r
- /**\r
- * Method isClientSI\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isClientSI() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
- COPSUtil.writeData(id, _data.getData(), _data.length());\r
- if (_padding != null) {\r
- COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
- }\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("client-SI: " + _data.str() + "\n").getBytes());\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Client Specific Information Object (RFC 2748)
+ *
+ * The various types of this object are required for requests, and used
+ * in reports and opens when required. It contains client-type specific
+ * information.
+ *
+ * C-Num = 9,
+ *
+ * C-Type = 1, Signaled ClientSI.
+ *
+ * Variable-length field. All objects/attributes specific to a client's
+ * signaling protocol or internal state are encapsulated within one or
+ * more signaled Client Specific Information Objects. The format of the
+ * data encapsulated in the ClientSI object is determined by the
+ * client-type.
+ *
+ * C-Type = 2, Named ClientSI.
+ *
+ * Variable-length field. Contains named configuration information
+ * useful for relaying specific information about the PEP, a request, or
+ * configured state to the PDP server.
+ */
+public class COPSClientSI extends COPSObjBase {
+
+ private final static Map<Integer, CSIType> VAL_TO_CSI = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_CSI.put(CSIType.NA.ordinal(), CSIType.NA);
+ VAL_TO_CSI.put(CSIType.SIGNALED.ordinal(), CSIType.SIGNALED);
+ VAL_TO_CSI.put(CSIType.NAMED.ordinal(), CSIType.NAMED);
+ }
+
+ /**
+ * This value is not being used here but stored only for clarity as it is being mapped directly to the
+ * ordinal value of the CType
+ */
+ private final CSIType _csiType;
+
+ /**
+ * The payload data
+ */
+ private final COPSData _data;
+
+ /**
+ * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes
+ */
+ private final COPSData _padding;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param csitype - the CSIType
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSClientSI(final CSIType csitype, final COPSData data) {
+ /* The CSIType does not map directly to the CType, therefore the hook to map to a CType below is
+ required to ensure the header value outputs the correct value when streamed
+ */
+ this(new COPSObjHeader(CNum.CSI, COPSObjHeader.VAL_TO_CTYPE.get(csitype.ordinal())), data);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSClientSI(final COPSObjHeader hdr, final COPSData data) {
+ super(hdr);
+ _csiType = VAL_TO_CSI.get(hdr.getCType().ordinal());
+
+ if (!hdr.getCNum().equals(CNum.CSI))
+ throw new IllegalArgumentException("CNum must be equal to " + CNum.CSI);
+ if (_csiType == null || _csiType.equals(CSIType.NA))
+ throw new IllegalArgumentException("Invalid CSIType");
+ if (_csiType.ordinal() != hdr.getCType().ordinal())
+ throw new IllegalArgumentException("Error mapping CSIType " + _csiType + " to CType" + hdr.getCType());
+ if (data == null) throw new IllegalArgumentException("Data must not be null");
+
+ _data = data;
+ if ((_data.length() % 4) != 0) {
+ final int padLen = 4 - (_data.length() % 4);
+ _padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ _padding = new COPSData();
+ }
+ }
+
+ /**
+ * Returns the CSIType
+ * @return - the type
+ */
+ public CSIType getCsiType() { return _csiType; }
+
+ /**
+ * Returns the data
+ * @return - the data
+ */
+ public COPSData getData() { return _data; }
+
+ @Override
+ /* The super says protected but this needs to be public due to usage in COPSDecisionMsgEX.java which is currently
+ calling this method. */
+ public int getDataLength() {
+ return _data.length() + _padding.length();
+ }
+
+ @Override
+ public void writeBody(final Socket socket) throws IOException {
+ COPSUtil.writeData(socket, _data.getData(), _data.length());
+ COPSUtil.writeData(socket, _padding.getData(), _padding.length());
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("CSI-type: " + _csiType + "\n").getBytes());
+ os.write(("client-SI: " + _data.str() + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSClientSI)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSClientSI that = (COPSClientSI) o;
+ return _data.equals(that._data) && _padding.equals(that._padding) ||
+ COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (_data != null ? _data.hashCode() : 0);
+ result = 31 * result + (_padding != null ? _padding.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSClientSI object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSClientSI parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ short dLen = (short) (objHdrData.msgByteCount - 4);
+ return new COPSClientSI(objHdrData.header, new COPSData(dataPtr, 4, dLen));
+ }
+
+ /**
+ * The different CSI types. NA does not exist but is a placeholder for 0 as the ordinal values will be used
+ * to determine which type for marshalling
+ */
+ public enum CSIType {
+ NA, SIGNALED, NAMED
+ }
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Context Object\r
- *\r
- * @version COPSContext.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSContext extends COPSObjBase {\r
-\r
- public final static byte IN_ADMIN = 0x01;\r
- public final static byte RES_ALLOC = 0x02;\r
- public final static byte OUT = 0x04;\r
- public final static byte CONFIG = 0x08;\r
-\r
- private COPSObjHeader _objHdr;\r
- private short _rType;\r
- private short _mType;\r
-\r
- ///\r
- public COPSContext(short rType, short mType ) {\r
- _objHdr = new COPSObjHeader(CNum.CONTEXT, CType.DEF);\r
- _rType = rType;\r
- _mType = mType;\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- Parse the data and create a Context object\r
- */\r
- protected COPSContext(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _rType |= ((short) dataPtr[4]) << 8;\r
- _rType |= ((short) dataPtr[5]) & 0xFF;\r
-\r
- _mType |= ((short) dataPtr[6]) << 8;\r
- _mType |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- _objHdr.setDataLength( (short) 4);\r
- }\r
-\r
- /**\r
- * Write object in network byte order to a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_rType >> 8);\r
- buf[1] = (byte) _rType;\r
-\r
- buf[2] = (byte) (_mType >> 8);\r
- buf[3] = (byte) _mType;\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * Returns the detail description of the request type\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String getDescription() {\r
- String retStr = new String();\r
- if ((_rType & 0x01) != 0) {\r
- retStr += (retStr.length() != 0) ? "," : "";\r
- retStr += "Incoming Message/Admission Control";\r
- }\r
- if ((_rType & 0x02) != 0) {\r
- retStr += (retStr.length() != 0) ? "," : "";\r
- retStr += "Resource allocation";\r
- }\r
- if ((_rType & 0x04) != 0) {\r
- retStr += (retStr.length() != 0) ? "," : "";\r
- retStr += "Outgoing message";\r
- }\r
- if ((_rType & 0x08) != 0) {\r
- retStr += (retStr.length() != 0) ? "," : "";\r
- retStr += "Configuration";\r
- }\r
- return retStr;\r
- }\r
-\r
- /**\r
- * Method isIncomingMessage\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIncomingMessage() {\r
- return (_rType & IN_ADMIN) != 0;\r
- };\r
-\r
- /**\r
- * Method isAdminControl\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAdminControl() {\r
- return (_rType & IN_ADMIN) != 0;\r
- };\r
-\r
- /**\r
- * Method isResourceAllocationReq\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isResourceAllocationReq() {\r
- return (_rType & RES_ALLOC) != 0;\r
- };\r
-\r
- /**\r
- * Method isOutgoingMessage\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isOutgoingMessage() {\r
- return (_rType & OUT) != 0;\r
- };\r
-\r
- /**\r
- * Method isConfigRequest\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isConfigRequest() {\r
- return (_rType & CONFIG) != 0;\r
- };\r
-\r
- /**\r
- * Method getMessageType\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getMessageType() {\r
- return (_mType) ;\r
- };\r
-\r
- /**\r
- * Method getRequestType\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getRequestType() {\r
- return (_rType);\r
- };\r
-\r
- /**\r
- * Method isContext\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isContext() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("context: " + getDescription() + "," + _mType + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Context Object (RFC 2748)
+ *
+ * Specifies the type of event(s) that triggered the query. Required for
+ * request messages. Admission control, resource allocation, and
+ * forwarding requests are all amenable to client-types that outsource
+ * their decision making facility to the PDP. For applicable client-
+ * types a PEP can also make a request to receive named configuration
+ * information from the PDP. This named configuration data may be in a
+ * form useful for setting system attributes on a PEP, or it may be in
+ * the form of policy rules that are to be directly verified by the PEP.
+ *
+ * Multiple flags can be set for the same request. This is only allowed,
+ * however, if the set of client specific information in the combined
+ * request is identical to the client specific information that would be
+ * specified if individual requests were made for each specified flag.
+ *
+ * C-num = 2, C-Type = 1
+ *
+ * R-Type (Request Type Flag)
+ *
+ * 0x01 = Incoming-Message/Admission Control request
+ * 0x02 = Resource-Allocation request
+ * 0x04 = Outgoing-Message request
+ * 0x08 = Configuration request
+ *
+ * M-Type (Message Type)
+ *
+ * Client Specific 16 bit values of protocol message types
+ */
+public class COPSContext extends COPSObjBase {
+
+ /**
+ * A Map containing each RType by the byte value
+ */
+ public final static Map<Integer, RType> VAL_TO_RTYPE = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_RTYPE.put(1, RType.IN_ADMIN);
+ VAL_TO_RTYPE.put(2, RType.RES_ALLOC);
+ VAL_TO_RTYPE.put(4, RType.OUT);
+ VAL_TO_RTYPE.put(8, RType.CONFIG);
+ }
+
+ /**
+ * A Map containing the byte value by RType
+ */
+ private final static Map<RType, Integer> RTYPE_TO_VAL = new ConcurrentHashMap<>();
+ static {
+ for (final Map.Entry<Integer, RType> entry : VAL_TO_RTYPE.entrySet()) {
+ RTYPE_TO_VAL.put(entry.getValue(), entry.getKey());
+ }
+ }
+
+ /**
+ * The request type
+ */
+ private final RType _rType;
+
+ /**
+ * The message type
+ * Cannot find a list of types in order to make this an enumeration
+ */
+ private short _mType;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param rType - the type of request
+ * @param mType - the type of message
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSContext(final RType rType, final short mType ) {
+ this(new COPSObjHeader(CNum.CONTEXT, CType.DEF), rType, mType);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param rType - the type of request
+ * @param mType - the type of message
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSContext(final COPSObjHeader objHdr, final RType rType, final short mType ) {
+ super(objHdr);
+
+ if (!objHdr.getCNum().equals(CNum.CONTEXT))
+ throw new IllegalArgumentException("CNum must be equal to " + CNum.CONTEXT);
+ if (!objHdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
+ if (rType == null) throw new IllegalArgumentException("Must have a valid RType");
+
+ _rType = rType;
+ _mType = mType;
+ }
+
+ @Override
+ public void writeBody(final Socket socket) throws IOException {
+ byte[] buf = new byte[4];
+
+ final int rType = RTYPE_TO_VAL.get(_rType);
+ buf[0] = (byte)((byte)rType >> 8);
+ buf[1] = (byte)rType;
+
+ buf[2] = (byte)(_mType >> 8);
+ buf[3] = (byte)_mType;
+
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ @Override
+ public int getDataLength() {
+ return 4;
+ }
+
+ /**
+ * Returns the detail description of the request type
+ * @return a String
+ */
+ public String getDescription() {
+ switch (_rType) {
+ case IN_ADMIN: return "Incoming Message/Admission Control";
+ case RES_ALLOC: return "Resource allocation";
+ case OUT: return "Outgoing message";
+ case CONFIG: return "Configuration";
+ default: return "";
+ }
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("context: " + getDescription() + "," + _mType + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSContext)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSContext that = (COPSContext) o;
+
+ return _mType == that._mType && _rType == that._rType;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _rType.hashCode();
+ result = 31 * result + (int) _mType;
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSContext object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSContext parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ short rType = 0;
+ rType |= ((short) dataPtr[4]) << 8;
+ rType |= ((short) dataPtr[5]) & 0xFF;
+
+ short mType = 0;
+ mType |= ((short) dataPtr[6]) << 8;
+ mType |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSContext(objHdrData.header, VAL_TO_RTYPE.get((int)rType), mType);
+ }
+
+ /**
+ * The request type
+ */
+ public enum RType {
+ IN_ADMIN, RES_ALLOC, OUT, CONFIG,
+ }
+
+}
+
+
* Default constructor\r
*/\r
public COPSData() {\r
- _dataBuf = null;\r
+ _dataBuf = new byte[0];\r
_dLen = 0;\r
}\r
\r
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Decision\r
- *\r
- * @version COPSDecision.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSDecision extends COPSObjBase {\r
-\r
- // CType\r
- @Deprecated public final static byte DEC_DEF = 1;\r
- @Deprecated public final static byte DEC_STATELESS = 2;\r
- @Deprecated public final static byte DEC_REPL = 3;\r
- @Deprecated public final static byte DEC_CSI = 4;\r
- @Deprecated public final static byte DEC_NAMED = 5;\r
-\r
- // Command\r
- @Deprecated public final static byte DEC_NULL = 0;\r
- @Deprecated public final static byte DEC_INSTALL = 1;\r
- @Deprecated public final static byte DEC_REMOVE = 2;\r
-\r
- // Flags\r
- @Deprecated public final static byte F_REQERROR = 0x1;\r
- @Deprecated public final static byte F_REQSTATE = 0x2;\r
-\r
- protected COPSObjHeader _objHdr;\r
- private COPSData _data;\r
- private short _cmdCode;\r
- private short _flags;\r
- private COPSData _padding;\r
-\r
- /**\r
- Constructor to create a Decision object. By default creates\r
- a decision object which is of fixed length.\r
- */\r
- public COPSDecision(byte cType) {\r
- _objHdr = new COPSObjHeader(CNum.DEC, COPSObjHeader.VAL_TO_CTYPE.get((int)cType));\r
- _cmdCode = 0;\r
- _flags = 0;\r
- if (cType == CType.DEF.ordinal()) _objHdr.setDataLength( (short) 4);\r
- }\r
-\r
- public COPSDecision() {\r
- _objHdr = new COPSObjHeader(CNum.DEC, CType.DEF);\r
- _cmdCode = 0;\r
- _flags = 0;\r
- _objHdr.setDataLength( (short) 4);\r
- }\r
-\r
- /**\r
- Initialize the decision object with values from COPSObj header\r
- */\r
- protected COPSDecision(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _cmdCode = 0;\r
- _flags = 0;\r
- if (_objHdr.getCType().equals(CType.DEF)) {\r
- _cmdCode |= ((short) dataPtr[4]) << 8;\r
- _cmdCode |= ((short) dataPtr[5]) & 0xFF;\r
- _flags |= ((short) dataPtr[6]) << 8;\r
- _flags |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- _objHdr.setDataLength((short) 4);\r
- } else {\r
- int dLen = _objHdr.getDataLength() - 4;\r
- COPSData d = new COPSData(dataPtr, 4, dLen);\r
- setData(d);\r
- }\r
- }\r
-\r
- /**\r
- * Method getDataLength\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- int lpadding = 0;\r
- if (_padding != null) lpadding = _padding.length();\r
- return ((short) (_objHdr.getDataLength() + lpadding));\r
- }\r
-\r
-\r
-\r
- /**\r
- * Get the associated data if decision object is of cType 2 or higher\r
- *\r
- * @return a COPSData\r
- *\r
- */\r
- public COPSData getData() {\r
- return (_data);\r
- }\r
-\r
- /**\r
- * Set the decision data if decision object is of cType 2 or higher\r
- *\r
- * @param data a COPSData\r
- *\r
- */\r
- public void setData(COPSData data) {\r
- if (data.length() % 4 != 0) {\r
- int padLen = 4 - data.length() % 4;\r
- _padding = getPadding(padLen);\r
- }\r
- _data = data;\r
- _objHdr.setDataLength((short) data.length());\r
- }\r
-\r
- /**\r
- * Retruns true if cType = 1\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isFlagSet() {\r
- return ( _objHdr.getCType().ordinal() == 1);\r
- };\r
-\r
- /**\r
- * If cType == 1 , get the flags associated\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getFlags() {\r
- return (_flags);\r
- };\r
-\r
- /**\r
- * If cType == 1 ,set the cmd code\r
- *\r
- * @param cCode a byte\r
- *\r
- */\r
- public void setCmdCode(byte cCode) {\r
- _cmdCode = (short) cCode;\r
- }\r
-\r
- /**\r
- * If cType == 1 ,set the cmd flags\r
- *\r
- * @param flags a short\r
- *\r
- */\r
- public void setFlags(short flags) {\r
- _flags = flags;\r
- }\r
-\r
- /**\r
- * Method isNullDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isNullDecision() {\r
- return ( _cmdCode == 0);\r
- };\r
-\r
- /**\r
- * Method isInstallDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isInstallDecision() {\r
- return ( _cmdCode == 1);\r
- };\r
-\r
- /**\r
- * Method isRemoveDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isRemoveDecision() {\r
- return ( _cmdCode == 2);\r
- };\r
-\r
- /**\r
- * Method getTypeStr\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String getTypeStr() {\r
- switch (_objHdr.getCType()) {\r
- case DEF:\r
- return "Default";\r
- case STATELESS:\r
- return "Stateless data";\r
- case REPL:\r
- return "Replacement data";\r
- case CSI:\r
- return "Client specific decision data";\r
- case NAMED:\r
- return "Named decision data";\r
- default:\r
- return "Unknown";\r
- }\r
- }\r
-\r
- /**\r
- * Method isDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isDecision() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Method isLocalDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isLocalDecision() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Writes data to a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- if (_objHdr.getCType().ordinal() >= 2) {\r
- COPSUtil.writeData(id, _data.getData(), _data.length());\r
- if (_padding != null) {\r
- COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
- }\r
- } else {\r
- byte[] buf = new byte[4];\r
- buf[0] = (byte) (_cmdCode >> 8);\r
- buf[1] = (byte) _cmdCode;\r
- buf[2] = (byte) (_flags >> 8);\r
- buf[3] = (byte) _flags;\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
-\r
- if (_objHdr.getCType().ordinal() == 1) {\r
- os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes());\r
- os.write(new String("Command code: " + _cmdCode + "\n").getBytes());\r
- os.write(new String("Command flags: " + _flags + "\n").getBytes());\r
- } else {\r
- os.write(new String("Decision (" + getTypeStr() + ")\n").getBytes());\r
- os.write(new String("Data: " + _data.str() + "\n").getBytes());\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Decision (RFC 2748)
+ *
+ * Decision made by the PDP. Appears in replies. The specific non-
+ * mandatory decision objects required in a decision to a particular
+ * request depend on the type of client.
+ *
+ * C-Num = 6
+ * C-Type = 1, Decision Flags (Mandatory)
+ *
+ * Commands:
+ * 0 = NULL Decision (No configuration data available)
+ * 1 = Install (Admit request/Install configuration)
+ * 2 = Remove (Remove request/Remove configuration)
+ *
+ * Flags:
+ * 0x01 = Trigger Error (Trigger error message if set)
+ * Note: Trigger Error is applicable to client-types that
+ * are capable of sending error notifications for signaled
+ * messages.
+ *
+ * Flag values not applicable to a given context's R-Type or
+ * client-type MUST be ignored by the PEP.
+ *
+ * C-Type = 2, Stateless Data
+ *
+ * This type of decision object carries additional stateless
+ * information that can be applied by the PEP locally. It is a
+ * variable length object and its internal format SHOULD be
+ * specified in the relevant COPS extension document for the given
+ * client-type. This object is optional in Decision messages and is
+ * interpreted relative to a given context.
+ *
+ * It is expected that even outsourcing PEPs will be able to make
+ * some simple stateless policy decisions locally in their LPDP. As
+ * this set is well known and implemented ubiquitously, PDPs are
+ * aware of it as well (either universally, through configuration,
+ * or using the Client-Open message). The PDP may also include this
+ * information in its decision, and the PEP MUST apply it to the
+ * resource allocation event that generated the request.
+ *
+ * C-Type = 3, Replacement Data
+ *
+ * This type of decision object carries replacement data that is to
+ * replace existing data in a signaled message. It is a variable
+ * length object and its internal format SHOULD be specified in the
+ * relevant COPS extension document for the given client-type. It is
+ * optional in Decision messages and is interpreted relative to a
+ * given context.
+ *
+ * C-Type = 4, Client Specific Decision Data
+ *
+ * Additional decision types can be introduced using the Client
+ * Specific Decision Data Object. It is a variable length object and
+ * its internal format SHOULD be specified in the relevant COPS
+ * extension document for the given client-type. It is optional in
+ * Decision messages and is interpreted relative to a given context.
+ *
+ * C-Type = 5, Named Decision Data
+ *
+ * Named configuration information is encapsulated in this version
+ * of the decision object in response to configuration requests. It
+ * is a variable length object and its internal format SHOULD be
+ * specified in the relevant COPS extension document for the given
+ * client-type. It is optional in Decision messages and is
+ * interpreted relative to both a given context and decision flags.
+ */
+public class COPSDecision extends COPSObjBase {
+
+ static Map<Integer, Command> VAL_TO_CMD = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_CMD.put(Command.NULL.ordinal(), Command.NULL);
+ VAL_TO_CMD.put(Command.INSTALL.ordinal(), Command.INSTALL);
+ VAL_TO_CMD.put(Command.REMOVE.ordinal(), Command.REMOVE);
+ }
+
+ static Map<Integer, DecisionFlag> VAL_TO_FLAG = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_FLAG.put(DecisionFlag.NA.ordinal(), DecisionFlag.NA);
+ VAL_TO_FLAG.put(DecisionFlag.REQERROR.ordinal(), DecisionFlag.REQERROR);
+ VAL_TO_FLAG.put(DecisionFlag.REQSTATE.ordinal(), DecisionFlag.REQSTATE);
+ }
+
+ /**
+ * All CTypes are supported except NA
+ */
+ private final Command _cmdCode;
+ private final DecisionFlag _flags;
+ private final COPSData _data;
+ private final COPSData _padding;
+
+ /**
+ * Constructor generally used for sending messages without any extra data
+ * @param cmdCode - the command
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDecision(final Command cmdCode) {
+ this(CType.DEF, cmdCode, DecisionFlag.NA, new COPSData());
+ }
+
+ /**
+ * Constructor generally used for sending messages with a specific CType and extra data and a NA decision flag
+ * @param cType - the CType
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDecision(final CType cType, final COPSData data) {
+ this(cType, Command.NULL, DecisionFlag.NA, data);
+ }
+
+ /**
+ * Constructor generally used for sending messages with a specific Command and DecisionFlag
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDecision(final Command cmdCode, final DecisionFlag flags) {
+ this(CType.DEF, cmdCode, flags, new COPSData());
+ }
+
+ /**
+ * Constructor generally used for sending messages with a specific, CType, Command and DecisionFlag
+ * @param cType - the CType
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDecision(final CType cType, final Command cmdCode, final DecisionFlag flags) {
+ this(cType, cmdCode, flags, new COPSData());
+ }
+
+ /**
+ * Constructor generally used for sending messages with a specific, CType, Command, DecisionFlag and data
+ * @param cType - the CType
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDecision(final CType cType, final Command cmdCode, final DecisionFlag flags,
+ final COPSData data) {
+ this(new COPSObjHeader(CNum.DEC, cType), cmdCode, flags, data);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSDecision(final COPSObjHeader hdr, final Command cmdCode, final DecisionFlag flags,
+ final COPSData data) {
+ super(hdr);
+ // TODO - find a better way to make this check
+ if (this.getClass().getName().equals("org.umu.cops.stack.COPSDecision") && !hdr.getCNum().equals(CNum.DEC))
+ throw new IllegalArgumentException("CNum must be equal to " + CNum.DEC);
+
+ if (hdr.getCType().equals(CType.NA)) throw new IllegalArgumentException("CType must not be " + CType.NA);
+ if (cmdCode == null) throw new IllegalArgumentException("Command code must not be null");
+ if (flags == null) throw new IllegalArgumentException("Flags must not be null");
+ if (data == null) throw new IllegalArgumentException("Data object must not be null");
+
+ _cmdCode = cmdCode;
+ _flags = flags;
+ _data = data;
+
+ if ((_data.length() % 4) != 0) {
+ final int padLen = 4 - (_data.length() % 4);
+ _padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ _padding = new COPSData();
+ }
+ }
+
+ /**
+ * Returns the command
+ * @return - the command
+ */
+ public Command getCommand() { return _cmdCode; }
+
+ @Override
+ public int getDataLength() {
+ return 4 + _data.length() + _padding.length();
+ }
+
+ /**
+ * Get the associated data if decision object is of cType 2 or higher
+ * @return a COPSData
+ */
+ public COPSData getData() {
+ return (_data);
+ }
+
+ /**
+ * If cType == 1 , get the flags associated
+ * @return a short
+ */
+ public DecisionFlag getFlag() {
+ return _flags;
+ }
+
+ /**
+ * Method getTypeStr
+ * @return a String
+ */
+ public String getTypeStr() {
+ switch (this.getHeader().getCType()) {
+ case DEF:
+ return "Default";
+ case STATELESS:
+ return "Stateless data";
+ case REPL:
+ return "Replacement data";
+ case CSI:
+ return "Client specific decision data";
+ case NAMED:
+ return "Named decision data";
+ default:
+ return "Unknown";
+ }
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ final byte[] buf = new byte[4];
+ buf[0] = (byte) (_cmdCode.ordinal() >> 8);
+ buf[1] = (byte) _cmdCode.ordinal();
+ buf[2] = (byte) (_flags.ordinal() >> 8);
+ buf[3] = (byte) _flags.ordinal();
+ COPSUtil.writeData(socket, buf, 4);
+
+ COPSUtil.writeData(socket, _data.getData(), _data.length());
+ if (_padding != null) {
+ COPSUtil.writeData(socket, _padding.getData(), _padding.length());
+ }
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ if (this.getHeader().getCType().equals(CType.DEF)) {
+ os.write(("Decision (" + getTypeStr() + ")\n").getBytes());
+ os.write(("Command code: " + _cmdCode + "\n").getBytes());
+ os.write(("Command flags: " + _flags + "\n").getBytes());
+ } else {
+ os.write(("Decision (" + getTypeStr() + ")\n").getBytes());
+ os.write(("Data: " + _data.str() + "\n").getBytes());
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSDecision)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSDecision that = (COPSDecision) o;
+
+ return _cmdCode == that._cmdCode && _flags == that._flags && _data.equals(that._data) &&
+ _padding.equals(that._padding) ||
+ COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _data.hashCode();
+ result = 31 * result + _cmdCode.hashCode();
+ result = 31 * result + _flags.hashCode();
+ result = 31 * result + _padding.hashCode();
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSDecision object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSDecision parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ int _cmdCode = 0;
+ _cmdCode |= ((short) dataPtr[4]) << 8;
+ _cmdCode |= ((short) dataPtr[5]) & 0xFF;
+
+ int _flags = 0;
+ _flags |= ((short) dataPtr[6]) << 8;
+ _flags |= ((short) dataPtr[7]) & 0xFF;
+
+ final COPSData d;
+ if (objHdrData.header.getCType().equals(CType.DEF)) {
+ d = null;
+ } else {
+ d = new COPSData(dataPtr, 8, objHdrData.msgByteCount - 8);
+ }
+ return new COPSDecision(objHdrData.header, COPSDecision.VAL_TO_CMD.get(_cmdCode),
+ COPSDecision.VAL_TO_FLAG.get(_flags), d);
+ }
+
+ /**
+ * Supported command types
+ */
+ public enum Command {
+ NULL, // No configuration data available
+ INSTALL, // Admit request/install configuration
+ REMOVE // Remove request/remove configuration
+ }
+
+ public enum DecisionFlag {
+ NA,
+ REQERROR, // = Trigger error
+ REQSTATE, // = ???
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-\r
-/**\r
- * COPS Decision Message\r
- *\r
- * @version COPSDecisionMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSDecisionMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSHandle _clientHandle;\r
- private COPSError _error;\r
- private Hashtable _decisions;\r
- private COPSIntegrity _integrity;\r
- private COPSContext _decContext;\r
- private COPSClientSI _decSI;\r
-\r
- ///\r
- public COPSDecisionMsg() {\r
- _clientHandle = null;\r
- _error = null;\r
- _decisions = new Hashtable(20);\r
- _integrity = null;\r
- _decContext = null;\r
- _decSI = null;\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_clientHandle == null) || ( (_error == null) && (_decisions.size() == 0))) {\r
- throw new COPSException("Bad message format");\r
- }\r
- }\r
-\r
- ///\r
- protected COPSDecisionMsg(byte[] data) throws COPSException {\r
- _decisions = new Hashtable(20);\r
- _clientHandle = null;\r
- _error = null;\r
- _integrity = null;\r
- _decContext = null;\r
- _decSI = null;\r
-\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Parses the data and fills COPSDecisionMsg with its constituents\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case HANDLE:\r
- _clientHandle = new COPSHandle(buf);\r
- _dataStart += _clientHandle.getDataLength();\r
- break;\r
- case CONTEXT:\r
- //dec context\r
- _decContext = new COPSContext(buf);\r
- _dataStart += _decContext.getDataLength();\r
- break;\r
- case ERROR:\r
- _error = new COPSError(buf);\r
- _dataStart += _error.getDataLength();\r
- break;\r
- case DEC:\r
- COPSDecision decs = new COPSDecision(buf);\r
- _dataStart += decs.getDataLength();\r
- addDecision(decs, _decContext);\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default: {\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Parses the data and fills that follows the header hdr and fills COPSDecisionMsg\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_DEC)\r
- throw new COPSException ("Error Header (no COPS_OP_DEC)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add client handle to the message\r
- *\r
- * @param handle a COPSHandle\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHandle handle) throws COPSException {\r
- if (handle == null)\r
- throw new COPSException ("Null Handle");\r
- _clientHandle = handle;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add an Error object\r
- *\r
- * @param error a COPSError\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSError error) throws COPSException {\r
- if (_decisions.size() != 0)\r
- throw new COPSException ("No null decisions");\r
- if (_error != null)\r
- throw new COPSException ("No null error");\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("No null integrity");\r
- _error = error;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add one or more local decision object for a given decision context\r
- * the context is optional, if null all decision object are tided to\r
- * message context\r
- *\r
- * @param decision a COPSDecision\r
- * @param context a COPSContext\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void addDecision(COPSDecision decision, COPSContext context) throws COPSException {\r
- //Either error or decision can be added\r
- //If error is aleady there assert\r
- if (_error != null)\r
- throw new COPSException ("No null error");\r
-\r
- if (decision.isLocalDecision())\r
- throw new COPSException ("Is local decision");\r
-\r
- Vector v = (Vector) _decisions.get(context);\r
- if (v == null) v = new Vector();\r
-\r
- if (decision.isFlagSet()) {//Commented out as advised by Felix\r
- //if (v.size() != 0)\r
- //{\r
- //Only one set of decision flags is allowed\r
- //for each context\r
- // throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");\r
- //}\r
- } else {\r
- if (v.size() == 0) {\r
- //The flags decision must precede any other\r
- //decision message, since the decision is not\r
- //flags throw exception\r
- throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");\r
- }\r
- }\r
- v.add(decision);\r
- _decisions.put(context,v);\r
-\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
- /**\r
- * Add clientSI object\r
- *\r
- * @param clientSI a COPSClientSI\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSClientSI clientSI) throws COPSException {\r
- if (clientSI == null)\r
- throw new COPSException ("Null clientSI");\r
- /*\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- */\r
- _decSI = clientSI;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_clientHandle != null) _clientHandle.writeData(id);\r
- if (_error != null) _error.writeData(id);\r
-\r
- //Display decisions\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- context.writeData(id);\r
-\r
- for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
- COPSDecision decision = (COPSDecision) ee.nextElement();\r
- decision.writeData(id);\r
- }\r
- }\r
-\r
- if (_decSI != null) _decSI.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Method getHeader\r
- *\r
- * @return a COPSHeader\r
- *\r
- */\r
- public COPSHeader getHeader() {\r
- return _hdr;\r
- }\r
-\r
- /**\r
- * Method getClientHandle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _clientHandle;\r
- }\r
-\r
- /**\r
- * Returns true if it has error object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasError() {\r
- return (_error != null);\r
- };\r
-\r
- /**\r
- * Should check hasError() before calling\r
- *\r
- * @return a COPSError\r
- *\r
- */\r
- public COPSError getError() {\r
- return _error;\r
- };\r
-\r
- /**\r
- * Returns a map of decision for which is an arry of context and vector\r
- * of associated decision object.\r
- *\r
- * @return a Hashtable\r
- *\r
- */\r
- public Hashtable getDecisions() {\r
- return _decisions;\r
- };\r
-\r
- /**\r
- * Returns true if it has integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- };\r
-\r
- /**\r
- * Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return _integrity;\r
- };\r
-\r
- /**\r
- * Method setMsgLength\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_clientHandle != null)\r
- len += _clientHandle.getDataLength();\r
- if (_error != null)\r
- len += _error.getDataLength();\r
-\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- len += context.getDataLength();\r
-\r
- for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
- COPSDecision decision = (COPSDecision) ee.nextElement();\r
- len += decision.getDataLength();\r
- }\r
- }\r
- if (_decSI != null) {\r
- len += _decSI.getDataLength();\r
- }\r
- if (_integrity != null) {\r
- len += _integrity.getDataLength();\r
- }\r
-\r
- _hdr.setMsgLength((int) len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_clientHandle != null)\r
- _clientHandle.dump(os);\r
- if (_error != null)\r
- _error.dump(os);\r
-\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- context.dump(os);\r
-\r
- for (Enumeration ee = v.elements() ; ee.hasMoreElements() ;) {\r
- COPSDecision decision = (COPSDecision) ee.nextElement();\r
- decision.dump(os);\r
- }\r
- }\r
- if (_decSI != null) {\r
- _decSI.dump(os);\r
- }\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.*;
+
+/**
+ * COPS Decision Message (RFC 2748 page. 23)
+ *
+ * The PDP responds to the REQ with a DEC message that includes the
+ * associated client handle and one or more decision objects grouped
+ * relative to a Context object and Decision Flags object type pair. If
+ * there was a protocol error an error object is returned instead.
+ *
+ * It is required that the first decision message for a new/updated
+ * request will have the solicited message flag set (value = 1) in the
+ * COPS header. This avoids the issue of keeping track of which updated
+ * request (that is, a request reissued for the same handle) a
+ * particular decision corresponds. It is important that, for a given
+ * handle, there be at most one outstanding solicited decision per
+ * request. This essentially means that the PEP SHOULD NOT issue more
+ * than one REQ (for a given handle) before it receives a corresponding
+ * DEC with the solicited message flag set. The PDP MUST always issue
+ * decisions for requests on a particular handle in the order they
+ * arrive and all requests MUST have a corresponding decision.
+ *
+ * To avoid deadlock, the PEP can always timeout after issuing a request
+ * that does not receive a decision. It MUST then delete the timed-out
+ * handle, and may try again using a new handle.
+ *
+ * The format of the Decision message is as follows:
+ *
+ * <Decision Message> ::= <Common Header>
+ * <Client Handle>
+ * <Decision(s)> | <Error>
+ * [<Integrity>]
+ *
+ * <Decision(s)> ::= <Decision> | <Decision(s)> <Decision>
+ *
+ * <Decision> ::= <Context>
+ * <Decision: Flags>
+ * [<Decision: Stateless Data>]
+ * [<Decision: Replacement Data>]
+ * [<Decision: ClientSI Data>]
+ * [<Decision: Named Data>]
+ *
+ * The Decision message may include either an Error object or one or
+ * more context plus associated decision objects. COPS protocol problems
+ * are reported in the Error object (e.g. an error with the format of
+ * the original request including malformed request messages, unknown
+ * COPS objects in the Request, etc.). The applicable Decision object(s)
+ * depend on the context and the type of client. The only ordering
+ * requirement for decision objects is that the required Decision Flags
+ * object type MUST precede the other Decision object types per context
+ * binding.
+ */
+public class COPSDecisionMsg extends COPSMsg {
+
+ // Required
+ private final COPSHandle _clientHandle;
+
+ // Optional
+ private final COPSError _error;
+ private final Map<COPSContext, Set<COPSDecision>> _decisions;
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor for Decision messages containing a COPS Error.
+ * As this has been deprecated, the constructor containing the version and Flag should be used going forward.
+ * @param clientType - the client type (required)
+ * @param clientHandle - the handle (required)
+ * @param error - the error (required)
+ * @param integrity - the integrity (optional)
+ */
+ @Deprecated
+ public COPSDecisionMsg(final short clientType, final COPSHandle clientHandle,
+ final COPSError error, final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.DEC, clientType), clientHandle, error, null, integrity);
+ }
+
+ /**
+ * Constructor for Decision messages containing a COPS Error.
+ * @param clientType - the client type (required)
+ * @param clientHandle - the handle (required)
+ * @param error - the error (required)
+ * @param integrity - the integrity (optional)
+ */
+ public COPSDecisionMsg(final int version, final Flag flag, final short clientType, final COPSHandle clientHandle,
+ final COPSError error, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.DEC, clientType), clientHandle, error, null, integrity);
+ }
+
+ /**
+ * Constructor for Decision messages containing decisions
+ * As this has been deprecated, the constructor containing the version and Flag should be used going forward.
+ * @param clientType - the client type (required)
+ * @param clientHandle - the handle (required)
+ * @param decisions - the decisions (required)
+ * @param integrity - the integrity (optional)
+ */
+ @Deprecated
+ public COPSDecisionMsg(final short clientType, final COPSHandle clientHandle,
+ final Map<COPSContext, Set<COPSDecision>> decisions, final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.DEC, clientType), clientHandle, null, decisions, integrity);
+ }
+
+ /**
+ * Constructor for Decision messages containing decisions
+ * @param clientType - the client type (required)
+ * @param clientHandle - the handle (required)
+ * @param decisions - the decisions (required)
+ * @param integrity - the integrity (optional)
+ */
+ public COPSDecisionMsg(final int version, final Flag flag, final short clientType, final COPSHandle clientHandle,
+ final Map<COPSContext, Set<COPSDecision>> decisions, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.DEC, clientType), clientHandle, null, decisions, integrity);
+ }
+
+ /**
+ * Constructor generally designed for Decision messages being parsed from a byte array.
+ * @param hdr - the header
+ * @param clientHandle - the handle
+ * @param error - the error (if null, decisions must not be null or empty)
+ * @param decisions - the decisions (must be empty or null if error is not)
+ * @param integrity - the integrity (optional)
+ */
+ protected COPSDecisionMsg(final COPSHeader hdr, final COPSHandle clientHandle,
+ final COPSError error, final Map<COPSContext, Set<COPSDecision>> decisions,
+ final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.DEC))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.DEC);
+ if (clientHandle == null) throw new IllegalArgumentException("Client handle must not be null");
+ if (error == null && (decisions == null || decisions.isEmpty()))
+ throw new IllegalArgumentException("Must contain either an COPSError or at least one decision");
+ if (error != null && (decisions != null && !decisions.isEmpty()))
+ throw new IllegalArgumentException("Must not contain a COPSError and decisions");
+
+ if(decisions == null) _decisions = Collections.unmodifiableMap(new HashMap<COPSContext, Set<COPSDecision>>());
+ else _decisions = Collections.unmodifiableMap(decisions);
+
+ for (Set<COPSDecision> decSet: _decisions.values()) {
+ if (decSet == null || decSet.isEmpty())
+ throw new IllegalArgumentException("Decisions are empty");
+ }
+
+ _clientHandle = clientHandle;
+ _error = error;
+ _integrity = integrity;
+
+ }
+
+ // Getters
+ public COPSHandle getClientHandle() {
+ return _clientHandle;
+ }
+ public COPSError getError() {
+ return _error;
+ }
+ public Map<COPSContext, Set<COPSDecision>> getDecisions() {
+ return _decisions;
+ }
+ public COPSIntegrity getIntegrity() {
+ return _integrity;
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = 0;
+ out += _clientHandle.getDataLength() + _clientHandle.getHeader().getHdrLength();
+ if (_error != null) out += _error.getDataLength() + _error.getHeader().getHdrLength();
+
+ for (final Map.Entry<COPSContext, Set<COPSDecision>> entry : _decisions.entrySet()) {
+ out += entry.getKey().getDataLength() + entry.getKey().getHeader().getHdrLength();
+ for (final COPSDecision decision : entry.getValue()) {
+ out += decision.getDataLength() + decision.getHeader().getHdrLength();
+ }
+ }
+
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+
+ return out;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _clientHandle.writeData(socket);
+ if (_error != null) _error.writeData(socket);
+
+ //Display decisions
+ //Display any local decisions
+ for (final Map.Entry<COPSContext, Set<COPSDecision>> entry : _decisions.entrySet()) {
+ entry.getKey().writeData(socket);
+ for (final COPSDecision decision : entry.getValue()) {
+ decision.writeData(socket);
+ }
+ }
+
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ if (_clientHandle != null)
+ _clientHandle.dump(os);
+ if (_error != null)
+ _error.dump(os);
+
+ //Display any local decisions
+ for (final Map.Entry<COPSContext, Set<COPSDecision>> entry : _decisions.entrySet()) {
+ entry.getKey().dump(os);
+ for (final COPSDecision decision : entry.getValue()) {
+ decision.dump(os);
+ }
+ }
+ if (_integrity != null) {
+ _integrity.dump(os);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSDecisionMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSDecisionMsg that = (COPSDecisionMsg) o;
+
+ for (final Map.Entry<COPSContext, Set<COPSDecision>> entry : this._decisions.entrySet()) {
+ final Set<COPSDecision> thatDecisions = that._decisions.get(entry.getKey());
+ if (thatDecisions == null) return false;
+
+ for (final COPSDecision thisDecision : entry.getValue()) {
+ boolean found = false;
+ for (final COPSDecision thatDecision: thatDecisions) {
+ if (thisDecision.equals(thatDecision)) {
+ found = true;
+ break;
+ }
+ }
+ if (! found) return false;
+ }
+ }
+
+ return _clientHandle.equals(that._clientHandle) &&
+ !(_error != null ? !_error.equals(that._error) : that._error != null) &&
+ !(_integrity != null ? !_integrity.equals(that._integrity) : that._integrity != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _clientHandle.hashCode();
+ result = 31 * result + (_error != null ? _error.hashCode() : 0);
+ result = 31 * result + _decisions.hashCode();
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSDecisionMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSHandle clientHandle = null;
+ COPSContext context = null;
+ COPSError error = null;
+ COPSIntegrity integrity = null;
+ final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case HANDLE:
+ clientHandle = COPSHandle.parse(objHdrData, buf);
+ break;
+ case CONTEXT:
+ if (context == null) {
+ context = COPSContext.parse(objHdrData, buf);
+ } else context = COPSContext.parse(objHdrData, buf);
+ break;
+ case ERROR:
+ error = COPSError.parse(objHdrData, buf);
+ break;
+ case DEC:
+ if (decisionMap.get(context) != null)
+ decisionMap.get(context).add(COPSDecision.parse(objHdrData, buf));
+ else {
+ final Set<COPSDecision> decisions = new HashSet<>();
+ decisions.add(COPSDecision.parse(objHdrData, buf));
+ decisionMap.put(context, decisions);
+ }
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSDecisionMsg(hdrData.header, clientHandle, error, decisionMap, integrity);
+ }
+
+}
\ No newline at end of file
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Delete Message (RFC 2748 pag. 24)\r
- *\r
- * When sent from the PEP this message indicates to the remote PDP that\r
- * the state identified by the client handle is no longer\r
- * available/relevant. This information will then be used by the remote\r
- * PDP to initiate the appropriate housekeeping actions. The reason code\r
- * object is interpreted with respect to the client-type and signifies\r
- * the reason for the removal.\r
- *\r
- * The format of the Delete Request State message is as follows:\r
- *\r
- * <Delete Request> ::= <Common Header>\r
- * <Client Handle>\r
- * <Reason>\r
- * [<Integrity>]\r
- *\r
- *\r
- * @version COPSDeleteMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSDeleteMsg extends COPSMsg {\r
- /* COPSHeader coming from base class */\r
- private COPSHandle _clientHandle;\r
- private COPSReason _reason;\r
- private COPSIntegrity _integrity;\r
-\r
- public COPSDeleteMsg() {\r
- _clientHandle = null;\r
- _reason = null;\r
- _integrity = null;\r
- }\r
-\r
- /**\r
- Parse data and create COPSDeleteMsg object\r
- */\r
- protected COPSDeleteMsg(byte[] data) throws COPSException {\r
- _clientHandle = null;\r
- _reason = null;\r
- _integrity = null;\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Checks the sanity of COPS message and throw an\r
- * COPSException when data is bad.\r
- *\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_clientHandle == null) || (_reason == null))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ)\r
- throw new COPSException ("Error Header (no COPS_OP_DRQ)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Reason object to the message\r
- *\r
- * @param reason a COPSReason\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSReason reason) throws COPSException {\r
- if (_reason != null)\r
- throw new COPSException ("No null Reason");\r
-\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("No null Integrity");\r
- _reason = reason;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Handle object\r
- *\r
- * @param handle a COPSHandle\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHandle handle) throws COPSException {\r
- if (handle == null)\r
- throw new COPSException ("Null Handle");\r
- _clientHandle = handle;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Get Client Handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _clientHandle;\r
- };\r
-\r
- /**\r
- * Get Reason\r
- *\r
- * @return a COPSReason\r
- *\r
- */\r
- public COPSReason getReason() {\r
- return _reason;\r
- };\r
-\r
- /**\r
- * Returns true if it has integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- };\r
-\r
- /**\r
- * Get Integrity. Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Writes data to given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_clientHandle != null) _clientHandle.writeData(id);\r
- if (_reason != null) _reason.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case HANDLE:\r
- _clientHandle = new COPSHandle(buf);\r
- _dataStart += _clientHandle.getDataLength();\r
- break;\r
- case REASON_CODE:\r
- _reason = new COPSReason(buf);\r
- _dataStart += _reason.getDataLength();\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_DRQ)\r
- throw new COPSException("Error Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_clientHandle != null) len += _clientHandle.getDataLength();\r
- if (_reason != null) len += _reason.getDataLength();\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_clientHandle != null)\r
- _clientHandle.dump(os);\r
-\r
- if (_reason != null)\r
- _reason.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Delete Message (RFC 2748 pag. 24)
+ *
+ * When sent from the PEP this message indicates to the remote PDP that
+ * the state identified by the client handle is no longer
+ * available/relevant. This information will then be used by the remote
+ * PDP to initiate the appropriate housekeeping actions. The reason code
+ * object is interpreted with respect to the client-type and signifies
+ * the reason for the removal.
+ *
+ * The format of the Delete Request State message is as follows:
+ *
+ * <Delete Request> ::= <Common Header>
+ * <Client Handle>
+ * <Reason>
+ * [<Integrity>]
+ *
+ *
+ * @version COPSDeleteMsg.java, v 1.00 2003
+ *
+ */
+public class COPSDeleteMsg extends COPSMsg {
+ // Required
+ private final COPSHandle _clientHandle;
+ private final COPSReason _reason;
+
+ // Optional
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the COPS Handle (required)
+ * @param reason - the reason (required)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSDeleteMsg(final short clientType, final COPSHandle handle, final COPSReason reason,
+ final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.DRQ, clientType), handle, reason, integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the COPS Handle (required)
+ * @param reason - the reason (required)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSDeleteMsg(final int version, final Flag flag, final short clientType, final COPSHandle handle,
+ final COPSReason reason, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.DRQ, clientType), handle, reason, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param handle - the COPS Handle (required)
+ * @param reason - the reason (required)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSDeleteMsg(final COPSHeader hdr, final COPSHandle handle, final COPSReason reason,
+ final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.DRQ))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.DRQ);
+ if (handle == null) throw new IllegalArgumentException("COPSHandle must not be null");
+ if (reason == null) throw new IllegalArgumentException("COPSReason must not be null");
+
+ _clientHandle = handle;
+ _reason = reason;
+ _integrity = integrity;
+ }
+
+ // Getters
+ public COPSHandle getClientHandle() {
+ return _clientHandle;
+ }
+ public COPSReason getReason() {
+ return _reason;
+ }
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _clientHandle.getDataLength() + _clientHandle.getHeader().getHdrLength();
+ out += _reason.getDataLength() + _reason.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _clientHandle.writeData(socket);
+ _reason.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ _clientHandle.dump(os);
+ _reason.dump(os);
+ if (_integrity != null) {
+ _integrity.dump(os);
+ }
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSDeleteMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSDeleteMsg that = (COPSDeleteMsg) o;
+
+ return _clientHandle.equals(that._clientHandle) &&
+ !(_integrity != null ? !_integrity.equals(that._integrity) : that._integrity != null) &&
+ _reason.equals(that._reason);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _clientHandle.hashCode();
+ result = 31 * result + _reason.hashCode();
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSDeleteMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSHandle clientHandle = null;
+ COPSReason reason = null;
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case HANDLE:
+ clientHandle = COPSHandle.parse(objHdrData, buf);
+ break;
+ case REASON_CODE:
+ reason = COPSReason.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSDeleteMsg(hdrData.header, clientHandle, reason, integrity);
+ }
+}
+
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Error\r
- *\r
- * @version COPSError.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSError extends COPSObjBase {\r
-\r
- public final static byte COPS_ERR_BAD_HANDLE = 1;\r
- public final static byte COPS_ERR_BAD_HANDLE_REF = 2;\r
- public final static byte COPS_ERR_BAD_MSG_FORMAT = 3;\r
- public final static byte COPS_ERR_FAIL_PROCESS = 4;\r
- public final static byte COPS_ERR_MISSING_INFO = 5;\r
- public final static byte COPS_ERR_UNSUPPORTED_CLIENT_TYPE = 6;\r
- public final static byte COPS_ERR_MANDATORY_OBJECT_MISSING = 7;\r
- public final static byte COPS_ERR_CLIENT_FAILURE = 8;\r
- public final static byte COPS_ERR_COMM_FAILURE = 9;\r
- public final static byte COPS_ERR_UNKNOWN = 10;\r
- public final static byte COPS_ERR_SHUTTING_DOWN = 11;\r
- public final static byte COPS_ERR_PDP_REDIRECT = 12;\r
- public final static byte COPS_ERR_UNKNOWN_OBJECT = 13;\r
- public final static byte COPS_ERR_AUTH_FAILURE = 14;\r
- public final static byte COPS_ERR_AUTH_REQUIRED = 15;\r
- public final static byte COPS_ERR_MA = 16;\r
-\r
- private final static String G_errmsgArray[] = {\r
- "Unknown.",\r
- "Bad handle.",\r
- "Invalid handle reference.",\r
- "Bad message format (Malformed message).",\r
- "Unable to process.",\r
- "Mandatory client-specific info missing.",\r
- "Unsupported client-type",\r
- "Mandatory COPS object missing.",\r
- "Client failure.",\r
- "Communication failure.",\r
- "Unknown.",\r
- "Shutting down.",\r
- "Redirect to preferred server.",\r
- "Unknown COPS object",\r
- "Authentication failure.",\r
- "Authentication required.",\r
- };\r
-\r
- private COPSObjHeader _objHdr;\r
- private short _errCode;\r
- private short _errSubCode;\r
-\r
- public COPSError(short errCode, short subCode) {\r
- _objHdr = new COPSObjHeader(CNum.ERROR, CType.DEF);\r
- _errCode = errCode;\r
- _errSubCode = subCode;\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- protected COPSError(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
- _errCode |= ((short) dataPtr[4]) << 8;\r
- _errCode |= ((short) dataPtr[5]) & 0xFF;\r
- _errSubCode |= ((short) dataPtr[6]) << 8;\r
- _errSubCode |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- // _objHdr.setDataLength(sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- public short getErrCode() {\r
- return _errCode;\r
- }\r
- \r
- public short getErrSubCode() {\r
- return _errSubCode;\r
- }\r
- /**\r
- * Returns size in number of octects\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- return (_objHdr.getDataLength());\r
- };\r
-\r
- /**\r
- * Method getDescription\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String getDescription() {\r
- String errStr1;\r
- String errStr2;\r
-\r
- ///Get the details from the error code\r
- errStr1 = G_errmsgArray[_errCode];\r
- //TODO - define error sub-codes\r
- errStr2 = "";\r
- return (errStr1 + ":" + errStr2);\r
- }\r
-\r
- /**\r
- * Method isError\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isError() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Writes object to given network socket in network byte order\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_errCode >> 8);\r
- buf[1] = (byte) _errCode;\r
- buf[2] = (byte) (_errSubCode >> 8);\r
- buf[3] = (byte) _errSubCode;\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Error Code: " + _errCode + "\n").getBytes());\r
- os.write(new String("Error Sub Code: " + _errSubCode + "\n").getBytes());\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Error (RFC 2748)
+ *
+ * This object is used to identify a particular COPS protocol error.
+ * The error sub-code field contains additional detailed client specific
+ * error codes. The appropriate Error Sub-codes for a particular
+ * client-type SHOULD be specified in the relevant COPS extensions
+ * document.
+ *
+ * C-Num = 8, C-Type = 1
+ *
+ * Error-Code:
+ *
+ * 1 = Bad handle
+ * 2 = Invalid handle reference
+ * 3 = Bad message format (Malformed Message)
+ * 4 = Unable to process (server gives up on query)
+ * 5 = Mandatory client-specific info missing
+ * 6 = Unsupported client-type
+ * 7 = Mandatory COPS object missing
+ * 8 = Client Failure
+ * 9 = Communication Failure
+ * 10= Unspecified
+ * 11= Shutting down
+ * 12= Redirect to Preferred Server
+ * 13= Unknown COPS Object:
+ * Sub-code (octet 2) contains unknown object's C-Num
+ * and (octet 3) contains unknown object's C-Type.
+ * 14= Authentication Failure
+ * 15= Authentication Required
+ */
+public class COPSError extends COPSObjBase {
+
+ public final static Map<Integer, ErrorTypes> ERROR_CODE_TO_TYPE = new ConcurrentHashMap<>();
+ static {
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.NA.ordinal(), ErrorTypes.NA);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE.ordinal(), ErrorTypes.BAD_HANDLE);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE_REF.ordinal(), ErrorTypes.BAD_HANDLE_REF);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_MSG_FORMAT.ordinal(), ErrorTypes.BAD_MSG_FORMAT);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.FAIL_PROCESS.ordinal(), ErrorTypes.FAIL_PROCESS);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.MISSING_INFO.ordinal(), ErrorTypes.MISSING_INFO);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE.ordinal(), ErrorTypes.UNSUPPORTED_CLIENT_TYPE);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.MANDATORY_OBJECT_MISSING.ordinal(), ErrorTypes.MANDATORY_OBJECT_MISSING);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.CLIENT_FAILURE.ordinal(), ErrorTypes.CLIENT_FAILURE);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.COMM_FAILURE.ordinal(), ErrorTypes.COMM_FAILURE);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN.ordinal(), ErrorTypes.UNKNOWN);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.SHUTTING_DOWN.ordinal(), ErrorTypes.SHUTTING_DOWN);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.PDP_REDIRECT.ordinal(), ErrorTypes.PDP_REDIRECT);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN_OBJECT.ordinal(), ErrorTypes.UNKNOWN_OBJECT);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_FAILURE.ordinal(), ErrorTypes.AUTH_FAILURE);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_REQUIRED.ordinal(), ErrorTypes.AUTH_REQUIRED);
+ ERROR_CODE_TO_TYPE.put(ErrorTypes.MA.ordinal(), ErrorTypes.MA);
+ }
+
+ private final static Map<ErrorTypes, String> ERROR_TYPE_TO_STRING = new ConcurrentHashMap<>();
+ static {
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.NA, "Unknown.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE, "Bad handle.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE_REF, "Invalid handle reference.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_MSG_FORMAT, "Bad message format (Malformed message).");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.FAIL_PROCESS, "Unable to process.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.MISSING_INFO, "Mandatory client-specific info missing.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, "Unsupported client-type");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.MANDATORY_OBJECT_MISSING, "Mandatory COPS object missing.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.CLIENT_FAILURE, "Client failure.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.COMM_FAILURE, "Communication failure.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN, "Unknown.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.SHUTTING_DOWN, "Shutting down.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.PDP_REDIRECT, "Redirect to preferred server.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN_OBJECT, "Unknown COPS object");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_FAILURE, "Authentication failure.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_REQUIRED, "Authentication required.");
+ ERROR_TYPE_TO_STRING.put(ErrorTypes.MA, "Authentication required.");
+ }
+
+ /**
+ * The error code
+ */
+ private ErrorTypes _errCode;
+
+ /**
+ * Additional detailed client specific error codes
+ */
+ private ErrorTypes _errSubCode;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param errCode - the error code
+ * @param subCode - the type of message
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSError(final ErrorTypes errCode, final ErrorTypes subCode) {
+ this(new COPSObjHeader(CNum.ERROR, CType.DEF), errCode, subCode);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param errCode - the error code
+ * @param subCode - the type of message
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSError(final COPSObjHeader hdr, final ErrorTypes errCode, final ErrorTypes subCode) {
+ super(hdr);
+ if (!hdr.getCNum().equals(CNum.ERROR))
+ throw new IllegalArgumentException("Must have a CNum value of " + CNum.ERROR);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
+ if (errCode == null || subCode == null) throw new IllegalArgumentException("Error codes must not be null");
+ if (errCode.equals(ErrorTypes.NA))
+ throw new IllegalArgumentException("Error code must not be of type " + ErrorTypes.NA);
+
+ _errCode = errCode;
+ _errSubCode = subCode;
+ }
+
+ public ErrorTypes getErrCode() {
+ return _errCode;
+ }
+
+ public ErrorTypes getErrSubCode() {
+ return _errSubCode;
+ }
+
+ @Override
+ public int getDataLength() {
+ return 4;
+ }
+
+ /**
+ * Method getDescription
+ * @return a String
+ */
+ public String getDescription() {
+ String errStr1;
+ String errStr2;
+
+ ///Get the details from the error code
+ errStr1 = ERROR_TYPE_TO_STRING.get(_errCode);
+ //TODO - define error sub-codes
+ errStr2 = "";
+ return (errStr1 + ":" + errStr2);
+ }
+
+ @Override
+ public void writeBody(final Socket socket) throws IOException {
+ final byte[] buf = new byte[4];
+
+ buf[0] = (byte) ((byte)_errCode.ordinal() >> 8);
+ buf[1] = (byte)_errCode.ordinal();
+ buf[2] = (byte) ((byte)_errSubCode.ordinal() >> 8);
+ buf[3] = (byte)_errSubCode.ordinal();
+
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Error Code: " + _errCode + "\n").getBytes());
+ os.write(("Error Sub Code: " + _errSubCode + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSError)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSError copsError = (COPSError) o;
+
+ return _errCode == copsError._errCode && _errSubCode == copsError._errSubCode;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (_errCode != null ? _errCode.hashCode() : 0);
+ result = 31 * result + (_errSubCode != null ? _errSubCode.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSError parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ int errCode = 0;
+ errCode |= ((short) dataPtr[4]) << 8;
+ errCode |= ((short) dataPtr[5]) & 0xFF;
+
+ int errSubCode = 0;
+ errSubCode |= ((short) dataPtr[6]) << 8;
+ errSubCode |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSError(objHdrData.header, ERROR_CODE_TO_TYPE.get(errCode), ERROR_CODE_TO_TYPE.get(errSubCode));
+ }
+
+ /**
+ * The different error types and the ordinal value will be serialized
+ */
+ public enum ErrorTypes {
+ NA,
+ BAD_HANDLE,
+ BAD_HANDLE_REF,
+ BAD_MSG_FORMAT,
+ FAIL_PROCESS,
+ MISSING_INFO,
+ UNSUPPORTED_CLIENT_TYPE,
+ MANDATORY_OBJECT_MISSING,
+ CLIENT_FAILURE,
+ COMM_FAILURE,
+ UNKNOWN,
+ SHUTTING_DOWN,
+ PDP_REDIRECT,
+ UNKNOWN_OBJECT,
+ AUTH_FAILURE,
+ AUTH_REQUIRED,
+ MA
+ }
+
+}
+
rc = retCode;\r
}\r
\r
+ public COPSException(String msg, Throwable t) {\r
+ super(msg, t);\r
+ }\r
+\r
/**\r
* Method returnCode\r
*\r
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Handle Object (RFC 2748 pag. 9)\r
- *\r
- * The Handle Object encapsulates a unique value that identifies an\r
- * installed state. This identification is used by most COPS operations.\r
- *\r
- * C-Num = 1\r
- *\r
- * C-Type = 1, Client Handle.\r
- *\r
- * Variable-length field, no implied format other than it is unique from\r
- * other client handles from the same PEP (a.k.a. COPS TCP connection)\r
- * for a particular client-type. It is always initially chosen by the\r
- * PEP and then deleted by the PEP when no longer applicable. The client\r
- * handle is used to refer to a request state initiated by a particular\r
- * PEP and installed at the PDP for a client-type. A PEP will specify a\r
- * client handle in its Request messages, Report messages and Delete\r
- * messages sent to the PDP. In all cases, <b>the client handle is used to\r
- * uniquely identify a particular PEP's request for a client-type</b>.\r
- *\r
- * The client handle value is set by the PEP and is opaque to the PDP.\r
- * The PDP simply performs a byte-wise comparison on the value in this\r
- * object with respect to the handle object values of other currently\r
- * installed requests.\r
- *\r
- * @version COPSHandle.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSHandle extends COPSObjBase {\r
-\r
- private final COPSObjHeader _objHdr;\r
- private final COPSData _id;\r
- private final COPSData _padding;\r
-\r
- /**\r
- * Constructor\r
- * @param id - the identifier (must not be null)\r
- * @throws java.lang.IllegalArgumentException when the id parameter is null\r
- */\r
- public COPSHandle(final COPSData id) {\r
- if (id == null) throw new IllegalArgumentException("COPSData must not be null");\r
- _objHdr = new COPSObjHeader(CNum.HANDLE, CType.DEF);\r
- _id = id;\r
- if ((_id.length() % 4) != 0) {\r
- final int padLen = 4 - (_id.length() % 4);\r
- _padding = getPadding(padLen);\r
- } else {\r
- _padding = new COPSData();\r
- }\r
- _objHdr.setDataLength((short) _id.length());\r
- }\r
-\r
- /**\r
- * Constructor\r
- * @param dataPtr - the data to parse for setting this object's attributes\r
- */\r
- protected COPSHandle(final byte[] dataPtr) {\r
- if (dataPtr == null || dataPtr.length < 5)\r
- throw new IllegalArgumentException("Data cannot be null or fewer than 5 bytes");\r
-\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- //Get the length of data following the obj header\r
- final int dLen = _objHdr.getDataLength() - 4;\r
- _id = new COPSData(dataPtr, 4, dLen);\r
- if ((_id.length() % 4) != 0) {\r
- final int padLen = 4 - (_id.length() % 4);\r
- _padding = getPadding(padLen);\r
- } else {\r
- _padding = new COPSData();\r
- }\r
- _objHdr.setDataLength((short) _id.length());\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- * @return a short\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- final int lpadding;\r
- if (_padding != null) lpadding = _padding.length();\r
- else lpadding = 0;\r
- return ((short) (_objHdr.getDataLength() + lpadding));\r
- }\r
-\r
- /**\r
- * Get handle value\r
- * @return a COPSData\r
- */\r
- public COPSData getId() {\r
- return _id;\r
- }\r
-\r
- @Override\r
- public boolean isClientHandle() {\r
- return true;\r
- }\r
-\r
- @Override\r
- public void writeData(final Socket socket) throws IOException {\r
- _objHdr.writeData(socket);\r
-\r
- COPSUtil.writeData(socket, _id.getData(), _id.length());\r
- if (_padding != null) {\r
- COPSUtil.writeData(socket, _padding.getData(), _padding.length());\r
- }\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- * @param os an OutputStream\r
- * @throws IOException\r
- */\r
- public void dump(final OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(("client-handle: " + _id.str() + "\n").getBytes());\r
- }\r
-\r
- @Override\r
- public boolean equals(Object o) {\r
- if (this == o) {\r
- return true;\r
- }\r
- if (!(o instanceof COPSHandle)) {\r
- return false;\r
- }\r
- final COPSHandle that = (COPSHandle) o;\r
- return _id.equals(that._id) && _objHdr.equals(that._objHdr);\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- int result = _objHdr.hashCode();\r
- result = 31 * result + _id.hashCode();\r
- return result;\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Handle Object (RFC 2748 pag. 9)
+ *
+ * The Handle Object encapsulates a unique value that identifies an
+ * installed state. This identification is used by most COPS operations.
+ *
+ * C-Num = 1
+ *
+ * C-Type = 1, Client Handle.
+ *
+ * Variable-length field, no implied format other than it is unique from
+ * other client handles from the same PEP (a.k.a. COPS TCP connection)
+ * for a particular client-type. It is always initially chosen by the
+ * PEP and then deleted by the PEP when no longer applicable. The client
+ * handle is used to refer to a request state initiated by a particular
+ * PEP and installed at the PDP for a client-type. A PEP will specify a
+ * client handle in its Request messages, Report messages and Delete
+ * messages sent to the PDP. In all cases, <b>the client handle is used to
+ * uniquely identify a particular PEP's request for a client-type</b>.
+ *
+ * The client handle value is set by the PEP and is opaque to the PDP.
+ * The PDP simply performs a byte-wise comparison on the value in this
+ * object with respect to the handle object values of other currently
+ * installed requests.
+ *
+ */
+public class COPSHandle extends COPSObjBase {
+
+ /**
+ * The payload data
+ */
+ private final COPSData _data;
+
+ /**
+ * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes
+ */
+ private final COPSData _padding;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param id - the identifier (must not be null)
+ * @throws java.lang.IllegalArgumentException when the id parameter is null
+ */
+ public COPSHandle(final COPSData id) {
+ this(new COPSObjHeader(CNum.HANDLE, CType.DEF), id);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param data - the ID
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSHandle(final COPSObjHeader objHdr, final COPSData data) {
+ super(objHdr);
+ if (!objHdr.getCNum().equals(CNum.HANDLE))
+ throw new IllegalArgumentException("CNum on header must be of type HANDLE");
+ if (!objHdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
+ if (data == null) throw new IllegalArgumentException("COPSData must not be null");
+
+ _data = data;
+
+ if ((_data.length() % 4) != 0) {
+ final int padLen = 4 - (_data.length() % 4);
+ _padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ _padding = new COPSData();
+ }
+ }
+
+ @Override
+ public int getDataLength() {
+ return _data.length() + _padding.length();
+ }
+
+ /**
+ * Get handle value
+ * @return a COPSData
+ */
+ public COPSData getId() {
+ return _data;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ COPSUtil.writeData(socket, _data.getData(), _data.length());
+ COPSUtil.writeData(socket, _padding.getData(), _padding.length());
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("client-handle: " + _data.str() + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSHandle)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSHandle that = (COPSHandle) o;
+
+ return _data.equals(that._data) && _padding.equals(that._padding) ||
+ COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _data.hashCode();
+ result = 31 * result + _padding.hashCode();
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSHandle object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSHandle parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ if (dataPtr == null || dataPtr.length < 5)
+ throw new IllegalArgumentException("Data cannot be null or fewer than 5 bytes");
+
+ //Get the length of data following the obj header
+ final COPSData id = new COPSData(dataPtr, 4, objHdrData.msgByteCount - objHdrData.header.getHdrLength());
+ return new COPSHandle(objHdrData.header, id);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Header (RFC 2748 pag. 6)\r
- *\r
- * Each COPS message consists of the COPS header followed by a number of\r
- * typed objects.\r
- *\r
- * 0 1 2 3\r
- * +--------------+--------------+--------------+--------------+\r
- * |Version| Flags| Op Code | Client-type |\r
- * +--------------+--------------+--------------+--------------+\r
- * | Message Length |\r
- * +--------------+--------------+--------------+--------------+\r
- *\r
- * Global note: //// implies field is reserved, set to 0.\r
- *\r
- * The fields in the header are:\r
- * Version: 4 bits\r
- * COPS version number. Current version is 1.\r
- *\r
- * Flags: 4 bits\r
- * Defined flag values (all other flags MUST be set to 0):\r
- * 0x1 Solicited Message Flag Bit\r
- * This flag is set when the message is solicited by\r
- * another COPS message. This flag is NOT to be set\r
- * (value=0) unless otherwise specified.\r
- *\r
- * Op Code: 8 bits\r
- * The COPS operations:\r
- * 1 = Request (REQ)\r
- * 2 = Decision (DEC)\r
- * 3 = Report State (RPT)\r
- * 4 = Delete Request State (DRQ)\r
- * 5 = Synchronize State Req (SSQ)\r
- * 6 = Client-Open (OPN)\r
- * 7 = Client-Accept (CAT)\r
- * 8 = Client-Close (CC)\r
- * 9 = Keep-Alive (KA)\r
- * 10= Synchronize Complete (SSC)\r
- *\r
- * Client-type: 16 bits\r
- *\r
- *\r
- * @version COPSHeader.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSHeader {\r
-\r
- public final static byte COPS_OP_REQ = 1;\r
- public final static byte COPS_OP_DEC = 2;\r
- public final static byte COPS_OP_RPT = 3;\r
- public final static byte COPS_OP_DRQ = 4;\r
- public final static byte COPS_OP_SSQ = 5;\r
- public final static byte COPS_OP_OPN = 6;\r
- public final static byte COPS_OP_CAT = 7;\r
- public final static byte COPS_OP_CC = 8;\r
- public final static byte COPS_OP_KA = 9;\r
- public final static byte COPS_OP_SSC = 10;\r
-\r
- public final static byte COPS_FLAG_NULL = 0;\r
- public final static byte COPS_FLAG_SOLICITED = 1;\r
-\r
- private byte _versionNflg;\r
- private byte _opCode;\r
- private short _cType;\r
- private int _msgLength;\r
-\r
- public COPSHeader() {\r
- _versionNflg = 0x10;\r
- _opCode = 0;\r
- _cType = 0;\r
- _msgLength = 0;\r
- }\r
-\r
- public COPSHeader(byte opCode, short clientType) {\r
- _versionNflg = 0x10;\r
- _opCode = opCode;\r
- _cType = clientType;\r
- _msgLength = 0;\r
- if (isAKeepAlive()) _cType = 0;\r
- }\r
-\r
- public COPSHeader(byte opCode) {\r
- _versionNflg = 0x10;\r
- _opCode = opCode;\r
- _cType = 0;\r
- _msgLength = 0;\r
- if (isAKeepAlive()) _cType = 0;\r
- }\r
-\r
- /**\r
- Parse data and create COPSHeader object\r
- */\r
- public COPSHeader(byte[] buf) {\r
- _versionNflg = (byte) buf[0];\r
- _opCode = (byte) buf[1];\r
- _cType |= ((short) buf[2]) << 8;\r
- _cType |= ((short) buf[3]) & 0xFF;\r
- _msgLength |= ((short) buf[4]) << 24;\r
- _msgLength |= ((short) buf[5]) << 16;\r
- _msgLength |= ((short) buf[6]) << 8;\r
- _msgLength |= ((short) buf[7]) & 0xFF;\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message Request, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isARequest() {\r
- return (_opCode == COPS_OP_REQ);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message Decision, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isADecision() {\r
- return (_opCode == COPS_OP_DEC);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message Report, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAReport() {\r
- return (_opCode == COPS_OP_RPT);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message DeleteRequest, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isADeleteReq() {\r
- return (_opCode == COPS_OP_DRQ);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message SyncStateReq, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isASyncStateReq() {\r
- return (_opCode == COPS_OP_SSQ);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message ClientOpen, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAClientOpen() {\r
- return (_opCode == COPS_OP_OPN);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message ClientAccept, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAClientAccept() {\r
- return (_opCode == COPS_OP_CAT);\r
- }\r
-\r
- /**\r
- * If operation code corresponds with a message ClientClose, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAClientClose() {\r
- return (_opCode == COPS_OP_CC);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message KeepAlive, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAKeepAlive() {\r
- return (_opCode == COPS_OP_KA);\r
- }\r
-\r
- /**\r
- * If the operation code corresponds with a message SSC, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isASyncComplete() {\r
- return (_opCode == COPS_OP_SSC);\r
- }\r
-\r
- /**\r
- * Get message length\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getMsgLength() {\r
- return _msgLength;\r
- }\r
-\r
- /**\r
- * Get header length\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getHdrLength() {\r
- // return (sizeof(u_int32_t) * 2);\r
- return ( 8 );\r
- }\r
-\r
- /**\r
- * Get Operation Code\r
- *\r
- * @return a byte\r
- *\r
- */\r
- public byte getOpCode() {\r
- return _opCode;\r
- }\r
-\r
- /**\r
- * Set the solicitation flag\r
- *\r
- * @param flg a byte\r
- *\r
- */\r
- public void setFlag(byte flg) {\r
- _versionNflg &= 0x10;\r
- _versionNflg |= flg;\r
- }\r
-\r
- /**\r
- * Returns the flags field\r
- * @return aByte Flags field in header\r
- */\r
- public byte getFlags() { //OJO\r
- return (byte) (_versionNflg & 0x0f);\r
- }\r
-\r
- /**\r
- * Set the client-type\r
- *\r
- * @param cType a short\r
- *\r
- */\r
- public void setClientType(short cType) {\r
- _cType = cType;\r
- };\r
-\r
- /**\r
- * Set the message length\r
- *\r
- * @param len an int\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void setMsgLength(int len) throws COPSException {\r
- if ((len % 4) != 0)\r
- throw new COPSException ("Message is not aligned on 32 bit intervals");\r
- _msgLength = len + 8;\r
- }\r
-\r
- /**\r
- * Get client-type\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getClientType() {\r
- return (_cType);\r
- };\r
-\r
- /**\r
- * Always return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isCOPSHeader() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Writes object to given network socket in network byte order\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- byte buf[] = new byte[8];\r
-\r
- buf[0] = (byte) _versionNflg;\r
- buf[1] = (byte) _opCode;\r
- buf[2] = (byte) (_cType >> 8);\r
- buf[3] = (byte) _cType;\r
- buf[4] = (byte) (_msgLength >> 24);\r
- buf[5] = (byte) (_msgLength >> 16);\r
- buf[6] = (byte) (_msgLength >> 8);\r
- buf[7] = (byte) _msgLength;\r
-\r
- COPSUtil.writeData(id, buf, 8);\r
- }\r
-\r
- /**\r
- * Get an object textual description\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String toString() {\r
- String str = new String();\r
-\r
- str += "**MSG HEADER** \n";\r
- str += "Version: " + (_versionNflg >> 4) + "\n";\r
- str += "Flags: " + (_versionNflg & 0x01) + "\n";\r
- str += "OpCode: " + _opCode + "\n";\r
- str += "Client-type: " + _cType + "\n";\r
- str += "Message-length(bytes): " + _msgLength + "\n";\r
- return str;\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- os.write(new String("**MSG HEADER**" + "\n").getBytes());\r
- os.write(new String("Version: " + (_versionNflg >> 4) + "\n").getBytes());\r
- os.write(new String("Flags: " + (_versionNflg & 0x01) + "\n").getBytes());\r
- os.write(new String("OpCode: " + _opCode + "\n").getBytes());\r
- os.write(new String("Client-type: " + _cType + "\n").getBytes());\r
- os.write(new String("Message-length(bytes): " + _msgLength + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Header (RFC 2748 pag. 6)
+ *
+ * Each COPS message consists of the COPS header followed by a number of
+ * typed objects.
+ *
+ * 0 1 2 3
+ * +--------------+--------------+--------------+--------------+
+ * |Version| Flags| Op Code | Client-type |
+ * +--------------+--------------+--------------+--------------+
+ * | Message Length |
+ * +--------------+--------------+--------------+--------------+
+ *
+ * Global note: //// implies field is reserved, set to 0.
+ *
+ * The fields in the header are:
+ * Version: 4 bits
+ * COPS version number. Current version is 1.
+ *
+ * Flags: 4 bits
+ * Defined flag values (all other flags MUST be set to 0):
+ * 0x1 Solicited Message Flag Bit
+ * This flag is set when the message is solicited by
+ * another COPS message. This flag is NOT to be set
+ * (value=0) unless otherwise specified.
+ *
+ * Op Code: 8 bits
+ * The COPS operations:
+ * 1 = Request (REQ)
+ * 2 = Decision (DEC)
+ * 3 = Report State (RPT)
+ * 4 = Delete Request State (DRQ)
+ * 5 = Synchronize State Req (SSQ)
+ * 6 = Client-Open (OPN)
+ * 7 = Client-Accept (CAT)
+ * 8 = Client-Close (CC)
+ * 9 = Keep-Alive (KA)
+ * 10= Synchronize Complete (SSC)
+ *
+ * Client-type: 16 bits
+ *
+ *
+ * @version COPSHeader.java, v 1.00 2003
+ *
+ */
+public class COPSHeader {
+
+ /**
+ * Map allowing for the quick retrieval of the operation based on the numeric value coming in via the
+ * COPS payload.
+ */
+ final static Map<Integer, OPCode> VAL_TO_OP = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_OP.put(OPCode.NA.ordinal(), OPCode.NA);
+ VAL_TO_OP.put(OPCode.REQ.ordinal(), OPCode.REQ);
+ VAL_TO_OP.put(OPCode.DEC.ordinal(), OPCode.DEC);
+ VAL_TO_OP.put(OPCode.RPT.ordinal(), OPCode.RPT);
+ VAL_TO_OP.put(OPCode.DRQ.ordinal(), OPCode.DRQ);
+ VAL_TO_OP.put(OPCode.SSQ.ordinal(), OPCode.SSQ);
+ VAL_TO_OP.put(OPCode.OPN.ordinal(), OPCode.OPN);
+ VAL_TO_OP.put(OPCode.CAT.ordinal(), OPCode.CAT);
+ VAL_TO_OP.put(OPCode.CC.ordinal(), OPCode.CC);
+ VAL_TO_OP.put(OPCode.KA.ordinal(), OPCode.KA);
+ VAL_TO_OP.put(OPCode.SSC.ordinal(), OPCode.SSC);
+ }
+
+ /**
+ * Represents the PCMM version number of the message
+ * Holds the first nibble of the COPS message
+ */
+ private final int _pcmmVersion;
+
+ /**
+ * Represents the second nibble of the message where solicited decisions will be set to 1 else 0
+ * Values 0 = UNSOLICITED | 1 = SOLICITED
+ */
+ private final Flag _flag;
+
+ /**
+ * Represents the type of operation which will be used to determine the type of COPSMsg this header will be a
+ * part of.
+ * Uses the byte value contained in the second byte of the message and inbound messages should use the constant
+ * Map VAL_TO_CT during construction
+ */
+ private final OPCode _opCode;
+
+ /**
+ * Represents client type which there are currently 3 types supported.
+ * Uses the 3rd byte of the message and inbound messages should use the constant Map VAL_TO_OP during construction
+ */
+ private final short _cType;
+
+ /**
+ * Easy constructor that implies version 1 and UNSOLICITED flag.
+ *
+ * User should leverage the main constructor below and set the version and flags.
+ *
+ * @param opCode - the Operation code denoting the type of message
+ * @param clientType - the client type generally denotes if it is an Ipv4 (TYPE_1) else Ipv6
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSHeader(final OPCode opCode, final short clientType) {
+ this(1, Flag.UNSOLICITED, opCode, clientType);
+ }
+
+ /**
+ * Should be the main constructor.
+ * @param version - PCMM Version
+ * @param flag - the header flag
+ * @param opCode - the COPS operation code
+ * @param clientType - the type of client interfacing
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSHeader(final int version, final Flag flag, final OPCode opCode, final short clientType) {
+ if(version < 1) throw new IllegalArgumentException("Invalid version number - " + version);
+ if(flag == null) throw new IllegalArgumentException("Flag is null");
+ if(opCode == null) throw new IllegalArgumentException("OPCode is null");
+ _pcmmVersion = version;
+ _flag = flag;
+ _opCode = opCode;
+ _cType = clientType;
+
+ // TODO - Determine why this??? - remove until this makes some sense
+// if (opCode.equals(OPCode.KA)) _cType = ClientType.NA;
+// else _cType = clientType;
+ }
+
+ // Getters
+ public int getPcmmVersion() { return _pcmmVersion; }
+ public Flag getFlag() { return _flag; }
+
+ /**
+ * Get header length
+ * @return an int
+ */
+ public int getHdrLength() {
+ return 8;
+ }
+
+ /**
+ * Get Operation Code
+ * @return a byte
+ */
+ public OPCode getOpCode() {
+ return _opCode;
+ }
+
+ /**
+ * Get client-type
+ * @return a short
+ */
+ public short getClientType() {
+ return _cType;
+ }
+
+ /**
+ * Writes object to given network socket in network byte order
+ * @param socket a Socket
+ * @throws IOException
+ */
+ public void writeData(final Socket socket, final int msgLength) throws IOException {
+ byte buf[] = new byte[8];
+ buf[0] = (byte) COPSMsgParser.combineNibbles((byte)_pcmmVersion, (byte) _flag.ordinal());
+ buf[1] = (byte) _opCode.ordinal();
+
+ final byte[] cTypeBytes = COPSMsgParser.shortToBytes(_cType);
+ buf[2] = cTypeBytes[0];
+ buf[3] = cTypeBytes[1];
+ buf[4] = (byte) (msgLength >> 24);
+ buf[5] = (byte) (msgLength >> 16);
+ buf[6] = (byte) (msgLength >> 8);
+ buf[7] = (byte) msgLength;
+ COPSUtil.writeData(socket, buf, 8);
+ }
+
+ @Override
+ public String toString() {
+ return "**MSG HEADER** \n"
+ + "Version: " + _pcmmVersion + "\n"
+ + "Flags: " + _flag + "\n"
+ + "OpCode: " + _opCode + "\n"
+ + "Client-type: " + _cType + "\n";
+ }
+
+ /**
+ * Write an object textual description in the output stream
+ * @param os an OutputStream
+ * @throws IOException
+ */
+ public void dump(OutputStream os) throws IOException {
+ os.write(("**MSG HEADER**" + "\n").getBytes());
+ os.write(("Version: " + _pcmmVersion + "\n").getBytes());
+ os.write(("Flags: " + _flag + "\n").getBytes());
+ os.write(("OpCode: " + _opCode + "\n").getBytes());
+ os.write(("Client-type: " + _cType + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSHeader)) {
+ return false;
+ }
+
+ final COPSHeader header = (COPSHeader) o;
+
+ return _pcmmVersion == header._pcmmVersion && _cType == header._cType && _flag == header._flag &&
+ _opCode == header._opCode;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = _pcmmVersion;
+ result = 31 * result + _flag.hashCode();
+ result = 31 * result + _opCode.hashCode();
+ result = 31 * result + _cType;
+ return result;
+ }
+
+ /**
+ * Represents the COPS Operation code and byte value corresponds to the item's ordinal value
+ * The COPS operations:
+ * 0 = N/A - placeholder for the invalid value of 0
+ * 1 = Request (REQ)
+ * 2 = Decision (DEC)
+ * 3 = Report State (RPT)
+ * 4 = Delete Request State (DRQ)
+ * 5 = Synchronize State Req (SSQ)
+ * 6 = Client-Open (OPN)
+ * 7 = Client-Accept (CAT)
+ * 8 = Client-Close (CC)
+ * 9 = Keep-Alive (KA)
+ * 10= Synchronize Complete (SSC)
+ */
+ public enum OPCode {
+ NA, REQ, DEC, RPT, DRQ, SSQ, OPN, CAT, CC, KA, SSC
+ }
+
+ /**
+ * Represents the COPS flags value where the inbound nibble value maps to the ordinal values.
+ */
+ public enum Flag {
+ UNSOLICITED, SOLICITED
+ }
+
+}
+
+
+
+
--- /dev/null
+package org.umu.cops.stack;
+
+/**
+ * Class designed for simply containing the COPSHeader and the total message's byte count.
+ *
+ * No need to test as this class will be tested implicitly via other tests and this does not contain or need
+ * any domain specific logic
+ */
+class COPSHeaderData {
+
+ /**
+ * The actual header to be injected into the appropriate COPSMsg object
+ */
+ final COPSHeader header;
+
+ /**
+ * The total number of bytes contained within the inbound message being parsed.
+ */
+ final int msgByteCount;
+
+ /**
+ * Constructor
+ * @param hdr - the COPS message header
+ * @param numBytes - the total number of bytes contained within the message envelope
+ */
+ public COPSHeaderData(final COPSHeader hdr, final int numBytes) {
+ this.header = hdr;
+ this.msgByteCount = numBytes;
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Integrity Object\r
- *\r
- * @version COPSIntegrity.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIntegrity extends COPSObjBase {\r
- private COPSObjHeader _objHdr;\r
- private int _keyId;\r
- private int _seqNum;\r
- private COPSData _keyDigest;\r
- private COPSData _padding;\r
-\r
- public COPSIntegrity() {\r
- _objHdr = new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF);\r
- _keyId = 0;\r
- _seqNum = 0;\r
- }\r
-\r
- public COPSIntegrity(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _keyId |= ((short) dataPtr[4]) << 24;\r
- _keyId |= ((short) dataPtr[5]) << 16;\r
- _keyId |= ((short) dataPtr[6]) << 8;\r
- _keyId |= ((short) dataPtr[7]) & 0xFF;\r
- _seqNum |= ((short) dataPtr[8]) << 24;\r
- _seqNum |= ((short) dataPtr[9]) << 16;\r
- _seqNum |= ((short) dataPtr[10]) << 8;\r
- _seqNum |= ((short) dataPtr[11]) & 0xFF;\r
-\r
- int dLen = _objHdr.getDataLength() - 12;\r
- COPSData d = new COPSData(dataPtr, 12, dLen);\r
- setKeyDigest(d);\r
- }\r
-\r
- /**\r
- * Method setKeyId\r
- *\r
- * @param keyId an int\r
- *\r
- */\r
- public void setKeyId(int keyId) {\r
- _keyId = keyId;\r
- };\r
-\r
- /**\r
- * Method setSeqNum\r
- *\r
- * @param seqNum an int\r
- *\r
- */\r
- public void setSeqNum(int seqNum) {\r
- _seqNum = seqNum;\r
- };\r
-\r
- /**\r
- * Method setKeyDigest\r
- *\r
- * @param keyDigest a COPSData\r
- *\r
- */\r
- public void setKeyDigest(COPSData keyDigest) {\r
- _keyDigest = keyDigest;\r
- if (_keyDigest.length() % 4 != 0) {\r
- int padLen = 4 - _keyDigest.length() % 4;\r
- _padding = getPadding(padLen);\r
- }\r
- // _objHdr.setDataLength(sizeof(u_int32_t)\r
- // + sizeof(u_int32_t) + _keyDigest.length());\r
- _objHdr.setDataLength((short) (8 + _keyDigest.length()));\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- int lpadding = 0;\r
- if (_padding != null) lpadding = _padding.length();\r
- return ((short) (_objHdr.getDataLength() + lpadding));\r
- }\r
-\r
- /**\r
- * Method getKeyId\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getKeyId() {\r
- return _keyId;\r
- };\r
-\r
- /**\r
- * Method getSeqNum\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getSeqNum() {\r
- return _seqNum;\r
- };\r
-\r
- /**\r
- * Method getKeyDigest\r
- *\r
- * @return a COPSData\r
- *\r
- */\r
- public COPSData getKeyDigest() {\r
- return _keyDigest;\r
- };\r
-\r
- /**\r
- * Method isMessageIntegrity\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isMessageIntegrity() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[8];\r
- buf[0] = (byte) (_keyId >> 24);\r
- buf[1] = (byte) (_keyId >> 16);\r
- buf[2] = (byte) (_keyId >> 8);\r
- buf[3] = (byte) _keyId;\r
- buf[4] = (byte) (_seqNum >> 24);\r
- buf[5] = (byte) (_seqNum >> 16);\r
- buf[6] = (byte) (_seqNum >> 8);\r
- buf[7] = (byte) _seqNum;\r
- COPSUtil.writeData(id, buf, 8);\r
-\r
- COPSUtil.writeData(id, _keyDigest.getData(), _keyDigest.length());\r
- if (_padding != null) {\r
- COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
- }\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Key Id: " + _keyId + "\n").getBytes());\r
- os.write(new String("Sequence: " + _seqNum + "\n").getBytes());\r
- os.write(new String("Key digest: " + _keyDigest.str() + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Integrity Object (RFC 2748)
+ *
+ * The integrity object includes a sequence number and a message digest
+ * useful for authenticating and validating the integrity of a COPS
+ * message. When used, integrity is provided at the end of a COPS
+ * message as the last COPS object. The digest is then computed over all
+ * of a particular COPS message up to but not including the digest value
+ * itself. The sender of a COPS message will compute and fill in the
+ * digest portion of the Integrity object. The receiver of a COPS
+ * message will then compute a digest over the received message and
+ * verify it matches the digest in the received Integrity object.
+ *
+ * C-Num = 16,
+ *
+ * C-Type = 1, HMAC digest
+ *
+ * The HMAC integrity object employs HMAC (Keyed-Hashing for Message
+ * Authentication) [HMAC] to calculate the message digest based on a key
+ * shared between the PEP and its PDP.
+ *
+ * This Integrity object specifies a 32-bit Key ID used to identify a
+ * specific key shared between a particular PEP and its PDP and the
+ * cryptographic algorithm to be used. The Key ID allows for multiple
+ * simultaneous keys to exist on the PEP with corresponding keys on the
+ * PDP for the given PEPID. The key identified by the Key ID was used to
+ * compute the message digest in the Integrity object. All
+ * implementations, at a minimum, MUST support HMAC-MD5-96, which is
+ * HMAC employing the MD5 Message-Digest Algorithm [MD5] truncated to
+ * 96-bits to calculate the message digest.
+ *
+ * This object also includes a sequence number that is a 32-bit unsigned
+ * integer used to avoid replay attacks. The sequence number is
+ * initiated during an initial Client-Open Client-Accept message
+ * exchange and is then incremented by one each time a new message is
+ * sent over the TCP connection in the same direction. If the sequence
+ * number reaches the value of 0xFFFFFFFF, the next increment will
+ * simply rollover to a value of zero.
+ *
+ * The variable length digest is calculated over a COPS message starting
+ * with the COPS Header up to the Integrity Object (which MUST be the
+ * last object in a COPS message) INCLUDING the Integrity object's
+ * header, Key ID, and Sequence Number. The Keyed Message Digest field
+ * is not included as part of the digest calculation. In the case of
+ * HMAC-MD5-96, HMAC-MD5 will produce a 128-bit digest that is then to
+ * be truncated to 96-bits before being stored in or verified against
+ * the Keyed Message Digest field as specified in [HMAC]. The Keyed
+ * Message Digest MUST be 96-bits when HMAC-MD5-96 is used.
+ */
+public class COPSIntegrity extends COPSObjBase {
+
+ private final int _keyId;
+ private final int _seqNum;
+ private final COPSData _keyDigest;
+ private final COPSData _padding;
+
+ /**
+ * Constructor generally used for sending messages
+ * // TODO - why aren't any classes requiring injection of the keyId, seqNum, or keyDigest members???
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIntegrity() {
+ this(0, 0, new COPSData());
+ }
+
+ public COPSIntegrity(final int keyId, final int seqNum, final COPSData keyDigest) {
+ this(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), keyId, seqNum, keyDigest);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param keyId - the keyId
+ * @param seqNum - the sequence number
+ * @param keyDigest - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIntegrity(final COPSObjHeader hdr, final int keyId, final int seqNum, final COPSData keyDigest) {
+ super(hdr);
+ if (!hdr.getCNum().equals(CNum.MSG_INTEGRITY))
+ throw new IllegalArgumentException("CNum must be of type - " + CNum.MSG_INTEGRITY);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("CType must be of type - " + CType.DEF);
+
+ _keyId = keyId;
+ _seqNum = seqNum;
+
+ if (keyDigest == null) _keyDigest = new COPSData();
+ else _keyDigest = keyDigest;
+ if ((_keyDigest.length() % 4) != 0) {
+ final int padLen = 4 - (_keyDigest.length() % 4);
+ _padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ _padding = new COPSData();
+ }
+ }
+
+ // Getters
+ public int getKeyId() { return _keyId; }
+ public int getSeqNum() { return _seqNum; }
+ public COPSData getKeyDigest() { return _keyDigest; }
+
+ @Override
+ public int getDataLength() {
+ return 8 + _keyDigest.length() + _padding.length();
+ }
+
+ @Override
+ public void writeBody(final Socket socket) throws IOException {
+ final byte[] buf = new byte[8];
+ buf[0] = (byte) (_keyId >> 24);
+ buf[1] = (byte) (_keyId >> 16);
+ buf[2] = (byte) (_keyId >> 8);
+ buf[3] = (byte) _keyId;
+ buf[4] = (byte) (_seqNum >> 24);
+ buf[5] = (byte) (_seqNum >> 16);
+ buf[6] = (byte) (_seqNum >> 8);
+ buf[7] = (byte) _seqNum;
+ COPSUtil.writeData(socket, buf, 8);
+
+ COPSUtil.writeData(socket, _keyDigest.getData(), _keyDigest.length());
+ if (_padding != null) {
+ COPSUtil.writeData(socket, _padding.getData(), _padding.length());
+ }
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Key Id: " + _keyId + "\n").getBytes());
+ os.write(("Sequence: " + _seqNum + "\n").getBytes());
+ os.write(("Key digest: " + _keyDigest.str() + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSIntegrity)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSIntegrity integrity = (COPSIntegrity) o;
+
+ if (_keyId != integrity._keyId) {
+ return false;
+ }
+ if (_seqNum != integrity._seqNum) {
+ return false;
+ }
+ if (_keyDigest.equals(integrity._keyDigest) && _padding.equals(integrity._padding)) return true;
+ else
+ return COPSUtil.copsDataPaddingEquals(this._keyDigest, this._padding,
+ integrity._keyDigest, integrity._padding);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _keyId;
+ result = 31 * result + _seqNum;
+ result = 31 * result + _keyDigest.hashCode();
+ result = 31 * result + _padding.hashCode();
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSIntegrity object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIntegrity parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ int keyId = 0;
+ keyId |= ((short) dataPtr[4]) << 24;
+ keyId |= ((short) dataPtr[5]) << 16;
+ keyId |= ((short) dataPtr[6]) << 8;
+ keyId |= ((short) dataPtr[7]) & 0xFF;
+
+ int seqNum = 0;
+ seqNum |= ((short) dataPtr[8]) << 24;
+ seqNum |= ((short) dataPtr[9]) << 16;
+ seqNum |= ((short) dataPtr[10]) << 8;
+ seqNum |= ((short) dataPtr[11]) & 0xFF;
+
+ final int usedBytes = objHdrData.header.getHdrLength() + 8;
+ if (objHdrData.msgByteCount > usedBytes)
+ return new COPSIntegrity(objHdrData.header, keyId, seqNum,
+ new COPSData(dataPtr, usedBytes, objHdrData.msgByteCount - usedBytes));
+ else return new COPSIntegrity(objHdrData.header, keyId, seqNum, new COPSData());
+ }
+
+}
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-\r
-\r
-/**\r
- * COPS Interface\r
- *\r
- * @version COPSInterface.java, v 1.00 2003\r
- *\r
- */\r
-abstract class COPSInterface extends COPSObjBase {\r
- /**\r
- * Method isIpv4Address\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- protected boolean isIpv4Address() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isIpv6Address\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- protected boolean isIpv6Address() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isInInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- protected boolean isInInterface() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isOutInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- protected boolean isOutInterface() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- protected boolean isInterface() {\r
- return true;\r
- }\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Abstract COPS Interface for extension of all COPS interface types
+ */
+abstract class COPSInterface extends COPSObjBase {
+
+ /**
+ * The associated address object for a given COPS Interfaace
+ */
+ protected final COPSIpAddress _addr;
+
+ /**
+ * The interface on which the protocol message was received
+ */
+ protected final int _ifindex;
+
+ /**
+ * Constructor
+ * @param objHdr - the object's header
+ * @param ifindex - the interface value
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSInterface(final COPSObjHeader objHdr, final COPSIpAddress addr, final int ifindex) {
+ super(objHdr);
+ if (addr == null) throw new IllegalArgumentException("Address object cannot be null");
+ _addr = addr;
+ _ifindex = ifindex;
+ }
+
+ public abstract boolean isInInterface();
+ public abstract boolean isIPv6();
+
+ @Override
+ protected int getDataLength() {
+ return _addr.getDataLength() + 4;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _addr.writeData(socket);
+ final byte[] buf = new byte[4];
+ buf[0] = (byte) (_ifindex >> 24);
+ buf[1] = (byte) (_ifindex >> 16);
+ buf[2] = (byte) (_ifindex >> 8);
+ buf[3] = (byte) _ifindex;
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Address: " + _addr.getIpName() + "\n").getBytes());
+ os.write(("ifindex: " + _ifindex + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSInterface)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSInterface that = (COPSInterface) o;
+
+ return _ifindex == that._ifindex && _addr.equals(that._addr);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _addr.hashCode();
+ result = 31 * result + _ifindex;
+ return result;
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * Abstract superclass for all COPS IP Addresses.
+ */
+public abstract class COPSIpAddress {
+
+ /**
+ * The byte array representation of an IP address
+ */
+ protected final byte[] _addr;
+
+ /**
+ * Creates an address for a given host
+ * @param hostName - the host name
+ * @throws java.net.UnknownHostException
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpAddress(final String hostName) throws UnknownHostException {
+ if (hostName == null) throw new IllegalArgumentException("Hostname must not be null");
+ _addr = deriveIpAddress(hostName);
+ }
+
+ protected COPSIpAddress(final byte[] addr) {
+ if (addr == null) throw new IllegalArgumentException("The addr parameter must not be null");
+ _addr = addr;
+ }
+
+ protected byte[] getAddressBytes() { return _addr; }
+
+ /**
+ * Derives the IP address in a byte array from the host name
+ * @param hostName a String
+ * @throws UnknownHostException
+ */
+ protected abstract byte[] deriveIpAddress(final String hostName) throws UnknownHostException;
+
+ /**
+ * Method getIpName
+ * @return a String
+ * @throws UnknownHostException
+ */
+ public abstract String getIpName() throws UnknownHostException;
+
+ /**
+ * Returns the number of bytes that will be written
+ * @return a short
+ */
+ public int getDataLength() {
+ return _addr.length;
+ }
+
+ /**
+ * Write data on a given network socket
+ * @param socket a Socket
+ * @throws IOException
+ */
+ public void writeData(Socket socket) throws IOException {
+ COPSUtil.writeData(socket, _addr, _addr.length);
+ }
+
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSIpAddress)) {
+ return false;
+ }
+
+ final COPSIpAddress that = (COPSIpAddress) o;
+
+ return Arrays.equals(_addr, that._addr);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(_addr);
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.IOException;\r
-import java.net.InetAddress;\r
-import java.net.Socket;\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv4 Address\r
- *\r
- * @version COPSIpv4Address.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv4Address {\r
-\r
- private byte[] _addr;\r
-\r
- public COPSIpv4Address() {\r
- _addr = new byte[4];\r
- }\r
-\r
- public COPSIpv4Address(String hostName) throws UnknownHostException {\r
- setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr = InetAddress.getByName(hostName).getAddress();\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return InetAddress.getByAddress(_addr).getHostName();\r
- }\r
-\r
- /**\r
- * Method getIpAddress\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getIpAddress() {\r
- int ipaddr = 0;\r
-\r
- ipaddr |= ((int) _addr[0]) << 24;\r
- ipaddr |= ((int) _addr[1]) << 16;\r
- ipaddr |= ((int) _addr[2]) << 8;\r
- ipaddr |= ((int) _addr[3]) & 0xFF;\r
-\r
- return ipaddr;\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param dataPtr a byte[]\r
- *\r
- */\r
- public void parse(byte[] dataPtr) {\r
- new ByteArrayInputStream(dataPtr).read(_addr,0,4);\r
- }\r
-\r
- /**\r
- * Method getDataLength\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- return (4);\r
- }\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- COPSUtil.writeData(id, _addr, 4);\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * COPS IPv4 Address
+ */
+public class COPSIpv4Address extends COPSIpAddress {
+
+ /**
+ * Creates an address for a given host
+ * @param hostName - the host name
+ * @throws UnknownHostException
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4Address(final String hostName) throws UnknownHostException {
+ super(hostName);
+ }
+
+ /**
+ * Creates an address for a given IP address contained within a byte array
+ * @param addr - the host name
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4Address(final byte[] addr) {
+ super(addr);
+ if (addr.length != 4) throw new IllegalArgumentException("The address must be 4 bytes");
+ }
+
+ @Override
+ protected byte[] deriveIpAddress(final String hostName) throws UnknownHostException {
+ final InetAddress[] addrs = Inet4Address.getAllByName(hostName);
+ for (final InetAddress addr : addrs) {
+ if (addr instanceof Inet4Address) {
+ return addr.getAddress();
+ }
+ }
+ throw new UnknownHostException("InetAddress could not be found");
+ }
+
+ @Override
+ public String getIpName() throws UnknownHostException {
+ return Inet4Address.getByAddress(_addr).getHostName();
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS IPv4 Input Address\r
- *\r
- * @version COPSIpv4InInterface.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv4InInterface extends COPSIpv4Interface {\r
- public COPSIpv4InInterface() {\r
- super(new COPSObjHeader(CNum.ININTF, CType.DEF));\r
- }\r
-\r
- public COPSIpv4InInterface(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method className\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String className() {\r
- return "COPSIpv4InInterface";\r
- }\r
-\r
- /**\r
- * Method isInInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isInInterface() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- }\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS IPv4 Input Address (RFC 2748)
+ *
+ * The In-Interface Object is used to identify the incoming interface on
+ * which a particular request applies and the address where the received
+ * message originated. For flows or messages generated from the PEP's
+ * local host, the loop back address and ifindex are used.
+ *
+ * This Interface object is also used to identify the incoming
+ * (receiving) interface via its ifindex. The ifindex may be used to
+ * differentiate between sub-interfaces and unnumbered interfaces (see
+ * RSVP's LIH for an example). When SNMP is supported by the PEP, this
+ * ifindex integer MUST correspond to the same integer value for the
+ * interface in the SNMP MIB-II interface index table.
+ *
+ * Note: The ifindex specified in the In-Interface is typically relative
+ * to the flow of the underlying protocol messages. The ifindex is the
+ * interface on which the protocol message was received.
+ *
+ * C-Num = 3
+ *
+ * C-Type = 1, IPv4 Address + Interface
+ *
+ * 0 1 2 3
+ * +--------------+--------------+--------------+--------------+
+ * | IPv4 Address format |
+ * +--------------+--------------+--------------+--------------+
+ * | ifindex |
+ * +--------------+--------------+--------------+--------------+
+ *
+ * For this type of the interface object, the IPv4 address specifies the
+ * IP address that the incoming message came from.
+ */
+public class COPSIpv4InInterface extends COPSIpv4Interface {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param ifindex - the interface value
+ * @param addr - the IPv4 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4InInterface(final COPSIpv4Address addr, final int ifindex) {
+ this(new COPSObjHeader(CNum.ININTF, CType.DEF), addr, ifindex);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param ifindex - the interface value
+ * @param addr - the IPv4 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4InInterface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ if (!objHdr.getCNum().equals(CNum.ININTF))
+ throw new IllegalArgumentException("CNum must be of type - " + CNum.ININTF);
+ if (!objHdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("CType must be of type - " + CType.DEF);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIpv4InInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ return new COPSIpv4InInterface(objHdrData.header, COPSIpv4Interface.parseAddress(dataPtr),
+ COPSIpv4Interface.parseIfIndex(dataPtr));
+ }
+
+ public boolean isInInterface() { return true; }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv4 Interface\r
- *\r
- * @version COPSIpv4Interface.java, v 1.00 2003\r
- *\r
- */\r
-public abstract class COPSIpv4Interface extends COPSInterface {\r
-\r
- protected COPSObjHeader _objHdr;\r
- private COPSIpv4Address _addr;\r
- private int _ifindex;\r
-\r
-\r
- /**\r
- * Method isIpv4Address\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv4Address() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr.setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return (_addr.getIpName());\r
- }\r
-\r
- /**\r
- * Method getIpAddress\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getIpAddress() {\r
- return (_addr.getIpAddress());\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- protected COPSIpv4Interface(COPSObjHeader hdr) {\r
- _objHdr = hdr;\r
-// _objHdr.setCType((byte) 1);\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- protected COPSIpv4Interface(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- byte[] buf = new byte[4];\r
- System.arraycopy(dataPtr,4,buf,0,4);\r
-\r
- _addr.parse(buf);\r
-\r
- _ifindex |= ((int) dataPtr[8]) << 24;\r
- _ifindex |= ((int) dataPtr[9]) << 16;\r
- _ifindex |= ((int) dataPtr[10]) << 8;\r
- _ifindex |= ((int) dataPtr[11]) & 0xFF;\r
-\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+/**
+ * COPS IPv4 Interface
+ *
+ * @version COPSIpv4Interface.java, v 1.00 2003
+ *
+ */
+public abstract class COPSIpv4Interface extends COPSInterface {
+
+ /**
+ * Constructor
+ * @param objHdr - the header
+ * @param ifindex - the interface value
+ * @param addr - the address object
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4Interface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ }
+
+ @Override
+ public boolean isIPv6() { return false; }
+
+ /**
+ * Creates a COPSIpv4Address object from a byte array.
+ * @param dataPtr - the byte array
+ * @return - the address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected static COPSIpv4Address parseAddress(final byte[] dataPtr) {
+ byte[] buf = new byte[4];
+ buf[0] = dataPtr[4];
+ buf[1] = dataPtr[5];
+ buf[2] = dataPtr[6];
+ buf[3] = dataPtr[7];
+ return new COPSIpv4Address(buf);
+ }
+
+ /**
+ * Parses the ifindex value from a byte array.
+ * @param dataPtr - the byte array
+ * @return - the index value
+ */
+ protected static int parseIfIndex(final byte[] dataPtr) {
+ int ifindex = 0;
+ ifindex |= ((int) dataPtr[8]) << 24;
+ ifindex |= ((int) dataPtr[9]) << 16;
+ ifindex |= ((int) dataPtr[10]) << 8;
+ ifindex |= ((int) dataPtr[11]) & 0xFF;
+ return ifindex;
+ }
+
+}
+
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-\r
-/**\r
- * COPS IPv4 Last PDP Address\r
- *\r
- * @version COPSIpv4LastPdpAddr.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv4LastPdpAddr extends COPSIpv4PdpAddress {\r
-\r
- public COPSIpv4LastPdpAddr() {\r
- super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF));\r
- }\r
-\r
- public COPSIpv4LastPdpAddr(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method isLastPdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isLastPdpAddress() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Ipv4PdpAddress" + "\n").getBytes());\r
- os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes());\r
- os.write(new String("Port: " + _tcpPort + "\n").getBytes());\r
- }\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.UnknownHostException;
+
+/**
+ * Last PDP Address (RFC 2748)
+ *
+ * When a PEP sends a Client-Open message for a particular client-type
+ * the PEP SHOULD specify the last PDP it has successfully opened
+ * (meaning it received a Client-Accept) since the PEP last rebooted.
+ * If no PDP was used since the last reboot, the PEP will simply not
+ * include this object in the Client-Open message.
+ *
+ * C-Num = 14,
+ *
+ * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr)
+ *
+ * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr)
+ */
+public class COPSIpv4LastPdpAddr extends COPSIpv4PdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param port - the associated port
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4LastPdpAddr(final String host, final int port, final short reserved) throws UnknownHostException {
+ super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), host, port, reserved);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4LastPdpAddr(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr, addr, tcpPort, reserved);
+ if (!objHdr.getCNum().equals(CNum.LAST_PDP_ADDR))
+ throw new IllegalArgumentException("CNum must be equal to - " + CNum.LAST_PDP_ADDR);
+ }
+
+ @Override
+ public void dumpBody(OutputStream os) throws IOException {
+ os.write(("Ipv4LastPdpAddress" + "\n").getBytes());
+ super.dumpBody(os);
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS IPv4 Output Interface\r
- *\r
- * @version COPSIpv4OutInterface.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv4OutInterface extends COPSIpv4Interface {\r
- public COPSIpv4OutInterface() {\r
- super(new COPSObjHeader(CNum.ININTF, CType.DEF));\r
- }\r
-\r
- public COPSIpv4OutInterface(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method className\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String className() {\r
- return "COPSIpv4OutInterface";\r
- }\r
-\r
- /**\r
- * Method isInInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isInInterface() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- }\r
-\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS IPv4 Output Interface (RFC 2748)
+ *
+ * The Out-Interface is used to identify the outgoing interface to which
+ * a specific request applies and the address for where the forwarded
+ * message is to be sent. For flows or messages destined to the PEP's
+ * local host, the loop back address and ifindex are used. The Out-
+ * Interface has the same formats as the In-Interface Object.
+ *
+ * This Interface object is also used to identify the outgoing
+ * (forwarding) interface via its ifindex. The ifindex may be used to
+ * differentiate between sub-interfaces and unnumbered interfaces (see
+ * RSVP's LIH for an example). When SNMP is supported by the PEP, this
+ * ifindex integer MUST correspond to the same integer value for the
+ * interface in the SNMP MIB-II interface index table.
+ *
+ * Note: The ifindex specified in the Out-Interface is typically
+ * relative to the flow of the underlying protocol messages. The ifindex
+ * is the one on which a protocol message is about to be forwarded.
+ *
+ * C-Num = 4
+ *
+ * C-Type = 1, IPv4 Address + Interface
+ *
+ * Same C-Type format as the In-Interface object. The IPv4 address
+ * specifies the IP address to which the outgoing message is going. The
+ * ifindex is used to refer to the MIB-II defined local outgoing
+ * interface on the PEP.
+ * C-Type = 2, IPv6 Address + Interface
+ *
+ * Same C-Type format as the In-Interface object. For this type of the
+ * interface object, the IPv6 address specifies the IP address to which
+ * the outgoing message is going. The ifindex is used to refer to the
+ * MIB-II defined local outgoing interface on the PEP.
+ */
+public class COPSIpv4OutInterface extends COPSIpv4Interface {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param ifindex - the interface value
+ * @param addr - the IPv4 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4OutInterface(final COPSIpv4Address addr, final int ifindex) {
+ this(new COPSObjHeader(CNum.OUTINTF, CType.DEF), addr, ifindex);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param ifindex - the interface value
+ * @param addr - the IPv4 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4OutInterface(final COPSObjHeader objHdr, final COPSIpv4Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIpv4OutInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ return new COPSIpv4OutInterface(objHdrData.header, COPSIpv4Interface.parseAddress(dataPtr),
+ COPSIpv4Interface.parseIfIndex(dataPtr));
+ }
+
+ public boolean isInInterface() { return false; }
+}
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv4 PDP Address\r
- *\r
- * @version COPSIpv4PdpAddress.java, v 1.00 2003\r
- *\r
- */\r
-abstract public class COPSIpv4PdpAddress extends COPSPdpAddress {\r
-\r
- protected COPSObjHeader _objHdr;\r
- protected COPSIpv4Address _addr;\r
- private short _reserved;\r
- protected short _tcpPort;\r
-\r
- protected COPSIpv4PdpAddress(COPSObjHeader hdr) {\r
- _addr = new COPSIpv4Address();\r
- _objHdr = hdr;\r
-// _objHdr.setCType((byte) 1);\r
- // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- protected COPSIpv4PdpAddress(byte[] dataPtr) {\r
- _addr = new COPSIpv4Address();\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- byte[] buf = new byte[4];\r
- System.arraycopy(dataPtr,2,buf,0,4);\r
- _addr.parse(buf);\r
-\r
- _reserved |= ((short) dataPtr[8]) << 8;\r
- _reserved |= ((short) dataPtr[9]) & 0xFF;\r
- _tcpPort |= ((short) dataPtr[10]) << 8;\r
- _tcpPort |= ((short) dataPtr[11]) & 0xFF;\r
-\r
- // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr.setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method setTcpPort\r
- *\r
- * @param port a short\r
- *\r
- */\r
- public void setTcpPort(short port) {\r
- _tcpPort = port;\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return (_addr.getIpName());\r
- }\r
-\r
- /**\r
- * Method getTcpPort\r
- *\r
- * @return a short\r
- *\r
- */\r
- short getTcpPort() {\r
- return _tcpPort;\r
- };\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * Method isIpv6PdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv6PdpAddress() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- //\r
- _objHdr.writeData(id);\r
- _addr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
- buf[0] = (byte) (_reserved & 0xFF);\r
- buf[1] = (byte) (_reserved << 8);\r
- buf[2] = (byte) (_tcpPort & 0xFF);\r
- buf[3] = (byte) (_tcpPort << 8);\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.net.UnknownHostException;
+
+/**
+ * Super for IPv4 PDP Addresses
+ */
+abstract public class COPSIpv4PdpAddress extends COPSPdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param tcpPort - the associated port
+ * @param reserved - not in use
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4PdpAddress(final COPSObjHeader objHdr, final String host, final int tcpPort, final short reserved)
+ throws UnknownHostException {
+ super(objHdr, new COPSIpv4Address(host), tcpPort, reserved);
+ if (!objHdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @param reserved - not in use
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4PdpAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr, new COPSIpv4Address(addr), tcpPort, reserved);
+ if (!objHdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
+ }
+
+
+}
+
--- /dev/null
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.UnknownHostException;
+
+/**
+ * PDP Redirect Address (RFC 2748 pg. 15)
+ *
+ * A PDP when closing a PEP session for a particular client-type may
+ optionally use this object to redirect the PEP to the specified PDP
+ server address and TCP port number:
+ *
+ * C-Num = 13,
+ *
+ * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr)
+ *
+ * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr)
+ */
+public class COPSIpv4PdpRedirectAddress extends COPSIpv4PdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param port - the associated port
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv4PdpRedirectAddress(final String host, final int port, final short reserved) throws UnknownHostException {
+ super(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), host, port, reserved);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv4PdpRedirectAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr, addr, tcpPort, reserved);
+ if (!objHdr.getCNum().equals(CNum.PDP_REDIR))
+ throw new IllegalArgumentException("CNum must be equal to - " + CNum.PDP_REDIR);
+ }
+
+ @Override
+ public void dumpBody(OutputStream os) throws IOException {
+ os.write(("Ipv4PdpRedirectAddress" + "\n").getBytes());
+ super.dumpBody(os);
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.IOException;\r
-import java.net.InetAddress;\r
-import java.net.Socket;\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv6 Address\r
- *\r
- * @version COPSIpv6Address.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv6Address {\r
-\r
- private byte[] _addr;\r
-\r
- public COPSIpv6Address() {\r
- _addr = new byte[16];\r
- }\r
-\r
- public COPSIpv6Address(String hostName) throws UnknownHostException {\r
- setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr = InetAddress.getByName(hostName).getAddress();\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return InetAddress.getByAddress(_addr).getHostName();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param dataPtr a byte[]\r
- *\r
- */\r
- public void parse(byte[] dataPtr) {\r
- new ByteArrayInputStream(dataPtr).read(_addr,0,16);\r
- }\r
-\r
- /**\r
- * Method getDataLength\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- return (16);\r
- }\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- COPSUtil.writeData(id, _addr, 16);\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * COPS IPv6 Address
+ */
+public class COPSIpv6Address extends COPSIpAddress {
+
+ /**
+ * Creates an address for a given host
+ * @param hostName - the host name
+ * @throws UnknownHostException
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6Address(final String hostName) throws UnknownHostException {
+ super(hostName);
+ }
+
+ /**
+ * Creates an address for a given IP address contained within a byte array
+ * @param addr - the host name
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6Address(final byte[] addr) {
+ super(addr);
+ if (addr.length != 16) throw new IllegalArgumentException("The address must be 16 bytes");
+ }
+
+
+ @Override
+ protected byte[] deriveIpAddress(final String hostName) throws UnknownHostException {
+ final InetAddress[] addrs = Inet4Address.getAllByName(hostName);
+ for (final InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ return addr.getAddress();
+ }
+ }
+ throw new UnknownHostException("InetAddress could not be found");
+ }
+
+ @Override
+ public String getIpName() throws UnknownHostException {
+ return Inet6Address.getByAddress(_addr).getHostName();
+ }
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS IPv6 Input Interface\r
- *\r
- * @version COPSIpv6InInterface.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv6InInterface extends COPSIpv6Interface {\r
- public COPSIpv6InInterface() {\r
- super(new COPSObjHeader(CNum.ININTF, CType.STATELESS));\r
- }\r
-\r
- public COPSIpv6InInterface(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method className\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String className() {\r
- return "COPSIpv6InInterface";\r
- }\r
-\r
- /**\r
- * Method isInInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isInInterface() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS IPv6 Input Address (RFC 2748)
+ *
+ * The In-Interface Object is used to identify the incoming interface on
+ * which a particular request applies and the address where the received
+ * message originated. For flows or messages generated from the PEP's
+ * local host, the loop back address and ifindex are used.
+ *
+ * This Interface object is also used to identify the incoming
+ * (receiving) interface via its ifindex. The ifindex may be used to
+ * differentiate between sub-interfaces and unnumbered interfaces (see
+ * RSVP's LIH for an example). When SNMP is supported by the PEP, this
+ * ifindex integer MUST correspond to the same integer value for the
+ * interface in the SNMP MIB-II interface index table.
+ *
+ * Note: The ifindex specified in the In-Interface is typically relative
+ * to the flow of the underlying protocol messages. The ifindex is the
+ * interface on which the protocol message was received.
+ *
+ * C-Type = 2, IPv6 Address + Interface
+ *
+ * 0 1 2 3
+ * +--------------+--------------+--------------+--------------+
+ * | |
+ * + +
+ * | |
+ * + IPv6 Address format +
+ * | |
+ * + +
+ * | |
+ * +--------------+--------------+--------------+--------------+
+ * | ifindex |
+ * +--------------+--------------+--------------+--------------+
+ *
+ * For this type of the interface object, the IPv6 address specifies the
+ * IP address that the incoming message came from. The ifindex is used
+ * to refer to the MIB-II defined local incoming interface on the PEP as
+ * described above.
+ */
+public class COPSIpv6InInterface extends COPSIpv6Interface {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param ifindex - the interface value
+ * @param addr - the IPv6 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6InInterface(final COPSIpv6Address addr, final int ifindex) {
+ super(new COPSObjHeader(CNum.ININTF, CType.STATELESS), addr, ifindex);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param ifindex - the interface value
+ * @param addr - the IPv6 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6InInterface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ if (!objHdr.getCNum().equals(CNum.ININTF))
+ throw new IllegalArgumentException("CNum must be of type - " + CNum.ININTF);
+ if (!objHdr.getCType().equals(CType.STATELESS))
+ throw new IllegalArgumentException("CType must be of type - " + CType.STATELESS);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIpv6InInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ return new COPSIpv6InInterface(objHdrData.header, COPSIpv6Interface.parseAddress(dataPtr),
+ COPSIpv6Interface.parseIfIndex(dataPtr));
+ }
+
+ public boolean isInInterface() { return true; }
+}
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv6 Interface\r
- *\r
- * @version COPSIpv6Interface.java, v 1.00 2003\r
- *\r
- */\r
-public abstract class COPSIpv6Interface extends COPSInterface {\r
-\r
- /**\r
- * Method isIpv6Address\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv6Address() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr.setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return (_addr.getIpName());\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- protected COPSIpv6Interface(COPSObjHeader hdr) {\r
- _objHdr = hdr;\r
-// _objHdr.setCType((byte) 2);\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- protected COPSIpv6Interface(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
- _objHdr.parse(dataPtr);\r
- // _objHdr.checkDataLength();\r
-\r
- byte[] buf = new byte[4];\r
- System.arraycopy(dataPtr,4,buf,0,16);\r
-\r
- _addr.parse(buf);\r
-\r
- _ifindex |= ((int) dataPtr[20]) << 24;\r
- _ifindex |= ((int) dataPtr[21]) << 16;\r
- _ifindex |= ((int) dataPtr[22]) << 8;\r
- _ifindex |= ((int) dataPtr[23]) & 0xFF;\r
-\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- private COPSObjHeader _objHdr;\r
- private COPSIpv6Address _addr;\r
- private int _ifindex;\r
-}\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.ByteArrayInputStream;
+
+/**
+ * COPS IPv6 Interface
+ *
+ * @version COPSIpv6Interface.java, v 1.00 2003
+ *
+ */
+public abstract class COPSIpv6Interface extends COPSInterface {
+
+ /**
+ * Constructor
+ * @param objHdr - the header
+ * @param ifindex - the interface value
+ * @param addr - the address object
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6Interface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ }
+
+ @Override
+ public boolean isIPv6() { return true; }
+
+ /**
+ * Creates a COPSIpv6Address object from a byte array.
+ * @param dataPtr - the byte array
+ * @return - the address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected static COPSIpv6Address parseAddress(final byte[] dataPtr) {
+ byte[] buf = new byte[16];
+ System.arraycopy(dataPtr, 4, buf, 0, 16);
+ new ByteArrayInputStream(dataPtr).read(buf, 0, 16);
+ return new COPSIpv6Address(buf);
+ }
+
+ /**
+ * Parses the ifindex value from a byte array.
+ * @param dataPtr - the byte array
+ * @return - the index value
+ */
+ protected static int parseIfIndex(final byte[] dataPtr) {
+ int ifindex = 0;
+ ifindex |= ((int) dataPtr[20]) << 24;
+ ifindex |= ((int) dataPtr[21]) << 16;
+ ifindex |= ((int) dataPtr[22]) << 8;
+ ifindex |= ((int) dataPtr[23]) & 0xFF;
+ return ifindex;
+ }
+
+}
+
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-\r
-/**\r
- * COPS IPv6 Last PDP Address\r
- *\r
- * @version COPSIpv6LastPdpAddr.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv6LastPdpAddr extends COPSIpv6PdpAddress {\r
-\r
- public COPSIpv6LastPdpAddr() {\r
- super();\r
- // TODO - FIXME later, currently not in use and the header is now immutable\r
-// _objHdr.setCNum(COPSObjHeader.COPS_LAST_PDP_ADDR);\r
- }\r
-\r
- public COPSIpv6LastPdpAddr(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method isLastPdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isLastPdpAddress() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Ipv6PdpAddress" + "\n").getBytes());\r
- os.write(new String("Address: " + _addr.getIpName() + "\n").getBytes());\r
- os.write(new String("Port: " + _tcpPort + "\n").getBytes());\r
- }\r
-};\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.UnknownHostException;
+
+/**
+ * Last PDP Address (RFC 2748)
+ *
+ * When a PEP sends a Client-Open message for a particular client-type
+ * the PEP SHOULD specify the last PDP it has successfully opened
+ * (meaning it received a Client-Accept) since the PEP last rebooted.
+ * If no PDP was used since the last reboot, the PEP will simply not
+ * include this object in the Client-Open message.
+ *
+ * C-Num = 14,
+ *
+ * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr)
+ *
+ * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr)
+ */
+public class COPSIpv6LastPdpAddr extends COPSIpv6PdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param tcpPort - the associated port
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6LastPdpAddr(final String host, final int tcpPort, final short reserved) throws UnknownHostException {
+ super(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), host, tcpPort, reserved);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6LastPdpAddr(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort, final short reserved) {
+ super(objHdr, addr, tcpPort, reserved);
+ if (!objHdr.getCNum().equals(CNum.LAST_PDP_ADDR))
+ throw new IllegalArgumentException("CNum must be equal to - " + CNum.LAST_PDP_ADDR);
+ }
+
+ @Override
+ public void dumpBody(OutputStream os) throws IOException {
+ os.write(("Ipv6LastPdpAddr" + "\n").getBytes());
+ super.dumpBody(os);
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS IPv6 Output Interface\r
- *\r
- * @version COPSIpv6OutInterface.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSIpv6OutInterface extends COPSIpv6Interface {\r
- public COPSIpv6OutInterface() {\r
- super(new COPSObjHeader(CNum.ININTF, CType.STATELESS));\r
- }\r
-\r
- public COPSIpv6OutInterface(byte[] dataPtr) {\r
- super(dataPtr);\r
- }\r
-\r
- /**\r
- * Method className\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String className() {\r
- return "COPSIpv6OutInterface";\r
- }\r
-\r
- /**\r
- * Method isInInterface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isInInterface() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS IPv6 Output Interface (RFC 2748)
+ *
+ * The Out-Interface is used to identify the outgoing interface to which
+ * a specific request applies and the address for where the forwarded
+ * message is to be sent. For flows or messages destined to the PEP's
+ * local host, the loop back address and ifindex are used. The Out-
+ * Interface has the same formats as the In-Interface Object.
+ *
+ * This Interface object is also used to identify the outgoing
+ * (forwarding) interface via its ifindex. The ifindex may be used to
+ * differentiate between sub-interfaces and unnumbered interfaces (see
+ * RSVP's LIH for an example). When SNMP is supported by the PEP, this
+ * ifindex integer MUST correspond to the same integer value for the
+ * interface in the SNMP MIB-II interface index table.
+ *
+ * Note: The ifindex specified in the Out-Interface is typically
+ * relative to the flow of the underlying protocol messages. The ifindex
+ * is the one on which a protocol message is about to be forwarded.
+ *
+ * C-Num = 4
+ *
+ * C-Type = 1, IPv4 Address + Interface
+ *
+ * Same C-Type format as the In-Interface object. The IPv4 address
+ * specifies the IP address to which the outgoing message is going. The
+ * ifindex is used to refer to the MIB-II defined local outgoing
+ * interface on the PEP.
+ * C-Type = 2, IPv6 Address + Interface
+ *
+ * Same C-Type format as the In-Interface object. For this type of the
+ * interface object, the IPv6 address specifies the IP address to which
+ * the outgoing message is going. The ifindex is used to refer to the
+ * MIB-II defined local outgoing interface on the PEP.
+ */
+public class COPSIpv6OutInterface extends COPSIpv6Interface {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param ifindex - the interface value
+ * @param addr - the IPv6 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6OutInterface(final COPSIpv6Address addr, final int ifindex) {
+ this(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), addr, ifindex);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param ifindex - the interface value
+ * @param addr - the IPv6 address
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6OutInterface(final COPSObjHeader objHdr, final COPSIpv6Address addr, final int ifindex) {
+ super(objHdr, addr, ifindex);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIpv6OutInterface parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ return new COPSIpv6OutInterface(objHdrData.header, COPSIpv6Interface.parseAddress(dataPtr),
+ COPSIpv6Interface.parseIfIndex(dataPtr));
+ }
+
+ public boolean isInInterface() { return false; }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.net.UnknownHostException;\r
-\r
-/**\r
- * COPS IPv6 PDP Address\r
- *\r
- * @version COPSIpv6PdpAddress.java, v 1.00 2003\r
- *\r
- */\r
-abstract public class COPSIpv6PdpAddress extends COPSPdpAddress {\r
-\r
- protected COPSObjHeader _objHdr;\r
- protected COPSIpv6Address _addr;\r
- private short _reserved;\r
- protected short _tcpPort;\r
-\r
- protected COPSIpv6PdpAddress() {\r
- _addr = new COPSIpv6Address();\r
- _objHdr = new COPSObjHeader(CNum.NA, CType.STATELESS);\r
- // _objHdr.setDataLength((short) _addr.getDataLength() + sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- protected COPSIpv6PdpAddress(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
- // _objHdr.checkDataLength();\r
-\r
- byte[] buf = new byte[16];\r
- System.arraycopy(dataPtr,2,buf,0,16);\r
- _addr.parse(buf);\r
-\r
- _reserved |= ((short) dataPtr[20]) << 8;\r
- _reserved |= ((short) dataPtr[21]) & 0xFF;\r
- _tcpPort |= ((short) dataPtr[22]) << 8;\r
- _tcpPort |= ((short) dataPtr[23]) & 0xFF;\r
-\r
- // _objHdr.setDataLength(_addr.getDataLength() + sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) (_addr.getDataLength() + 4));\r
- }\r
-\r
- /**\r
- * Method setIpAddress\r
- *\r
- * @param hostName a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public void setIpAddress(String hostName) throws UnknownHostException {\r
- _addr.setIpAddress(hostName);\r
- }\r
-\r
- /**\r
- * Method setTcpPort\r
- *\r
- * @param port a short\r
- *\r
- */\r
- public void setTcpPort(short port) {\r
- _tcpPort = port;\r
- }\r
-\r
- /**\r
- * Method getIpName\r
- *\r
- * @return a String\r
- *\r
- * @throws UnknownHostException\r
- *\r
- */\r
- public String getIpName() throws UnknownHostException {\r
- return (_addr.getIpName());\r
- }\r
-\r
- /**\r
- * Method getTcpPort\r
- *\r
- * @return a short\r
- *\r
- */\r
- short getTcpPort() {\r
- return _tcpPort;\r
- };\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * Method isIpv6PdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv6PdpAddress() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write data on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- //\r
- _objHdr.writeData(id);\r
- _addr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
- buf[0] = (byte) (_reserved >> 8);\r
- buf[1] = (byte) _reserved;\r
- buf[2] = (byte) (_tcpPort >> 8);\r
- buf[3] = (byte) _tcpPort ;\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.net.UnknownHostException;
+
+/**
+ * Super for IPv6 PDP Addresses
+ */
+abstract public class COPSIpv6PdpAddress extends COPSPdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param tcpPort - the associated port
+ * @param reserved - not in use
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6PdpAddress(final COPSObjHeader objHdr, final String host, final int tcpPort, final short reserved)
+ throws UnknownHostException {
+ super(objHdr, new COPSIpv6Address(host), tcpPort, reserved);
+ if (!objHdr.getCType().equals(CType.STATELESS))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.STATELESS);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @param reserved - not in use
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6PdpAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr, new COPSIpv6Address(addr), tcpPort, reserved);
+ if (!objHdr.getCType().equals(CType.STATELESS))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.STATELESS);
+ }
+
+}
+
+
--- /dev/null
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.UnknownHostException;
+
+/**
+ * PDP Redirect Address (RFC 2748 pg. 15)
+ *
+ * A PDP when closing a PEP session for a particular client-type may
+ optionally use this object to redirect the PEP to the specified PDP
+ server address and TCP port number:
+ *
+ * C-Num = 13,
+ *
+ * C-Type = 1, IPv4 Address (Same format as PDPRedirAddr)
+ *
+ * C-Type = 2, IPv6 Address (Same format as PDPRedirAddr)
+ */
+public final class COPSIpv6PdpRedirectAddress extends COPSIpv6PdpAddress {
+
+ /**
+ * Constructor generally used for sending messages
+ * @param host - the host name
+ * @param port - the associated port
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSIpv6PdpRedirectAddress(final String host, final int port, final short reserved) throws UnknownHostException {
+ super(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), host, port, reserved);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param objHdr - the object header
+ * @param addr - the byte array representation of a host
+ * @param tcpPort - the associated port
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSIpv6PdpRedirectAddress(final COPSObjHeader objHdr, final byte[] addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr, addr, tcpPort, reserved);
+ if (!objHdr.getCNum().equals(CNum.PDP_REDIR))
+ throw new IllegalArgumentException("CNum must be equal to - " + CNum.PDP_REDIR);
+ }
+
+ @Override
+ public void dumpBody(OutputStream os) throws IOException {
+ os.write(("Ipv6PdpRedirectAddress" + "\n").getBytes());
+ super.dumpBody(os);
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Keep Alive Message\r
- *\r
- * @version COPSKAMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSKAMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSIntegrity _integrity;\r
-\r
- public COPSKAMsg() {\r
- _integrity = null;\r
- }\r
-\r
- protected COPSKAMsg(byte[] data) throws COPSException {\r
- _integrity = null;\r
- parse(data);\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- //The client type in the header MUST always be set to 0\r
- //as KA is used for connection verification.RFC 2748\r
- if ((_hdr == null) && (_hdr.getClientType() != 0))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_KA)\r
- throw new COPSException ("Error Header (no COPS_OP_KA)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Integrity objects\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Returns true if it has Integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- };\r
-\r
- /**\r
- * Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Writes data to given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default: {\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_KA)\r
- throw new COPSException("Error Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- private void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Keep Alive Message (RFC 2748 pg. 27)
+ *
+ * The keep-alive message MUST be transmitted by the PEP within the
+ * period defined by the minimum of all KA Timer values specified in all
+ * received CAT messages for the connection. A KA message MUST be
+ * generated randomly between 1/4 and 3/4 of this minimum KA timer
+ * interval. When the PDP receives a keep-alive message from a PEP, it
+ * MUST echo a keep-alive back to the PEP. This message provides
+ * validation for each side that the connection is still functioning
+ * even when there is no other messaging.
+ *
+ * Note: The client-type in the header MUST always be set to 0 as the KA
+ * is used for connection verification (not per client session
+ * verification).
+ *
+ * <Keep-Alive> ::= <Common Header>
+ * [<Integrity>]
+ * Both client and server MAY assume the TCP connection is insufficient
+ * for the client-type with the minimum time value (specified in the CAT
+ * message) if no communication activity is detected for a period
+ * exceeding the timer period. For the PEP, such detection implies the
+ * remote PDP or connection is down and the PEP SHOULD now attempt to
+ * use an alternative/backup PDP.
+ */
+public class COPSKAMsg extends COPSMsg {
+
+ // Optional
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSKAMsg(final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.KA, (short)0), integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSKAMsg(final int version, final Flag flag, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.KA, (short)0), integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSKAMsg(final COPSHeader hdr, final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.KA))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.KA);
+ if (hdr.getClientType() != 0) throw new IllegalArgumentException("Client type must be 0");
+ _integrity = integrity;
+ }
+
+ // Getter
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected int getDataLength() {
+ if (_integrity != null) return _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ else return 0;
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSKAMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSKAMsg copskaMsg = (COPSKAMsg) o;
+
+ return !(_integrity != null ? !_integrity.equals(copskaMsg._integrity) : copskaMsg._integrity != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSKAMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSKAMsg(hdrData.header, integrity);
+ }
+
+}
+
+
+
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-/**\r
- * COPS Keep Alive Timer\r
- *\r
- * @version COPSKATimer.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSKATimer extends COPSTimer {\r
-\r
- public COPSKATimer() {\r
- super(new COPSObjHeader(CNum.KA, CType.DEF), (short) 1);\r
- }\r
-\r
- ///\r
- public COPSKATimer(short timeVal) {\r
- super(new COPSObjHeader(CNum.KA, CType.DEF), timeVal);\r
- }\r
-\r
- /**\r
- * Method isKATimer\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isKATimer() {\r
- return true;\r
- }\r
-\r
- protected COPSKATimer(byte[] dataPtr) {\r
- super (dataPtr);\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS Keep Alive Timer (RFC 2748)
+ *
+ * Times are encoded as 2 octet integer values and are in units of
+ * seconds. The timer value is treated as a delta.
+ *
+ * C-Num = 10,
+ *
+ * C-Type = 1, Keep-alive timer value
+ * Timer object used to specify the maximum time interval over which a
+ * COPS message MUST be sent or received. The range of finite timeouts
+ * is 1 to 65535 seconds represented as an unsigned two-octet integer.
+ * The value of zero implies infinity.
+ */
+public class COPSKATimer extends COPSTimer {
+
+ /**
+ * Constructor generally used for sending messages
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSKATimer(final short timeVal) {
+ this((short)0, timeVal);
+ }
+
+ /**
+ * Constructor to override the reserved member value from 0
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSKATimer(final short reserved, final short timeVal) {
+ this(new COPSObjHeader(CNum.KA, CType.DEF), reserved, timeVal);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param reserved - ???
+ * @param timeVal - the timer value
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSKATimer(final COPSObjHeader hdr, final short reserved, final short timeVal) {
+ super(hdr, reserved, timeVal);
+ if (!hdr.getCNum().equals(CNum.KA))
+ throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.KA);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Invalid CType value. Must be " + CType.DEF);
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSKATimer parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ short reserved = 0;
+ reserved |= ((short) dataPtr[4]) << 8;
+ reserved |= ((short) dataPtr[5]) & 0xFF;
+
+ short timerValue = 0;
+ timerValue |= ((short) dataPtr[6]) << 8;
+ timerValue |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSKATimer(objHdrData.header, reserved, timerValue);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-\r
-\r
-/**\r
- * COPS LPDP Decision Object\r
- *\r
- * @version COPSLPDPDecision.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSLPDPDecision extends COPSDecision {\r
-\r
- /**\r
- Constructor to create a Local Decision object.\r
- */\r
- public COPSLPDPDecision(byte cType) {\r
- super (cType);\r
-// TODO - FIXME later, currently not in use and the header is now immutable\r
-// _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC);\r
- }\r
-\r
- public COPSLPDPDecision() {\r
- super ();\r
-// TODO - FIXME later, currently not in use and the header is now immutable\r
-// _objHdr.setCNum(COPSObjHeader.COPS_LPDP_DEC);\r
- }\r
-\r
- /**\r
- * Method isLocalDecision\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isLocalDecision() {\r
- return true;\r
- }\r
-\r
- protected COPSLPDPDecision(byte[] data) {\r
- super (data);\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+/**
+ * COPS LPDP Decision Object (local decision) (RFC 2748)
+ *
+ * Decision made by the PEP's local policy decision point (LPDP). May
+ * appear in requests. These objects correspond to and are formatted the
+ * same as the client specific decision objects defined above.
+ *
+ * C-Num = 7
+ *
+ * C-Type = (same C-Type as for Decision objects)
+ */
+public class COPSLPDPDecision extends COPSDecision {
+
+ /**
+ * Constructor generally used for sending messages with a specific, CType, Command and DecisionFlag
+ * @param cType - the CType
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSLPDPDecision(final CType cType, final Command cmdCode, final DecisionFlag flags, final COPSData data) {
+ this(new COPSObjHeader(CNum.LPDP_DEC, cType), cmdCode, flags, data);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param cmdCode - the command
+ * @param flags - the flags
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSLPDPDecision(final COPSObjHeader hdr, final Command cmdCode, final DecisionFlag flags,
+ final COPSData data) {
+ super(hdr, cmdCode, flags, data);
+
+ if (!hdr.getCNum().equals(CNum.LPDP_DEC))
+ throw new IllegalArgumentException("Invalid CNum value. Must be " + CNum.LPDP_DEC);
+ }
+
+ /**
+ * Parses bytes to return a COPSLPDPDecision object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSLPDPDecision parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ final COPSObjHeader tempHdr = new COPSObjHeader(CNum.DEC, objHdrData.header.getCType());
+ final COPSObjHeaderData tempObjHdrData = new COPSObjHeaderData(tempHdr, objHdrData.msgByteCount);
+ final COPSDecision decision = COPSDecision.parse(tempObjHdrData, dataPtr);
+ return new COPSLPDPDecision(objHdrData.header, decision.getCommand(), decision.getFlag(), decision.getData());
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Message\r
- *\r
- * @version COPSMsg.java, v 1.00 2003\r
- *\r
- */\r
-abstract public class COPSMsg {\r
-\r
- protected COPSHeader _hdr;\r
- protected int _dataLength;\r
- protected int _dataStart;\r
-\r
- /**\r
- * Method getHeader\r
- *\r
- * @return a COPSHeader\r
- *\r
- */\r
- public COPSHeader getHeader() {\r
- return _hdr;\r
- }\r
-\r
- /**\r
- * Method writeData\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public abstract void writeData(Socket id) throws IOException;\r
-\r
- /**\r
- * Method getMsgLength\r
- *\r
- * @return an int\r
- *\r
- */\r
- public int getMsgLength() {\r
- return _hdr.getMsgLength();\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected abstract void parse(COPSHeader hdr, byte[] data) throws COPSException;\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected abstract void parse(byte[] data) throws COPSException;\r
-\r
- /**\r
- * Method parseHeader\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parseHeader(byte[] data) throws COPSException {\r
- _dataLength = 0;\r
- _dataStart = 0;\r
- if (_hdr == null) {\r
- // _hdr = new COPSHeader(COPSHeader.COPS_OP_CAT);\r
- _hdr = new COPSHeader(data);\r
- _dataStart += 8;\r
- _dataLength = _hdr.getMsgLength();\r
- } else {\r
- //header is already read\r
- _dataLength = _hdr.getMsgLength() - 8;\r
- }\r
-\r
- //validate the message length\r
- //Should fill on the 32bit boundary\r
- if ((_hdr.getMsgLength() % 4 != 0)) {\r
- throw new COPSException("Bad message format: COPS message is not on 32 bit bounday");\r
- }\r
- }\r
-\r
- /** Checks the sanity of COPS message and throw an\r
- COPSBadDataException when data is bad.\r
- */\r
- public abstract void checkSanity()throws COPSException;\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- os.write(new String("COPS Message").getBytes());\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Represents messages coming from and going to a COPS device such as a CMTS
+ */
+abstract public class COPSMsg {
+
+ private static final Logger logger = LoggerFactory.getLogger(COPSMsg.class);
+
+ /**
+ * The COPS header that is associated with all COPS messages
+ */
+ private final COPSHeader _hdr;
+
+ /**
+ * Base constructor
+ * @param hdr - the header
+ */
+ public COPSMsg(final COPSHeader hdr) {
+ if (hdr == null) throw new IllegalArgumentException("Header must not be null");
+ this._hdr = hdr;
+ }
+ /**
+ * Returns the message header object
+ * @return a COPSHeader
+ */
+ public COPSHeader getHeader() {
+ return _hdr;
+ }
+
+ /**
+ * Method writeData. Implementers should be calling super.writeData() for the header prior to writing out the rest.
+ * @param socket a Socket
+ * @throws IOException
+ */
+ public final void writeData(final Socket socket) throws IOException {
+ logger.info("Writing data for OPCode - " + _hdr.getOpCode());
+ _hdr.writeData(socket, _hdr.getHdrLength() + getDataLength());
+ writeBody(socket);
+ }
+
+ /**
+ * Returns the number of bytes to be contained within the payload excluding the header
+ * @return - a positive value including the header size
+ */
+ protected abstract int getDataLength();
+
+ /**
+ * Writes out the body data over a socket
+ * @param socket - the socket to which to write
+ */
+ protected abstract void writeBody(Socket socket) throws IOException;
+
+ /**
+ * Write an object textual description in the output stream
+ * @param os an OutputStream
+ * @throws IOException
+ */
+ final public void dump(final OutputStream os) throws IOException {
+ _hdr.dump(os);
+ dumpBody(os);
+ }
+
+ /**
+ * Creates a string representation of this object and sends it to an output stream
+ * @param os - the output stream
+ * @throws IOException
+ */
+ protected abstract void dumpBody(final OutputStream os) throws IOException;
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSMsg)) {
+ return false;
+ }
+
+ final COPSMsg copsMsg = (COPSMsg) o;
+
+ return _hdr.equals(copsMsg._hdr);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return _hdr.hashCode();
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-/**\r
- * COPS Message Parser\r
- *\r
- * @version COPSMsgParser.java, v 1.00 2003\r
- *\r
- */\r
-\r
-// import org.umu.cops.common.COPSDebug;\r
-\r
-public class COPSMsgParser {\r
- ///\r
- public COPSMsgParser() {\r
-\r
- }\r
-\r
- /** Parses the given COPS data and returns a COPSMsg object\r
- * with COPS object filed in.The COPSMsg object is allocated in the\r
- * call and it is the responsibility of the caller to free the memory\r
- *\r
- * @param data a byte[]\r
- *\r
- * @return a COPSMsg\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public COPSMsg parse(byte[] data) throws COPSException {\r
- COPSHeader hdr = new COPSHeader(data);\r
-\r
- byte[] buf = new byte[data.length - 8];\r
- System.arraycopy(data,8,buf,0,data.length - 8);\r
-\r
- return (parse(hdr, buf));\r
- }\r
-\r
- /**\r
- * Parse the message with given header , the data is pointing\r
- * to the data following the header\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @return a COPSMsg\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public COPSMsg parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- COPSMsg copsMsg = null;\r
- short cCode = hdr.getOpCode();\r
- switch (cCode) {\r
- case COPSHeader.COPS_OP_REQ: {\r
- // COPSDebug.out(getClass().getName(), "Creating REQ msg");\r
- copsMsg = new COPSReqMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_DEC: {\r
- // COPSDebug.out(getClass().getName(), "Creating DEC msg");\r
- copsMsg = new COPSDecisionMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_RPT: {\r
- // COPSDebug.out(getClass().getName(), "Creating RPT msg");\r
- copsMsg = new COPSReportMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_DRQ: {\r
- // COPSDebug.out(getClass().getName(), "Creating DRQ msg");\r
- copsMsg = new COPSDeleteMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_OPN: {\r
- // COPSDebug.out(getClass().getName(), "Creating Client-Open msg");\r
- copsMsg = new COPSClientOpenMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_CAT: {\r
- // COPSDebug.out(getClass().getName(), "Creating Client-Accept msg");\r
- copsMsg = new COPSClientAcceptMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_CC: {\r
- // COPSDebug.out(getClass().getName(), "Creating Client-Close msg");\r
- copsMsg = new COPSClientCloseMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_KA: {\r
- // COPSDebug.out(getClass().getName(), "Creating KA msg");\r
- copsMsg = new COPSKAMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_SSQ: {\r
- // COPSDebug.out(getClass().getName(), "Creating Sync-State Request msg");\r
- copsMsg = new COPSSyncStateMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- case COPSHeader.COPS_OP_SSC: {\r
- // COPSDebug.out(getClass().getName(), "Creating Sync-State Complete msg");\r
- copsMsg = new COPSSyncStateMsg();\r
- copsMsg.parse(hdr, data);\r
- }\r
- break;\r
- default:\r
- // COPSDebug.out(getClass().getName(), "Unknown message type");\r
- break;\r
- }\r
-\r
-\r
- // if(copsMsg != null)\r
- // try { copsMsg.dump(COPSDebug.out); } catch (Exception e) {};\r
-\r
- return copsMsg;\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Date;
+
+/**
+ * Utility for parsing COPS messages obtained from a Socket connection
+ */
+
+public class COPSMsgParser {
+
+ public final static Logger logger = LoggerFactory.getLogger(COPSMsgParser.class);
+
+ /**
+ * Transforms a COPS message streaming in from a Socket connection into a COPSMsg object
+ * @param socket - the socket
+ * @return - an implementation of the abstract COPSMsg object
+ * @throws IOException
+ * @throws COPSException
+ */
+ public static COPSMsg parseMessage(final Socket socket) throws IOException, COPSException {
+ final COPSHeaderData hdrData = readHeader(socket);
+ return readBody(socket, hdrData);
+ }
+
+
+ /**
+ * Unmarshalls the COPS Header data from the bytes received on the Socket
+ * @param socket - the socket
+ * @return - the header data
+ * @throws IOException
+ */
+ private static COPSHeaderData readHeader(final Socket socket) throws IOException {
+ logger.info("Reading COPS Header");
+ final byte[] data = new byte[8];
+ final int bytesRead = readData(socket, data, 8);
+ if (bytesRead != 8) throw new IOException("Expected 8 bytes, read in " + bytesRead);
+
+ final byte[] vFlagsNibbles = splitByteToNibbles(data[0]);
+ byte version = vFlagsNibbles[0];
+ final Flag flag;
+ if (vFlagsNibbles[1] == 1) flag = Flag.SOLICITED; else flag = Flag.UNSOLICITED;
+
+ final OPCode opCode;
+ if (COPSHeader.VAL_TO_OP.get((int)data[1]) == null) opCode = OPCode.NA;
+ else opCode = COPSHeader.VAL_TO_OP.get((int)data[1]);
+
+ short cType = bytesToShort(data[2], data[3]);
+
+ int msgLength = ((short) data[4]) << 24;
+ msgLength |= ((short) data[5]) << 16;
+ msgLength |= ((short) data[6]) << 8;
+ msgLength |= ((short) data[7]) & 0xFF;
+
+ return new COPSHeaderData(new COPSHeader(version, flag, opCode, cType), msgLength);
+ }
+
+ /**
+ * Takes a short value and splits it into 2 bytes
+ * @param val - the value to split
+ * @return - a 2 byte array
+ */
+ public static byte[] shortToBytes(final short val) {
+ final byte[] out = new byte[2];
+ out[0] = (byte) (val >> 8);
+ out[1] = (byte) val;
+ return out;
+ }
+
+ /**
+ * Takes two bytes and concatenates the two into a short value
+ * @param byte1 - the first byte
+ * @param byte2 - the training byte
+ * @return - the short value
+ */
+ public static short bytesToShort(final byte byte1, final byte byte2) {
+ short out = 0;
+ out |= ((short) byte1) << 8;
+ out |= ((short) byte2) & 0xFF;
+ return out;
+ }
+
+ private static COPSMsg readBody(final Socket socket, final COPSHeaderData hdrData) throws IOException, COPSException {
+ logger.info("Reading COPS Body of type - " + hdrData.header.getOpCode());
+ final int expectedBytes = hdrData.msgByteCount - hdrData.header.getHdrLength();
+ final byte[] buffer = new byte[expectedBytes];
+ final int nread = readData(socket, buffer, expectedBytes);
+// buffer[expectedBytes] = (byte) '\0';
+ if (nread != expectedBytes) {
+ throw new COPSException("Bad COPS message");
+ }
+ return parse(hdrData, buffer);
+ }
+
+ /**
+ * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error
+ * bRead returns the bytes read.
+ * @param socket a Socket
+ * @param dataRead a byte[] - this array should be initialized to the proper size but is then
+ * populated by reference
+ * @param nchar an int
+ * @return an int
+ * @throws IOException
+ */
+ public static int readData(final Socket socket, final byte[] dataRead, final int nchar) throws IOException {
+ final InputStream input = socket.getInputStream();
+ int nread = 0;
+ int startTime = (int) (new Date().getTime());
+ do {
+ if (input.available() != 0) {
+ nread += input.read(dataRead, nread, nchar-nread);
+ startTime = (int) (new Date().getTime());
+ } else {
+ int nowTime = (int) (new Date().getTime());
+ // Read Timeout - TODO - May want to make this configurable
+ if ((nowTime - startTime) > 2000)
+ break;
+ }
+ } while (nread != nchar);
+ return nread;
+ }
+ /**
+ * Parse the message with given header , the data is pointing
+ * to the data following the header
+ * @param hdrData - contains the header and the
+ * @param data a byte[]
+ * @return a COPSMsg
+ * @throws COPSException
+ */
+ private static COPSMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ final OPCode cCode = hdrData.header.getOpCode();
+ switch (cCode) {
+ case REQ:
+ return COPSReqMsg.parse(hdrData, data);
+ case DEC:
+ return COPSDecisionMsg.parse(hdrData, data);
+ case RPT:
+ return COPSReportMsg.parse(hdrData, data);
+ case DRQ:
+ return COPSDeleteMsg.parse(hdrData, data);
+ case OPN:
+ return COPSClientOpenMsg.parse(hdrData, data);
+ case CAT:
+ return COPSClientAcceptMsg.parse(hdrData, data);
+ case CC:
+ return COPSClientCloseMsg.parse(hdrData, data);
+ case KA:
+ return COPSKAMsg.parse(hdrData, data);
+ case SSQ:
+ case SSC:
+ return COPSSyncStateMsg.parse(hdrData, data);
+ default:
+ throw new COPSException("Unsupported client code");
+ }
+ }
+
+ /**
+ * Builds two nibbles represented as bytes from a single byte. Each nibble returned must not be > 15
+ * @param b the byte to divide into nibbles
+ * @return two bytes where the first represents bits 1-4 and second represents bits 5-8
+ */
+ public static byte[] splitByteToNibbles(final byte b) {
+ return new byte[]{
+ //move the four high bits to the right,
+ //fill up with zeros
+ (byte)(b >>> 4 & 0xF),
+ //zero out the four high bits and leave
+ //the low bits untouched
+ (byte)(b & 0x0F)
+ };
+ }
+
+ /**
+ * Combines two bytes representing a nibble into a single byte
+ * @param byte1 - nibble #1 (0-15)
+ * @param byte2 - nibble #2 (0-15)
+ * @return - one byte representing both nibbles
+ * @throws java.lang.IllegalArgumentException if either value is < 0 || > 15
+ */
+ public static int combineNibbles(final byte byte1, final byte byte2) {
+ if (byte1 > 15 || byte1 < 0 || byte2 > 15 || byte2 < 0)
+ throw new IllegalArgumentException("Each byte representing a nibble shall not exceed 15 (0xf)");
+ return (byte1 << 4) | byte2;
+ }
+
+}
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-import java.util.Arrays;\r
-\r
-/**\r
- * COPS Object\r
- *\r
- * TODO - this should be an interface and all of these default return values can be dangerous\r
- * @version COPSObjBase.java, v 1.00 2003\r
- *\r
- */\r
-public abstract class COPSObjBase {\r
- /**\r
- * Add padding in the data, if the data does not fall on 32-bit boundary\r
- * @param len an int\r
- * @return a COPSData\r
- */\r
- static COPSData getPadding(final int len) {\r
- byte[] padBuf = new byte[len];\r
- Arrays.fill(padBuf, (byte) 0);\r
- return new COPSData(padBuf, 0, len);\r
- }\r
-\r
- /**\r
- * Writes data to a given network _socket\r
- * @param id a Socket\r
- * @throws IOException\r
- */\r
- public abstract void writeData(Socket id) throws IOException;\r
-\r
- /**\r
- * Method getDataLength\r
- * @return a short\r
- */\r
- short getDataLength() {\r
- return 0;\r
- }\r
-\r
- /**\r
- * Method isCOPSHeader\r
- * @return a boolean\r
- */\r
- boolean isCOPSHeader() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isClientHandle\r
- * @return a boolean\r
- */\r
- boolean isClientHandle() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isContext\r
- * @return a boolean\r
- */\r
- boolean isContext() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isInterface\r
- * @return a boolean\r
- */\r
- boolean isInterface() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isDecision\r
- * @return a boolean\r
- */\r
- boolean isDecision() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isLocalDecision\r
- * @return a boolean\r
- */\r
- boolean isLocalDecision() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isReport\r
- * @return a boolean\r
- */\r
- boolean isReport() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isError\r
- * @return a boolean\r
- */\r
- boolean isError() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isTimer\r
- * @return a boolean\r
- */\r
- boolean isTimer() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isPepId\r
- * @return a boolean\r
- */\r
- boolean isPepId() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isReason\r
- * @return a boolean\r
- */\r
- boolean isReason() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isPdpAddress\r
- * @return a boolean\r
- */\r
- boolean isPdpAddress() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isClientSI\r
- * @return a boolean\r
- */\r
- boolean isClientSI() {\r
- return false;\r
- }\r
-\r
- /**\r
- * Method isMessageIntegrity\r
- * @return a boolean\r
- */\r
- boolean isMessageIntegrity() {\r
- return false;\r
- }\r
-\r
-}\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Represents objects that can be contained within COPS messages.
+ */
+public abstract class COPSObjBase {
+
+ /**
+ * Generally used to determine the type of message
+ */
+ private final COPSObjHeader _objHdr;
+
+ /**
+ * The base object constructor
+ * @param objHdr - the header (required)
+ */
+ public COPSObjBase(final COPSObjHeader objHdr) {
+ if (objHdr == null) throw new IllegalArgumentException("Object header must not be null");
+ this._objHdr = objHdr;
+ }
+
+ /**
+ * Returns the header
+ * @return - the header
+ */
+ public COPSObjHeader getHeader() { return _objHdr; }
+
+ /**
+ * Writes data to a given network _socket
+ * @param socket a Socket
+ * @throws IOException
+ */
+ final public void writeData(final Socket socket) throws IOException {
+ _objHdr.writeData(socket, getDataLength());
+ writeBody(socket);
+ }
+
+ protected abstract void writeBody(Socket socket) throws IOException;
+
+ /**
+ * Returns the length of the body data to be output (not including header)
+ * @return a short
+ */
+ protected abstract int getDataLength();
+
+ /**
+ * Write an object textual description in the output stream
+ * @param os an OutputStream
+ * @throws IOException
+ */
+ final public void dump(final OutputStream os) throws IOException {
+ _objHdr.dump(os);
+ dumpBody(os);
+ }
+
+ protected abstract void dumpBody(OutputStream os) throws IOException;
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSObjBase)) {
+ return false;
+ }
+
+ final COPSObjBase that = (COPSObjBase) o;
+ return _objHdr.equals(that._objHdr);
+ }
+
+ @Override
+ public int hashCode() {
+ return _objHdr.hashCode();
+ }
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-import java.util.Map;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-\r
-/**\r
- * COPS Object Header\r
- *\r
- * @version COPSObjHeader.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSObjHeader {\r
-\r
- static Map<Integer, CNum> VAL_TO_CNUM = new ConcurrentHashMap<>();\r
- static {\r
- VAL_TO_CNUM.put(CNum.NA.ordinal(), CNum.NA);\r
- VAL_TO_CNUM.put(CNum.HANDLE.ordinal(), CNum.HANDLE);\r
- VAL_TO_CNUM.put(CNum.CONTEXT.ordinal(), CNum.CONTEXT);\r
- VAL_TO_CNUM.put(CNum.ININTF.ordinal(), CNum.ININTF);\r
- VAL_TO_CNUM.put(CNum.OUTINTF.ordinal(), CNum.OUTINTF);\r
- VAL_TO_CNUM.put(CNum.REASON_CODE.ordinal(), CNum.REASON_CODE);\r
- VAL_TO_CNUM.put(CNum.DEC.ordinal(), CNum.DEC);\r
- VAL_TO_CNUM.put(CNum.LPDP_DEC.ordinal(), CNum.LPDP_DEC);\r
- VAL_TO_CNUM.put(CNum.ERROR.ordinal(), CNum.ERROR);\r
- VAL_TO_CNUM.put(CNum.CSI.ordinal(), CNum.CSI);\r
- VAL_TO_CNUM.put(CNum.KA.ordinal(), CNum.KA);\r
- VAL_TO_CNUM.put(CNum.PEPID.ordinal(), CNum.PEPID);\r
- VAL_TO_CNUM.put(CNum.RPT.ordinal(), CNum.RPT);\r
- VAL_TO_CNUM.put(CNum.PDP_REDIR.ordinal(), CNum.PDP_REDIR);\r
- VAL_TO_CNUM.put(CNum.LAST_PDP_ADDR.ordinal(), CNum.LAST_PDP_ADDR);\r
- VAL_TO_CNUM.put(CNum.ACCT_TIMER.ordinal(), CNum.ACCT_TIMER);\r
- VAL_TO_CNUM.put(CNum.MSG_INTEGRITY.ordinal(), CNum.MSG_INTEGRITY);\r
- }\r
-\r
- static Map<Integer, CType> VAL_TO_CTYPE = new ConcurrentHashMap<>();\r
- static {\r
- VAL_TO_CTYPE.put(CType.NA.ordinal(), CType.NA);\r
- VAL_TO_CTYPE.put(CType.DEF.ordinal(), CType.DEF);\r
- VAL_TO_CTYPE.put(CType.STATELESS.ordinal(), CType.STATELESS);\r
- VAL_TO_CTYPE.put(CType.REPL.ordinal(), CType.REPL);\r
- VAL_TO_CTYPE.put(CType.CSI.ordinal(), CType.CSI);\r
- VAL_TO_CTYPE.put(CType.NAMED.ordinal(), CType.NAMED);\r
- }\r
-\r
- /**\r
- * Denotes the type of COPSMsg\r
- */\r
- private final CNum _cNum;\r
-\r
- /**\r
- * Subtype or version of the information.\r
- */\r
- private final CType _cType;\r
-\r
- /**\r
- * TODO - remove this attribute as the body of the COPS message should return the body length\r
- */\r
- @Deprecated\r
- private short _len;\r
-\r
- /**\r
- * Constructor\r
- * @param cNum - the cNum value\r
- * @param cType - the cType value\r
- * @throws java.lang.IllegalArgumentException\r
- */\r
- public COPSObjHeader(final CNum cNum, final CType cType) {\r
- if (cNum == null || cType == null) throw new IllegalArgumentException("CNum and CType must not be null");\r
- _cNum = cNum;\r
- _cType = cType;\r
- _len = 4;\r
- }\r
-\r
- /**\r
- * Get the data length in number of octets\r
- * @return a short\r
- */\r
- public short getHdrLength() {\r
- return (short)4;\r
- }\r
-\r
- /**\r
- * Get the class information identifier cNum\r
- * @return a byte\r
- */\r
-\r
- public CNum getCNum() {\r
- return _cNum;\r
- }\r
-\r
- /**\r
- * Get the type per cNum\r
- * @return a byte\r
- */\r
- public CType getCType() {\r
- return _cType;\r
- }\r
-\r
- /**\r
- * Get stringified CNum\r
- * @return a String\r
- */\r
- public String getStrCNum() {\r
- switch (_cNum) {\r
- case HANDLE:\r
- return ("Client-handle");\r
- case CONTEXT:\r
- return ("Context");\r
- case ININTF:\r
- return ("In-Interface");\r
- case OUTINTF:\r
- return ("Out-Interface");\r
- case REASON_CODE:\r
- return ("Reason");\r
- case DEC:\r
- return ("Decision");\r
- case LPDP_DEC:\r
- return ("Local-Decision");\r
- case ERROR:\r
- return ("Error");\r
- case CSI:\r
- return ("Client-SI");\r
- case KA:\r
- return ("KA-timer");\r
- case PEPID:\r
- return ("PEP-id");\r
- case RPT:\r
- return ("Report");\r
- case PDP_REDIR:\r
- return ("Redirect PDP addr");\r
- case LAST_PDP_ADDR:\r
- return ("Last PDP addr");\r
- case ACCT_TIMER:\r
- return ("Account-Timer");\r
- case MSG_INTEGRITY:\r
- return ("Message-Integrity");\r
- default:\r
- return ("Unknown");\r
- }\r
- }\r
-\r
- /**\r
- * Set the obj length, the length is the length of the data following\r
- * the object header.The length of the object header (4 bytes) is added\r
- * to the length passed.\r
- *\r
- * TODO - The data length will be removed from the header in a subsequent patch\r
- *\r
- * @param len a short\r
- */\r
- @Deprecated\r
- public void setDataLength(short len) {\r
- //Add the length of the header also\r
- _len = (short) (len + 4);\r
- }\r
-\r
- /**\r
- * Get the data length in number of octets\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- return _len;\r
- }\r
-\r
- /**\r
- * Writes data to a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_len >> 8);\r
- buf[1] = (byte) _len;\r
- buf[2] = (byte) _cNum.ordinal();\r
- buf[3] = (byte) _cType.ordinal();\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- * @param os an OutputStream\r
- * @throws IOException\r
- */\r
- public void dump(final OutputStream os) throws IOException {\r
- os.write(("**" + getStrCNum() + "**" + "\n").getBytes());\r
- os.write(("C-num: " + _cNum + "\n").getBytes());\r
- os.write(("C-type: " + _cType + "\n").getBytes());\r
- }\r
-\r
- @Override\r
- public boolean equals(Object o) {\r
- if (this == o) {\r
- return true;\r
- }\r
- if (!(o instanceof COPSObjHeader)) {\r
- return false;\r
- }\r
-\r
- final COPSObjHeader header = (COPSObjHeader) o;\r
-\r
- return _cNum == header._cNum && _cType == header._cType;\r
-\r
- }\r
-\r
- @Override\r
- public int hashCode() {\r
- int result = _cNum.hashCode();\r
- result = 31 * result + _cType.hashCode();\r
- return result;\r
- }\r
-\r
- /**\r
- * Method parse\r
- *\r
- * @param data a byte[]\r
- *\r
- */\r
- public final static COPSObjHeader parse(byte[] data) {\r
- short len = 0;\r
- len = 0;\r
- len |= ((short) data[0]) << 8;\r
- len |= ((short) data[1]) & 0xFF;\r
-\r
- int cNum = 0;\r
- cNum |= data[2];\r
-\r
- int cType = 0;\r
- cType |= data[3];\r
-\r
- final COPSObjHeader hdr = new COPSObjHeader(VAL_TO_CNUM.get(cNum), VAL_TO_CTYPE.get(cType));\r
- hdr.setDataLength(len);\r
- return hdr;\r
- }\r
-\r
- public enum CNum {\r
- NA,\r
- HANDLE,\r
- CONTEXT,\r
- ININTF,\r
- OUTINTF,\r
- REASON_CODE,\r
- DEC,\r
- LPDP_DEC,\r
- ERROR,\r
- CSI,\r
- KA,\r
- PEPID,\r
- RPT,\r
- PDP_REDIR,\r
- LAST_PDP_ADDR,\r
- ACCT_TIMER,\r
- MSG_INTEGRITY,\r
- }\r
-\r
- public enum CType {\r
- NA,\r
- DEF,\r
- STATELESS,\r
- REPL,\r
- CSI,\r
- NAMED\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Object Header
+ *
+ * @version COPSObjHeader.java, v 1.00 2003
+ *
+ */
+public class COPSObjHeader {
+
+ static Map<Integer, CNum> VAL_TO_CNUM = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_CNUM.put(CNum.NA.ordinal(), CNum.NA);
+ VAL_TO_CNUM.put(CNum.HANDLE.ordinal(), CNum.HANDLE);
+ VAL_TO_CNUM.put(CNum.CONTEXT.ordinal(), CNum.CONTEXT);
+ VAL_TO_CNUM.put(CNum.ININTF.ordinal(), CNum.ININTF);
+ VAL_TO_CNUM.put(CNum.OUTINTF.ordinal(), CNum.OUTINTF);
+ VAL_TO_CNUM.put(CNum.REASON_CODE.ordinal(), CNum.REASON_CODE);
+ VAL_TO_CNUM.put(CNum.DEC.ordinal(), CNum.DEC);
+ VAL_TO_CNUM.put(CNum.LPDP_DEC.ordinal(), CNum.LPDP_DEC);
+ VAL_TO_CNUM.put(CNum.ERROR.ordinal(), CNum.ERROR);
+ VAL_TO_CNUM.put(CNum.CSI.ordinal(), CNum.CSI);
+ VAL_TO_CNUM.put(CNum.KA.ordinal(), CNum.KA);
+ VAL_TO_CNUM.put(CNum.PEPID.ordinal(), CNum.PEPID);
+ VAL_TO_CNUM.put(CNum.RPT.ordinal(), CNum.RPT);
+ VAL_TO_CNUM.put(CNum.PDP_REDIR.ordinal(), CNum.PDP_REDIR);
+ VAL_TO_CNUM.put(CNum.LAST_PDP_ADDR.ordinal(), CNum.LAST_PDP_ADDR);
+ VAL_TO_CNUM.put(CNum.ACCT_TIMER.ordinal(), CNum.ACCT_TIMER);
+ VAL_TO_CNUM.put(CNum.MSG_INTEGRITY.ordinal(), CNum.MSG_INTEGRITY);
+ }
+
+ static Map<Integer, CType> VAL_TO_CTYPE = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_CTYPE.put(CType.NA.ordinal(), CType.NA);
+ VAL_TO_CTYPE.put(CType.DEF.ordinal(), CType.DEF);
+ VAL_TO_CTYPE.put(CType.STATELESS.ordinal(), CType.STATELESS);
+ VAL_TO_CTYPE.put(CType.REPL.ordinal(), CType.REPL);
+ VAL_TO_CTYPE.put(CType.CSI.ordinal(), CType.CSI);
+ VAL_TO_CTYPE.put(CType.NAMED.ordinal(), CType.NAMED);
+ }
+
+ /**
+ * Denotes the type of COPSMsg
+ */
+ private final CNum _cNum;
+
+ /**
+ * Subtype or version of the information.
+ */
+ private final CType _cType;
+
+ /**
+ * Constructor
+ * @param cNum - the cNum value
+ * @param cType - the cType value
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSObjHeader(final CNum cNum, final CType cType) {
+ if (cNum == null || cType == null) throw new IllegalArgumentException("CNum and CType must not be null");
+ _cNum = cNum;
+ _cType = cType;
+ }
+
+ /**
+ * Get the data length in number of octets
+ * @return a short
+ */
+ public short getHdrLength() {
+ return (short)4;
+ }
+
+ /**
+ * Get the class information identifier cNum
+ * @return a byte
+ */
+
+ public CNum getCNum() {
+ return _cNum;
+ }
+
+ /**
+ * Get the type per cNum
+ * @return a byte
+ */
+ public CType getCType() {
+ return _cType;
+ }
+
+ /**
+ * Get stringified CNum
+ * @return a String
+ */
+ public String getStrCNum() {
+ switch (_cNum) {
+ case HANDLE:
+ return ("Client-handle");
+ case CONTEXT:
+ return ("Context");
+ case ININTF:
+ return ("In-Interface");
+ case OUTINTF:
+ return ("Out-Interface");
+ case REASON_CODE:
+ return ("Reason");
+ case DEC:
+ return ("Decision");
+ case LPDP_DEC:
+ return ("Local-Decision");
+ case ERROR:
+ return ("Error");
+ case CSI:
+ return ("Client-SI");
+ case KA:
+ return ("KA-timer");
+ case PEPID:
+ return ("PEP-id");
+ case RPT:
+ return ("Report");
+ case PDP_REDIR:
+ return ("Redirect PDP addr");
+ case LAST_PDP_ADDR:
+ return ("Last PDP addr");
+ case ACCT_TIMER:
+ return ("Account-Timer");
+ case MSG_INTEGRITY:
+ return ("Message-Integrity");
+ default:
+ return ("Unknown");
+ }
+ }
+
+ /**
+ * Writes data to a given network _socket
+ * @param socket a Socket
+ * @throws IOException
+ */
+ public void writeData(final Socket socket, final int dataLength) throws IOException {
+ final int payloadSize = + getHdrLength() + dataLength;
+ final byte[] buf = new byte[4];
+ buf[0] = (byte) (payloadSize >> 8);
+ buf[1] = (byte) payloadSize;
+ buf[2] = (byte)_cNum.ordinal();
+ buf[3] = (byte)_cType.ordinal();
+
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ /**
+ * Write an object textual description in the output stream
+ * @param os an OutputStream
+ * @throws IOException
+ */
+ public void dump(final OutputStream os) throws IOException {
+ os.write(("**" + getStrCNum() + "**" + "\n").getBytes());
+ os.write(("C-num: " + _cNum + "\n").getBytes());
+ os.write(("C-type: " + _cType + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSObjHeader)) {
+ return false;
+ }
+
+ final COPSObjHeader header = (COPSObjHeader) o;
+
+ return _cNum == header._cNum && _cType == header._cType;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = _cNum.hashCode();
+ result = 31 * result + _cType.hashCode();
+ return result;
+ }
+
+ public enum CNum {
+ NA,
+ HANDLE,
+ CONTEXT,
+ ININTF,
+ OUTINTF,
+ REASON_CODE,
+ DEC,
+ LPDP_DEC,
+ ERROR,
+ CSI,
+ KA,
+ PEPID,
+ RPT,
+ PDP_REDIR,
+ LAST_PDP_ADDR,
+ ACCT_TIMER,
+ MSG_INTEGRITY,
+ }
+
+ public enum CType {
+ NA,
+ DEF,
+ STATELESS,
+ REPL,
+ CSI,
+ NAMED
+ }
+
+}
+
--- /dev/null
+package org.umu.cops.stack;
+
+/**
+ * Class designed for simply containing the COPSHeader and the total message's byte count.
+ *
+ * No need to test as this class will be tested implicitly via other tests and this does not contain or need
+ * any domain specific logic
+ */
+public class COPSObjHeaderData {
+
+ /**
+ * The actual header to be injected into the appropriate COPSMsg object
+ */
+ final public COPSObjHeader header;
+
+ /**
+ * The total number of bytes contained within the inbound message being parsed.
+ */
+ final public int msgByteCount;
+
+ /**
+ * Constructor
+ * @param hdr - the COPS message header
+ * @param numBytes - the total number of bytes contained within the message envelope
+ */
+ public COPSObjHeaderData(final COPSObjHeader hdr, final int numBytes) {
+ this.header = hdr;
+ this.msgByteCount = numBytes;
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import java.util.Arrays;
+
+/**
+ * Static utilitarian methods for parsing COPS objects contained within COPS messages.
+ */
+public class COPSObjectParser {
+
+ /**
+ * Parses the header information for a COPSObjBase object.
+ * @param data - the data to parse
+ * @return - the header
+ */
+ public static COPSObjHeaderData parseObjHeader(final byte[] data) {
+ if (data == null || data.length < 4)
+ throw new IllegalArgumentException("Data cannot be null or fewer than 4 bytes");
+
+ // TODO - Determine what setting the _len value from the data buffer really means
+ int len = 0;
+ len |= ((short) data[0]) << 8;
+ len |= ((short) data[1]) & 0xFF;
+
+ int cNum = 0;
+ cNum |= data[2];
+
+ int cType = 0;
+ cType |= data[3];
+
+ return new COPSObjHeaderData(
+ new COPSObjHeader(COPSObjHeader.VAL_TO_CNUM.get(cNum), COPSObjHeader.VAL_TO_CTYPE.get(cType)), len);
+ }
+
+ /**
+ * Parses bytes to return a COPSInterface object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSInterface parseIpv4Interface(final COPSObjHeaderData objHdrData, final byte[] dataPtr,
+ final boolean isIn) {
+ if (isIn) return COPSIpv4InInterface.parse(objHdrData, dataPtr);
+ else return COPSIpv4OutInterface.parse(objHdrData, dataPtr);
+ }
+
+ /**
+ * Parses bytes to return a COPSIpv6Interface object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSIpv6Interface parseIpv6Interface(final COPSObjHeaderData objHdrData, final byte[] dataPtr,
+ final boolean isIn) {
+ if (isIn) return COPSIpv6InInterface.parse(objHdrData, dataPtr);
+ else return COPSIpv6OutInterface.parse(objHdrData, dataPtr);
+ }
+
+ /**
+ * Add padding in the data, if the data does not fall on 32-bit boundary
+ * @param len an int
+ * @return a COPSData
+ */
+ public static COPSData getPadding(final int len) {
+ byte[] padBuf = new byte[len];
+ Arrays.fill(padBuf, (byte) 0);
+ return new COPSData(padBuf, 0, len);
+ }
+
+}
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-\r
-/**\r
- * COPS PDP Address\r
- *\r
- * @version COPSPdpAddress.java, v 1.00 2003\r
- *\r
- */\r
-abstract public class COPSPdpAddress extends COPSObjBase {\r
-\r
- /**\r
- * Method isPdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isPdpAddress() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Method isIpv4PdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv4PdpAddress() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isIpv6PdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isIpv6PdpAddress() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isLastPdpAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isLastPdpAddress() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isPdpredirectAddress\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isPdpredirectAddress() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- abstract public void dump(OutputStream os) throws IOException;\r
-};\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * Superclass for all PDP Address classes for which we appear to only have 2 concrete implementations and 4
+ * subclasses meaning this class hierarchy is ripe for further refactoring.
+ */
+abstract public class COPSPdpAddress extends COPSObjBase {
+
+ /**
+ * The address
+ */
+ private COPSIpAddress _addr;
+
+ /**
+ * The port number
+ */
+ private final int _tcpPort;
+
+ /**
+ * Currently the space holding this value is not in use.
+ */
+ private final short _reserved;
+
+ /**
+ * Constructor
+ * @param objHdr - the object's header info
+ * @param tcpPort - the port associated with an IP device
+ * @param reserved - not in use
+ */
+ protected COPSPdpAddress(final COPSObjHeader objHdr, final COPSIpAddress addr, final int tcpPort,
+ final short reserved) {
+ super(objHdr);
+ if (addr == null) throw new IllegalArgumentException("Address must not be null");
+ if (tcpPort < 1) throw new IllegalArgumentException("Invalid port number - " + tcpPort);
+ this._addr = addr;
+ this._tcpPort = tcpPort;
+ this._reserved = reserved;
+ }
+
+ public int getTcpPort() {
+ return _tcpPort;
+ }
+
+ public short getReserved() {
+ return _reserved;
+ }
+
+ /**
+ * Creates the correct object of this type from a byte array.
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSPdpAddress parse(final COPSObjHeaderData objHdrData, final byte[] dataPtr) {
+ short reserved = 0;
+ int tcpPort = 0;
+
+ switch (objHdrData.header.getCType()) {
+ case DEF:
+ final byte[] addr4 = new byte[4];
+ System.arraycopy(dataPtr, 4, addr4, 0, 4);
+ reserved |= ((short) dataPtr[8]) << 8;
+ reserved |= ((short) dataPtr[9]) & 0xFF;
+ tcpPort |= ((short) dataPtr[10]) << 8;
+ tcpPort |= ((short) dataPtr[11]) & 0xFF;
+
+ switch (objHdrData.header.getCNum()) {
+ case LAST_PDP_ADDR:
+ return new COPSIpv4LastPdpAddr(objHdrData.header, addr4, tcpPort, reserved);
+ case PDP_REDIR:
+ return new COPSIpv4PdpRedirectAddress(objHdrData.header, addr4, tcpPort, reserved);
+ default:
+ throw new IllegalArgumentException("Unsupported CNum - " + objHdrData.header.getCNum());
+ }
+ case STATELESS:
+ final byte[] addr6 = new byte[16];
+ System.arraycopy(dataPtr, 4, addr6, 0, 16);
+ reserved |= ((short) dataPtr[20]) << 8;
+ reserved |= ((short) dataPtr[21]) & 0xFF;
+ tcpPort |= ((short) dataPtr[22]) << 8;
+ tcpPort |= ((short) dataPtr[23]) & 0xFF;
+ switch (objHdrData.header.getCNum()) {
+ case LAST_PDP_ADDR:
+ return new COPSIpv6LastPdpAddr(objHdrData.header, addr6, tcpPort, reserved);
+ case PDP_REDIR:
+ return new COPSIpv6PdpRedirectAddress(objHdrData.header, addr6, tcpPort, reserved);
+ default:
+ throw new IllegalArgumentException("Unsupported CNum - " + objHdrData.header.getCNum());
+ }
+ default:
+ throw new IllegalArgumentException("CType was not DEF(1) or STATELESS (2)");
+ }
+ }
+
+ @Override
+ public int getDataLength() {
+ return _addr.getDataLength() + 4;
+ }
+
+ @Override
+ public void dumpBody(OutputStream os) throws IOException {
+ os.write(("Address: " + _addr.getIpName() + "\n").getBytes());
+ os.write(("Port: " + _tcpPort + "\n").getBytes());
+ }
+
+ @Override
+ public void writeBody(final Socket socket) throws IOException {
+ _addr.writeData(socket);
+
+ byte[] buf = new byte[4];
+ buf[0] = (byte) (_reserved >> 8);
+ buf[1] = (byte) _reserved;
+ buf[2] = (byte) (_tcpPort >> 8);
+ buf[3] = (byte) _tcpPort ;
+
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSPdpAddress)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSPdpAddress that = (COPSPdpAddress) o;
+
+ return _reserved == that._reserved && _tcpPort == that._tcpPort && _addr.equals(that._addr);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _addr.hashCode();
+ result = 31 * result + _tcpPort;
+ result = 31 * result + (int) _reserved;
+ return result;
+ }
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS PEP Identification Object\r
- *\r
- * @version COPSPepId.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSPepId extends COPSObjBase {\r
-\r
- COPSObjHeader _objHdr;\r
- COPSData _data;\r
- COPSData _padding;\r
-\r
- public COPSPepId() {\r
- _objHdr = new COPSObjHeader(CNum.PEPID, CType.DEF);\r
- }\r
-\r
- protected COPSPepId(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- //Get the length of data following the obj header\r
- short dLen = (short) (_objHdr.getDataLength() - 4);\r
- COPSData d = new COPSData (dataPtr, 4, dLen);\r
- setData(d);\r
- }\r
-\r
- /**\r
- * Method setData\r
- *\r
- * @param data a COPSData\r
- *\r
- */\r
- public void setData(COPSData data) {\r
- _data = data;\r
- if (_data.length() % 4 != 0) {\r
- int padLen = 4 - _data.length() % 4;\r
- _padding = getPadding(padLen);\r
- }\r
- _objHdr.setDataLength((short)_data.length());\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- int lpadding = 0;\r
- if (_padding != null) lpadding = _padding.length();\r
- return ((short) (_objHdr.getDataLength() + lpadding));\r
- }\r
-\r
- /**\r
- * Method getData\r
- *\r
- * @return a COPSData\r
- *\r
- */\r
- public COPSData getData() {\r
- return _data;\r
- };\r
-\r
- /**\r
- * Method isPepId\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isPepId() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Write data to given netwrok socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
- COPSUtil.writeData(id, _data.getData(), _data.length());\r
- if (_padding != null) {\r
- COPSUtil.writeData(id, _padding.getData(), _padding.length());\r
- }\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("PEPID: " + _data.str() + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS PEP Identification Object (RFC 2748)
+ *
+ * The PEP Identification Object is used to identify the PEP client to
+ * the remote PDP. It is required for Client-Open messages.
+ *
+ * C-Num = 11, C-Type = 1
+ *
+ * Variable-length field. It is a NULL terminated ASCII string that is
+ * also zero padded to a 32-bit word boundary (so the object length is a
+ * multiple of 4 octets). The PEPID MUST contain an ASCII string that
+ * uniquely identifies the PEP within the policy domain in a manner that
+ * is persistent across PEP reboots. For example, it may be the PEP's
+ * statically assigned IP address or DNS name. This identifier may
+ * safely be used by a PDP as a handle for identifying the PEP in its
+ * policy rules.
+ */
+public class COPSPepId extends COPSObjBase {
+
+ /**
+ * The payload data
+ */
+ final COPSData _data;
+
+ /**
+ * Bytes to add to outbound payload to ensure the length is divisible by 4 bytes
+ */
+ final COPSData _padding;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSPepId(final COPSData data) {
+ this(new COPSObjHeader(CNum.PEPID, CType.DEF), data);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param data - the data
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSPepId(final COPSObjHeader hdr, final COPSData data) {
+ super(hdr);
+
+ if (!hdr.getCNum().equals(CNum.PEPID))
+ throw new IllegalArgumentException("CNum must be equal to " + CNum.PEPID);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("CType must be equal to " + CType.DEF);
+ if (data == null) throw new IllegalArgumentException("Data must not be null");
+
+ _data = data;
+ if ((_data.length() % 4) != 0) {
+ final int padLen = 4 - (_data.length() % 4);
+ _padding = COPSObjectParser.getPadding(padLen);
+ } else {
+ _padding = new COPSData();
+ }
+ }
+
+ @Override
+ protected int getDataLength() {
+ return _data.length() + _padding.length();
+ }
+
+ /**
+ * Method getData
+ * @return a COPSData
+ */
+ public COPSData getData() {
+ return _data;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ COPSUtil.writeData(socket, _data.getData(), _data.length());
+ if (_padding != null) {
+ COPSUtil.writeData(socket, _padding.getData(), _padding.length());
+ }
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ os.write(("PEPID: " + _data.str() + "\n").getBytes());
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSPepId)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSPepId that = (COPSPepId) o;
+
+ return _data.equals(that._data) && _padding.equals(that._padding) ||
+ COPSUtil.copsDataPaddingEquals(this._data, this._padding, that._data, that._padding);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _data.hashCode();
+ result = 31 * result + _padding.hashCode();
+ return result;
+ }
+
+ /**
+ * Parses bytes to return a COPSPepId object
+ * @param objHdrData - the associated header
+ * @param dataPtr - the data to parse
+ * @return - the object
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSPepId parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ short dLen = (short)(objHdrData.msgByteCount - 4);
+ return new COPSPepId(objHdrData.header, new COPSData (dataPtr, 4, dLen));
+ }
+
+}
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Reason Object (RFC 2748 pag. 12)\r
- *\r
- * This object specifies the reason why the request state was deleted.\r
- * It appears in the delete request (DRQ) message. The Reason Sub-code\r
- * field is reserved for more detailed client-specific reason codes\r
- * defined in the corresponding documents.\r
- *\r
- * C-Num = 5, C-Type = 1\r
- *\r
- * 0 1 2 3\r
- * +--------------+--------------+--------------+--------------+\r
- * | Reason-Code | Reason Sub-code |\r
- * +--------------+--------------+--------------+--------------+\r
- *\r
- * Reason Code:\r
- * 1 = Unspecified\r
- * 2 = Management\r
- * 3 = Preempted (Another request state takes precedence)\r
- * 4 = Tear (Used to communicate a signaled state removal)\r
- * 5 = Timeout (Local state has timed-out)\r
- * 6 = Route Change (Change invalidates request state)\r
- * 7 = Insufficient Resources (No local resource available)\r
- * 8 = PDP's Directive (PDP decision caused the delete)\r
- * 9 = Unsupported decision (PDP decision not supported)\r
- * 10= Synchronize Handle Unknown\r
- * 11= Transient Handle (stateless event)\r
- * 12= Malformed Decision (could not recover)\r
- * 13= Unknown COPS Object from PDP:\r
- * Sub-code (octet 2) contains unknown object's C-Num\r
- * and (octet 3) contains unknown object's C-Type.\r
- *\r
- * @version COPSReason.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSReason extends COPSPrObjBase {\r
-\r
- public final static String[] G_msgArray = {\r
- "Unknown.",\r
- "Unspecified.",\r
- "Management.",\r
- "Preempted (Another request state takes precedence).",\r
- "Tear (Used to communicate a signaled state removal).",\r
- "Timeout ( Local state has timed-out).",\r
- "Route change (Change invalidates request state).",\r
- "Insufficient Resources.",\r
- "PDP's Directive.",\r
- "Unsupported decision.",\r
- "Synchronize handle unknown.",\r
- "Transient handle.",\r
- "Malformed decision.",\r
- "Unknown COPS object from PDP.",\r
- };\r
-\r
- private COPSObjHeader _objHdr;\r
- private short _reasonCode;\r
- private short _reasonSubCode;\r
-\r
- ///\r
- public COPSReason(short reasonCode, short subCode) {\r
- _objHdr = new COPSObjHeader(CNum.REASON_CODE, CType.DEF);\r
- _reasonCode = reasonCode;\r
- _reasonSubCode = subCode;\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- Parse data and create COPSReason object\r
- */\r
- protected COPSReason(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _reasonCode |= ((short) dataPtr[4]) << 8;\r
- _reasonCode |= ((short) dataPtr[5]) & 0xFF;\r
- _reasonSubCode |= ((short) dataPtr[6]) << 8;\r
- _reasonSubCode |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * Get Reason description\r
- *\r
- * @return a String\r
- *\r
- */\r
- public String getDescription() {\r
- String reasonStr1;\r
- String reasonStr2;\r
-\r
- ///Get the details from the error code\r
- reasonStr1 = G_msgArray[_reasonCode];\r
- //TODO - defind reason sub-codes\r
- reasonStr2 = "";\r
- return (reasonStr1 + ":" + reasonStr2);\r
- }\r
-\r
- /**\r
- * Always return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isReason() {\r
- return true;\r
- }\r
-\r
- /**\r
- * Write object in network byte order to a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
-\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_reasonCode >> 8);\r
- buf[1] = (byte) _reasonCode;\r
- buf[2] = (byte) (_reasonSubCode >> 8);\r
- buf[3] = (byte) _reasonSubCode;\r
-\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Reason Code: " + _reasonCode + "\n").getBytes());\r
- os.write(new String("Reason Sub Code: " + _reasonSubCode + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Reason Object (RFC 2748 page. 12)
+ *
+ * This object specifies the reason why the request state was deleted.
+ * It appears in the delete request (DRQ) message. The Reason Sub-code
+ * field is reserved for more detailed client-specific reason codes
+ * defined in the corresponding documents.
+ *
+ * C-Num = 5, C-Type = 1
+ *
+ * 0 1 2 3
+ * +--------------+--------------+--------------+--------------+
+ * | Reason-Code | Reason Sub-code |
+ * +--------------+--------------+--------------+--------------+
+ *
+ * Reason Code:
+ * 1 = Unspecified
+ * 2 = Management
+ * 3 = Preempted (Another request state takes precedence)
+ * 4 = Tear (Used to communicate a signaled state removal)
+ * 5 = Timeout (Local state has timed-out)
+ * 6 = Route Change (Change invalidates request state)
+ * 7 = Insufficient Resources (No local resource available)
+ * 8 = PDP's Directive (PDP decision caused the delete)
+ * 9 = Unsupported decision (PDP decision not supported)
+ * 10= Synchronize Handle Unknown
+ * 11= Transient Handle (stateless event)
+ * 12= Malformed Decision (could not recover)
+ * 13= Unknown COPS Object from PDP:
+ * Sub-code (octet 2) contains unknown object's C-Num
+ * and (octet 3) contains unknown object's C-Type.
+ *
+ * @version COPSReason.java, v 1.00 2003
+ *
+ */
+public class COPSReason extends COPSObjBase {
+
+ private final static Map<Integer, ReasonCode> VAL_TO_REASON = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_REASON.put(ReasonCode.NA.ordinal(), ReasonCode.NA);
+ VAL_TO_REASON.put(ReasonCode.UNSPECIFIED.ordinal(), ReasonCode.UNSPECIFIED);
+ VAL_TO_REASON.put(ReasonCode.MANAGEMENT.ordinal(), ReasonCode.MANAGEMENT);
+ VAL_TO_REASON.put(ReasonCode.PREEMPTED.ordinal(), ReasonCode.PREEMPTED);
+ VAL_TO_REASON.put(ReasonCode.TEAR.ordinal(), ReasonCode.TEAR);
+ VAL_TO_REASON.put(ReasonCode.TIMEOUT.ordinal(), ReasonCode.TIMEOUT);
+ VAL_TO_REASON.put(ReasonCode.ROUTE_CHANGE.ordinal(), ReasonCode.ROUTE_CHANGE);
+ VAL_TO_REASON.put(ReasonCode.INSUFF_RESOURCES.ordinal(), ReasonCode.INSUFF_RESOURCES);
+ VAL_TO_REASON.put(ReasonCode.PDP_DIRECTIVE.ordinal(), ReasonCode.PDP_DIRECTIVE);
+ VAL_TO_REASON.put(ReasonCode.UNSUPPORT_DEC.ordinal(), ReasonCode.UNSUPPORT_DEC);
+ VAL_TO_REASON.put(ReasonCode.SYNC_HANDLE.ordinal(), ReasonCode.SYNC_HANDLE);
+ VAL_TO_REASON.put(ReasonCode.TRANS_HANDLE.ordinal(), ReasonCode.TRANS_HANDLE);
+ VAL_TO_REASON.put(ReasonCode.MALFORMED_DEC.ordinal(), ReasonCode.MALFORMED_DEC);
+ VAL_TO_REASON.put(ReasonCode.UNKNOWN_COPS_OBJ.ordinal(), ReasonCode.UNKNOWN_COPS_OBJ);
+ }
+
+ private final static Map<ReasonCode, String> REASON_TO_STRING = new ConcurrentHashMap<>();
+ static {
+ REASON_TO_STRING.put(ReasonCode.NA, "Unknown.");
+ REASON_TO_STRING.put(ReasonCode.UNSPECIFIED, "Unspecified.");
+ REASON_TO_STRING.put(ReasonCode.MANAGEMENT, "Management.");
+ REASON_TO_STRING.put(ReasonCode.PREEMPTED, "Preempted (Another request state takes precedence).");
+ REASON_TO_STRING.put(ReasonCode.TEAR, "Tear (Used to communicate a signaled state removal).");
+ REASON_TO_STRING.put(ReasonCode.TIMEOUT, "Timeout ( Local state has timed-out).");
+ REASON_TO_STRING.put(ReasonCode.ROUTE_CHANGE, "Route change (Change invalidates request state).");
+ REASON_TO_STRING.put(ReasonCode.INSUFF_RESOURCES, "Insufficient Resources.");
+ REASON_TO_STRING.put(ReasonCode.PDP_DIRECTIVE, "PDP's Directive.");
+ REASON_TO_STRING.put(ReasonCode.UNSUPPORT_DEC, "Unsupported decision.");
+ REASON_TO_STRING.put(ReasonCode.SYNC_HANDLE, "Synchronize handle unknown.");
+ REASON_TO_STRING.put(ReasonCode.TRANS_HANDLE, "Transient handle.");
+ REASON_TO_STRING.put(ReasonCode.MALFORMED_DEC, "Malformed decision.");
+ REASON_TO_STRING.put(ReasonCode.UNKNOWN_COPS_OBJ, "Unknown COPS object from PDP.");
+ }
+
+ /**
+ * The reason
+ */
+ private final ReasonCode _reasonCode;
+
+ /**
+ * Reserved for more detailed client-specific reasons
+ */
+ private final ReasonCode _reasonSubCode;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param reasonCode - the reason code
+ * @param subCode - more detailed reasons
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSReason(final ReasonCode reasonCode, final ReasonCode subCode) {
+ this(new COPSObjHeader(CNum.REASON_CODE, CType.DEF), reasonCode, subCode);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param reasonCode - the reason code
+ * @param subCode - the type of message
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSReason(final COPSObjHeader hdr, final ReasonCode reasonCode, final ReasonCode subCode) {
+ super(hdr);
+ if (!hdr.getCNum().equals(CNum.REASON_CODE))
+ throw new IllegalArgumentException("Must have a CNum value of " + CNum.REASON_CODE);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
+ if (reasonCode == null || subCode == null) throw new IllegalArgumentException("Error codes must not be null");
+ if (reasonCode.equals(ReasonCode.NA))
+ throw new IllegalArgumentException("Error code must not be of type " + ReasonCode.NA);
+
+ _reasonCode = reasonCode;
+ _reasonSubCode = subCode;
+ }
+
+ public ReasonCode getReasonCode() { return _reasonCode; }
+ public ReasonCode getReasonSubCode() { return _reasonSubCode; }
+
+ @Override
+ protected int getDataLength() {
+ return 4;
+ }
+
+ /**
+ * Get Reason description
+ * @return a String
+ */
+ public String getDescription() {
+ return (REASON_TO_STRING.get(_reasonCode) + ":");
+ }
+
+ @Override
+ protected void writeBody(final Socket id) throws IOException {
+ final byte[] buf = new byte[4];
+ buf[0] = (byte) (_reasonCode.ordinal() >> 8);
+ buf[1] = (byte) _reasonCode.ordinal();
+ buf[2] = (byte) (_reasonSubCode.ordinal() >> 8);
+ buf[3] = (byte) _reasonSubCode.ordinal();
+ COPSUtil.writeData(id, buf, 4);
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Reason Code: " + _reasonCode + "\n").getBytes());
+ os.write(("Reason Sub Code: " + _reasonSubCode + "\n").getBytes());
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSReason parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ short reasonCode = 0;
+ reasonCode |= ((short) dataPtr[4]) << 8;
+ reasonCode |= ((short) dataPtr[5]) & 0xFF;
+
+ short reasonSubCode = 0;
+ reasonSubCode |= ((short) dataPtr[6]) << 8;
+ reasonSubCode |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSReason(objHdrData.header, VAL_TO_REASON.get((int)reasonCode),
+ VAL_TO_REASON.get((int)reasonSubCode));
+ }
+
+ /**
+ * All of the supported reason codes
+ */
+ public enum ReasonCode {
+ NA, UNSPECIFIED, MANAGEMENT, PREEMPTED, TEAR, TIMEOUT, ROUTE_CHANGE, INSUFF_RESOURCES, PDP_DIRECTIVE,
+ UNSUPPORT_DEC, SYNC_HANDLE, TRANS_HANDLE, MALFORMED_DEC, UNKNOWN_COPS_OBJ
+ }
+
+}
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Vector;\r
-\r
-/**\r
- * COPS Report Message (RFC 2748 pag. 25)\r
- *\r
- * The RPT message is used by the PEP to communicate to the PDP its\r
- * success or failure in carrying out the PDP's decision, or to report\r
- * an accounting related change in state. The Report-Type specifies the\r
- * kind of report and the optional ClientSI can carry additional\r
- * information per Client-Type.\r
- *\r
- * For every DEC message containing a configuration context that is\r
- * received by a PEP, the PEP MUST generate a corresponding Report State\r
- * message with the Solicited Message flag set describing its success or\r
- * failure in applying the configuration decision. In addition,\r
- * outsourcing decisions from the PDP MAY result in a corresponding\r
- * solicited Report State from the PEP depending on the context and the\r
- * type of client. RPT messages solicited by decisions for a given\r
- * Client Handle MUST set the Solicited Message flag and MUST be sent in\r
- * the same order as their corresponding Decision messages were\r
- * received. There MUST never be more than one Report State message\r
- * generated with the Solicited Message flag set per Decision.\r
- *\r
- * The Report State may also be used to provide periodic updates of\r
- * client specific information for accounting and state monitoring\r
- * purposes depending on the type of the client. In such cases the\r
- * accounting report type should be specified utilizing the appropriate\r
- * client specific information object.\r
- *\r
- * <Report State> ::== <Common Header>\r
- * <Client Handle>\r
- * <Report-Type>\r
- * [<ClientSI>]\r
- * [<Integrity>]\r
- *\r
- * @version COPSReportMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSReportMsg extends COPSMsg {\r
- /* COPSHeader coming from base class */\r
- private COPSHandle _clientHandle;\r
- private COPSReportType _report;\r
- private Vector _clientSI;\r
- private COPSIntegrity _integrity;\r
-\r
- public COPSReportMsg() {\r
- _clientHandle = null;\r
- _report = null;\r
- _integrity = null;\r
- _clientSI = new Vector(20);\r
- }\r
-\r
- /**\r
- Parse data and create COPSReportMsg object\r
- */\r
- protected COPSReportMsg (byte[] data) throws COPSException {\r
- _clientHandle = null;\r
- _report = null;\r
- _integrity = null;\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Checks the sanity of COPS message and throw an\r
- * COPSException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_clientHandle == null) || (_report == null))\r
- throw new COPSException("Bad message format");\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)\r
- throw new COPSException ("Error Header (no COPS_OP_REQ)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Report object to the message\r
- *\r
- * @param report a COPSReportType\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSReportType report) throws COPSException {\r
- if (report == null)\r
- throw new COPSException ("Null Handle");\r
-\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("No null Handle");\r
-\r
- _report = report;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add client handle to the message\r
- *\r
- * @param handle a COPSHandle\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHandle handle) throws COPSException {\r
- if (handle == null)\r
- throw new COPSException ("Null Handle");\r
-\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("No null Handle");\r
-\r
- _clientHandle = handle;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add one or more clientSI objects\r
- *\r
- * @param clientSI a COPSClientSI\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSClientSI clientSI) throws COPSException {\r
- if (clientSI == null)\r
- throw new COPSException ("Null ClientSI");\r
- _clientSI.add(clientSI);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Get client Handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _clientHandle;\r
- }\r
-\r
- /**\r
- * Get report type\r
- *\r
- * @return a COPSReportType\r
- *\r
- */\r
- public COPSReportType getReport() {\r
- return _report;\r
- }\r
-\r
- /**\r
- * Get clientSI\r
- *\r
- * @return a Vector\r
- *\r
- */\r
- public Vector getClientSI() {\r
- return _clientSI;\r
- }\r
-\r
- /**\r
- * Returns true if it has Integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- }\r
-\r
-\r
- /**\r
- * Get Integrity. Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Writes data to given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- //checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_clientHandle != null) _clientHandle.writeData(id);\r
- if (_report != null) _report.writeData(id);\r
-\r
- for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- clientSI.writeData(id);\r
- }\r
-\r
- if (_integrity != null) _integrity.writeData(id);\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case HANDLE:\r
- _clientHandle = new COPSHandle(buf);\r
- _dataStart += _clientHandle.getDataLength();\r
- break;\r
- case RPT:\r
- _report = new COPSReportType(buf);\r
- _dataStart += _report.getDataLength();\r
- break;\r
- case CSI:\r
- COPSClientSI csi = new COPSClientSI(buf);\r
- _dataStart += csi.getDataLength();\r
- _clientSI.add(csi);\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)\r
- throw new COPSException ("Null Header");\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_clientHandle != null) len += _clientHandle.getDataLength();\r
- if (_report != null) len += _report.getDataLength();\r
-\r
- for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- len += clientSI.getDataLength();\r
- }\r
-\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_clientHandle != null)\r
- _clientHandle.dump(os);\r
-\r
- if (_report != null)\r
- _report.dump(os);\r
-\r
- for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- clientSI.dump(os);\r
- }\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Report Message (RFC 2748 pag. 25)
+ *
+ * The RPT message is used by the PEP to communicate to the PDP its
+ * success or failure in carrying out the PDP's decision, or to report
+ * an accounting related change in state. The Report-Type specifies the
+ * kind of report and the optional ClientSI can carry additional
+ * information per Client-Type.
+ *
+ * For every DEC message containing a configuration context that is
+ * received by a PEP, the PEP MUST generate a corresponding Report State
+ * message with the Solicited Message flag set describing its success or
+ * failure in applying the configuration decision. In addition,
+ * outsourcing decisions from the PDP MAY result in a corresponding
+ * solicited Report State from the PEP depending on the context and the
+ * type of client. RPT messages solicited by decisions for a given
+ * Client Handle MUST set the Solicited Message flag and MUST be sent in
+ * the same order as their corresponding Decision messages were
+ * received. There MUST never be more than one Report State message
+ * generated with the Solicited Message flag set per Decision.
+ *
+ * The Report State may also be used to provide periodic updates of
+ * client specific information for accounting and state monitoring
+ * purposes depending on the type of the client. In such cases the
+ * accounting report type should be specified utilizing the appropriate
+ * client specific information object.
+ *
+ * <Report State> ::== <Common Header>
+ * <Client Handle>
+ * <Report-Type>
+ * [<ClientSI>]
+ * [<Integrity>]
+ *
+ * @version COPSReportMsg.java, v 1.00 2003
+ *
+ */
+public class COPSReportMsg extends COPSMsg {
+ // Required
+ private final COPSHandle _clientHandle;
+ private final COPSReportType _report;
+ private final COPSIntegrity _integrity;
+
+ // TODO - Determine why previous implementation had a collection of Client SIs when the specification reads
+ // that there may be only one. May need to revert back to a Set<COPSClientSI>
+ // Optional
+ private final COPSClientSI _clientSI;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param clientHandle - the COPS Handle (required)
+ * @param report - the report (required)
+ * @param clientSI - the client SI (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSReportMsg(final short clientType, final COPSHandle clientHandle, final COPSReportType report,
+ final COPSClientSI clientSI, final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.RPT, clientType), clientHandle, report, clientSI, integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param clientType - the type of client that created the message (required)
+ * @param clientHandle - the COPS Handle (required)
+ * @param report - the report (required)
+ * @param clientSI - the client SI (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSReportMsg(final int version, final Flag flag, final short clientType, final COPSHandle clientHandle, final COPSReportType report,
+ final COPSClientSI clientSI, final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.RPT, clientType), clientHandle, report, clientSI, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param clientHandle - the COPS Handle (required)
+ * @param report - the report (required)
+ * @param clientSI - the client SI (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSReportMsg(final COPSHeader hdr, final COPSHandle clientHandle, final COPSReportType report,
+ final COPSClientSI clientSI, final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.RPT))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.RPT);
+ if (clientHandle == null) throw new IllegalArgumentException("COPSHandle must not be null");
+ if (report == null) throw new IllegalArgumentException("COPSReportType must not be null");
+
+ _clientHandle = clientHandle;
+ _report = report;
+ _clientSI = clientSI;
+ _integrity = integrity;
+ }
+
+ // Getters
+ public COPSHandle getClientHandle() {
+ return _clientHandle;
+ }
+ public COPSReportType getReport() {
+ return _report;
+ }
+ public COPSClientSI getClientSI() {
+ return _clientSI;
+ }
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _clientHandle.getDataLength() + _clientHandle.getHeader().getHdrLength();
+ out += _report.getDataLength() + _report.getHeader().getHdrLength();
+ if (_clientSI != null) out += _clientSI.getDataLength() + _clientSI.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _clientHandle.writeData(socket);
+ _report.writeData(socket);
+ if (_clientSI != null) _clientSI.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ _clientHandle.dump(os);
+ _report.dump(os);
+ if (_clientSI != null) _clientSI.dump(os);
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSReportMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSReportMsg that = (COPSReportMsg) o;
+
+ return _clientHandle.equals(that._clientHandle) &&
+ !(_clientSI != null ? !_clientSI.equals(that._clientSI) : that._clientSI != null) &&
+ !(_integrity != null ? !_integrity.equals(that._integrity) : that._integrity != null) &&
+ _report.equals(that._report);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _clientHandle.hashCode();
+ result = 31 * result + _report.hashCode();
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ result = 31 * result + (_clientSI != null ? _clientSI.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSDecisionMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSReportMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSHandle clientHandle = null;
+ COPSReportType report = null;
+ COPSIntegrity integrity = null;
+ COPSClientSI clientSI = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case HANDLE:
+ clientHandle = COPSHandle.parse(objHdrData, buf);
+ break;
+ case RPT:
+ report = COPSReportType.parse(objHdrData, buf);
+ break;
+ case CSI:
+ clientSI = COPSClientSI.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSReportMsg(hdrData.header, clientHandle, report, clientSI, integrity);
+ }
+}
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import org.umu.cops.stack.COPSObjHeader.CNum;\r
-import org.umu.cops.stack.COPSObjHeader.CType;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Report Type (RFC 2748 pag. 16\r
- *\r
- * The Type of Report on the request state associated with a handle:\r
- *\r
- * C-Num = 12, C-Type = 1\r
- *\r
- * 0 1 2 3\r
- * +--------------+--------------+--------------+--------------+\r
- * | Report-Type | ///////////// |\r
- * +--------------+--------------+--------------+--------------+\r
- *\r
- * Report-Type:\r
- * 1 = Success : Decision was successful at the PEP\r
- * 2 = Failure : Decision could not be completed by PEP\r
- * 3 = Accounting: Accounting update for an installed state\r
- *\r
- *\r
- * @version COPSReportType.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSReportType extends COPSPrObjBase {\r
-\r
- public final static String[] msgMap = {\r
- "Unknown",\r
- "Success",\r
- "Failure",\r
- "Accounting",\r
- };\r
-\r
- private COPSObjHeader _objHdr;\r
- private short _rType;\r
- private short _reserved;\r
-\r
- public final static short SUCCESS = 1;\r
- public final static short FAILURE = 2;\r
- public final static short ACCT = 3;\r
-\r
- public COPSReportType(short rType) {\r
- _objHdr = new COPSObjHeader(CNum.RPT, CType.DEF);\r
- _rType = rType;\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- Parse data and create COPSReportType object\r
- */\r
- protected COPSReportType(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _rType |= ((short) dataPtr[4]) << 8;\r
- _rType |= ((short) dataPtr[5]) & 0xFF;\r
- _reserved |= ((short) dataPtr[6]) << 8;\r
- _reserved |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * If it is Success, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isSuccess() {\r
- return (_rType == SUCCESS );\r
- };\r
-\r
- /**\r
- * If it is Failure, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isFailure() {\r
- return (_rType == FAILURE);\r
- };\r
-\r
- /**\r
- * If it is Accounting, return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAccounting() {\r
- return (_rType == ACCT);\r
- };\r
-\r
- /**\r
- * Always return true\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isReport() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Write data in network byte order on a given network socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_rType >> 8);\r
- buf[1] = (byte) _rType;\r
- buf[2] = (byte) (_reserved >> 8);\r
- buf[3] = (byte) _reserved;\r
-\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Report: " + msgMap[_rType] + "\n").getBytes());\r
- }\r
-}\r
-\r
-\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * COPS Report Type (RFC 2748 pg. 16)
+ *
+ * The Type of Report on the request state associated with a handle:
+ *
+ * C-Num = 12, C-Type = 1
+ *
+ * 0 1 2 3
+ * +--------------+--------------+--------------+--------------+
+ * | Report-Type | ///////////// |
+ * +--------------+--------------+--------------+--------------+
+ *
+ * Report-Type:
+ * 1 = Success : Decision was successful at the PEP
+ * 2 = Failure : Decision could not be completed by PEP
+ * 3 = Accounting: Accounting update for an installed state
+ *
+ *
+ * @version COPSReportType.java, v 1.00 2003
+ *
+ */
+public class COPSReportType extends COPSObjBase {
+
+ private final static Map<Integer, ReportType> VAL_TO_RPT_TYPE = new ConcurrentHashMap<>();
+ static {
+ VAL_TO_RPT_TYPE.put(ReportType.NA.ordinal(), ReportType.NA);
+ VAL_TO_RPT_TYPE.put(ReportType.SUCCESS.ordinal(), ReportType.SUCCESS);
+ VAL_TO_RPT_TYPE.put(ReportType.FAILURE.ordinal(), ReportType.FAILURE);
+ VAL_TO_RPT_TYPE.put(ReportType.ACCOUNTING.ordinal(), ReportType.ACCOUNTING);
+ }
+
+ private final static Map<ReportType, String> RPT_TYPE_TO_STRING = new ConcurrentHashMap<>();
+ static {
+ RPT_TYPE_TO_STRING.put(ReportType.NA, "Unknown.");
+ RPT_TYPE_TO_STRING.put(ReportType.SUCCESS, "Success.");
+ RPT_TYPE_TO_STRING.put(ReportType.FAILURE, "Failure.");
+ RPT_TYPE_TO_STRING.put(ReportType.ACCOUNTING, "Accounting.");
+ }
+
+ /**
+ * The type of report
+ */
+ private final ReportType _rType;
+
+ /**
+ * What is this attribute used for???
+ */
+ private final short _reserved;
+
+ /**
+ * Constructor generally used for sending messages
+ * @param rType - the report type
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSReportType(final ReportType rType) {
+ this(new COPSObjHeader(CNum.RPT, CType.DEF), rType, (short)0);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param hdr - the object header
+ * @param rType - the report type
+ * @param reserved - ???
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSReportType(final COPSObjHeader hdr, final ReportType rType, final short reserved) {
+ super(hdr);
+ if (!hdr.getCNum().equals(CNum.RPT))
+ throw new IllegalArgumentException("Must have a CNum value of " + CNum.RPT);
+ if (!hdr.getCType().equals(CType.DEF))
+ throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
+ if (rType == null) throw new IllegalArgumentException("Report type must not be null");
+ if (rType.equals(ReportType.NA))
+ throw new IllegalArgumentException("Report type must not be of type " + ReportType.NA);
+
+ _rType = rType;
+ _reserved = reserved;
+ }
+
+ public ReportType getReportType() { return _rType; }
+
+ @Override
+ public int getDataLength() {
+ return 4;
+ }
+
+ @Override
+ protected void writeBody(final Socket id) throws IOException {
+ final byte[] buf = new byte[4];
+
+ buf[0] = (byte) (_rType.ordinal() >> 8);
+ buf[1] = (byte) _rType.ordinal();
+ buf[2] = (byte) (_reserved >> 8);
+ buf[3] = (byte) _reserved;
+
+ COPSUtil.writeData(id, buf, 4);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Report: " + RPT_TYPE_TO_STRING.get(_rType) + "\n").getBytes());
+ }
+
+ /**
+ * Creates this object from a byte array
+ * @param objHdrData - the header
+ * @param dataPtr - the data to parse
+ * @return - a new Timer
+ * @throws java.lang.IllegalArgumentException
+ */
+ public static COPSReportType parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
+ short rType = 0;
+ rType |= ((short) dataPtr[4]) << 8;
+ rType |= ((short) dataPtr[5]) & 0xFF;
+
+ short reserved = 0;
+ reserved |= ((short) dataPtr[6]) << 8;
+ reserved |= ((short) dataPtr[7]) & 0xFF;
+
+ return new COPSReportType(objHdrData.header, VAL_TO_RPT_TYPE.get((int)rType), reserved);
+ }
+
+ /**
+ * The supported report types
+ */
+ public enum ReportType {
+ NA, SUCCESS, FAILURE, ACCOUNTING
+ }
+
+}
+
+
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-import java.util.Enumeration;\r
-import java.util.Hashtable;\r
-import java.util.Vector;\r
-\r
-/**\r
- * COPS Request Message (RFC 2748 pag. 22)\r
- *\r
- * The PEP establishes a request state client handle for which the\r
- * remote PDP may maintain state. The remote PDP then uses this handle\r
- * to refer to the exchanged information and decisions communicated over\r
- * the TCP connection to a particular PEP for a given client-type.\r
- *\r
- * Once a stateful handle is established for a new request, any\r
- * subsequent modifications of the request can be made using the REQ\r
- * message specifying the previously installed handle. The PEP is\r
- * responsible for notifying the PDP whenever its local state changes so\r
- * the PDP's state will be able to accurately mirror the PEP's state.\r
- *\r
- * The format of the Request message is as follows:\r
- *\r
- * <Request Message> ::= <Common Header>\r
- * <Client Handle>\r
- * <Context>\r
- * [<IN-Int>]\r
- * [<OUT-Int>]\r
- * [<ClientSI(s)>]\r
- * [<LPDPDecision(s)>]\r
- * [<Integrity>]\r
- *\r
- * <ClientSI(s)> ::= <ClientSI> | <ClientSI(s)> <ClientSI>\r
- *\r
- * <LPDPDecision(s)> ::= <LPDPDecision> |\r
- * <LPDPDecision(s)> <LPDPDecision>\r
- *\r
- * <LPDPDecision> ::= [<Context>]\r
- * <LPDPDecision: Flags>\r
- * [<LPDPDecision: Stateless Data>]\r
- * [<LPDPDecision: Replacement Data>]\r
- * [<LPDPDecision: ClientSI Data>]\r
- * [<LPDPDecision: Named Data>]\r
- *\r
- * The context object is used to determine the context within which all\r
- * the other objects are to be interpreted. It also is used to determine\r
- * the kind of decision to be returned from the policy server. This\r
- * decision might be related to admission control, resource allocation,\r
- * object forwarding and substitution, or configuration.\r
- *\r
- * The interface objects are used to determine the corresponding\r
- * interface on which a signaling protocol message was received or is\r
- * about to be sent. They are typically used if the client is\r
- * participating along the path of a signaling protocol or if the client\r
- * is requesting configuration data for a particular interface.\r
- *\r
- * ClientSI, the client specific information object, holds the client-\r
- * type specific data for which a policy decision needs to be made. In\r
- * the case of configuration, the Named ClientSI may include named\r
- * information about the module, interface, or functionality to be\r
- * configured. The ordering of multiple ClientSIs is not important.\r
- *\r
- * Finally, LPDPDecision object holds information regarding the local\r
- * decision made by the LPDP.\r
- *\r
- * Malformed Request messages MUST result in the PDP specifying a\r
- * Decision message with the appropriate error code.\r
- *\r
- * @version COPSReqMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSReqMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSHandle _clientHandle;\r
- private COPSContext _context;\r
- private COPSInterface _inInterface;\r
- private COPSInterface _outInterface;\r
- private Vector _clientSIs;\r
- private Hashtable _decisions;\r
- private COPSIntegrity _integrity;\r
- private COPSContext _lpdpContext;\r
-\r
- public COPSReqMsg() {\r
- _clientHandle = null;\r
- _context = null;\r
- _inInterface = null;\r
- _outInterface = null;\r
- _clientSIs = new Vector(20);\r
- _decisions = new Hashtable();\r
- _integrity = null;\r
- _lpdpContext = null;\r
- }\r
-\r
- /**\r
- Parse data and create COPSReqMsg object\r
- */\r
- protected COPSReqMsg(byte[] data) throws COPSException {\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Checks the sanity of COPS message and throw an\r
- * COPSBadDataException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if ((_hdr == null) || (_clientHandle == null) || (_context == null)) {\r
- throw new COPSException("Bad message format");\r
- }\r
- }\r
-\r
- /**\r
- * Add an IN or OUT interface object\r
- *\r
- * @param inter a COPSInterface\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSInterface inter) throws COPSException {\r
- if (!(inter.isInInterface() || inter.isOutInterface()))\r
- throw new COPSException ("No Interface");\r
-\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("Integrity should be the last one");\r
-\r
- if (inter.isInInterface()) {\r
- if (_inInterface != null)\r
- throw new COPSException ("Object inInterface exits");\r
-\r
- if (inter.isIpv4Address()) {\r
- COPSIpv4InInterface inInter = (COPSIpv4InInterface) inter;\r
- _inInterface = inInter;\r
- } else {\r
- COPSIpv6InInterface inInter = (COPSIpv6InInterface) inter;\r
- _inInterface = inInter;\r
- }\r
- } else {\r
- if (_outInterface != null)\r
- throw new COPSException ("Object outInterface exits");\r
-\r
- if (inter.isIpv4Address()) {\r
- COPSIpv4OutInterface outInter = (COPSIpv4OutInterface) inter;\r
- _outInterface = outInter;\r
- } else {\r
- COPSIpv6OutInterface outInter = (COPSIpv6OutInterface) inter;\r
- _outInterface = outInter;\r
- }\r
- }\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add header to the message\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if (hdr.getOpCode() != COPSHeader.COPS_OP_REQ)\r
- throw new COPSException ("Error Header (no COPS_OP_REQ)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add Context object to the message\r
- *\r
- * @param context a COPSContext\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSContext context) throws COPSException {\r
- if (context == null)\r
- throw new COPSException ("Null Context");\r
- _context = context;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add client handle to the message\r
- *\r
- * @param handle a COPSHandle\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHandle handle) throws COPSException {\r
- if (handle == null)\r
- throw new COPSException ("Null Handle");\r
- _clientHandle = handle;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add one or more clientSI objects\r
- *\r
- * @param clientSI a COPSClientSI\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSClientSI clientSI) throws COPSException {\r
- if (clientSI == null)\r
- throw new COPSException ("Null ClientSI");\r
- _clientSIs.add(clientSI);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add one or more local decision object for a given decision context\r
- * the context is optional, if null all decision object are tided to\r
- * message context\r
- *\r
- * @param decision a COPSLPDPDecision\r
- * @param context a COPSContext\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void addLocalDecision(COPSLPDPDecision decision, COPSContext context) throws COPSException {\r
- if (!decision.isLocalDecision())\r
- throw new COPSException ("Local Decision");\r
-\r
- Vector v = (Vector) _decisions.get(context);\r
- if (decision.isFlagSet()) {\r
- if (v.size() != 0) {\r
- //Only one set of decision flags is allowed\r
- //for each context\r
- throw new COPSException ("Bad Message format, only one set of decision flags is allowed.");\r
- }\r
- } else {\r
- if (v.size() == 0) {\r
- //The flags decision must precede any other\r
- //decision message, since the decision is not\r
- //flags throw exception\r
- throw new COPSException ("Bad Message format, flags decision must precede any other decision object.");\r
- }\r
- }\r
- v.add(decision);\r
- _decisions.put(context,v);\r
-\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_clientHandle != null) _clientHandle.writeData(id);\r
- if (_context != null) _context.writeData(id);\r
-\r
- for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- clientSI.writeData(id);\r
- }\r
-\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- context.writeData(id);\r
-\r
- for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
- COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
- decision.writeData(id);\r
- }\r
- }\r
-\r
- if (_integrity != null) _integrity.writeData(id);\r
-\r
- }\r
-\r
- /**\r
- * Return Header\r
- *\r
- * @return a COPSHeader\r
- *\r
- */\r
- public COPSHeader getHeader() {\r
- return _hdr;\r
- }\r
-\r
- /**\r
- * Return client Handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _clientHandle;\r
- }\r
-\r
- /**\r
- * Return Context\r
- *\r
- * @return a COPSContext\r
- *\r
- */\r
- public COPSContext getContext() {\r
- return _context;\r
- }\r
-\r
- /**\r
- * Returns true if it has In Interface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasInInterface() {\r
- return (_inInterface == null);\r
- }\r
-\r
- /**\r
- * Should check hasInInterface() before calling\r
- *\r
- * @return a COPSInterface\r
- *\r
- */\r
- public COPSInterface getInInterface() {\r
- return _inInterface;\r
- }\r
-\r
- /**\r
- * Returns true if it has Out interface\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasOutInterface() {\r
- return (_outInterface == null);\r
- }\r
-\r
- /**\r
- * Should check hasOutInterface() before calling\r
- *\r
- * @return a COPSInterface\r
- *\r
- */\r
- public COPSInterface getOutInterface() {\r
- return _outInterface;\r
- }\r
-\r
- /**\r
- * Returns a vector if ClientSI objects\r
- *\r
- * @return a Vector\r
- *\r
- */\r
- public Vector getClientSI() {\r
- return _clientSIs;\r
- }\r
-\r
- /**\r
- * Returns a HashTable of any local decisions\r
- *\r
- * @return a Hashtable\r
- *\r
- */\r
- public Hashtable getLpdpDecisions() {\r
- return _decisions;\r
- }\r
-\r
- /**\r
- * Returns true if it has Integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity == null);\r
- }\r
-\r
- /**\r
- * Get Integrity. Should check hasIntegrity() becfore calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return _integrity;\r
- }\r
-\r
- /**\r
- * Parses the data and fills COPSReqMsg with its constituents\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case HANDLE:\r
- _clientHandle = new COPSHandle(buf);\r
- _dataStart += _clientHandle.getDataLength();\r
- break;\r
- case CONTEXT:\r
- if (_context == null) {\r
- //Message context\r
- _context = new COPSContext(buf);\r
- _dataStart += _context.getDataLength();\r
- } else {\r
- //lpdp context\r
- _lpdpContext = new COPSContext(buf);\r
- _dataStart += _lpdpContext.getDataLength();\r
- }\r
- break;\r
- case ININTF:\r
- if (objHdr.getCType().ordinal() == 1) {\r
- _inInterface = new COPSIpv4InInterface(buf);\r
- } else {\r
- _inInterface = new COPSIpv6InInterface(buf);\r
- }\r
- _dataStart += _inInterface.getDataLength();\r
- break;\r
- case OUTINTF:\r
- if (objHdr.getCType().ordinal() == 1) {\r
- _outInterface = new COPSIpv4OutInterface(buf);\r
- } else {\r
- _outInterface = new COPSIpv6OutInterface(buf);\r
- }\r
- _dataStart += _outInterface.getDataLength();\r
- break;\r
- case LPDP_DEC:\r
- COPSLPDPDecision lpdp = new COPSLPDPDecision(buf);\r
- _dataStart += lpdp.getDataLength();\r
- addLocalDecision(lpdp, _lpdpContext);\r
- break;\r
- case CSI:\r
- COPSClientSI csi = new COPSClientSI (buf);\r
- _dataStart += csi.getDataLength();\r
- _clientSIs.add(csi);\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- checkSanity();\r
-\r
- }\r
-\r
- /**\r
- * Parses the data and fills that follows the header hdr and fills COPSReqMsg\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
-\r
- if (_clientHandle != null)\r
- len += _clientHandle.getDataLength();\r
-\r
- if (_context != null)\r
- len += _context.getDataLength();\r
-\r
- for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- len += clientSI.getDataLength();\r
- }\r
-\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- len += context.getDataLength();\r
-\r
- for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
- COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
- len += decision.getDataLength();\r
- }\r
- }\r
-\r
- if (_integrity != null) {\r
- len += _integrity.getDataLength();\r
- }\r
-\r
- _hdr.setMsgLength((int) len);\r
-\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_clientHandle != null)\r
- _clientHandle.dump(os);\r
-\r
- if (_context != null)\r
- _context.dump(os);\r
-\r
- for (Enumeration e = _clientSIs.elements() ; e.hasMoreElements() ;) {\r
- COPSClientSI clientSI = (COPSClientSI) e.nextElement();\r
- clientSI.dump(os);\r
- }\r
-\r
- //Display any local decisions\r
- for (Enumeration e = _decisions.keys() ; e.hasMoreElements() ;) {\r
-\r
- COPSContext context = (COPSContext) e.nextElement();\r
- Vector v = (Vector) _decisions.get(context);\r
- context.dump(os);\r
-\r
- for (Enumeration ee = v.elements() ; e.hasMoreElements() ;) {\r
- COPSLPDPDecision decision = (COPSLPDPDecision) ee.nextElement();\r
- decision.dump(os);\r
- }\r
- }\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.*;
+
+/**
+ * COPS Request Message (RFC 2748 page. 22)
+ *
+ * The PEP establishes a request state client handle for which the
+ * remote PDP may maintain state. The remote PDP then uses this handle
+ * to refer to the exchanged information and decisions communicated over
+ * the TCP connection to a particular PEP for a given client-type.
+ *
+ * Once a stateful handle is established for a new request, any
+ * subsequent modifications of the request can be made using the REQ
+ * message specifying the previously installed handle. The PEP is
+ * responsible for notifying the PDP whenever its local state changes so
+ * the PDP's state will be able to accurately mirror the PEP's state.
+ *
+ * The format of the Request message is as follows:
+ *
+ * <Request Message> ::= <Common Header>
+ * <Client Handle>
+ * <Context>
+ * [<IN-Int>]
+ * [<OUT-Int>]
+ * [<ClientSI(s)>]
+ * [<LPDPDecision(s)>]
+ * [<Integrity>]
+ *
+ * <ClientSI(s)> ::= <ClientSI> | <ClientSI(s)> <ClientSI>
+ *
+ * <LPDPDecision(s)> ::= <LPDPDecision> |
+ * <LPDPDecision(s)> <LPDPDecision>
+ *
+ * <LPDPDecision> ::= [<Context>]
+ * <LPDPDecision: Flags>
+ * [<LPDPDecision: Stateless Data>]
+ * [<LPDPDecision: Replacement Data>]
+ * [<LPDPDecision: ClientSI Data>]
+ * [<LPDPDecision: Named Data>]
+ *
+ * The context object is used to determine the context within which all
+ * the other objects are to be interpreted. It also is used to determine
+ * the kind of decision to be returned from the policy server. This
+ * decision might be related to admission control, resource allocation,
+ * object forwarding and substitution, or configuration.
+ *
+ * The interface objects are used to determine the corresponding
+ * interface on which a signaling protocol message was received or is
+ * about to be sent. They are typically used if the client is
+ * participating along the path of a signaling protocol or if the client
+ * is requesting configuration data for a particular interface.
+ *
+ * ClientSI, the client specific information object, holds the client-
+ * type specific data for which a policy decision needs to be made. In
+ * the case of configuration, the Named ClientSI may include named
+ * information about the module, interface, or functionality to be
+ * configured. The ordering of multiple ClientSIs is not important.
+ *
+ * Finally, LPDPDecision object holds information regarding the local
+ * decision made by the LPDP.
+ *
+ * Malformed Request messages MUST result in the PDP specifying a
+ * Decision message with the appropriate error code.
+ *
+ * @version COPSReqMsg.java, v 1.00 2003
+ *
+ */
+public class COPSReqMsg extends COPSMsg {
+
+ // Required Attributes
+ private final COPSHandle _clientHandle;
+ private final COPSContext _context;
+
+ // Optional Attributes
+ private final COPSInterface _inInterface;
+ private final COPSInterface _outInterface;
+ private final COPSIntegrity _integrity;
+
+ // Collection Attributes (can be empty)
+ private final Set<COPSClientSI> _clientSIs;
+ private final Map<COPSContext, Set<COPSLPDPDecision>> _decisions;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the COPS Handle (required)
+ * @param context - the COPS Context (required)
+ * @param integrity - the COPS Integrity (optional)
+ * @param inInterface - the In Interface (optional)
+ * @param outInterface - the Out interface (optional)
+ * @param clientSIs - the Client SIs (optional)
+ * @param decisions - the Decisions by context (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSReqMsg(final short clientType, final COPSHandle handle, final COPSContext context,
+ final COPSIntegrity integrity, final COPSInterface inInterface, final COPSInterface outInterface,
+ final Set<COPSClientSI> clientSIs, final Map<COPSContext, Set<COPSLPDPDecision>> decisions) {
+ this(1, Flag.UNSOLICITED, clientType, handle, context, integrity, inInterface, outInterface,
+ clientSIs, decisions);
+ }
+
+ /**
+ * Recommended constructor generally for use by a client sending messages.
+ * @param version - the supported PCMM Version (required)
+ * @param flag - the flag... (required)
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the COPS Handle (required)
+ * @param context - the COPS Context (required)
+ * @param integrity - the COPS Integrity (optional)
+ * @param inInterface - the In Interface (optional)
+ * @param outInterface - the Out interface (optional)
+ * @param clientSIs - the Client SIs (optional)
+ * @param decisions - the Decisions by context (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSReqMsg(final int version, final Flag flag, final short clientType, final COPSHandle handle,
+ final COPSContext context, final COPSIntegrity integrity, final COPSInterface inInterface,
+ final COPSInterface outInterface, final Set<COPSClientSI> clientSIs,
+ final Map<COPSContext, Set<COPSLPDPDecision>> decisions) {
+ this(new COPSHeader(version, flag, OPCode.REQ, clientType), handle, context, integrity, inInterface,
+ outInterface, clientSIs, decisions);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header (required)
+ * @param handle - the COPS Handle (required)
+ * @param context - the COPS Context (required)
+ * @param integrity - the COPS Integrity (optional)
+ * @param inInterface - the In Interface (optional)
+ * @param outInterface - the Out interface (optional)
+ * @param clientSIs - the Client SIs (optional)
+ * @param decisions - the Decisions by context (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSReqMsg(final COPSHeader hdr, final COPSHandle handle, final COPSContext context,
+ final COPSIntegrity integrity, final COPSInterface inInterface, final COPSInterface outInterface,
+ final Set<COPSClientSI> clientSIs, final Map<COPSContext, Set<COPSLPDPDecision>> decisions) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.REQ))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.REQ);
+ if (handle == null) throw new IllegalArgumentException("COPSHandle must not be null");
+ if (context == null) throw new IllegalArgumentException("COPSContext must not be null");
+
+ _clientHandle = handle;
+ _context = context;
+ _integrity = integrity;
+ _inInterface = inInterface;
+ _outInterface = outInterface;
+
+ if (clientSIs == null) _clientSIs = Collections.unmodifiableSet(new HashSet<COPSClientSI>());
+ else _clientSIs = Collections.unmodifiableSet(clientSIs);
+
+ if (decisions == null) _decisions = Collections.unmodifiableMap(new HashMap<COPSContext, Set<COPSLPDPDecision>>());
+ else _decisions = Collections.unmodifiableMap(decisions);
+ }
+
+
+ // Getters of optional members - all can return null
+ public COPSIntegrity getIntegrity() { return _integrity; }
+ public COPSInterface getInInterface() { return _inInterface; }
+ public COPSInterface getOutInterface() { return _outInterface; }
+// public COPSContext getLpdpContext() { return _lpdpContext; }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ _clientHandle.writeData(socket);
+ _context.writeData(socket);
+
+ if (_inInterface != null) _inInterface.writeData(socket);
+ if (_outInterface != null) _outInterface.writeData(socket);
+
+ for (final COPSClientSI clientSI : _clientSIs) {
+ clientSI.writeData(socket);
+ }
+
+ //Display any local decisions
+ for (final Map.Entry<COPSContext, Set<COPSLPDPDecision>> entry : _decisions.entrySet()) {
+ entry.getKey().writeData(socket);
+ for (final COPSDecision decision : entry.getValue()) {
+ decision.writeData(socket);
+ }
+ }
+
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = _context.getDataLength() + _context.getHeader().getHdrLength();
+ out += _clientHandle.getDataLength() + _clientHandle.getHeader().getHdrLength();
+ if (_inInterface != null) out += _inInterface.getDataLength() + _inInterface.getHeader().getHdrLength();
+ if (_outInterface != null) out += _outInterface.getDataLength() + _outInterface.getHeader().getHdrLength();
+
+ for (final COPSClientSI clientSI : _clientSIs) {
+ out += clientSI.getDataLength() + clientSI.getHeader().getHdrLength();
+ }
+
+ for (final Map.Entry<COPSContext, Set<COPSLPDPDecision>> entry : _decisions.entrySet()) {
+ out += entry.getKey().getDataLength() + entry.getKey().getHeader().getHdrLength();
+ for (final COPSDecision decision : entry.getValue()) {
+ out += decision.getDataLength() + decision.getHeader().getHdrLength();
+ }
+ }
+
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ /**
+ * Return client Handle
+ * @return a COPSHandle
+ */
+ public COPSHandle getClientHandle() {
+ return _clientHandle;
+ }
+
+ /**
+ * Return Context
+ * @return a COPSContext
+ */
+ public COPSContext getContext() {
+ return _context;
+ }
+
+ /**
+ * Returns a Set of ClientSI objects
+ * @return not null but can be empty
+ */
+ public Set<COPSClientSI> getClientSI() {
+ return _clientSIs;
+ }
+
+ /**
+ * Returns a Map of COPSDecision objects
+ * @return not null but can be empty
+ */
+ public Map<COPSContext, Set<COPSLPDPDecision>> getDecisions() {
+ return _decisions;
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ if (_clientHandle != null)
+ _clientHandle.dump(os);
+
+ if (_context != null)
+ _context.dump(os);
+
+ for (final COPSClientSI clientSI : _clientSIs) {
+ clientSI.dump(os);
+ }
+
+ //Display any local decisions
+ for (final Map.Entry<COPSContext, Set<COPSLPDPDecision>> entry : _decisions.entrySet()) {
+ entry.getKey().dump(os);
+
+ for (final COPSDecision decision : entry.getValue()) {
+ decision.dump(os);
+ }
+ }
+
+ if (_integrity != null) {
+ _integrity.dump(os);
+ }
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSReqMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSReqMsg that = (COPSReqMsg) o;
+
+ if (this._clientSIs.size() != that._clientSIs.size()) return false;
+ for (final COPSClientSI thisClientSI : this._clientSIs) {
+ boolean found = false;
+ for (final COPSClientSI thatClientSI: that._clientSIs) {
+ if (thisClientSI.equals(thatClientSI)) {
+ found = true;
+ break;
+ }
+ }
+ if (! found) return false;
+ }
+
+ for (final Map.Entry<COPSContext, Set<COPSLPDPDecision>> entry : this._decisions.entrySet()) {
+ final Set<COPSLPDPDecision> thatDecisions = that._decisions.get(entry.getKey());
+ if (thatDecisions == null) return false;
+
+ for (final COPSLPDPDecision thisDecision : entry.getValue()) {
+ boolean found = false;
+ for (final COPSLPDPDecision thatDecision: thatDecisions) {
+ if (thisDecision.equals(thatDecision)) {
+ found = true;
+ break;
+ }
+ }
+ if (! found) return false;
+ }
+ }
+
+ if (!this._clientHandle.equals(that._clientHandle)) return false;
+ if (!this._context.equals(that._context)) return false;
+
+ if (this._integrity == null && that._integrity != null) return false;
+ if (this._integrity != null && that._integrity == null) return false;
+ if (this._integrity != null && that._integrity != null)
+ if (!this._integrity.equals(that._integrity)) return false;
+
+ if (this._inInterface == null && that._inInterface != null) return false;
+ if (this._inInterface != null && that._inInterface == null) return false;
+ if (this._inInterface != null && that._inInterface != null)
+ if (!this._inInterface.equals(that._inInterface)) return false;
+
+ if (this._outInterface == null && that._outInterface != null) return false;
+ if (this._outInterface != null && that._outInterface == null) return false;
+ if (this._outInterface != null && that._outInterface != null)
+ if (!this._outInterface.equals(that._outInterface)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + _clientHandle.hashCode();
+ result = 31 * result + _context.hashCode();
+ result = 31 * result + (_inInterface != null ? _inInterface.hashCode() : 0);
+ result = 31 * result + (_outInterface != null ? _outInterface.hashCode() : 0);
+ result = 31 * result + _clientSIs.hashCode();
+ result = 31 * result + _decisions.hashCode();
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSReqMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSReqMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSHandle clientHandle = null;
+ COPSContext context = null;
+ COPSContext lpdpContext = null;
+ COPSIntegrity integrity = null;
+ COPSInterface inInterface = null;
+ COPSInterface outInterface = null;
+ Set<COPSClientSI> clientSIs = new HashSet<>();
+ Map<COPSContext, Set<COPSLPDPDecision>> localDecisions = new HashMap<>();
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case HANDLE:
+ clientHandle = COPSHandle.parse(objHdrData, buf);
+ break;
+ case CONTEXT:
+ if (context == null) context = COPSContext.parse(objHdrData, buf);
+ else lpdpContext = COPSContext.parse(objHdrData, buf);
+ break;
+ case ININTF:
+ if (objHdrData.header.getCType().equals(CType.DEF)) {
+ inInterface = COPSObjectParser.parseIpv4Interface(objHdrData, buf, true);
+ } else inInterface = COPSObjectParser.parseIpv6Interface(objHdrData, buf, true);
+ break;
+ case OUTINTF:
+ if (objHdrData.header.getCType().equals(CType.DEF)) {
+ outInterface = COPSObjectParser.parseIpv4Interface(objHdrData, buf, false);
+ } else outInterface = COPSObjectParser.parseIpv6Interface(objHdrData, buf, false);
+ break;
+ case LPDP_DEC:
+ if (localDecisions.get(lpdpContext) != null)
+ localDecisions.get(lpdpContext).add(COPSLPDPDecision.parse(objHdrData, buf));
+ else {
+ final Set<COPSLPDPDecision> decisions = new HashSet<>();
+ decisions.add(COPSLPDPDecision.parse(objHdrData, buf));
+ localDecisions.put(lpdpContext, decisions);
+ }
+ break;
+ case CSI:
+ clientSIs.add(COPSClientSI.parse(objHdrData, buf));
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSReqMsg(hdrData.header, clientHandle, context, integrity, inInterface, outInterface,
+ clientSIs, localDecisions);
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Sync State Message (RFC 2748 pag. 26 and pag. 29\r
- *\r
- * The format of the Synchronize State Query message is as follows:\r
- *\r
- * <Synchronize State> ::= <Common Header>\r
- * [<Client Handle>]\r
- * [<Integrity>]\r
- *\r
- * This message indicates that the remote PDP wishes the client (which\r
- * appears in the common header) to re-send its state. If the optional\r
- * Client Handle is present, only the state associated with this handle\r
- * is synchronized. If the PEP does not recognize the requested handle,\r
- * it MUST immediately send a DRQ message to the PDP for the handle that\r
- * was specified in the SSQ message. If no handle is specified in the\r
- * SSQ message, all the active client state MUST be synchronized with\r
- * the PDP.\r
- *\r
- * The client performs state synchronization by re-issuing request\r
- * queries of the specified client-type for the existing state in the\r
- * PEP. When synchronization is complete, the PEP MUST issue a\r
- * synchronize state complete message to the PDP.\r
- *\r
- * <Synchronize State Complete> ::= <Common Header>\r
- * [<Client Handle>]\r
- * [<Integrity>]\r
- *\r
- * The Client Handle object only needs to be included if the corresponding\r
- * Synchronize State Message originally referenced a specific handle.\r
- *\r
- * @version COPSSyncStateMsg.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSSyncStateMsg extends COPSMsg {\r
-\r
- /* COPSHeader coming from base class */\r
- private COPSHandle _clientHandle;\r
- private COPSIntegrity _integrity;\r
-\r
- public COPSSyncStateMsg() {\r
- _clientHandle = null;\r
- _integrity = null;\r
- }\r
-\r
- /**\r
- Parse data and create COPSSyncStateMsg object\r
- */\r
- protected COPSSyncStateMsg(byte[] data) throws COPSException {\r
- _clientHandle = null;\r
- _integrity = null;\r
- parse(data);\r
- }\r
-\r
- /**\r
- * Checks the sanity of COPS message and throw an\r
- * COPSException when data is bad.\r
- */\r
- public void checkSanity() throws COPSException {\r
- if (_hdr == null) {\r
- throw new COPSException("Bad message format");\r
- }\r
- }\r
-\r
- /**\r
- * Add message header\r
- *\r
- * @param hdr a COPSHeader\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHeader hdr) throws COPSException {\r
- if (hdr == null)\r
- throw new COPSException ("Null Header");\r
- if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
- (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
- throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
- _hdr = hdr;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add client handle to the message\r
- *\r
- * @param handle a COPSHandle\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSHandle handle) throws COPSException {\r
- if (handle == null)\r
- throw new COPSException ("Null Handle");\r
-\r
- //Message integrity object should be the very last one\r
- //If it is already added\r
- if (_integrity != null)\r
- throw new COPSException ("No null Handle");\r
-\r
- _clientHandle = handle;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Add integrity object\r
- *\r
- * @param integrity a COPSIntegrity\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- public void add (COPSIntegrity integrity) throws COPSException {\r
- if (integrity == null)\r
- throw new COPSException ("Null Integrity");\r
- if (!integrity.isMessageIntegrity())\r
- throw new COPSException ("Error Integrity");\r
- _integrity = integrity;\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * If the optional Client Handle is present, only the state associated\r
- * with this handle is synchronized. If no handle is specified in the\r
- * SSQ message, all the active client state MUST be synchronized with\r
- * the PDP.\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasClientHandle() {\r
- return (_clientHandle != null);\r
- }\r
-\r
- /**\r
- * Get client Handle\r
- *\r
- * @return a COPSHandle\r
- *\r
- */\r
- public COPSHandle getClientHandle() {\r
- return _clientHandle;\r
- }\r
-\r
- /**\r
- * Returns true if it has integrity object\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean hasIntegrity() {\r
- return (_integrity != null);\r
- }\r
-\r
- /**\r
- * Get Integrity. Should check hasIntegrity() before calling\r
- *\r
- * @return a COPSIntegrity\r
- *\r
- */\r
- public COPSIntegrity getIntegrity() {\r
- return (_integrity);\r
- }\r
-\r
- /**\r
- * Writes data to given socket\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- // checkSanity();\r
- if (_hdr != null) _hdr.writeData(id);\r
- if (_clientHandle != null) _clientHandle.writeData(id);\r
- if (_integrity != null) _integrity.writeData(id);\r
-\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(byte[] data) throws COPSException {\r
- super.parseHeader(data);\r
-\r
- while (_dataStart < _dataLength) {\r
- byte[] buf = new byte[data.length - _dataStart];\r
- System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);\r
-\r
- COPSObjHeader objHdr = COPSObjHeader.parse(buf);\r
- switch (objHdr.getCNum()) {\r
- case HANDLE:\r
- _clientHandle = new COPSHandle(buf);\r
- _dataStart += _clientHandle.getDataLength();\r
- break;\r
- case MSG_INTEGRITY:\r
- _integrity = new COPSIntegrity(buf);\r
- _dataStart += _integrity.getDataLength();\r
- break;\r
- default:\r
- throw new COPSException("Bad Message format, unknown object type");\r
- }\r
- }\r
- checkSanity();\r
- }\r
-\r
- /**\r
- * Parse data\r
- *\r
- * @param hdr a COPSHeader\r
- * @param data a byte[]\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void parse(COPSHeader hdr, byte[] data) throws COPSException {\r
-\r
- if ((hdr.getOpCode() != COPSHeader.COPS_OP_SSC) &&\r
- (hdr.getOpCode() != COPSHeader.COPS_OP_SSQ))\r
- throw new COPSException ("Error Header (no COPS_OP_SSX)");\r
-\r
- _hdr = hdr;\r
- parse(data);\r
- setMsgLength();\r
- }\r
-\r
- /**\r
- * Set the message length, base on the set of objects it contains\r
- *\r
- * @throws COPSException\r
- *\r
- */\r
- protected void setMsgLength() throws COPSException {\r
- short len = 0;\r
- if (_clientHandle != null) len += _clientHandle.getDataLength();\r
- if (_integrity != null) len += _integrity.getDataLength();\r
- _hdr.setMsgLength(len);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _hdr.dump(os);\r
-\r
- if (_clientHandle != null)\r
- _clientHandle.dump(os);\r
-\r
- if (_integrity != null) {\r
- _integrity.dump(os);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * COPS Sync State Message (RFC 2748 pg. 26 and pg. 29
+ *
+ * The format of the Synchronize State Query message is as follows:
+ *
+ * <Synchronize State> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ *
+ * This message indicates that the remote PDP wishes the client (which
+ * appears in the common header) to re-send its state. If the optional
+ * Client Handle is present, only the state associated with this handle
+ * is synchronized. If the PEP does not recognize the requested handle,
+ * it MUST immediately send a DRQ message to the PDP for the handle that
+ * was specified in the SSQ message. If no handle is specified in the
+ * SSQ message, all the active client state MUST be synchronized with
+ * the PDP.
+ *
+ * The client performs state synchronization by re-issuing request
+ * queries of the specified client-type for the existing state in the
+ * PEP. When synchronization is complete, the PEP MUST issue a
+ * synchronize state complete message to the PDP.
+ *
+ * <Synchronize State Complete> ::= <Common Header>
+ * [<Client Handle>]
+ * [<Integrity>]
+ *
+ * The Client Handle object only needs to be included if the corresponding
+ * Synchronize State Message originally referenced a specific handle.
+ *
+ * @version COPSSyncStateMsg.java, v 1.00 2003
+ *
+ */
+public class COPSSyncStateMsg extends COPSMsg {
+
+ // Optional
+ private final COPSHandle _clientHandle;
+ private final COPSIntegrity _integrity;
+
+ /**
+ * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
+ * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the handle (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ @Deprecated
+ public COPSSyncStateMsg(final short clientType, final COPSHandle handle, final COPSIntegrity integrity) {
+ this(new COPSHeader(OPCode.SSQ, clientType), handle, integrity);
+ }
+
+ /**
+ * Constructor (generally used for sending messages).
+ * @param version - the supported PCMM Version
+ * @param flag - the flag...
+ * @param clientType - the type of client that created the message (required)
+ * @param handle - the handle (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ public COPSSyncStateMsg(final int version, final Flag flag, final short clientType, final COPSHandle handle,
+ final COPSIntegrity integrity) {
+ this(new COPSHeader(version, flag, OPCode.SSQ, clientType), handle, integrity);
+ }
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSHeader information is known.
+ * @param hdr - COPS Header
+ * @param handle - the handle (optional)
+ * @param integrity - the integrity (optional)
+ * @throws java.lang.IllegalArgumentException
+ */
+ protected COPSSyncStateMsg(final COPSHeader hdr, final COPSHandle handle, final COPSIntegrity integrity) {
+ super(hdr);
+ if (!hdr.getOpCode().equals(OPCode.SSQ))
+ throw new IllegalArgumentException("OPCode must be of type - " + OPCode.SSQ);
+ _clientHandle = handle;
+ _integrity = integrity;
+ }
+
+ // Getters
+ public COPSHandle getClientHandle() {
+ return _clientHandle;
+ }
+ public COPSIntegrity getIntegrity() {
+ return (_integrity);
+ }
+
+ @Override
+ protected int getDataLength() {
+ int out = 0;
+ if (_clientHandle != null) out += _clientHandle.getDataLength() + _clientHandle.getHeader().getHdrLength();
+ if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
+ return out;
+ }
+
+ @Override
+ protected void writeBody(final Socket socket) throws IOException {
+ if (_clientHandle != null) _clientHandle.writeData(socket);
+ if (_integrity != null) _integrity.writeData(socket);
+ }
+
+ @Override
+ protected void dumpBody(final OutputStream os) throws IOException {
+ if (_clientHandle != null) _clientHandle.dump(os);
+ if (_integrity != null) _integrity.dump(os);
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof COPSSyncStateMsg)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final COPSSyncStateMsg that = (COPSSyncStateMsg) o;
+
+ return !(_clientHandle != null ? !_clientHandle.equals(that._clientHandle) : that._clientHandle != null) &&
+ !(_integrity != null ? !_integrity.equals(that._integrity) : that._integrity != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (_clientHandle != null ? _clientHandle.hashCode() : 0);
+ result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Responsible for parsing a byte array to create a COPSReqMsg object
+ * @param hdrData - the object's header data
+ * @param data - the byte array to parse
+ * @return - the message object
+ * @throws COPSException
+ */
+ public static COPSSyncStateMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
+ // Variables for constructor
+ COPSHandle clientHandle = null;
+ COPSIntegrity integrity = null;
+
+ int dataStart = 0;
+ while (dataStart < data.length) {
+ final byte[] buf = new byte[data.length - dataStart];
+ System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
+
+ final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
+ switch (objHdrData.header.getCNum()) {
+ case HANDLE:
+ clientHandle = COPSHandle.parse(objHdrData, buf);
+ break;
+ case MSG_INTEGRITY:
+ integrity = COPSIntegrity.parse(objHdrData, buf);
+ break;
+ default:
+ throw new COPSException("Bad Message format, unknown object type");
+ }
+ dataStart += objHdrData.msgByteCount;
+ }
+
+ return new COPSSyncStateMsg(hdrData.header, clientHandle, integrity);
+ }
+
+}
+
+
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-\r
-/**\r
- * COPS Timer Object\r
- *\r
- * @version COPSTimer.java, v 1.00 2003\r
- *\r
- */\r
-public abstract class COPSTimer extends COPSObjBase {\r
-\r
- protected COPSObjHeader _objHdr;\r
- private short _reserved;\r
- private short _timerValue;\r
-\r
- /**\r
- * Returns size in number of octects, including header\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getDataLength() {\r
- //Add the size of the header also\r
- return (_objHdr.getDataLength());\r
- }\r
-\r
- /**\r
- * Method getTimerVal\r
- *\r
- * @return a short\r
- *\r
- */\r
- public short getTimerVal() {\r
- return _timerValue;\r
- };\r
-\r
- /**\r
- * Method isTimer\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isTimer() {\r
- return true;\r
- };\r
-\r
- /**\r
- * Method isKATimer\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isKATimer() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Method isAcctTimer\r
- *\r
- * @return a boolean\r
- *\r
- */\r
- public boolean isAcctTimer() {\r
- return false;\r
- };\r
-\r
- /**\r
- * Write data to given socket in Network byte order\r
- *\r
- * @param id a Socket\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void writeData(Socket id) throws IOException {\r
- _objHdr.writeData(id);\r
-\r
- byte[] buf = new byte[4];\r
-\r
- buf[0] = (byte) (_reserved >> 8);\r
- buf[1] = (byte) _reserved;\r
- buf[2] = (byte) (_timerValue >> 8);\r
- buf[3] = (byte) _timerValue;\r
- COPSUtil.writeData(id, buf, 4);\r
- }\r
-\r
- protected COPSTimer(COPSObjHeader hdr, short timeVal) {\r
- _objHdr = hdr;\r
- //Time range is 1 - 65535 seconds\r
- _timerValue = timeVal;\r
- // _objHdr.setDataLength(sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- * Receive data that is in netwrok byte order and fill in the obj.\r
- */\r
- protected COPSTimer(byte[] dataPtr) {\r
- _objHdr = COPSObjHeader.parse(dataPtr);\r
-\r
- _reserved |= ((short) dataPtr[4]) << 8;\r
- _reserved |= ((short) dataPtr[5]) & 0xFF;\r
- _timerValue |= ((short) dataPtr[6]) << 8;\r
- _timerValue |= ((short) dataPtr[7]) & 0xFF;\r
-\r
- // _objHdr.setDataLength(sizeof(u_int32_t));\r
- _objHdr.setDataLength((short) 4);\r
- }\r
-\r
- /**\r
- * Write an object textual description in the output stream\r
- *\r
- * @param os an OutputStream\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- public void dump(OutputStream os) throws IOException {\r
- _objHdr.dump(os);\r
- os.write(new String("Timer val: " + _timerValue + "\n").getBytes());\r
- }\r
-\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.Socket;
+
+/**
+ * For extension by other COPS Timer Objects such as COPSAcctTimer & COPSKATimer
+ */
+public abstract class COPSTimer extends COPSObjBase {
+
+ // TODO - determine what is the function of this member
+ private final short _reserved;
+
+ /**
+ * The timer values
+ */
+ private final short _timerValue;
+
+ /**
+ * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
+ * COPSObjHeader information is known
+ * @param header - the object header
+ * @param reserved - ???
+ * @param timerVal - the timer value
+ */
+ protected COPSTimer(final COPSObjHeader header, final short reserved, final short timerVal) {
+ super(header);
+ _reserved = reserved;
+ _timerValue = timerVal;
+ }
+
+ /**
+ * Method getTimerVal
+ * @return a short
+ */
+ public short getTimerVal() {
+ return _timerValue;
+ }
+
+ @Override
+ public void writeBody(Socket socket) throws IOException {
+ byte[] buf = new byte[4];
+
+ buf[0] = (byte) (_reserved >> 8);
+ buf[1] = (byte) _reserved;
+ buf[2] = (byte) (_timerValue >> 8);
+ buf[3] = (byte) _timerValue;
+ COPSUtil.writeData(socket, buf, 4);
+ }
+
+ @Override
+ protected int getDataLength() {
+ return 4;
+ }
+
+ @Override
+ public void dumpBody(final OutputStream os) throws IOException {
+ os.write(("Timer val: " + _timerValue + "\n").getBytes());
+ }
+
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.net.Socket;\r
-\r
-// import org.umu.cops.common.COPSDebug;\r
-\r
-/**\r
- * COPS Transceiver\r
- *\r
- * @version COPSTransceiver.java, v 1.00 2003\r
- *\r
- */\r
-public class COPSTransceiver {\r
-\r
- /**\r
- * Method sendMsg\r
- *\r
- * @param msg a COPSMsg\r
- * @param fd a Socket\r
- *\r
- * @throws IOException\r
- * @throws COPSException\r
- *\r
- */\r
- static public void sendMsg(COPSMsg msg, Socket fd) throws IOException, COPSException {\r
- // COPSDebug.out("COPSTransceiver", "sendMsg ******************************** START" );\r
-\r
- msg.checkSanity();\r
- msg.writeData(fd);\r
-\r
- // COPSDebug.out("COPSTransceiver", "sendMsg ******************************** END" );\r
- }\r
-\r
- /**\r
- * Method receiveMsg\r
- *\r
- * @param fd a Socket\r
- *\r
- * @return a COPSMsg\r
- *\r
- * @throws IOException\r
- * @throws COPSException\r
- *\r
- */\r
- static public COPSMsg receiveMsg (Socket fd) throws IOException, COPSException {\r
- int nread = 0;\r
- byte[] hBuf = new byte[8];\r
-\r
- // COPSDebug.out("COPSTransceiver", "receiveMsg ******************************** START" );\r
-\r
- nread = COPSUtil.readData(fd, hBuf, 8);\r
-\r
- if (nread == 0) {\r
- throw new COPSException("Error reading connection");\r
- }\r
-\r
- if (nread != 8) {\r
- throw new COPSException("Bad COPS message");\r
- }\r
-\r
- COPSHeader hdr = new COPSHeader(hBuf);\r
- int dataLen = hdr.getMsgLength() - hdr.getHdrLength();\r
- // COPSDebug.out("COPSTransceiver", "COPS Msg length :[" + dataLen + "]\n" );\r
- byte[] buf = new byte[dataLen + 1];\r
- nread = 0;\r
-\r
- nread = COPSUtil.readData(fd, buf, dataLen);\r
- buf[dataLen] = (byte) '\0';\r
- // COPSDebug.out("COPSTransceiver", "Data read length:[" + nread + "]\n");\r
-\r
- if (nread != dataLen) {\r
- throw new COPSException("Bad COPS message");\r
- }\r
-\r
- COPSMsgParser prser = new COPSMsgParser();\r
- COPSMsg msg = prser.parse(hdr, buf);\r
-\r
- // COPSDebug.out("COPSTransceiver", "Message received");\r
-\r
- // COPSDebug.out("COPSTransceiver", "receiveMsg ******************************** END" );\r
- return msg;\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * Utilities for sending and receiving COPS messages
+ *
+ * @version COPSTransceiver.java, v 1.00 2003
+ *
+ */
+public class COPSTransceiver {
+
+ /**
+ * Method sendMsg
+ * @param msg a COPSMsg
+ * @param fd a Socket
+ * @throws IOException
+ * @throws COPSException
+ */
+ static public void sendMsg(final COPSMsg msg, final Socket fd) throws IOException, COPSException {
+ msg.writeData(fd);
+ }
+
+ /**
+ * Parses a COPS message coming in via the socket
+ * @param socket - the socket from which the message will arrive
+ * @return a COPSMsg object
+ * @throws IOException
+ * @throws COPSException
+ */
+ static public COPSMsg receiveMsg(final Socket socket) throws IOException, COPSException {
+ return COPSMsgParser.parseMessage(socket);
+ }
+}
+
-/*\r
- * Copyright (c) 2003 University of Murcia. All rights reserved.\r
- * --------------------------------------------------------------\r
- * For more information, please see <http://www.umu.euro6ix.org/>.\r
- */\r
-\r
-package org.umu.cops.stack;\r
-\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-import java.net.Socket;\r
-import java.util.Date;\r
-\r
-/**\r
- * COPS Utils\r
- *\r
- * @version COPSUtil.java, v 2.00 2004\r
- *\r
- */\r
-public class COPSUtil {\r
-\r
- /**\r
- * Method writeData\r
- *\r
- * @param id a Socket\r
- * @param data a byte[]\r
- * @param len an int\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- static void writeData(Socket id, byte[] data, int len) throws IOException {\r
- OutputStream output;\r
- output = id.getOutputStream();\r
-\r
- output.write(data,0,len);\r
- }\r
-\r
- /**\r
- * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error\r
- * bRead returns the bytes read\r
- *\r
- * @param connId a Socket\r
- * @param dataRead a byte[]\r
- * @param nchar an int\r
- *\r
- * @return an int\r
- *\r
- * @throws IOException\r
- *\r
- */\r
- static int readData(Socket connId, byte[] dataRead, int nchar) throws IOException {\r
- InputStream input;\r
- input = connId.getInputStream();\r
-\r
- int nread = 0;\r
- int startTime = (int) (new Date().getTime());\r
- do {\r
- if (input.available() != 0) {\r
- nread += input.read(dataRead,nread,nchar-nread);\r
- startTime = (int) (new Date().getTime());\r
- } else {\r
- int nowTime = (int) (new Date().getTime());\r
- if ((int)(nowTime - startTime) > 2000)\r
- break;\r
- }\r
- } while (nread != nchar);\r
-\r
- return nread;\r
- }\r
-}\r
-\r
+/*
+ * Copyright (c) 2003 University of Murcia. All rights reserved.
+ * --------------------------------------------------------------
+ * For more information, please see <http://www.umu.euro6ix.org/>.
+ */
+
+package org.umu.cops.stack;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.Date;
+
+/**
+ * Class to hold static utilitarian methods for streaming bytes over a Socket.
+ *
+ * @version COPSUtil.java, v 2.00 2004
+ *
+ */
+public class COPSUtil {
+
+ private final static Logger logger = LoggerFactory.getLogger(COPSUtil.class);
+
+ /**
+ * Streams COPS data
+ * @param socket a Socket
+ * @param data a byte[]
+ * @param len an int
+ * @throws IOException
+ */
+ public static void writeData(final Socket socket, final byte[] data, final int len) throws IOException {
+ logger.trace("Writing COPS data");
+ socket.getOutputStream().write(data, 0, len);
+ }
+
+ /**
+ * Returns true if the data contained within data1 + padding1 is equivalent to data2 + padding2
+ * @param data1 - the data from the first
+ * @param padding1 - the padding from the first
+ * @param data2 - the data from the second
+ * @param padding2 - the padding from the second
+ * @return - t/f
+ */
+ public static boolean copsDataPaddingEquals(final COPSData data1, final COPSData padding1,
+ final COPSData data2, final COPSData padding2) {
+ final byte[] data1Bytes = data1.getData();
+ final byte[] padding1Bytes = padding1.getData();
+
+ final byte[] data2Bytes = data2.getData();
+ final byte[] padding2Bytes = padding2.getData();
+
+ if (data1Bytes.length + padding1Bytes.length != data2Bytes.length + padding2Bytes.length)
+ return false;
+
+ final ByteArrayOutputStream thisStream = new ByteArrayOutputStream();
+ final ByteArrayOutputStream thatStream = new ByteArrayOutputStream();
+ try {
+ thisStream.write(data1Bytes);
+ thisStream.write(padding1Bytes);
+ thatStream.write(data2Bytes);
+ thatStream.write(padding2Bytes);
+ return Arrays.equals(thisStream.toByteArray(), thatStream.toByteArray());
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Reads nchar from a given sockets, blocks on read untill nchar are read of conenction has error
+ * bRead returns the bytes read
+ *
+ * @param connId a Socket
+ * @param dataRead a byte[]
+ * @param nchar an int
+ *
+ * @return an int
+ *
+ * @throws IOException
+ *
+ */
+ @Deprecated
+ static int readData(Socket connId, byte[] dataRead, int nchar) throws IOException {
+ InputStream input;
+ input = connId.getInputStream();
+
+ int nread = 0;
+ int startTime = (int) (new Date().getTime());
+ do {
+ if (input.available() != 0) {
+ nread += input.read(dataRead,nread,nchar-nread);
+ startTime = (int) (new Date().getTime());
+ } else {
+ int nowTime = (int) (new Date().getTime());
+ if ((nowTime - startTime) > 2000)
+ break;
+ }
+ } while (nread != nchar);
+
+ return nread;
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSAcctTimer class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSAcctTimerTest {
+
+ private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF);
+
+ @Test
+ public void testValidTimeAndDefaultHeader() {
+ final COPSAcctTimer timer = new COPSAcctTimer((short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(defaultHeader, timer.getHeader());
+ }
+
+ @Test
+ public void testValidTimeReservedAndDefaultHeader() {
+ final COPSAcctTimer timer = new COPSAcctTimer((short) 4, (short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(defaultHeader, timer.getHeader());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidCNum() {
+ new COPSAcctTimer(new COPSObjHeader(CNum.CONTEXT, CType.DEF), (short) 4, (short)10);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidCType() {
+ new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.REPL), (short) 4, (short)10);
+ }
+
+ @Test
+ public void testValidCustomHeader() {
+ final COPSAcctTimer timer = new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), (short) 4, (short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), timer.getHeader());
+ }
+
+ @Test
+ public void testDumpDefaultHeader() throws Exception {
+ final COPSAcctTimer timer = new COPSAcctTimer((short) 4, (short)10);
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ timer.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Account-Timer**", lines[0]);
+ Assert.assertEquals("C-num: ACCT_TIMER", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Timer val: 10", lines[3]);
+ }
+
+ @Test
+ public void testDumpCustomHeader() throws Exception {
+ final COPSAcctTimer timer = new COPSAcctTimer(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF),
+ (short) 4, (short)100);
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ timer.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Account-Timer**", lines[0]);
+ Assert.assertEquals("C-num: ACCT_TIMER", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Timer val: 100", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSClientAcceptMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSClientAcceptMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSClientAcceptMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSClientAcceptMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSKATimer((short)1), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSClientAcceptMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSKATimer((short)1), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullTimer() {
+ new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSClientAcceptMsg(hdr, new COPSKATimer((short)1), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CC, IPCMMClient.CLIENT_TYPE);
+ new COPSClientAcceptMsg(hdr, new COPSKATimer((short)1), null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSClientAcceptMsg msg = new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSKATimer((short)1), null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSKATimer((short)1), msg.getKATimer());
+ Assert.assertNull(msg.getAcctTimer());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() {
+ final COPSClientAcceptMsg msg = new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSKATimer((short)1), new COPSAcctTimer((short)1), new COPSIntegrity());
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSKATimer((short)1), msg.getKATimer());
+ Assert.assertEquals(new COPSAcctTimer((short)1), msg.getAcctTimer());
+ Assert.assertEquals(new COPSIntegrity(), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientAcceptMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSClientAcceptMsg msg = new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSKATimer((short)1), new COPSAcctTimer((short)1), new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(19, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: CAT", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientAcceptMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSClientAcceptMsg msg = new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSKATimer((short)5), null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientAcceptMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSClientAcceptMsg msg = new COPSClientAcceptMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSKATimer((short)5), new COPSAcctTimer((short)6),
+ new COPSIntegrity(8, 9, new COPSData("12345")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSClientCloseMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSClientCloseMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSClientCloseMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSClientCloseMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSClientCloseMsg(1, null, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullError() {
+ new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSClientCloseMsg(hdr, new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.NA, IPCMMClient.CLIENT_TYPE);
+ new COPSClientCloseMsg(hdr, new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSClientCloseMsg msg = new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), msg.getError());
+ Assert.assertNull(msg.getRedirAddr());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() throws Exception {
+ final COPSClientCloseMsg msg = new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED),
+ new COPSIpv4PdpRedirectAddress("localhost", 7777, (short)0),
+ new COPSIntegrity());
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), msg.getError());
+ Assert.assertEquals(new COPSIpv4PdpRedirectAddress("localhost", 7777, (short) 0), msg.getRedirAddr());
+ Assert.assertEquals(new COPSIntegrity(), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientCloseMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSClientCloseMsg msg = new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED),
+ new COPSIpv4PdpRedirectAddress("localhost", 7777, (short)0),
+ new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(22, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: CC", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientCloseMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSClientCloseMsg msg = new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.AUTH_REQUIRED), null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientCloseMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSClientCloseMsg msg = new COPSClientCloseMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSError(ErrorTypes.BAD_HANDLE_REF, ErrorTypes.MA),
+ new COPSIpv4PdpRedirectAddress("localhost", 7777, (short)0),
+ new COPSIntegrity(8, 9, new COPSData("12345")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSClientOpenMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSClientOpenMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSClientOpenMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSClientOpenMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSPepId(new COPSData()),
+ null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSClientOpenMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSPepId(new COPSData()), null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullPepId() {
+ new COPSClientOpenMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSClientOpenMsg(hdr, new COPSPepId(new COPSData()), null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ new COPSClientOpenMsg(hdr, new COPSPepId(new COPSData()), null, null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")), null, null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSPepId(new COPSData("12345")), msg.getPepId());
+ Assert.assertNull(msg.getClientSI());
+ Assert.assertNull(msg.getPdpAddress());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAllIpv4() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")),
+ new COPSClientSI(CSIType.NAMED, new COPSData("123456")),
+ new COPSIpv4LastPdpAddr("localhost", 7777, (short)0),
+ new COPSIntegrity(3, 4, new COPSData("1234567")));
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.UNSOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSPepId(new COPSData("12345")), msg.getPepId());
+ Assert.assertEquals(new COPSClientSI(CSIType.NAMED, new COPSData("123456")), msg.getClientSI());
+ Assert.assertEquals(new COPSIpv4LastPdpAddr("localhost", 7777, (short) 0), msg.getPdpAddress());
+ Assert.assertEquals(new COPSIntegrity(3, 4, new COPSData("1234567")), msg.getIntegrity());
+ }
+
+ @Test
+ public void validAllIpv6() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")),
+ new COPSClientSI(CSIType.NAMED, new COPSData("123456")),
+ new COPSIpv6LastPdpAddr("localhost", 7777, (short)0),
+ new COPSIntegrity(3, 4, new COPSData("1234567")));
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.UNSOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSPepId(new COPSData("12345")), msg.getPepId());
+ Assert.assertEquals(new COPSClientSI(CSIType.NAMED, new COPSData("123456")), msg.getClientSI());
+ Assert.assertEquals(new COPSIpv6LastPdpAddr("localhost", 7777, (short)0), msg.getPdpAddress());
+ Assert.assertEquals(new COPSIntegrity(3, 4, new COPSData("1234567")), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientOpenMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")),
+ new COPSClientSI(CSIType.NAMED, new COPSData("123456")),
+ new COPSIpv4LastPdpAddr("localhost", 7777, (short)0),
+ new COPSIntegrity(3, 4, new COPSData("1234567")));
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(26, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: UNSOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: OPN", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientOpenMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")), null, null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientOpenMsg object without any nulls for IPv4 addresses
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAllIpv4() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")),
+ new COPSClientSI(CSIType.NAMED, new COPSData("123456")),
+ new COPSIpv4LastPdpAddr("localhost", 7777, (short)0),
+ new COPSIntegrity(3, 4, new COPSData("1234567")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSClientOpenMsg object without any nulls for IPv6 addresses
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAllIpv6() throws Exception {
+ final COPSClientOpenMsg msg = new COPSClientOpenMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSPepId(new COPSData("12345")),
+ new COPSClientSI(CSIType.NAMED, new COPSData("123456")),
+ new COPSIpv6LastPdpAddr("localhost", 7777, (short)0),
+ new COPSIntegrity(3, 4, new COPSData("1234567")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSClientSI class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSClientSITest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCSItype() {
+ new COPSClientSI(CSIType.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullData() {
+ new COPSClientSI(CSIType.SIGNALED, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSClientSI(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSClientSI(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), new COPSData());
+ }
+
+ @Test
+ public void csiSignaledEmptyData() {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData());
+ Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType());
+ Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum());
+ Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal());
+ Assert.assertEquals(new COPSData(), clientSI.getData());
+ Assert.assertEquals(0, clientSI.getDataLength());
+ }
+
+ @Test
+ public void csiSignaledUnPaddedData() {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("1234"));
+ Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType());
+ Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum());
+ Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal());
+ Assert.assertEquals(new COPSData("1234"), clientSI.getData());
+ Assert.assertEquals(4, clientSI.getDataLength());
+ }
+
+ @Test
+ public void csiSignaledPaddedData() {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("12345"));
+ Assert.assertEquals(CSIType.SIGNALED, clientSI.getCsiType());
+ Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum());
+ Assert.assertEquals(CSIType.SIGNALED.ordinal(), clientSI.getHeader().getCType().ordinal());
+ Assert.assertEquals(new COPSData("12345"), clientSI.getData());
+ Assert.assertEquals(8, clientSI.getDataLength());
+ }
+
+ @Test
+ public void csiNamedPaddedData() {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.NAMED, new COPSData("12345"));
+ Assert.assertEquals(CSIType.NAMED, clientSI.getCsiType());
+ Assert.assertEquals(CNum.CSI, clientSI.getHeader().getCNum());
+ Assert.assertEquals(CSIType.NAMED.ordinal(), clientSI.getHeader().getCType().ordinal());
+ Assert.assertEquals(new COPSData("12345"), clientSI.getData());
+ Assert.assertEquals(8, clientSI.getDataLength());
+ }
+
+ @Test
+ public void csiNamedDumpPadded() throws Exception {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.NAMED, new COPSData("12345"));
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ clientSI.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Client-SI**", lines[0]);
+ Assert.assertEquals("C-num: CSI", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("CSI-type: NAMED", lines[3]);
+ Assert.assertEquals("client-SI: 12345", lines[4]);
+ }
+
+ @Test
+ public void csiSignaledDumpUnpadded() throws Exception {
+ final COPSClientSI clientSI = new COPSClientSI(CSIType.SIGNALED, new COPSData("1234"));
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ clientSI.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Client-SI**", lines[0]);
+ Assert.assertEquals("C-num: CSI", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("CSI-type: SIGNALED", lines[3]);
+ Assert.assertEquals("client-SI: 1234", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSContext class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSContextTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullRType() {
+ new COPSContext(null, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSContext(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), RType.CONFIG, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSContext(new COPSObjHeader(CNum.CONTEXT, CType.NA), RType.CONFIG, (short)0);
+ }
+
+ @Test
+ public void dumpConfig0() throws Exception {
+ final COPSContext context = new COPSContext(RType.CONFIG, (short)0);
+ Assert.assertEquals(4, context.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ context.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Context**", lines[0]);
+ Assert.assertEquals("C-num: CONTEXT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("context: Configuration,0", lines[3]);
+ }
+
+ @Test
+ public void dumpInAdmin99() throws Exception {
+ final COPSContext context = new COPSContext(RType.IN_ADMIN, (short)99);
+ Assert.assertEquals(4, context.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ context.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Context**", lines[0]);
+ Assert.assertEquals("C-num: CONTEXT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("context: Incoming Message/Admission Control,99", lines[3]);
+ }
+
+ @Test
+ public void dumpResAlloc25() throws Exception {
+ final COPSContext context = new COPSContext(RType.RES_ALLOC, (short)25);
+ Assert.assertEquals(4, context.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ context.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Context**", lines[0]);
+ Assert.assertEquals("C-num: CONTEXT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("context: Resource allocation,25", lines[3]);
+ }
+
+ @Test
+ public void dumpOut15() throws Exception {
+ final COPSContext context = new COPSContext(RType.OUT, (short)15);
+ Assert.assertEquals(4, context.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ context.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Context**", lines[0]);
+ Assert.assertEquals("C-num: CONTEXT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("context: Outgoing message,15", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
@Test
public void defaultConstructor() {
final COPSData data = new COPSData();
- Assert.assertEquals(null, data.getData());
+ Assert.assertArrayEquals(new byte[0], data.getData());
Assert.assertEquals(0, data.length());
Assert.assertEquals("", data.str());
Assert.assertTrue(data.equals(new COPSData()));
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for the first constructor of the COPSDecisionMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSDecisionMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSDecisionMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ final static Map<COPSContext, Set<COPSDecision>> staticDecisions = new HashMap<>();
+ static {
+ final Set<COPSDecision> decisions1 = new HashSet<>();
+ decisions1.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData("12345")));
+ staticDecisions.put(new COPSContext(RType.CONFIG, (short)1), decisions1);
+ }
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0WithError() {
+ new COPSDecisionMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0WithDecisions() {
+ new COPSDecisionMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlagWithError() {
+ new COPSDecisionMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlagWithDecisions() {
+ new COPSDecisionMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandleDeprecatedWithError() {
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, null,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandleDeprecatedWithDecisions() {
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, null, staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandleWithError() {
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, null,
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandleWithDecisions() {
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, null, staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorDeprecated() {
+ final COPSError error = null;
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), error, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullError() {
+ final COPSError error = null;
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), error, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDecisionsDeprecated() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = null;
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDecisions() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = null;
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyDecisionsMapDeprecated() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyDecisionsMap() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDecisionsSetDeprecated() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ decisions.put(new COPSContext(RType.CONFIG, (short)1), null);
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullDecisionsSet() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ decisions.put(new COPSContext(RType.CONFIG, (short)1), null);
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyDecisionsSetDeprecated() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ decisions.put(new COPSContext(RType.CONFIG, (short)1), new HashSet<COPSDecision>());
+ new COPSDecisionMsg(IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyDecisionsSet() {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ decisions.put(new COPSContext(RType.CONFIG, (short)1), new HashSet<COPSDecision>());
+ new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), decisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeaderErrorOnly() {
+ final COPSHeader hdr = null;
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA),
+ null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeaderDecisionsOnly() {
+ final COPSHeader hdr = null;
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), null, staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHdrErrorOnly() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CC, IPCMMClient.CLIENT_TYPE);
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA),
+ null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHdrDecisionsOnly() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CC, IPCMMClient.CLIENT_TYPE);
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), null, staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void withErrorAndDecisions() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.DEC, IPCMMClient.CLIENT_TYPE);
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA),
+ staticDecisions, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorAndDecisions() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.DEC, IPCMMClient.CLIENT_TYPE);
+ new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()), null, null, null);
+ }
+
+ @Test
+ public void validProtectedError() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.DEC, IPCMMClient.CLIENT_TYPE);
+ final COPSDecisionMsg msg = new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()),
+ new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), null, null);
+ Assert.assertEquals(OPCode.DEC, msg.getHeader().getOpCode());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(hdr, msg.getHeader());
+ Assert.assertEquals(new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA), msg.getError());
+ Assert.assertNotNull(msg.getDecisions());
+ Assert.assertTrue(msg.getDecisions().isEmpty());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validProtectedDecisions() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.DEC, IPCMMClient.CLIENT_TYPE);
+ final COPSDecisionMsg msg = new COPSDecisionMsg(hdr, new COPSHandle(new COPSData()),
+ null, staticDecisions, null);
+ Assert.assertEquals(OPCode.DEC, msg.getHeader().getOpCode());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(hdr, msg.getHeader());
+ Assert.assertNull(msg.getError());
+ Assert.assertNotNull(msg.getDecisions());
+ Assert.assertFalse(msg.getDecisions().isEmpty());
+ Assert.assertNotSame(staticDecisions, msg.getDecisions());
+ Assert.assertEquals(staticDecisions, msg.getDecisions());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSDecisionMsg object with error and no decisions
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpErrorAll() throws Exception {
+ final COPSDecisionMsg msg = new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData()), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.NA),
+ new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(20, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: UNSOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: DEC", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSDecisionMsg object with error and no decisions
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpDecisionsAll() throws Exception {
+ final COPSDecisionMsg msg = new COPSDecisionMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData()), staticDecisions, new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(24, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: UNSOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: DEC", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSDecisionMsg error object with the minimal necessary attributes.
+ * It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteErrorMin() throws Exception {
+ final COPSDecisionMsg msg = new COPSDecisionMsg(2, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData("12345")), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.COMM_FAILURE),
+ null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSDecisionMsg error object with all valid attributes.
+ * It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteErrorWithIntegrity() throws Exception {
+ final COPSDecisionMsg msg = new COPSDecisionMsg(2, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData("12345")), new COPSError(ErrorTypes.AUTH_FAILURE, ErrorTypes.COMM_FAILURE),
+ new COPSIntegrity(2, 3, new COPSData("123456")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSDecisionMsg error object with all valid attributes.
+ * It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteDecisionsWithIntegrity() throws Exception {
+ final Map<COPSContext, Set<COPSDecision>> decisions = new HashMap<>();
+ final COPSContext context1 = new COPSContext(RType.CONFIG, (short)1);
+ final Set<COPSDecision> decisions1 = new HashSet<>();
+ decisions1.add(new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData("12345")));
+ decisions1.add(new COPSDecision(CType.NAMED, Command.NULL, DecisionFlag.REQSTATE, new COPSData("123456")));
+ decisions.put(context1, decisions1);
+
+ final COPSContext context2 = new COPSContext(RType.IN_ADMIN, (short)2);
+ final Set<COPSDecision> decisions2 = new HashSet<>();
+ decisions2.add(new COPSDecision(CType.STATELESS, Command.REMOVE, DecisionFlag.REQERROR, new COPSData("1234567")));
+ decisions.put(context2, decisions2);
+
+ final COPSDecisionMsg msg = new COPSDecisionMsg(2, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData("12345")), decisions, new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSDecision class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSDecisionTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullCommand() {
+ new COPSDecision(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullCType() {
+ new COPSDecision(null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NaCType() {
+ new COPSDecision(CType.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullData() {
+ new COPSDecision(CType.DEF, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor3NullCommand() {
+ new COPSDecision(null, DecisionFlag.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor3NullDecisionFlag() {
+ new COPSDecision(Command.INSTALL, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor4NullCType() {
+ new COPSDecision(null, Command.INSTALL, DecisionFlag.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor4NaCType() {
+ new COPSDecision(CType.NA, Command.INSTALL, DecisionFlag.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor4NullCommand() {
+ new COPSDecision(CType.CSI, null, DecisionFlag.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor4NullFlags() {
+ new COPSDecision(CType.CSI, Command.INSTALL, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor5NullCType() {
+ final CType cType = null;
+ new COPSDecision(cType, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor5NaCType() {
+ new COPSDecision(CType.NA, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor5NullCommand() {
+ new COPSDecision(CType.CSI, null, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor5NullFlags() {
+ new COPSDecision(CType.CSI, Command.INSTALL, null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor5NullData() {
+ new COPSDecision(CType.CSI, Command.INSTALL, DecisionFlag.NA, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor6NullHeader() {
+ final COPSObjHeader hdr = null;
+ new COPSDecision(hdr, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor6InvalidCNum() {
+ new COPSDecision(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), Command.INSTALL, DecisionFlag.NA,
+ new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor6NullCommand() {
+ new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), null, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor6NullDecison() {
+ new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), Command.INSTALL, null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor6NullData() {
+ new COPSDecision(new COPSObjHeader(CNum.DEC, CType.CSI), Command.INSTALL, DecisionFlag.NA, null);
+ }
+
+ @Test
+ public void constructor1CommandInstall() throws Exception {
+ final COPSDecision decision = new COPSDecision(Command.INSTALL);
+ Assert.assertEquals(Command.INSTALL, decision.getCommand());
+ Assert.assertEquals(4, decision.getDataLength());
+ Assert.assertEquals(new COPSData(), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: INSTALL", lines[4]);
+ Assert.assertEquals("Command flags: NA", lines[5]);
+ }
+
+ @Test
+ public void constructor1CommandRemove() throws Exception {
+ final COPSDecision decision = new COPSDecision(Command.REMOVE);
+ Assert.assertEquals(Command.REMOVE, decision.getCommand());
+ Assert.assertEquals(4, decision.getDataLength());
+ Assert.assertEquals(new COPSData(), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: REMOVE", lines[4]);
+ Assert.assertEquals("Command flags: NA", lines[5]);
+ }
+
+ @Test
+ public void constructor2ValidCTypeEmptyData() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData());
+ Assert.assertEquals(Command.NULL, decision.getCommand());
+ Assert.assertEquals(4, decision.getDataLength());
+ Assert.assertEquals(new COPSData(), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: NULL", lines[4]);
+ Assert.assertEquals("Command flags: NA", lines[5]);
+ }
+
+ @Test
+ public void constructor2ValidCTypeDefUnpaddedData() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData("1234"));
+ Assert.assertEquals(Command.NULL, decision.getCommand());
+ Assert.assertEquals(8, decision.getDataLength());
+ Assert.assertEquals(new COPSData("1234"), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: NULL", lines[4]);
+ Assert.assertEquals("Command flags: NA", lines[5]);
+ }
+
+ @Test
+ public void constructor2ValidCTypeDefPaddedData() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.DEF, new COPSData("12345"));
+ Assert.assertEquals(Command.NULL, decision.getCommand());
+ Assert.assertEquals(12, decision.getDataLength());
+ Assert.assertEquals(new COPSData("12345"), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: NULL", lines[4]);
+ Assert.assertEquals("Command flags: NA", lines[5]);
+ }
+
+ @Test
+ public void constructor2ValidCTypeNamedPaddedData() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.NAMED, new COPSData("12345"));
+ Assert.assertEquals(Command.NULL, decision.getCommand());
+ Assert.assertEquals(12, decision.getDataLength());
+ Assert.assertEquals(new COPSData("12345"), decision.getData());
+ Assert.assertEquals(DecisionFlag.NA, decision.getFlag());
+ Assert.assertEquals("Named decision data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: NAMED", lines[2]);
+ Assert.assertEquals("Decision (Named decision data)", lines[3]);
+ Assert.assertEquals("Data: 12345", lines[4]);
+ }
+
+ @Test
+ public void constructor3Valid() throws Exception {
+ final COPSDecision decision = new COPSDecision(Command.INSTALL, DecisionFlag.REQERROR);
+ Assert.assertEquals(Command.INSTALL, decision.getCommand());
+ Assert.assertEquals(4, decision.getDataLength());
+ Assert.assertEquals(new COPSData(), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag());
+ Assert.assertEquals("Default", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Decision (Default)", lines[3]);
+ Assert.assertEquals("Command code: INSTALL", lines[4]);
+ Assert.assertEquals("Command flags: REQERROR", lines[5]);
+ }
+
+ @Test
+ public void constructor4Valid() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.NAMED, Command.REMOVE, DecisionFlag.REQSTATE);
+ Assert.assertEquals(Command.REMOVE, decision.getCommand());
+ Assert.assertEquals(4, decision.getDataLength());
+ Assert.assertEquals(new COPSData(), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag());
+ Assert.assertEquals("Named decision data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: NAMED", lines[2]);
+ Assert.assertEquals("Decision (Named decision data)", lines[3]);
+ Assert.assertEquals("Data: ", lines[4]);
+ }
+
+ @Test
+ public void constructor5Valid() throws Exception {
+ final COPSDecision decision = new COPSDecision(CType.CSI, Command.REMOVE, DecisionFlag.REQSTATE,
+ new COPSData("1234"));
+ Assert.assertEquals(Command.REMOVE, decision.getCommand());
+ Assert.assertEquals(8, decision.getDataLength());
+ Assert.assertEquals(new COPSData("1234"), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag());
+ Assert.assertEquals("Client specific decision data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: CSI", lines[2]);
+ Assert.assertEquals("Decision (Client specific decision data)", lines[3]);
+ Assert.assertEquals("Data: 1234", lines[4]);
+ }
+
+ @Test
+ public void constructor6Valid() throws Exception {
+ final COPSDecision decision = new COPSDecision(new COPSObjHeader(CNum.DEC, CType.STATELESS), Command.INSTALL,
+ DecisionFlag.REQERROR, new COPSData("1234"));
+ Assert.assertEquals(Command.INSTALL, decision.getCommand());
+ Assert.assertEquals(8, decision.getDataLength());
+ Assert.assertEquals(new COPSData("1234"), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag());
+ Assert.assertEquals("Stateless data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Decision**", lines[0]);
+ Assert.assertEquals("C-num: DEC", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Decision (Stateless data)", lines[3]);
+ Assert.assertEquals("Data: 1234", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+import org.umu.cops.stack.COPSReason.ReasonCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSDeleteMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSDeleteMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSDeleteMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSDeleteMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSDeleteMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandle() {
+ new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null,
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullReasonType() {
+ new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSDeleteMsg(hdr, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ new COPSDeleteMsg(hdr, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSDeleteMsg msg = new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), msg.getReason());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() {
+ final COPSDeleteMsg msg = new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), msg.getReason());
+ Assert.assertEquals(new COPSIntegrity(4, 5, new COPSData("123456")), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSDeleteMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSDeleteMsg msg = new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(20, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: DRQ", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSDeleteMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSDeleteMsg msg = new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA), null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSDeleteMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSDeleteMsg msg = new COPSDeleteMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.NA),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSError.ErrorTypes;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSError class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSErrorTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorCode() {
+ new COPSError(null, ErrorTypes.AUTH_FAILURE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidErrorCode() {
+ new COPSError(ErrorTypes.NA, ErrorTypes.AUTH_FAILURE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullErrorSubCode() {
+ new COPSError(ErrorTypes.AUTH_FAILURE, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSError(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ErrorTypes.AUTH_FAILURE, ErrorTypes.BAD_HANDLE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSError(new COPSObjHeader(CNum.ERROR, CType.CSI), ErrorTypes.NA, ErrorTypes.BAD_HANDLE);
+ }
+
+ @Test
+ public void valid1() throws Exception {
+ final COPSError error = new COPSError(ErrorTypes.BAD_HANDLE, ErrorTypes.NA);
+ Assert.assertEquals(ErrorTypes.BAD_HANDLE, error.getErrCode());
+ Assert.assertEquals(ErrorTypes.NA, error.getErrSubCode());
+ Assert.assertEquals(4, error.getDataLength());
+ Assert.assertEquals("Bad handle.:", error.getDescription());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ error.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Error**", lines[0]);
+ Assert.assertEquals("C-num: ERROR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Error Code: BAD_HANDLE", lines[3]);
+ Assert.assertEquals("Error Sub Code: NA", lines[4]);
+ }
+
+ @Test
+ public void valid2() throws Exception {
+ final COPSError error = new COPSError(ErrorTypes.AUTH_REQUIRED, ErrorTypes.FAIL_PROCESS);
+ Assert.assertEquals(ErrorTypes.AUTH_REQUIRED, error.getErrCode());
+ Assert.assertEquals(ErrorTypes.FAIL_PROCESS, error.getErrSubCode());
+ Assert.assertEquals(4, error.getDataLength());
+ Assert.assertEquals("Authentication required.:", error.getDescription());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ error.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Error**", lines[0]);
+ Assert.assertEquals("C-num: ERROR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Error Code: AUTH_REQUIRED", lines[3]);
+ Assert.assertEquals("Error Sub Code: FAIL_PROCESS", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
public void constructWithDefaultId() {
final COPSData id = new COPSData();
final COPSHandle handle = new COPSHandle(id);
- Assert.assertEquals(4, handle.getDataLength());
+ Assert.assertEquals(0, handle.getDataLength());
Assert.assertTrue(id.equals(handle.getId()));
- validateSuperMethods(handle);
final COPSHandle eqHash = new COPSHandle(id);
Assert.assertTrue(handle.equals(eqHash));
@Test
public void constructWithData() {
- final COPSData id = new COPSData("12345678");
+ final COPSData id = new COPSData("12345");
final COPSHandle handle = new COPSHandle(id);
// TODO - need to determine if 12 is indeed correct given the value "123456778"
- Assert.assertEquals(12, handle.getDataLength());
+ Assert.assertEquals(8, handle.getDataLength());
Assert.assertTrue(id.equals(handle.getId()));
- validateSuperMethods(handle);
final COPSHandle eqHash = new COPSHandle(id);
Assert.assertTrue(handle.equals(eqHash));
Assert.assertEquals(handle.hashCode(), eqHash.hashCode());
}
- private void validateSuperMethods(final COPSHandle handle) {
- Assert.assertTrue(handle.isClientHandle());
- Assert.assertFalse(handle.isMessageIntegrity());
- Assert.assertFalse(handle.isClientSI());
- Assert.assertFalse(handle.isContext());
- Assert.assertFalse(handle.isCOPSHeader());
- Assert.assertFalse(handle.isDecision());
- Assert.assertFalse(handle.isError());
- Assert.assertFalse(handle.isInterface());
- Assert.assertFalse(handle.isLocalDecision());
- Assert.assertFalse(handle.isPdpAddress());
- Assert.assertFalse(handle.isPepId());
- Assert.assertFalse(handle.isReason());
- Assert.assertFalse(handle.isReport());
- Assert.assertFalse(handle.isTimer());
- }
}
+++ /dev/null
-package org.umu.cops.stack;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-/**
- * Tests for the second constructor of the COPSHandle class.
- * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSHandle had been
- * released and my assumptions may be incorrect.
- */
-public class COPSHandleSecondConstructorTest {
-
- @Test(expected = IllegalArgumentException.class)
- public void nullBytes() {
- final byte[] bytes = null;
- new COPSHandle(bytes);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void emptyBytes() {
- new COPSHandle(new byte[]{});
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void oneByte() {
- new COPSHandle(new byte[]{(byte)1});
- }
-
-// @Test
- // TODO - Determine what values this byte array should contain??? As written, an exception is thrown in COPSData
- // TODO - when attempting to set the _len attribute.
- public void fourBytes() {
- final byte[] bytes = new byte[]{(byte)1, (byte)2, (byte)3, (byte)4, (byte)5};
- final COPSHandle handle = new COPSHandle(bytes);
- Assert.assertEquals(4, handle.getDataLength());
- Assert.fail("Implement me");
- }
-
- // TODO - implement more tests once we can determine how exactly to properly instantiate a COPSHandle object
-
-}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSHandle class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSHandle had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSHandleTest {
+
+ private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.HANDLE, CType.DEF);
+
+ @Test (expected = IllegalArgumentException.class)
+ public void constructWithNullId() {
+ final COPSData id = null;
+ new COPSHandle(id);
+ }
+
+ @Test
+ public void constructWithDefaultId() {
+ final COPSData id = new COPSData();
+ final COPSHandle handle = new COPSHandle(id);
+
+ Assert.assertEquals(defaultHeader, handle.getHeader());
+ Assert.assertEquals(0, handle.getDataLength());
+ Assert.assertTrue(id.equals(handle.getId()));
+
+ final COPSHandle eqHash = new COPSHandle(id);
+ Assert.assertTrue(handle.equals(eqHash));
+ Assert.assertEquals(handle.hashCode(), eqHash.hashCode());
+ }
+
+ @Test
+ public void constructWithDataNoPadding() {
+ final COPSData id = new COPSData("12345678");
+ final COPSHandle handle = new COPSHandle(id);
+
+ Assert.assertEquals(defaultHeader, handle.getHeader());
+ Assert.assertEquals(8, handle.getDataLength());
+ Assert.assertTrue(id.equals(handle.getId()));
+
+ final COPSHandle eqHash = new COPSHandle(id);
+ Assert.assertTrue(handle.equals(eqHash));
+ Assert.assertEquals(handle.hashCode(), eqHash.hashCode());
+ }
+
+ @Test
+ public void constructWithDataWithPadding() {
+ final COPSData id = new COPSData("123456789");
+ final COPSHandle handle = new COPSHandle(id);
+
+ Assert.assertEquals(defaultHeader, handle.getHeader());
+ Assert.assertEquals(12, handle.getDataLength());
+ Assert.assertTrue(id.equals(handle.getId()));
+
+ final COPSHandle eqHash = new COPSHandle(id);
+ Assert.assertTrue(handle.equals(eqHash));
+ Assert.assertEquals(handle.hashCode(), eqHash.hashCode());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructWithNullHeader() {
+ new COPSHandle(null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructWithHeaderInvalidCNum() {
+ new COPSHandle(new COPSObjHeader(CNum.KA, CType.DEF), new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructWithHeaderInvalidCType() {
+ new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.REPL), new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructWithNullData() {
+ new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.DEF), null);
+ }
+
+ @Test
+ public void constructWithHeaderValidCTypeAndDump() throws Exception {
+ final COPSHandle handle = new COPSHandle(new COPSObjHeader(CNum.HANDLE, CType.DEF), new COPSData());
+ Assert.assertEquals(new COPSObjHeader(CNum.HANDLE, CType.DEF), handle.getHeader());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ handle.dump(os);
+ final String out = new String(os.toByteArray());
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Client-handle**", lines[0]);
+ Assert.assertEquals("C-num: HANDLE", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("client-handle: ", lines[3]);
+ System.out.println(out);
+ os.close();
+ }
+
+ @Test
+ public void dumpNoPadding() throws Exception {
+ final COPSHandle handle = new COPSHandle(new COPSData("12345678"));
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ handle.dump(os);
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Client-handle**", lines[0]);
+ Assert.assertEquals("C-num: HANDLE", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("client-handle: 12345678", lines[3]);
+ os.close();
+ }
+
+ @Test
+ public void dumpWithPadding() throws Exception {
+ final COPSData id = new COPSData("123456789");
+ final COPSHandle handle = new COPSHandle(id);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ handle.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Client-handle**", lines[0]);
+ Assert.assertEquals("C-num: HANDLE", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("client-handle: 123456789", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+/**
+ * Tests the construction of the COPSHeader class
+ */
+public class COPSHeaderTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullOPCode1() {
+ new COPSHeader(null, IPCMMClient.CLIENT_TYPE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void zeroVersion() {
+ new COPSHeader(0, Flag.UNSOLICITED, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlags() {
+ new COPSHeader(1, null, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullOPCode2() {
+ new COPSHeader(1, Flag.UNSOLICITED, null, IPCMMClient.CLIENT_TYPE);
+ }
+
+ @Test
+ public void validConstructor1() {
+ final COPSHeader header = new COPSHeader(OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ Assert.assertEquals(1, header.getPcmmVersion());
+ Assert.assertEquals(Flag.UNSOLICITED, header.getFlag());
+ Assert.assertEquals(OPCode.CAT, header.getOpCode());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, header.getClientType());
+ }
+
+ @Test
+ public void validConstructor2() {
+ final COPSHeader header = new COPSHeader(2, Flag.SOLICITED, OPCode.DEC, IPCMMClient.CLIENT_TYPE);
+ Assert.assertEquals(2, header.getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, header.getFlag());
+ Assert.assertEquals(OPCode.DEC, header.getOpCode());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, header.getClientType());
+ }
+
+ // writeData() will be tested implicitly via the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSError class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIntegrityTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSIntegrity(new COPSObjHeader(CNum.NA, CType.DEF), 0, 0, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.NA), 0, 0, new COPSData());
+ }
+
+ @Test
+ public void defaultConstructor() throws Exception {
+ final COPSIntegrity integrity = new COPSIntegrity();
+ Assert.assertEquals(0, integrity.getKeyId());
+ Assert.assertEquals(0, integrity.getSeqNum());
+ Assert.assertEquals(new COPSData(), integrity.getKeyDigest());
+ Assert.assertEquals(8, integrity.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ integrity.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Message-Integrity**", lines[0]);
+ Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Key Id: 0", lines[3]);
+ Assert.assertEquals("Sequence: 0", lines[4]);
+ Assert.assertEquals("Key digest: ", lines[5]);
+ }
+
+ @Test
+ public void nullData() {
+ final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 1, 2, null);
+ Assert.assertEquals(1, integrity.getKeyId());
+ Assert.assertEquals(2, integrity.getSeqNum());
+ Assert.assertEquals(new COPSData(), integrity.getKeyDigest());
+ }
+
+ @Test
+ public void protectedConstructorNoPadding() throws Exception {
+ final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 5, 6,
+ new COPSData("1234"));
+ Assert.assertEquals(5, integrity.getKeyId());
+ Assert.assertEquals(6, integrity.getSeqNum());
+ Assert.assertEquals(new COPSData("1234"), integrity.getKeyDigest());
+ Assert.assertEquals(12, integrity.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ integrity.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Message-Integrity**", lines[0]);
+ Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Key Id: 5", lines[3]);
+ Assert.assertEquals("Sequence: 6", lines[4]);
+ Assert.assertEquals("Key digest: 1234", lines[5]);
+ }
+
+ @Test
+ public void protectedConstructorWithPadding() throws Exception {
+ final COPSIntegrity integrity = new COPSIntegrity(new COPSObjHeader(CNum.MSG_INTEGRITY, CType.DEF), 5, 6,
+ new COPSData("12345"));
+ Assert.assertEquals(5, integrity.getKeyId());
+ Assert.assertEquals(6, integrity.getSeqNum());
+ Assert.assertEquals(new COPSData("12345"), integrity.getKeyDigest());
+ Assert.assertEquals(16, integrity.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ integrity.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Message-Integrity**", lines[0]);
+ Assert.assertEquals("C-num: MSG_INTEGRITY", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Key Id: 5", lines[3]);
+ Assert.assertEquals("Sequence: 6", lines[4]);
+ Assert.assertEquals("Key digest: 12345", lines[5]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the COPSIpv4Address class.
+ */
+public class COPSIpv4AddressTest {
+
+ @Test(expected = UnknownHostException.class)
+ public void badHost() throws Exception {
+ new COPSIpv4Address("foo");
+ }
+
+ @Test
+ public void localhost() throws Exception {
+ final COPSIpv4Address address = new COPSIpv4Address("localhost");
+ Assert.assertEquals(4, address.getDataLength());
+ Assert.assertArrayEquals(InetAddress.getByName("localhost").getAddress(), address.getAddressBytes());
+ Assert.assertEquals("localhost", address.getIpName());
+ }
+
+ @Test
+ public void addrBytes() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ final COPSIpv4Address address = new COPSIpv4Address(addr);
+ Assert.assertEquals(4, address.getDataLength());
+ Assert.assertArrayEquals(addr, address.getAddressBytes());
+ Assert.assertEquals("localhost", address.getIpName());
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSIpv4InInterface class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv4InInterfaceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddress() {
+ new COPSIpv4InInterface(null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() throws Exception {
+ new COPSIpv4InInterface(null, new COPSIpv4Address("localhost"), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddressWithHeader() {
+ new COPSIpv4InInterface(new COPSObjHeader(CNum.ININTF, CType.DEF), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSIpv4InInterface(new COPSObjHeader(CNum.HANDLE, CType.DEF), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSIpv4InInterface(new COPSObjHeader(CNum.ININTF, CType.STATELESS), null, 0);
+ }
+
+ @Test
+ public void valid() throws Exception {
+ final COPSIpv4Address address = new COPSIpv4Address("localhost");
+ final COPSIpv4InInterface intf = new COPSIpv4InInterface(address, 5);
+ Assert.assertEquals(new COPSObjHeader(CNum.ININTF, CType.DEF), intf.getHeader());
+ Assert.assertEquals(8, intf.getDataLength());
+ Assert.assertEquals(address, intf._addr);
+ Assert.assertEquals(5, intf._ifindex);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ intf.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**In-Interface**", lines[0]);
+ Assert.assertEquals("C-num: ININTF", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Address: localhost", lines[3]);
+ Assert.assertEquals("ifindex: 5", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the first constructor of the COPSIpv4LastPdpAddr class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv4LastPdpAddrTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHost() throws Exception {
+ new COPSIpv4LastPdpAddr(null, 1234, (short)0);
+ }
+
+ @Test(expected = UnknownHostException.class)
+ public void invalidHost() throws Exception {
+ new COPSIpv4LastPdpAddr("foo", 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidPort() throws Exception {
+ new COPSIpv4LastPdpAddr("localhost", 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor1() throws Exception {
+ final COPSIpv4LastPdpAddr lastAddr = new COPSIpv4LastPdpAddr("localhost", 1234, (short)0);
+ Assert.assertEquals(8, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Last PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Ipv4LastPdpAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullObjHeader() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4LastPdpAddr(null, addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddr() throws Exception {
+ new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), null, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void zeroPort() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), addr, 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor2() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ final COPSIpv4LastPdpAddr lastAddr = new COPSIpv4LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF),
+ addr, 1234, (short)0);
+ Assert.assertEquals(8, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Last PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Ipv4LastPdpAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSIpv4OutInterfaceTest class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv4OutInterfaceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddress() {
+ new COPSIpv4OutInterface(null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() throws Exception {
+ new COPSIpv4OutInterface(null, new COPSIpv4Address("localhost"), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddressWithHeader() {
+ new COPSIpv4OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.DEF), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSIpv4OutInterface(new COPSObjHeader(CNum.HANDLE, CType.DEF), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSIpv4OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), null, 0);
+ }
+
+ @Test
+ public void valid() throws Exception {
+ final COPSIpv4Address address = new COPSIpv4Address("localhost");
+ final COPSIpv4OutInterface intf = new COPSIpv4OutInterface(address, 5);
+ Assert.assertEquals(new COPSObjHeader(CNum.OUTINTF, CType.DEF), intf.getHeader());
+ Assert.assertEquals(8, intf.getDataLength());
+ Assert.assertEquals(address, intf._addr);
+ Assert.assertEquals(5, intf._ifindex);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ intf.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Out-Interface**", lines[0]);
+ Assert.assertEquals("C-num: OUTINTF", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Address: localhost", lines[3]);
+ Assert.assertEquals("ifindex: 5", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the first constructor of the COPSIpv4PdpRedirectAddress class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv4PdpRedirectAddressTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHost() throws Exception {
+ new COPSIpv4PdpRedirectAddress(null, 1234, (short)0);
+ }
+
+ @Test(expected = UnknownHostException.class)
+ public void invalidHost() throws Exception {
+ new COPSIpv4PdpRedirectAddress("foo", 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidPort() throws Exception {
+ new COPSIpv4PdpRedirectAddress("localhost", 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor1() throws Exception {
+ final COPSIpv4PdpRedirectAddress lastAddr = new COPSIpv4PdpRedirectAddress("localhost", 1234, (short)0);
+ Assert.assertEquals(8, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Redirect PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: PDP_REDIR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Ipv4PdpRedirectAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullObjHeader() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4PdpRedirectAddress(null, addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddr() throws Exception {
+ new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), null, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void zeroPort() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), addr, 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor2() throws Exception {
+ final byte[] addr = InetAddress.getByName("localhost").getAddress();
+ final COPSIpv4PdpRedirectAddress lastAddr = new COPSIpv4PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF),
+ addr, 1234, (short)0);
+ Assert.assertEquals(8, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Redirect PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: PDP_REDIR", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Ipv4PdpRedirectAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the COPSIpv6Address class.
+ */
+public class COPSIpv6AddressTest {
+
+ @Test(expected = UnknownHostException.class)
+ public void badHost() throws Exception {
+ new COPSIpv6Address("foo");
+ }
+
+ @Test
+ public void localhost() throws Exception {
+ final COPSIpv6Address address = new COPSIpv6Address("localhost");
+ Assert.assertEquals(16, address.getDataLength());
+ Assert.assertArrayEquals(getLocalhostIpv6Address(), address.getAddressBytes());
+ Assert.assertEquals("localhost", address.getIpName());
+ }
+
+ @Test
+ public void addrBytes() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ final COPSIpv6Address address = new COPSIpv6Address(addr);
+ Assert.assertEquals(16, address.getDataLength());
+ Assert.assertArrayEquals(addr, address.getAddressBytes());
+ Assert.assertEquals("localhost", address.getIpName());
+ }
+
+ private byte[] getLocalhostIpv6Address() throws UnknownHostException {
+ final InetAddress[] addrs = Inet4Address.getAllByName("localhost");
+ for (final InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ return addr.getAddress();
+ }
+ }
+ throw new UnknownHostException("InetAddress could not be found");
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSIpv6InInterface class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv6InInterfaceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddress() {
+ new COPSIpv6InInterface(null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() throws Exception {
+ new COPSIpv6InInterface(null, new COPSIpv6Address("localhost"), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddressWithHeader() {
+ new COPSIpv6InInterface(new COPSObjHeader(CNum.ININTF, CType.STATELESS), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSIpv6InInterface(new COPSObjHeader(CNum.HANDLE, CType.STATELESS), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSIpv6InInterface(new COPSObjHeader(CNum.ININTF, CType.DEF), null, 0);
+ }
+
+ @Test
+ public void valid() throws Exception {
+ final COPSIpv6Address address = new COPSIpv6Address("localhost");
+ final COPSIpv6InInterface intf = new COPSIpv6InInterface(address, 5);
+ Assert.assertEquals(new COPSObjHeader(CNum.ININTF, CType.STATELESS), intf.getHeader());
+ Assert.assertEquals(20, intf.getDataLength());
+ Assert.assertEquals(address, intf._addr);
+ Assert.assertEquals(5, intf._ifindex);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ intf.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**In-Interface**", lines[0]);
+ Assert.assertEquals("C-num: ININTF", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Address: localhost", lines[3]);
+ Assert.assertEquals("ifindex: 5", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the first constructor of the COPSIpv6PdpRedirectAddress class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv6LastPdpAddrTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHost() throws Exception {
+ new COPSIpv6LastPdpAddr(null, 1234, (short)0);
+ }
+
+ @Test(expected = UnknownHostException.class)
+ public void invalidHost() throws Exception {
+ new COPSIpv6LastPdpAddr("foo", 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidPort() throws Exception {
+ new COPSIpv6LastPdpAddr("localhost", 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor1() throws Exception {
+ final COPSIpv6LastPdpAddr lastAddr = new COPSIpv6LastPdpAddr("localhost", 1234, (short)0);
+ Assert.assertEquals(20, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Last PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Ipv6LastPdpAddr", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullObjHeader() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6LastPdpAddr(null, addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.ACCT_TIMER, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.DEF), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddr() throws Exception {
+ new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), null, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void ipv4Addr() throws Exception {
+ final byte[] addr = new byte[] { 127, 0, 0, 1};
+ new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void zeroPort() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), addr, 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor2() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ final COPSIpv6LastPdpAddr lastAddr = new COPSIpv6LastPdpAddr(new COPSObjHeader(CNum.LAST_PDP_ADDR,
+ CType.STATELESS), addr, 1234, (short)0);
+ Assert.assertEquals(20, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.LAST_PDP_ADDR, CType.STATELESS), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Last PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: LAST_PDP_ADDR", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Ipv6LastPdpAddr", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+
+ private byte[] getLocalhostIpv6Address() throws UnknownHostException {
+ final InetAddress[] addrs = Inet4Address.getAllByName("localhost");
+ for (final InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ return addr.getAddress();
+ }
+ }
+ throw new UnknownHostException("InetAddress could not be found");
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSIpv6OutInterfaceTest class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv6OutInterfaceTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddress() {
+ new COPSIpv6OutInterface(null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() throws Exception {
+ new COPSIpv6OutInterface(null, new COPSIpv6Address("localhost"), 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddressWithHeader() {
+ new COPSIpv6OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSIpv6OutInterface(new COPSObjHeader(CNum.HANDLE, CType.STATELESS), null, 0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSIpv6OutInterface(new COPSObjHeader(CNum.OUTINTF, CType.DEF), null, 0);
+ }
+
+ @Test
+ public void valid() throws Exception {
+ final COPSIpv6Address address = new COPSIpv6Address("localhost");
+ final COPSIpv6OutInterface intf = new COPSIpv6OutInterface(address, 5);
+ Assert.assertEquals(new COPSObjHeader(CNum.OUTINTF, CType.STATELESS), intf.getHeader());
+ Assert.assertEquals(20, intf.getDataLength());
+ Assert.assertEquals(address, intf._addr);
+ Assert.assertEquals(5, intf._ifindex);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ intf.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Out-Interface**", lines[0]);
+ Assert.assertEquals("C-num: OUTINTF", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Address: localhost", lines[3]);
+ Assert.assertEquals("ifindex: 5", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * Tests for the first constructor of the COPSIpv6PdpRedirectAddress class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSIpv6PdpRedirectAddressTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHost() throws Exception {
+ new COPSIpv6PdpRedirectAddress(null, 1234, (short)0);
+ }
+
+ @Test(expected = UnknownHostException.class)
+ public void invalidHost() throws Exception {
+ new COPSIpv6PdpRedirectAddress("foo", 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidPort() throws Exception {
+ new COPSIpv6PdpRedirectAddress("localhost", 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor1() throws Exception {
+ final COPSIpv6PdpRedirectAddress lastAddr = new COPSIpv6PdpRedirectAddress("localhost", 1234, (short)0);
+ Assert.assertEquals(20, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Redirect PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: PDP_REDIR", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Ipv6PdpRedirectAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullObjHeader() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6PdpRedirectAddress(null, addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.ACCT_TIMER, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.DEF), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullAddr() throws Exception {
+ new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), null, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void ipv4Addr() throws Exception {
+ final byte[] addr = new byte[] { 127, 0, 0, 1};
+ new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 1234, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void zeroPort() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), addr, 0, (short)0);
+ }
+
+ @Test
+ public void validConstructor2() throws Exception {
+ final byte[] addr = getLocalhostIpv6Address();
+ final COPSIpv6PdpRedirectAddress lastAddr = new COPSIpv6PdpRedirectAddress(new COPSObjHeader(CNum.PDP_REDIR,
+ CType.STATELESS), addr, 1234, (short)0);
+ Assert.assertEquals(20, lastAddr.getDataLength());
+ Assert.assertEquals(new COPSObjHeader(CNum.PDP_REDIR, CType.STATELESS), lastAddr.getHeader());
+ Assert.assertEquals(1234, lastAddr.getTcpPort());
+ Assert.assertEquals(0, lastAddr.getReserved());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ lastAddr.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(6, lines.length);
+ Assert.assertEquals("**Redirect PDP addr**", lines[0]);
+ Assert.assertEquals("C-num: PDP_REDIR", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Ipv6PdpRedirectAddress", lines[3]);
+ Assert.assertEquals("Address: localhost", lines[4]);
+ Assert.assertEquals("Port: 1234", lines[5]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+
+ private byte[] getLocalhostIpv6Address() throws UnknownHostException {
+ final InetAddress[] addrs = Inet4Address.getAllByName("localhost");
+ for (final InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ return addr.getAddress();
+ }
+ }
+ throw new UnknownHostException("InetAddress could not be found");
+ }
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSKAMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSKAMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSKAMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSKAMsg(0, Flag.SOLICITED, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSKAMsg(1, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSKAMsg(hdr, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.NA, IPCMMClient.CLIENT_TYPE);
+ new COPSKAMsg(hdr, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSKAMsg msg = new COPSKAMsg(1, Flag.SOLICITED, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals((short)0, msg.getHeader().getClientType());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() throws Exception {
+ final COPSKAMsg msg = new COPSKAMsg(1, Flag.SOLICITED, new COPSIntegrity());
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals((short)0, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSIntegrity(), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSKAMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSKAMsg msg = new COPSKAMsg(1, Flag.SOLICITED, new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(11, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: KA", lines[3]);
+ Assert.assertEquals("Client-type: 0", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSKAMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSKAMsg msg = new COPSKAMsg(1, Flag.SOLICITED, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSKAMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSKAMsg msg = new COPSKAMsg(1, Flag.SOLICITED, new COPSIntegrity(8, 9, new COPSData("12345")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSKATimer class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSKATimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSKATimerTest {
+
+ private final static COPSObjHeader defaultHeader = new COPSObjHeader(CNum.KA, CType.DEF);
+
+ @Test
+ public void testValidTimeAndDefaultHeader() {
+ final COPSKATimer timer = new COPSKATimer((short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(defaultHeader, timer.getHeader());
+ }
+
+ @Test
+ public void testValidTimeReservedAndDefaultHeader() {
+ final COPSKATimer timer = new COPSKATimer((short) 4, (short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(defaultHeader, timer.getHeader());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidCNum() {
+ new COPSKATimer(new COPSObjHeader(CNum.CONTEXT, CType.DEF), (short) 4, (short)10);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidCType() {
+ new COPSKATimer(new COPSObjHeader(CNum.KA, CType.REPL), (short) 4, (short)10);
+ }
+
+ @Test
+ public void testValidCustomHeader() {
+ final COPSKATimer timer = new COPSKATimer(new COPSObjHeader(CNum.KA, CType.DEF), (short) 4, (short)10);
+ Assert.assertEquals((short)10, timer.getTimerVal());
+ Assert.assertEquals(new COPSObjHeader(CNum.KA, CType.DEF), timer.getHeader());
+ }
+
+ @Test
+ public void testDumpDefaultHeader() throws Exception {
+ final COPSKATimer timer = new COPSKATimer((short) 4, (short)10);
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ timer.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**KA-timer**", lines[0]);
+ Assert.assertEquals("C-num: KA", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Timer val: 10", lines[3]);
+ }
+
+ @Test
+ public void testDumpCustomHeader() throws Exception {
+ final COPSKATimer timer = new COPSKATimer(new COPSObjHeader(CNum.KA, CType.DEF),
+ (short) 4, (short)100);
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ timer.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**KA-timer**", lines[0]);
+ Assert.assertEquals("C-num: KA", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Timer val: 100", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSLPDPDecision class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSLPDPDecisionTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullCType() {
+ final CType cType = null;
+ new COPSLPDPDecision(cType, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NaCType() {
+ new COPSLPDPDecision(CType.NA, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullCommand() {
+ new COPSLPDPDecision(CType.CSI, null, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullFlags() {
+ new COPSLPDPDecision(CType.CSI, Command.INSTALL, null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor1NullData() {
+ new COPSLPDPDecision(CType.CSI, Command.INSTALL, DecisionFlag.NA, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullHeader() {
+ final COPSObjHeader hdr = null;
+ new COPSLPDPDecision(hdr, Command.INSTALL, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2InvalidCNum() {
+ new COPSLPDPDecision(new COPSObjHeader(CNum.ACCT_TIMER, CType.CSI), Command.INSTALL, DecisionFlag.NA,
+ new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullCommand() {
+ new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), null, DecisionFlag.NA, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullDecison() {
+ new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), Command.INSTALL, null, new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void constructor2NullData() {
+ new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.CSI), Command.INSTALL, DecisionFlag.NA, null);
+ }
+
+ @Test
+ public void constructor1Valid() throws Exception {
+ final COPSLPDPDecision decision = new COPSLPDPDecision(CType.CSI, Command.REMOVE, DecisionFlag.REQSTATE,
+ new COPSData("1234"));
+ Assert.assertEquals(Command.REMOVE, decision.getCommand());
+ Assert.assertEquals(8, decision.getDataLength());
+ Assert.assertEquals(new COPSData("1234"), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQSTATE, decision.getFlag());
+ Assert.assertEquals("Client specific decision data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Local-Decision**", lines[0]);
+ Assert.assertEquals("C-num: LPDP_DEC", lines[1]);
+ Assert.assertEquals("C-type: CSI", lines[2]);
+ Assert.assertEquals("Decision (Client specific decision data)", lines[3]);
+ Assert.assertEquals("Data: 1234", lines[4]);
+ }
+
+ @Test
+ public void constructor2Valid() throws Exception {
+ final COPSLPDPDecision decision = new COPSLPDPDecision(new COPSObjHeader(CNum.LPDP_DEC, CType.STATELESS), Command.INSTALL,
+ DecisionFlag.REQERROR, new COPSData("1234"));
+ Assert.assertEquals(Command.INSTALL, decision.getCommand());
+ Assert.assertEquals(8, decision.getDataLength());
+ Assert.assertEquals(new COPSData("1234"), decision.getData());
+ Assert.assertEquals(DecisionFlag.REQERROR, decision.getFlag());
+ Assert.assertEquals("Stateless data", decision.getTypeStr());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ decision.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Local-Decision**", lines[0]);
+ Assert.assertEquals("C-num: LPDP_DEC", lines[1]);
+ Assert.assertEquals("C-type: STATELESS", lines[2]);
+ Assert.assertEquals("Decision (Stateless data)", lines[3]);
+ Assert.assertEquals("Data: 1234", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+
+/**
+ * Tests the public static COPSMsgParser methods
+ */
+public class COPSMsgParserTest {
+
+ @Test
+ public void testCombineTwoBytesToOne() {
+
+ byte byte1 = (byte)2;
+ byte byte2 = (byte)15;
+ byte combined = (byte)((byte1) * 16 + (byte2));
+
+ System.out.println("Combined value =" + combined + " Hex value = " + Integer.toHexString(combined) );
+
+ }
+
+ @Test
+ public void testCombineAndSplitForAllValidCombinations() {
+ for (byte byte1 = 0; byte1 < 16; byte1++ ) {
+ for (byte byte2 = 0; byte2 < 16; byte2++ ) {
+ int combined = COPSMsgParser.combineNibbles(byte1, byte2);
+ System.out.println("byte1 = " + byte1 + " byte2 = " + byte2 + " Combined value =" + combined + " Hex value = " + Integer.toHexString(combined) );
+
+ Assert.assertTrue(combined >= 0 && combined < 256);
+ byte[] nibbles = COPSMsgParser.splitByteToNibbles((byte) combined);
+
+ Assert.assertEquals("Nibble 1 value = " + nibbles[0], byte1, nibbles[0]);
+ Assert.assertEquals("Nibble 2 value = " + nibbles[1], byte2, nibbles[1]);
+ }
+ }
+ }
+
+ @Test
+ public void testBytesToShortMin() {
+ final byte byte1 = (byte)0;
+ final byte byte2 = (byte)0;
+ final short val = COPSMsgParser.bytesToShort(byte1, byte2);
+ final byte[] outBytes = COPSMsgParser.shortToBytes(val);
+ Assert.assertEquals(byte1, outBytes[0]);
+ Assert.assertEquals(byte2, outBytes[1]);
+ Assert.assertEquals(0, val);
+ }
+
+ @Test
+ public void testBytesToShortMax() {
+ final byte byte1 = (byte)255;
+ final byte byte2 = (byte)255;
+ final short val = COPSMsgParser.bytesToShort(byte1, byte2);
+ final byte[] outBytes = COPSMsgParser.shortToBytes(val);
+ Assert.assertEquals(byte1, outBytes[0]);
+ Assert.assertEquals(byte2, outBytes[1]);
+ }
+
+ @Test
+ public void testBytesToShortPCMMClientType() {
+ final byte[] outBytes = COPSMsgParser.shortToBytes(IPCMMClient.CLIENT_TYPE);
+ final short val = COPSMsgParser.bytesToShort(outBytes[0], outBytes[1]);
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, val);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCombineByte1TooBig() {
+ COPSMsgParser.combineNibbles((byte)16, (byte)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCombineByte2TooBig() {
+ COPSMsgParser.combineNibbles((byte)0, (byte)16);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCombineByte1TooSmall() {
+ COPSMsgParser.combineNibbles((byte)-1, (byte)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCombineByte2TooSmall() {
+ COPSMsgParser.combineNibbles((byte)0, (byte)-1);
+ }
+
+ // TODO - determine if tests for marshalling & un should be done with this class or implicitly via the COPSMsg objects
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSPepId class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSPepIdTest {
+
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullData() {
+ new COPSPepId(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSPepId(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), new COPSData());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSPepId(new COPSObjHeader(CNum.PEPID, CType.CSI), new COPSData());
+ }
+
+ @Test
+ public void emptyData() throws Exception {
+ final COPSPepId pepId = new COPSPepId(new COPSData());
+ Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum());
+ Assert.assertEquals(new COPSData(), pepId.getData());
+ Assert.assertEquals(0, pepId.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ pepId.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**PEP-id**", lines[0]);
+ Assert.assertEquals("C-num: PEPID", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("PEPID: ", lines[3]);
+ }
+
+ @Test
+ public void unpaddedData() throws Exception {
+ final COPSPepId pepId = new COPSPepId(new COPSData("1234"));
+ Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum());
+ Assert.assertEquals(new COPSData("1234"), pepId.getData());
+ Assert.assertEquals(4, pepId.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ pepId.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**PEP-id**", lines[0]);
+ Assert.assertEquals("C-num: PEPID", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("PEPID: 1234", lines[3]);
+ }
+
+ @Test
+ public void paddedData() throws Exception {
+ final COPSPepId pepId = new COPSPepId(new COPSData("12345"));
+ Assert.assertEquals(CNum.PEPID, pepId.getHeader().getCNum());
+ Assert.assertEquals(new COPSData("12345"), pepId.getData());
+ Assert.assertEquals(8, pepId.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ pepId.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**PEP-id**", lines[0]);
+ Assert.assertEquals("C-num: PEPID", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("PEPID: 12345", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSReason.ReasonCode;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSReason class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSReasonTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullReasonCode() {
+ new COPSReason(null, ReasonCode.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidReasonCode() {
+ new COPSReason(ReasonCode.NA, ReasonCode.MALFORMED_DEC);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullSubCode() {
+ new COPSReason(ReasonCode.MANAGEMENT, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSReason(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ReasonCode.ROUTE_CHANGE, ReasonCode.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSReason(new COPSObjHeader(CNum.REASON_CODE, CType.CSI), ReasonCode.PREEMPTED, ReasonCode.SYNC_HANDLE);
+ }
+
+ @Test
+ public void valid1() throws Exception {
+ final COPSReason reason = new COPSReason(ReasonCode.TRANS_HANDLE, ReasonCode.NA);
+ Assert.assertEquals(ReasonCode.TRANS_HANDLE, reason.getReasonCode());
+ Assert.assertEquals(ReasonCode.NA, reason.getReasonSubCode());
+ Assert.assertEquals(4, reason.getDataLength());
+ Assert.assertEquals("Transient handle.:", reason.getDescription());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ reason.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Reason**", lines[0]);
+ Assert.assertEquals("C-num: REASON_CODE", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Reason Code: TRANS_HANDLE", lines[3]);
+ Assert.assertEquals("Reason Sub Code: NA", lines[4]);
+ }
+
+ @Test
+ public void valid2() throws Exception {
+ final COPSReason reason = new COPSReason(ReasonCode.INSUFF_RESOURCES, ReasonCode.TEAR);
+ Assert.assertEquals(ReasonCode.INSUFF_RESOURCES, reason.getReasonCode());
+ Assert.assertEquals(ReasonCode.TEAR, reason.getReasonSubCode());
+ Assert.assertEquals(4, reason.getDataLength());
+ Assert.assertEquals("Insufficient Resources.:", reason.getDescription());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ reason.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(5, lines.length);
+ Assert.assertEquals("**Reason**", lines[0]);
+ Assert.assertEquals("C-num: REASON_CODE", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Reason Code: INSUFF_RESOURCES", lines[3]);
+ Assert.assertEquals("Reason Sub Code: TEAR", lines[4]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSReportMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSReportMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSReportMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSReportMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSReportMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandle() {
+ new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null,
+ new COPSReportType(ReportType.ACCOUNTING), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullReportType() {
+ new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSReportMsg(hdr, new COPSHandle(new COPSData()), new COPSReportType(ReportType.ACCOUNTING), null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ new COPSReportMsg(hdr, new COPSHandle(new COPSData()), new COPSReportType(ReportType.ACCOUNTING), null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSReportMsg msg = new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSReportType(ReportType.ACCOUNTING), msg.getReport());
+ Assert.assertNull(msg.getClientSI());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() {
+ final COPSReportMsg msg = new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), new COPSClientSI(CSIType.NAMED, new COPSData("1")),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSReportType(ReportType.ACCOUNTING), msg.getReport());
+ Assert.assertEquals(new COPSClientSI(CSIType.NAMED, new COPSData("1")), msg.getClientSI());
+ Assert.assertEquals(new COPSIntegrity(4, 5, new COPSData("123456")), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSReportMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSReportMsg msg = new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), new COPSClientSI(CSIType.NAMED, new COPSData("1")),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(24, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: RPT", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSReportMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSReportMsg msg = new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSReportMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSReportMsg msg = new COPSReportMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSReportType(ReportType.ACCOUNTING), new COPSClientSI(CSIType.NAMED, new COPSData("1")),
+ new COPSIntegrity(4, 5, new COPSData("123456")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.umu.cops.stack.COPSObjHeader.CNum;
+import org.umu.cops.stack.COPSObjHeader.CType;
+import org.umu.cops.stack.COPSReportType.ReportType;
+
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the first constructor of the COPSReportType class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSAcctTimer had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSReportTypeTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullReportType() {
+ new COPSReportType(null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidReportType() {
+ new COPSReportType(ReportType.NA);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCNum() {
+ new COPSReportType(new COPSObjHeader(CNum.ACCT_TIMER, CType.DEF), ReportType.ACCOUNTING, (short)0);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidCType() {
+ new COPSReportType(new COPSObjHeader(CNum.RPT, CType.CSI), ReportType.FAILURE, (short)0);
+ }
+
+ @Test
+ public void validSuccessRpt() throws Exception {
+ final COPSReportType reason = new COPSReportType(ReportType.SUCCESS);
+ Assert.assertEquals(ReportType.SUCCESS, reason.getReportType());
+ Assert.assertEquals(4, reason.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ reason.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Report**", lines[0]);
+ Assert.assertEquals("C-num: RPT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Report: Success.", lines[3]);
+ }
+
+ @Test
+ public void validFailureRpt() throws Exception {
+ final COPSReportType reason = new COPSReportType(ReportType.FAILURE);
+ Assert.assertEquals(ReportType.FAILURE, reason.getReportType());
+ Assert.assertEquals(4, reason.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ reason.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Report**", lines[0]);
+ Assert.assertEquals("C-num: RPT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Report: Failure.", lines[3]);
+ }
+
+ @Test
+ public void validAccountingRpt() throws Exception {
+ final COPSReportType reason = new COPSReportType(ReportType.ACCOUNTING);
+ Assert.assertEquals(ReportType.ACCOUNTING, reason.getReportType());
+ Assert.assertEquals(4, reason.getDataLength());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ reason.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(4, lines.length);
+ Assert.assertEquals("**Report**", lines[0]);
+ Assert.assertEquals("C-num: RPT", lines[1]);
+ Assert.assertEquals("C-type: DEF", lines[2]);
+ Assert.assertEquals("Report: Accounting.", lines[3]);
+ }
+
+ // The writeData() method will be tested implicitly via any of the COPSMsg tests
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSClientSI.CSIType;
+import org.umu.cops.stack.COPSContext.RType;
+import org.umu.cops.stack.COPSDecision.Command;
+import org.umu.cops.stack.COPSDecision.DecisionFlag;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+import org.umu.cops.stack.COPSObjHeader.CType;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Tests for the first constructor of the COPSReqMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSReqMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSReqMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSReqMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSContext(RType.CONFIG, (short)0), null, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSReqMsg(1, null, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSContext(RType.CONFIG, (short)0), null, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHandle() {
+ new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null,
+ new COPSContext(RType.CONFIG, (short)0), null, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullContext() {
+ new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ null, null, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSReqMsg(hdr, new COPSHandle(new COPSData()), new COPSContext(RType.CONFIG, (short)0),
+ null, null, null, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.CAT, IPCMMClient.CLIENT_TYPE);
+ new COPSReqMsg(hdr, new COPSHandle(new COPSData()), new COPSContext(RType.CONFIG, (short)0),
+ null, null, null, null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSContext(RType.CONFIG, (short)0), null, null, null, null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSContext(RType.CONFIG, (short) 0), msg.getContext());
+ Assert.assertNull(msg.getIntegrity());
+ Assert.assertNull(msg.getInInterface());
+ Assert.assertNull(msg.getOutInterface());
+ Assert.assertTrue(msg.getClientSI().isEmpty());
+ Assert.assertTrue(msg.getDecisions().isEmpty());
+ }
+
+ @Test
+ public void validAllNonCollections() throws Exception {
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSContext(RType.CONFIG, (short)0), new COPSIntegrity(),
+ new COPSIpv4InInterface(new COPSIpv4Address("localhost"), 0),
+ new COPSIpv4OutInterface(new COPSIpv4Address("localhost"), 0),
+ null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSContext(RType.CONFIG, (short)0), msg.getContext());
+ Assert.assertEquals(new COPSIntegrity(), msg.getIntegrity());
+ Assert.assertEquals(new COPSIpv4InInterface(new COPSIpv4Address("localhost"), 0), msg.getInInterface());
+ Assert.assertEquals(new COPSIpv4OutInterface(new COPSIpv4Address("localhost"), 0), msg.getOutInterface());
+ Assert.assertTrue(msg.getClientSI().isEmpty());
+ Assert.assertTrue(msg.getDecisions().isEmpty());
+ }
+
+ @Test
+ public void validNonEmptyCollections() {
+ final Set<COPSClientSI> clientSIs = new HashSet<>();
+ clientSIs.add(new COPSClientSI(CSIType.NAMED, new COPSData("1")));
+ clientSIs.add(new COPSClientSI(CSIType.SIGNALED, new COPSData("2")));
+
+ final Map<COPSContext, Set<COPSLPDPDecision>> decisions = new HashMap<>();
+ final COPSContext context1 = new COPSContext(RType.CONFIG, (short)1);
+ final Set<COPSLPDPDecision> decisions1 = new HashSet<>();
+ decisions1.add(new COPSLPDPDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData("12345")));
+ decisions1.add(new COPSLPDPDecision(CType.NAMED, Command.NULL, DecisionFlag.REQSTATE, new COPSData("123456")));
+ decisions.put(context1, decisions1);
+
+ final COPSContext context2 = new COPSContext(RType.IN_ADMIN, (short)2);
+ final Set<COPSLPDPDecision> decisions2 = new HashSet<>();
+ decisions2.add(new COPSLPDPDecision(CType.STATELESS, Command.REMOVE, DecisionFlag.REQERROR, new COPSData("1234567")));
+ decisions.put(context2, decisions2);
+
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.UNSOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData("123")),
+ new COPSContext(RType.IN_ADMIN, (short)2), null, null, null, clientSIs, decisions);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.UNSOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData("123")), msg.getClientHandle());
+ Assert.assertEquals(new COPSContext(RType.IN_ADMIN, (short) 2), msg.getContext());
+ Assert.assertNull(msg.getIntegrity());
+ Assert.assertNull(msg.getInInterface());
+ Assert.assertNull(msg.getOutInterface());
+ Assert.assertEquals(clientSIs, msg.getClientSI());
+ Assert.assertNotSame(clientSIs, msg.getClientSI());
+ Assert.assertEquals(decisions, msg.getDecisions());
+ Assert.assertNotSame(decisions, msg.getDecisions());
+ }
+
+ /**
+ * This test is responsible for creating a COPSReqMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final Set<COPSClientSI> clientSIs = new HashSet<>();
+ clientSIs.add(new COPSClientSI(CSIType.NAMED, new COPSData("1")));
+ clientSIs.add(new COPSClientSI(CSIType.SIGNALED, new COPSData("2")));
+
+ final Map<COPSContext, Set<COPSLPDPDecision>> decisions = new HashMap<>();
+ final COPSContext context1 = new COPSContext(RType.CONFIG, (short)1);
+ final Set<COPSLPDPDecision> decisions1 = new HashSet<>();
+ decisions1.add(new COPSLPDPDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData("12345")));
+ decisions1.add(new COPSLPDPDecision(CType.NAMED, Command.NULL, DecisionFlag.REQSTATE, new COPSData("123456")));
+ decisions.put(context1, decisions1);
+
+ final COPSContext context2 = new COPSContext(RType.IN_ADMIN, (short)2);
+ final Set<COPSLPDPDecision> decisions2 = new HashSet<>();
+ decisions2.add(new COPSLPDPDecision(CType.STATELESS, Command.REMOVE, DecisionFlag.REQERROR, new COPSData("1234567")));
+ decisions.put(context2, decisions2);
+
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData()),
+ new COPSContext(RType.CONFIG, (short)0), new COPSIntegrity(),
+ new COPSIpv4InInterface(new COPSIpv4Address("localhost"), 0),
+ new COPSIpv4OutInterface(new COPSIpv4Address("localhost"), 0),
+ clientSIs, decisions);
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(52, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: REQ", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSReqMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData("12345")),
+ new COPSContext(RType.CONFIG, (short)5), null,
+ null, null, null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSReqMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final Set<COPSClientSI> clientSIs = new HashSet<>();
+ clientSIs.add(new COPSClientSI(CSIType.NAMED, new COPSData("12345")));
+ clientSIs.add(new COPSClientSI(CSIType.SIGNALED, new COPSData("123456")));
+
+ final Map<COPSContext, Set<COPSLPDPDecision>> decisions = new HashMap<>();
+ final COPSContext context1 = new COPSContext(RType.CONFIG, (short)1);
+ final Set<COPSLPDPDecision> decisions1 = new HashSet<>();
+ decisions1.add(new COPSLPDPDecision(CType.CSI, Command.INSTALL, DecisionFlag.REQERROR, new COPSData("12345")));
+ decisions1.add(new COPSLPDPDecision(CType.NAMED, Command.NULL, DecisionFlag.REQSTATE, new COPSData("123456")));
+ decisions.put(context1, decisions1);
+
+ final COPSContext context2 = new COPSContext(RType.IN_ADMIN, (short)2);
+ final Set<COPSLPDPDecision> decisions2 = new HashSet<>();
+ decisions2.add(new COPSLPDPDecision(CType.STATELESS, Command.REMOVE, DecisionFlag.REQERROR, new COPSData("1234567")));
+ decisions.put(context2, decisions2);
+
+ final COPSReqMsg msg = new COPSReqMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, new COPSHandle(new COPSData("12345")),
+ new COPSContext(RType.CONFIG, (short)5), new COPSIntegrity(3, 4, new COPSData("12345")),
+ new COPSIpv4InInterface(new COPSIpv4Address("localhost"), 5),
+ new COPSIpv4OutInterface(new COPSIpv4Address("localhost"), 6),
+ clientSIs, decisions);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.pcmm.rcd.IPCMMClient;
+import org.umu.cops.stack.COPSHeader.Flag;
+import org.umu.cops.stack.COPSHeader.OPCode;
+
+import java.io.ByteArrayOutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * Tests for the first constructor of the COPSSyncStateMsg class.
+ * Should any of these tests be inaccurate it is due to the fact that they have been written after COPSSyncStateMsg had been
+ * released and my assumptions may be incorrect.
+ */
+public class COPSSyncStateMsgTest {
+
+ private final static int testPort = 7777;
+ TestCOPSServer server;
+ Socket outSocket;
+
+ @Before
+ public void setup() throws Exception {
+ server = new TestCOPSServer(testPort);
+ server.start();
+ outSocket = new Socket(InetAddress.getLocalHost(), testPort);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ outSocket.close();
+ server.close();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void version0() {
+ new COPSSyncStateMsg(0, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullFlag() {
+ new COPSSyncStateMsg(1, null, IPCMMClient.CLIENT_TYPE, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void nullHeader() {
+ final COPSHeader hdr = null;
+ new COPSSyncStateMsg(hdr, null, null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidHeader() {
+ final COPSHeader hdr = new COPSHeader(1, Flag.UNSOLICITED, OPCode.NA, IPCMMClient.CLIENT_TYPE);
+ new COPSSyncStateMsg(hdr, null, null);
+ }
+
+ @Test
+ public void validMinimal() {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null);
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertNull(msg.getClientHandle());
+ Assert.assertNull(msg.getIntegrity());
+ }
+
+ @Test
+ public void validAll() throws Exception {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData()),
+ new COPSIntegrity());
+
+ Assert.assertEquals(1, msg.getHeader().getPcmmVersion());
+ Assert.assertEquals(Flag.SOLICITED, msg.getHeader().getFlag());
+ Assert.assertEquals(IPCMMClient.CLIENT_TYPE, msg.getHeader().getClientType());
+ Assert.assertEquals(new COPSHandle(new COPSData()), msg.getClientHandle());
+ Assert.assertEquals(new COPSIntegrity(), msg.getIntegrity());
+ }
+
+ /**
+ * This test is responsible for creating a COPSSyncStateMsg object without any nulls or empty collections
+ * and then is dumped to an OutputStream.
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testDumpAll() throws Exception {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData()),
+ new COPSIntegrity());
+
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ msg.dump(os);
+
+ final String out = new String(os.toByteArray());
+ System.out.println(out);
+ final String[] lines = out.split("\n");
+ Assert.assertEquals(15, lines.length);
+
+ // Only checking COPSMsg elements as the COPSObjectMsg elements have already been validated in their own tests
+ Assert.assertEquals("**MSG HEADER**", lines[0]);
+ Assert.assertEquals("Version: 1", lines[1]);
+ Assert.assertEquals("Flags: SOLICITED", lines[2]);
+ Assert.assertEquals("OpCode: SSQ", lines[3]);
+ Assert.assertEquals("Client-type: -32758", lines[4]);
+ }
+
+ /**
+ * This test is responsible for creating a COPSSyncStateMsg object with the minimal necessary attributes to make
+ * it valid. It is then streamed over a socket (unmarshalled) then reassembled (marshalled).
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteMinimal() throws Exception {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE, null, null);
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+ /**
+ * This test is responsible for creating a COPSSyncStateMsg object without any nulls or empty collections
+ * and then is streamed over a socket (unmarshalled) then reassembled (marshalled)
+ * @throws Exception - Test should fail if any exception is thrown
+ */
+ @Test
+ public void testWriteAll() throws Exception {
+ final COPSSyncStateMsg msg = new COPSSyncStateMsg(1, Flag.SOLICITED, IPCMMClient.CLIENT_TYPE,
+ new COPSHandle(new COPSData()),
+ new COPSIntegrity(8, 9, new COPSData("12345")));
+
+ msg.writeData(outSocket);
+
+ final long start = System.currentTimeMillis();
+ while (server.copsMsgs.size() < 1) {
+ Thread.sleep(5);
+ if (System.currentTimeMillis() - start > 2000) break;
+ }
+
+ Assert.assertEquals(1, server.copsMsgs.size());
+ Assert.assertEquals(msg, server.copsMsgs.get(0));
+ }
+
+}
--- /dev/null
+package org.umu.cops.stack;
+
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Server used to test client/server socket communications.
+ */
+public class TestCOPSServer extends Thread {
+
+ private final static Logger logger = LoggerFactory.getLogger(TestCOPSServer.class);
+ private final ServerSocket serverSocket;
+ final List<COPSMsg> copsMsgs = new ArrayList<>();
+
+ public TestCOPSServer(final int port) throws IOException {
+ serverSocket = new ServerSocket(port);
+ Assert.assertTrue(serverSocket.isBound());
+ }
+
+ public void close() throws IOException {
+ this.interrupt();
+ serverSocket.close();
+ }
+
+ public void run() {
+ try {
+ final Socket socket = serverSocket.accept();
+ final COPSMsg copsMsg = COPSTransceiver.receiveMsg(socket);
+ logger.info("Read value = " + copsMsg);
+ copsMsgs.add(copsMsg);
+ socket.close();
+ } catch (Exception e) {
+ logger.error("Error processing message", e);
+ }
+
+ }
+}