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.prpdp;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11 import org.umu.cops.COPSConnection;
12 import org.umu.cops.stack.*;
14 import javax.annotation.concurrent.ThreadSafe;
15 import java.io.IOException;
16 import java.net.Socket;
17 import java.util.Date;
19 import java.util.concurrent.ConcurrentHashMap;
22 * Class for managing an provisioning connection at the PDP side.
25 public class COPSPdpConnection extends COPSConnection {
27 public final static Logger logger = LoggerFactory.getLogger(COPSPdpConnection.class);
31 * TODO FIXME - Why is this member never being used?
33 private final COPSPepId _pepId;
36 * Time of the latest keep-alive sent
37 * TODO FIXME - Why is this member never being used?
39 private volatile Date _lastKa;
42 * Maps a Client Handle to a Handler
44 protected final Map<COPSHandle, COPSPdpReqStateMan> _managerMap;
47 * PDP policy data processor class
49 protected final COPSPdpDataProcess _process;
52 * Creates a new PDP connection
54 * @param pepId PEP-ID of the connected PEP
55 * @param sock Socket connected to PEP
56 * @param process Object for processing policy data
58 public COPSPdpConnection(final COPSPepId pepId, Socket sock, final COPSPdpDataProcess process) {
59 this(pepId, sock, process, (short)0, (short)0);
63 * Constructor for this or extended classes
64 * @param pepId - PEP-ID of the connected PEP
65 * @param sock - Socket connected to PEP
66 * @param process - Object for processing policy data
67 * @param kaTimer - the Keep-alive timer value
68 * @param acctTimer - the accounting timer value
70 protected COPSPdpConnection(final COPSPepId pepId, Socket sock, final COPSPdpDataProcess process,
71 final short kaTimer, final short acctTimer) {
72 super(sock, kaTimer, acctTimer);
76 _managerMap = new ConcurrentHashMap<>();
83 Date lastSendKa = new Date();
84 Date lastRecKa = new Date();
86 while (!_sock.isClosed()) {
87 if (_sock.getInputStream().available() != 0) {
88 processMessage(_sock);
89 lastRecKa = new Date();
95 int _startTime = (int) (lastRecKa.getTime());
96 int cTime = (int) (new Date().getTime());
98 if ((cTime - _startTime) > _kaTimer*1000) {
100 // Notify all Request State Managers
101 notifyNoKAAllReqStateMan();
105 _startTime = (int) (lastSendKa.getTime());
106 cTime = (int) (new Date().getTime());
108 if ((cTime - _startTime) > ((_kaTimer*3/4)*1000)) {
109 // TODO - what should the real clientType be here???
110 final COPSKAMsg msg = new COPSKAMsg(null);
111 COPSTransceiver.sendMsg(msg, _sock);
112 lastSendKa = new Date();
118 } catch (Exception e) {
119 logger.error("Exception thrown while sleeping", e);
123 } catch (Exception e) {
124 logger.error("Error while processing socket messages", e);
127 // connection closed by server
130 } catch (IOException e) {
131 logger.error("Error closing socket", e);
134 // Notify all Request State Managers
136 notifyCloseAllReqStateMan();
137 } catch (COPSException e) {
138 logger.error("Error closing state managers");
143 * Gets a COPS message from the socket and processes it
144 * @param conn Socket connected to the PEP
146 private void processMessage(final Socket conn) throws COPSException, IOException {
147 final COPSMsg msg = COPSTransceiver.receiveMsg(conn);
148 switch (msg.getHeader().getOpCode()) {
150 handleClientCloseMsg(conn, (COPSClientCloseMsg)msg);
153 handleKeepAliveMsg(conn, (COPSKAMsg)msg);
156 handleRequestMsg(conn, (COPSReqMsg)msg);
159 handleReportMsg(conn, (COPSReportMsg)msg);
162 handleDeleteRequestMsg(conn, (COPSDeleteMsg)msg);
165 handleSyncComplete(conn, (COPSSyncStateMsg)msg);
168 throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
173 * Handle Keep Alive Message
174 * @param conn a Socket
175 * @param kaMsg a COPSKAMsg
177 private void handleKeepAliveMsg(final Socket conn, final COPSKAMsg kaMsg) {
180 if (kaMsg.getIntegrity() != null) {
181 logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
183 kaMsg.writeData(conn);
184 _lastKa = new Date();
185 } catch (Exception unae) {
186 logger.error("Unexpected exception while writing COPS data", unae);
191 * Handle Delete Request Message
192 * @param conn a Socket
193 * @param cMsg a COPSDeleteMsg
195 private void handleDeleteRequestMsg(final Socket conn, final COPSDeleteMsg cMsg) throws COPSException {
197 if (cMsg.getIntegrity() != null) {
198 logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
201 final COPSPdpReqStateMan man = _managerMap.remove(cMsg.getClientHandle());
203 logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());
205 man.processDeleteRequestState(cMsg);
210 * Handle Request Message
211 * @param conn a Socket
212 * @param reqMsg a COPSReqMsg
214 protected void handleRequestMsg(final Socket conn, final COPSReqMsg reqMsg) throws COPSException {
215 final COPSHeader header = reqMsg.getHeader();
218 if (reqMsg.getIntegrity() != null) {
219 logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
222 final COPSPdpReqStateMan man;
223 if (_managerMap.get(reqMsg.getClientHandle()) == null) {
225 man = createStateManager(reqMsg);
226 _managerMap.put(reqMsg.getClientHandle(), man);
227 man.initRequestState(_sock);
229 logger.info("createHandler called, clientType=" + header.getClientType() + " msgType=" + ", connId=" +
232 man = _managerMap.get(reqMsg.getClientHandle());
234 man.processRequest(reqMsg);
238 * Returns an instance of a COPSPdpReqStateMan
239 * @param reqMsg - the request on which to create the state manager
240 * @return - the state manager
242 protected COPSPdpReqStateMan createStateManager(final COPSReqMsg reqMsg) {
243 return new COPSPdpReqStateMan(reqMsg.getHeader().getClientType(), reqMsg.getClientHandle(), _process);
247 * Handle Report Message
248 * @param conn a Socket
249 * @param repMsg a COPSReportMsg
251 private void handleReportMsg(final Socket conn, final COPSReportMsg repMsg) throws COPSException {
253 if (repMsg.getIntegrity() != null) {
254 logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
257 final COPSPdpReqStateMan man = _managerMap.get(repMsg.getClientHandle());
259 logger.warn("No state manager found with ID - " + repMsg.getClientHandle().getId().str());
261 man.processReport(repMsg);
266 * Method handleSyncComplete
267 * @param conn a Socket
268 * @param cMsg a COPSSyncStateMsg
270 private void handleSyncComplete(final Socket conn, final COPSSyncStateMsg cMsg) throws COPSException {
272 if (cMsg.getIntegrity() != null) {
273 logger.warn("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
276 final COPSPdpReqStateMan man = _managerMap.get(cMsg.getClientHandle());
278 logger.warn("No state manager found with ID - " + cMsg.getClientHandle().getId().str());
280 man.processSyncComplete(cMsg);
285 * Requests a COPS sync from the PEP
286 * @throws COPSException
287 * @throws COPSPdpException
289 public void syncAllRequestState() throws COPSException {
290 for (final COPSPdpReqStateMan man : _managerMap.values()) {
291 man.syncRequestState();
295 private void notifyCloseAllReqStateMan() throws COPSException {
296 for (final COPSPdpReqStateMan man : _managerMap.values()) {
297 man.processClosedConnection(_error);
301 private void notifyNoKAAllReqStateMan() throws COPSException {
302 for (final COPSPdpReqStateMan man : _managerMap.values()) {
303 man.processNoKAConnection();