7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.umu.cops.prpdp.COPSPdpException;
10 import org.umu.cops.stack.*;
12 import java.io.IOException;
13 import java.net.Socket;
14 import java.util.Date;
15 import java.util.Enumeration;
16 import java.util.Hashtable;
19 * Class for managing an provisioning connection at the PDP side.
21 public class PCMMPdpConnection implements Runnable {
24 public final static Logger logger = LoggerFactory.getLogger(PCMMPdpConnection.class);
27 Socket connected to PEP
34 private COPSPepId _pepId;
37 Time of the latest keep-alive sent
42 Opcode of the latest message sent
44 private byte _lastmessage;
47 * Time of the latest keep-alive received
49 protected Date _lastRecKa;
52 Maps a Client Handle to a Handler
54 protected Hashtable _managerMap;
55 // map < String(COPSHandle), COPSPdpHandler> HandlerMap;
58 * PDP policy data processor class
60 protected PCMMPdpDataProcess _process;
63 Accounting timer value (secs)
65 protected short _acctTimer;
68 Keep-alive timer value (secs)
70 protected short _kaTimer;
73 COPS error returned by PEP
75 protected COPSError _error;
78 * Creates a new PDP connection
80 * @param pepId PEP-ID of the connected PEP
81 * @param sock Socket connected to PEP
82 * @param process Object for processing policy data
84 public PCMMPdpConnection(COPSPepId pepId, Socket sock, PCMMPdpDataProcess process) {
89 _lastmessage = COPSHeader.COPS_OP_OPN;
90 _managerMap = new Hashtable(20);
97 * Gets the time of that latest keep-alive sent
98 * @return Time of that latest keep-alive sent
100 public Date getLastKAlive() {
105 * Sets the keep-alive timer value
106 * @param kaTimer Keep-alive timer value (secs)
108 public void setKaTimer(short kaTimer) {
113 * Gets the keep-alive timer value
114 * @return Keep-alive timer value (secs)
116 public short getKaTimer() {
121 * Sets the accounting timer value
122 * @param acctTimer Accounting timer value (secs)
124 public void setAccTimer(short acctTimer) {
125 _acctTimer = acctTimer;
129 * Gets the accounting timer value
130 * @return Accounting timer value (secs)
132 public short getAcctTimer() {
137 * Gets the latest COPS message
138 * @return Code of the latest message sent
140 public byte getLastMessage() {
145 * Gets active handles
146 * @return An <tt>Enumeration</tt> holding all active handles
148 public Enumeration getHandles() {
149 return _managerMap.keys();
153 * Gets the handle map
154 * @return A <tt>Hashtable</tt> holding the handle map
156 public Hashtable getReqStateMans() {
162 * @return The ID of the PEP, as a <tt>String</tt>
164 public String getPepId() {
165 return _pepId.getData().str();
169 * Checks whether the socket to the PEP is closed or not
170 * @return <tt>true</tt> if closed, <tt>false</tt> otherwise
172 public boolean isClosed() {
173 return _sock.isClosed();
177 * Closes the socket to the PEP
178 * @throws IOException
180 protected void close()
186 * Gets the socket to the PEP
187 * @return Socket connected to the PEP
189 public Socket getSocket() {
197 Date _lastSendKa = new Date();
198 _lastRecKa = new Date();
200 while (!_sock.isClosed()) {
201 if (_sock.getInputStream().available() != 0) {
202 _lastmessage = processMessage(_sock);
203 _lastRecKa = new Date();
209 int _startTime = (int) (_lastRecKa.getTime());
210 int cTime = (int) (new Date().getTime());
212 if ((int)(cTime - _startTime) > _kaTimer*1000) {
214 // Notify all Request State Managers
215 notifyNoKAAllReqStateMan();
219 _startTime = (int) (_lastSendKa.getTime());
220 cTime = (int) (new Date().getTime());
222 if ((cTime - _startTime) > ((_kaTimer * 3/4) * 1000)) {
223 COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);
224 COPSKAMsg msg = new COPSKAMsg();
228 COPSTransceiver.sendMsg(msg, _sock);
229 _lastSendKa = new Date();
235 } catch (Exception e) {
236 logger.error("Unexpected exception while sleeping", e);
240 } catch (Exception e) {
241 logger.error("Error reading messages from socket", e);
244 // connection closed by server
245 // COPSDebug.out(getClass().getName(),"Connection closed by client");
248 } catch (IOException e) {
249 logger.error("Error closing socket", e);
252 // Notify all Request State Managers
254 notifyCloseAllReqStateMan();
255 } catch (COPSPdpException e) {
256 logger.error("Error closing state managers", e);
261 * Gets a COPS message from the socket and processes it
262 * @param conn Socket connected to the PEP
263 * @return Type of COPS message
265 private byte processMessage(Socket conn)
266 throws COPSPdpException, COPSException, IOException {
267 COPSMsg msg = COPSTransceiver.receiveMsg(conn);
269 if (msg.getHeader().isAClientClose()) {
270 handleClientCloseMsg(conn, msg);
271 return COPSHeader.COPS_OP_CC;
272 } else if (msg.getHeader().isAKeepAlive()) {
273 handleKeepAliveMsg(conn, msg);
274 return COPSHeader.COPS_OP_KA;
275 } else if (msg.getHeader().isARequest()) {
276 handleRequestMsg(conn, msg);
277 return COPSHeader.COPS_OP_REQ;
278 } else if (msg.getHeader().isAReport()) {
279 handleReportMsg(conn, msg);
280 return COPSHeader.COPS_OP_RPT;
281 } else if (msg.getHeader().isADeleteReq()) {
282 handleDeleteRequestMsg(conn, msg);
283 return COPSHeader.COPS_OP_DRQ;
284 } else if (msg.getHeader().isASyncComplete()) {
285 handleSyncComplete(conn, msg);
286 return COPSHeader.COPS_OP_SSC;
288 throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
293 * Handle Client Close Message, close the passed connection
295 * @param conn a Socket
296 * @param msg a COPSMsg
299 * <Client-Close> ::= <Common Header>
303 * Not support [<Integrity>]
306 private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
307 COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
308 _error = cMsg.getError();
310 // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
311 // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
315 if (cMsg.getIntegrity() != null) {
316 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
320 } catch (Exception unae) {
321 logger.error("Unexpected exception closing connection", unae);
326 * Gets the occurred COPS Error
327 * @return <tt>COPSError</tt> object
329 protected COPSError getError() {
334 * Handle Keep Alive Message
336 * <Keep-Alive> ::= <Common Header>
339 * Not support [<Integrity>]
341 * @param conn a Socket
342 * @param msg a COPSMsg
345 private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
346 COPSKAMsg cMsg = (COPSKAMsg) msg;
348 COPSKAMsg kaMsg = (COPSKAMsg) msg;
351 if (cMsg.getIntegrity() != null) {
352 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
355 kaMsg.writeData(conn);
356 } catch (Exception unae) {
357 logger.error("Unexpected exception while writing keep-alive message", unae);
362 * Handle Delete Request Message
364 * <Delete Request> ::= <Common Header>
369 * Not support [<Integrity>]
371 * @param conn a Socket
372 * @param msg a COPSMsg
375 private void handleDeleteRequestMsg(Socket conn, COPSMsg msg)
376 throws COPSPdpException {
377 COPSDeleteMsg cMsg = (COPSDeleteMsg) msg;
378 // COPSDebug.out(getClass().getName(),"Removing ClientHandle for " +
379 // conn.getInetAddress() + ":" + conn.getPort() + ":[Reason " + cMsg.getReason().getDescription() + "]");
382 if (cMsg.getIntegrity() != null) {
383 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
386 // Delete clientHandler
387 if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {
388 // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +
389 // cMsg.getClientHandle().getId().getData());
392 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
394 logger.warn("State manager not found");
396 man.processDeleteRequestState(cMsg);
402 * Handle Request Message
404 * <Request> ::= <Common Header>
407 * *(<Named ClientSI>)
409 * <Named ClientSI> ::= <*(<PRID> <EPD>)>
411 * Not support [<Integrity>]
413 * @param conn a Socket
414 * @param msg a COPSMsg
417 private void handleRequestMsg(Socket conn, COPSMsg msg)
418 throws COPSPdpException {
420 COPSReqMsg reqMsg = (COPSReqMsg) msg;
421 COPSContext cntxt = reqMsg.getContext();
422 COPSHeader header = reqMsg.getHeader();
423 //short reqType = cntxt.getRequestType();
424 short cType = header.getClientType();
427 if (reqMsg.getIntegrity() != null) {
428 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
431 PCMMPdpReqStateMan man;
432 man = (PCMMPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());
435 man = new PCMMPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());
436 _managerMap.put(reqMsg.getClientHandle().getId().str(),man);
437 man.setDataProcess(_process);
438 man.initRequestState(_sock);
440 // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +
441 // header.getClientType() + " msgType=" +
442 // cntxt.getMessageType() + ", connId=" + conn.toString());
445 man.processRequest(reqMsg);
449 * Handle Report Message
451 * <Report State> ::= <Common Header>
454 * *(<Named ClientSI>)
457 * Not support [<Integrity>]
459 * @param conn a Socket
460 * @param msg a COPSMsg
463 private void handleReportMsg(Socket conn, COPSMsg msg)
464 throws COPSPdpException {
465 COPSReportMsg repMsg = (COPSReportMsg) msg;
466 // COPSHandle handle = repMsg.getClientHandle();
467 // COPSHeader header = repMsg.getHeader();
470 if (repMsg.getIntegrity() != null) {
471 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
474 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());
476 logger.warn("State manager not found");
478 man.processReport(repMsg);
483 * Method handleSyncComplete
485 * @param conn a Socket
486 * @param msg a COPSMsg
489 private void handleSyncComplete(Socket conn, COPSMsg msg)
490 throws COPSPdpException {
491 COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
492 // COPSHandle handle = cMsg.getClientHandle();
493 // COPSHeader header = cMsg.getHeader();
496 if (cMsg.getIntegrity() != null) {
497 logger.error("Unsupported objects (Integrity) to connection " + conn.getInetAddress());
500 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
502 logger.warn("State manager not found");
504 man.processSyncComplete(cMsg);
509 * Requests a COPS sync from the PEP
510 * @throws COPSException
511 * @throws COPSPdpException
513 protected void syncAllRequestState()
514 throws COPSException, COPSPdpException {
515 if (_managerMap.size() > 0) {
516 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
517 String handle = (String) e.nextElement();
518 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
520 man.syncRequestState();
525 private void notifyCloseAllReqStateMan()
526 throws COPSPdpException {
527 if (_managerMap.size() > 0) {
528 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
529 String handle = (String) e.nextElement();
530 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
532 man.processClosedConnection(_error);
537 private void notifyNoKAAllReqStateMan()
538 throws COPSPdpException {
539 if (_managerMap.size() > 0) {
540 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
541 String handle = (String) e.nextElement();
542 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
544 man.processNoKAConnection();