/* * Copyright (c) 2004 University of Murcia. All rights reserved. * -------------------------------------------------------------- * For more information, please see . */ package org.umu.cops.prpep; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Hashtable; import org.umu.cops.stack.COPSAcctTimer; import org.umu.cops.stack.COPSClientAcceptMsg; import org.umu.cops.stack.COPSClientCloseMsg; import org.umu.cops.stack.COPSClientOpenMsg; import org.umu.cops.stack.COPSData; import org.umu.cops.stack.COPSError; import org.umu.cops.stack.COPSException; import org.umu.cops.stack.COPSHeader; import org.umu.cops.stack.COPSKATimer; import org.umu.cops.stack.COPSMsg; import org.umu.cops.stack.COPSPepId; import org.umu.cops.stack.COPSTransceiver; /** * This is a provisioning COPS PEP. Responsible for making * connection to the PDP and maintaining it */ public class 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(String pepID, short clientType) { _pepID = pepID; _clientType = clientType; } /** * Creates a PEP agent with a PEP-ID equal to "noname" * @param clientType Client-type */ public COPSPepAgent(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 true if PDP accepts the connection; false otherwise * @throws java.net.UnknownHostException * @throws java.io.IOException * @throws COPSException * @throws COPSPepException */ public boolean connect(String psHost, int psPort) throws UnknownHostException, 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 COPSError returned by PDP */ public COPSError getConnectionError() { return _error; } /** * Disconnects from the PDP * @param error Reason * @throws COPSException * @throws IOException */ public void disconnect(COPSError error) throws COPSException, IOException { COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType); COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(); closeMsg.add(cHdr); if (error != null) closeMsg.add(error); closeMsg.writeData(_conn.getSocket()); _conn.close(); _conn = null; } /** * Adds a request state to the connection manager. * @return The newly created connection manager * @throws COPSPepException * @throws COPSException */ public COPSPepReqStateMan addRequestState (String handle, 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 (COPSPepReqStateMan man) throws COPSPepException, COPSException { if (_conn != null) _conn.deleteRequestState(man); } /** * Gets all the request state managers * @return A Hashtable holding all active request state managers */ public Hashtable getReqStateMans() { if (_conn != null) return _conn.getReqStateMans(); return null; } /** * Establish connection to PDP's IP address * * ::= * * [] * [] * [] * * Not support [], [], [] * * ::= * * [] * [] * * Not send [] * * ::= * * [] * [] * * Not send [], [] * * @throws UnknownHostException * @throws IOException * @throws COPSException * @throws COPSPepException * */ private COPSPepConnection processConnection(String psHost, int psPort) throws UnknownHostException, IOException, COPSException, COPSPepException { // Build OPN COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType); COPSPepId pepId = new COPSPepId(); COPSData d = new COPSData(_pepID); pepId.setData(d); COPSClientOpenMsg msg = new COPSClientOpenMsg(); msg.add(hdr); msg.add(pepId); // Create Socket and send OPN InetAddress addr = InetAddress.getByName(psHost); Socket socket = new Socket(addr,psPort); msg.writeData(socket); // Receive the response COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket); if (recvmsg.getHeader().isAClientAccept()) { COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg; // Support if (cMsg.getIntegrity() != null) { throw new COPSPepException("Unsupported object (Integrity)"); } // Mandatory KATimer COPSKATimer kt = cMsg.getKATimer(); if (kt == null) throw new COPSPepException ("Mandatory COPS object missing (KA Timer)"); short _kaTimeVal = kt.getTimerVal(); // ACTimer COPSAcctTimer at = cMsg.getAcctTimer(); short _acctTimer = 0; if (at != null) _acctTimer = at.getTimerVal(); // Create the connection manager COPSPepConnection conn = new COPSPepConnection(_clientType, socket); conn.setKaTimer(_kaTimeVal); conn.setAcctTimer(_acctTimer); new Thread(conn).start(); return conn; } else if (recvmsg.getHeader().isAClientClose()) { COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg; _error = cMsg.getError(); socket.close(); return null; } else { // messages of other types are not expected throw new COPSPepException("Message not expected. Closing connection for " + socket.toString()); } } }