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