7 import java.io.IOException;
\r
8 import java.net.Socket;
\r
9 import java.util.Date;
\r
10 import java.util.Enumeration;
\r
11 import java.util.Hashtable;
\r
13 import org.umu.cops.common.COPSDebug;
\r
14 import org.umu.cops.prpdp.COPSPdpException;
\r
15 import org.umu.cops.stack.COPSClientCloseMsg;
\r
16 import org.umu.cops.stack.COPSContext;
\r
17 import org.umu.cops.stack.COPSDeleteMsg;
\r
18 import org.umu.cops.stack.COPSError;
\r
19 import org.umu.cops.stack.COPSException;
\r
20 import org.umu.cops.stack.COPSHeader;
\r
21 import org.umu.cops.stack.COPSKAMsg;
\r
22 import org.umu.cops.stack.COPSMsg;
\r
23 import org.umu.cops.stack.COPSPepId;
\r
24 import org.umu.cops.stack.COPSReportMsg;
\r
25 import org.umu.cops.stack.COPSReqMsg;
\r
26 import org.umu.cops.stack.COPSSyncStateMsg;
\r
27 import org.umu.cops.stack.COPSTransceiver;
\r
30 * Class for managing an provisioning connection at the PDP side.
\r
32 public class PCMMPdpConnection implements Runnable {
\r
35 Socket connected to PEP
\r
37 private Socket _sock;
\r
42 private COPSPepId _pepId;
\r
45 Time of the latest keep-alive sent
\r
47 private Date _lastKa;
\r
50 Opcode of the latest message sent
\r
52 private byte _lastmessage;
\r
55 * Time of the latest keep-alive received
\r
57 protected Date _lastRecKa;
\r
60 Maps a Client Handle to a Handler
\r
62 protected Hashtable _managerMap;
\r
63 // map < String(COPSHandle), COPSPdpHandler> HandlerMap;
\r
66 * PDP policy data processor class
\r
68 protected PCMMPdpDataProcess _process;
\r
71 Accounting timer value (secs)
\r
73 protected short _acctTimer;
\r
76 Keep-alive timer value (secs)
\r
78 protected short _kaTimer;
\r
81 COPS error returned by PEP
\r
83 protected COPSError _error;
\r
86 * Creates a new PDP connection
\r
88 * @param pepId PEP-ID of the connected PEP
\r
89 * @param sock Socket connected to PEP
\r
90 * @param process Object for processing policy data
\r
92 public PCMMPdpConnection(COPSPepId pepId, Socket sock, PCMMPdpDataProcess process) {
\r
96 _lastKa = new Date();
\r
97 _lastmessage = COPSHeader.COPS_OP_OPN;
\r
98 _managerMap = new Hashtable(20);
\r
101 _process = process;
\r
105 * Gets the time of that latest keep-alive sent
\r
106 * @return Time of that latest keep-alive sent
\r
108 public Date getLastKAlive() {
\r
113 * Sets the keep-alive timer value
\r
114 * @param kaTimer Keep-alive timer value (secs)
\r
116 public void setKaTimer(short kaTimer) {
\r
117 _kaTimer = kaTimer;
\r
121 * Gets the keep-alive timer value
\r
122 * @return Keep-alive timer value (secs)
\r
124 public short getKaTimer() {
\r
129 * Sets the accounting timer value
\r
130 * @param acctTimer Accounting timer value (secs)
\r
132 public void setAccTimer(short acctTimer) {
\r
133 _acctTimer = acctTimer;
\r
137 * Gets the accounting timer value
\r
138 * @return Accounting timer value (secs)
\r
140 public short getAcctTimer() {
\r
145 * Gets the latest COPS message
\r
146 * @return Code of the latest message sent
\r
148 public byte getLastMessage() {
\r
149 return _lastmessage;
\r
153 * Gets active handles
\r
154 * @return An <tt>Enumeration</tt> holding all active handles
\r
156 public Enumeration getHandles() {
\r
157 return _managerMap.keys();
\r
161 * Gets the handle map
\r
162 * @return A <tt>Hashtable</tt> holding the handle map
\r
164 public Hashtable getReqStateMans() {
\r
165 return _managerMap;
\r
170 * @return The ID of the PEP, as a <tt>String</tt>
\r
172 public String getPepId() {
\r
173 return _pepId.getData().str();
\r
177 * Checks whether the socket to the PEP is closed or not
\r
178 * @return <tt>true</tt> if closed, <tt>false</tt> otherwise
\r
180 public boolean isClosed() {
\r
181 return _sock.isClosed();
\r
185 * Closes the socket to the PEP
\r
186 * @throws IOException
\r
188 protected void close()
\r
189 throws IOException {
\r
194 * Gets the socket to the PEP
\r
195 * @return Socket connected to the PEP
\r
197 public Socket getSocket() {
\r
204 public void run () {
\r
205 Date _lastSendKa = new Date();
\r
206 _lastRecKa = new Date();
\r
208 while (!_sock.isClosed()) {
\r
209 if (_sock.getInputStream().available() != 0) {
\r
210 _lastmessage = processMessage(_sock);
\r
211 _lastRecKa = new Date();
\r
215 if (_kaTimer > 0) {
\r
217 int _startTime = (int) (_lastRecKa.getTime());
\r
218 int cTime = (int) (new Date().getTime());
\r
220 if ((int)(cTime - _startTime) > _kaTimer*1000) {
\r
222 // Notify all Request State Managers
\r
223 notifyNoKAAllReqStateMan();
\r
227 _startTime = (int) (_lastSendKa.getTime());
\r
228 cTime = (int) (new Date().getTime());
\r
230 if ((int)(cTime - _startTime) > ((_kaTimer*3/4)*1000)) {
\r
231 COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);
\r
232 COPSKAMsg msg = new COPSKAMsg();
\r
236 COPSTransceiver.sendMsg(msg, _sock);
\r
237 _lastSendKa = new Date();
\r
243 } catch (Exception e) {};
\r
246 } catch (Exception e) {
\r
247 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);
\r
250 // connection closed by server
\r
251 // COPSDebug.out(getClass().getName(),"Connection closed by client");
\r
254 } catch (IOException e) {};
\r
256 // Notify all Request State Managers
\r
258 notifyCloseAllReqStateMan();
\r
259 } catch (COPSPdpException e) {};
\r
263 * Gets a COPS message from the socket and processes it
\r
264 * @param conn Socket connected to the PEP
\r
265 * @return Type of COPS message
\r
267 private byte processMessage(Socket conn)
\r
268 throws COPSPdpException, COPSException, IOException {
\r
269 COPSMsg msg = COPSTransceiver.receiveMsg(conn);
\r
271 if (msg.getHeader().isAClientClose()) {
\r
272 handleClientCloseMsg(conn, msg);
\r
273 return COPSHeader.COPS_OP_CC;
\r
274 } else if (msg.getHeader().isAKeepAlive()) {
\r
275 handleKeepAliveMsg(conn, msg);
\r
276 return COPSHeader.COPS_OP_KA;
\r
277 } else if (msg.getHeader().isARequest()) {
\r
278 handleRequestMsg(conn, msg);
\r
279 return COPSHeader.COPS_OP_REQ;
\r
280 } else if (msg.getHeader().isAReport()) {
\r
281 handleReportMsg(conn, msg);
\r
282 return COPSHeader.COPS_OP_RPT;
\r
283 } else if (msg.getHeader().isADeleteReq()) {
\r
284 handleDeleteRequestMsg(conn, msg);
\r
285 return COPSHeader.COPS_OP_DRQ;
\r
286 } else if (msg.getHeader().isASyncComplete()) {
\r
287 handleSyncComplete(conn, msg);
\r
288 return COPSHeader.COPS_OP_SSC;
\r
290 throw new COPSPdpException("Message not expected (" + msg.getHeader().getOpCode() + ").");
\r
295 * Handle Client Close Message, close the passed connection
\r
297 * @param conn a Socket
\r
298 * @param msg a COPSMsg
\r
301 * <Client-Close> ::= <Common Header>
\r
305 * Not support [<Integrity>]
\r
308 private void handleClientCloseMsg(Socket conn, COPSMsg msg) {
\r
309 COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;
\r
310 _error = cMsg.getError();
\r
312 // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +
\r
313 // conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");
\r
317 if (cMsg.getIntegrity() != null) {
\r
318 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
319 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
323 } catch (Exception unae) { };
\r
327 * Gets the occurred COPS Error
\r
328 * @return <tt>COPSError</tt> object
\r
330 protected COPSError getError() {
\r
335 * Handle Keep Alive Message
\r
337 * <Keep-Alive> ::= <Common Header>
\r
340 * Not support [<Integrity>]
\r
342 * @param conn a Socket
\r
343 * @param msg a COPSMsg
\r
346 private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {
\r
347 COPSKAMsg cMsg = (COPSKAMsg) msg;
\r
349 COPSKAMsg kaMsg = (COPSKAMsg) msg;
\r
352 if (cMsg.getIntegrity() != null) {
\r
353 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
354 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
357 kaMsg.writeData(conn);
\r
358 } catch (Exception 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 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
384 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
387 // Delete clientHandler
\r
388 if (_managerMap.remove(cMsg.getClientHandle().getId().str()) == null) {
\r
389 // COPSDebug.out(getClass().getName(),"Missing for ClientHandle " +
\r
390 // cMsg.getClientHandle().getId().getData());
\r
393 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
\r
395 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
\r
397 man.processDeleteRequestState(cMsg);
\r
403 * Handle Request Message
\r
405 * <Request> ::= <Common Header>
\r
408 * *(<Named ClientSI>)
\r
410 * <Named ClientSI> ::= <*(<PRID> <EPD>)>
\r
412 * Not support [<Integrity>]
\r
414 * @param conn a Socket
\r
415 * @param msg a COPSMsg
\r
418 private void handleRequestMsg(Socket conn, COPSMsg msg)
\r
419 throws COPSPdpException {
\r
421 COPSReqMsg reqMsg = (COPSReqMsg) msg;
\r
422 COPSContext cntxt = reqMsg.getContext();
\r
423 COPSHeader header = reqMsg.getHeader();
\r
424 //short reqType = cntxt.getRequestType();
\r
425 short cType = header.getClientType();
\r
428 if (reqMsg.getIntegrity() != null) {
\r
429 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
430 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
433 PCMMPdpReqStateMan man;
\r
434 man = (PCMMPdpReqStateMan) _managerMap.get(reqMsg.getClientHandle().getId().str());
\r
437 man = new PCMMPdpReqStateMan(cType, reqMsg.getClientHandle().getId().str());
\r
438 _managerMap.put(reqMsg.getClientHandle().getId().str(),man);
\r
439 man.setDataProcess(_process);
\r
440 man.initRequestState(_sock);
\r
442 // COPSDebug.out(getClass().getName(),"createHandler called, clientType=" +
\r
443 // header.getClientType() + " msgType=" +
\r
444 // cntxt.getMessageType() + ", connId=" + conn.toString());
\r
447 man.processRequest(reqMsg);
\r
451 * Handle Report Message
\r
453 * <Report State> ::= <Common Header>
\r
456 * *(<Named ClientSI>)
\r
459 * Not support [<Integrity>]
\r
461 * @param conn a Socket
\r
462 * @param msg a COPSMsg
\r
465 private void handleReportMsg(Socket conn, COPSMsg msg)
\r
466 throws COPSPdpException {
\r
467 COPSReportMsg repMsg = (COPSReportMsg) msg;
\r
468 // COPSHandle handle = repMsg.getClientHandle();
\r
469 // COPSHeader header = repMsg.getHeader();
\r
472 if (repMsg.getIntegrity() != null) {
\r
473 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
474 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
477 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(repMsg.getClientHandle().getId().str());
\r
479 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
\r
481 man.processReport(repMsg);
\r
486 * Method handleSyncComplete
\r
488 * @param conn a Socket
\r
489 * @param msg a COPSMsg
\r
492 private void handleSyncComplete(Socket conn, COPSMsg msg)
\r
493 throws COPSPdpException {
\r
494 COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;
\r
495 // COPSHandle handle = cMsg.getClientHandle();
\r
496 // COPSHeader header = cMsg.getHeader();
\r
499 if (cMsg.getIntegrity() != null) {
\r
500 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,
\r
501 "Unsupported objects (Integrity) to connection " + conn.getInetAddress());
\r
504 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());
\r
506 COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);
\r
508 man.processSyncComplete(cMsg);
\r
513 * Requests a COPS sync from the PEP
\r
514 * @throws COPSException
\r
515 * @throws COPSPdpException
\r
517 protected void syncAllRequestState()
\r
518 throws COPSException, COPSPdpException {
\r
519 if (_managerMap.size() > 0) {
\r
520 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
\r
521 String handle = (String) e.nextElement();
\r
522 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
\r
524 man.syncRequestState();
\r
529 private void notifyCloseAllReqStateMan()
\r
530 throws COPSPdpException {
\r
531 if (_managerMap.size() > 0) {
\r
532 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
\r
533 String handle = (String) e.nextElement();
\r
534 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
\r
536 man.processClosedConnection(_error);
\r
541 private void notifyNoKAAllReqStateMan()
\r
542 throws COPSPdpException {
\r
543 if (_managerMap.size() > 0) {
\r
544 for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {
\r
545 String handle = (String) e.nextElement();
\r
546 PCMMPdpReqStateMan man = (PCMMPdpReqStateMan) _managerMap.get(handle);
\r
548 man.processNoKAConnection();
\r