2 * Copyright (c) 2004 University of Murcia. All rights reserved.
3 * --------------------------------------------------------------
4 * For more information, please see <http://www.umu.euro6ix.org/>.
7 package org.umu.cops.prpep;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.umu.cops.stack.*;
12 import org.umu.cops.stack.COPSError.ErrorTypes;
13 import org.umu.cops.stack.COPSHeader.OPCode;
15 import java.io.IOException;
16 import java.net.InetAddress;
17 import java.net.Socket;
20 * This is a provisioning COPS PEP. Responsible for making
21 * connection to the PDP and maintaining it
23 public class COPSPepAgent {
25 /** Well-known port for COPS */
26 public static final int WELL_KNOWN_CMTS_PORT = 3918;
28 private final static Logger logger = LoggerFactory.getLogger(COPSPepAgent.class);
33 protected final short _clientType;
38 protected final COPSPepId _pepID;
43 private final int _psPort;
45 // The next two attributes are instantiated after the connect() method has successfully completed.
47 * PEP-PDP connection manager
49 protected transient COPSPepConnection _conn;
52 * The thread object to manage the connection thread.
54 private transient Thread thread;
58 * @param clientType Client-type
60 * @param port the server socket port to open on this host
62 public COPSPepAgent(final short clientType, final COPSPepId pepID, final int port) {
63 _clientType = clientType;
69 * Connects to a PDP and is responsible for setting up the connection
70 * @throws java.io.IOException
71 * @throws COPSException
72 * @throws COPSPepException
74 public void connect() throws IOException, COPSException {
75 logger.info("Thread ( " + _pepID + ") - Connecting to PDP");
77 // Check whether it already exists
79 _conn = processConnection();
81 // Check if it's closed
82 if (_conn.isClosed()) {
83 _conn = processConnection();
85 disconnect(new COPSError(ErrorTypes.SHUTTING_DOWN, ErrorTypes.NA));
86 _conn = processConnection();
90 if (_conn == null) throw new COPSException("Unable to process PEP connection");
94 * Disconnects from the PDP
96 * @throws COPSException
99 public void disconnect(final COPSError error) throws COPSException, IOException {
100 final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg(_clientType, error, null, null);
103 closeMsg.writeData(_conn.getSocket());
109 * Adds a request state to the connection manager.
110 * @return The newly created connection manager
111 * @throws COPSPepException
112 * @throws COPSException
114 public COPSPepReqStateMan addRequestState(final COPSHandle handle, final COPSPepDataProcess process)
115 throws COPSException {
117 return _conn.addRequestState(handle, process);
124 * Queries the connection manager to delete a request state
125 * @param man Request state manager
126 * @throws COPSPepException
127 * @throws COPSException
129 public void deleteRequestState(final COPSPepReqStateMan man) throws COPSException {
131 _conn.deleteRequestState(man);
135 * Establish connection to PDP's IP address
136 * @throws COPSException
137 * @throws COPSPepException
139 private COPSPepConnection processConnection() throws IOException, COPSException {
140 // Create Socket and send OPN
141 final InetAddress addr = InetAddress.getLocalHost();
142 return processConnection(new Socket(addr, _psPort));
146 * Establish connection to PDP's IP address
147 * @throws COPSException
148 * @throws COPSPepException
150 private COPSPepConnection processConnection(final Socket socket) throws IOException, COPSException {
151 // Create Socket and send OPN
152 final COPSClientOpenMsg msg = new COPSClientOpenMsg(_clientType, _pepID, null, null, null);
153 msg.writeData(socket);
155 // Receive the response
156 final COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
158 if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
159 final COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
162 if (cMsg.getIntegrity() != null) {
163 throw new COPSPepException("Unsupported object (Integrity)");
167 final COPSKATimer kt = cMsg.getKATimer();
169 throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");
170 short _kaTimeVal = kt.getTimerVal();
173 final COPSAcctTimer at = cMsg.getAcctTimer();
174 short _acctTimer = 0;
176 _acctTimer = at.getTimerVal();
178 // Create the connection manager
179 final COPSPepConnection conn = createPepConnection(socket);
180 conn.setKaTimer(_kaTimeVal);
181 conn.setAcctTimer(_acctTimer);
182 thread = new Thread(conn);
186 } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
187 final COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
188 logger.error("Received client-close message with error description [" + cMsg.getError().getDescription()
189 + "]. Closing socket.");
192 } else { // messages of other types are not expected
193 throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());
198 * Creates a COPSPepConnection object
199 * @param socket - the socket on which to create the connection
200 * @return - the connection object
202 protected COPSPepConnection createPepConnection(final Socket socket) {
203 return new COPSPepConnection(_clientType, socket);