Fixed building of models, moved code into directory structure.
[packetcable.git] / protocol_plugins.packetcable / src / main / java / org / umu / cops / ospep / COPSPepOSConnection.java
diff --git a/protocol_plugins.packetcable/src/main/java/org/umu/cops/ospep/COPSPepOSConnection.java b/protocol_plugins.packetcable/src/main/java/org/umu/cops/ospep/COPSPepOSConnection.java
new file mode 100644 (file)
index 0000000..31a0b64
--- /dev/null
@@ -0,0 +1,469 @@
+package org.umu.cops.ospep;\r
+\r
+import java.io.IOException;\r
+import java.net.Socket;\r
+import java.util.Date;\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+import org.umu.cops.common.COPSDebug;\r
+import org.umu.cops.stack.COPSClientCloseMsg;\r
+import org.umu.cops.stack.COPSDecisionMsg;\r
+import org.umu.cops.stack.COPSError;\r
+import org.umu.cops.stack.COPSException;\r
+import org.umu.cops.stack.COPSHandle;\r
+import org.umu.cops.stack.COPSHeader;\r
+import org.umu.cops.stack.COPSKAMsg;\r
+import org.umu.cops.stack.COPSMsg;\r
+import org.umu.cops.stack.COPSSyncStateMsg;\r
+import org.umu.cops.stack.COPSTransceiver;\r
+\r
+/**\r
+ * COPSPepConnection represents a PEP-PDP Connection Manager.\r
+ * Responsible for processing messages received from PDP.\r
+ */\r
+public class COPSPepOSConnection implements Runnable {\r
+    /** Socket connected to PDP */\r
+    protected Socket _sock;\r
+\r
+    /** Time to wait responses (milliseconds), default is 10 seconds */\r
+    protected int _responseTime;\r
+\r
+    /** COPS Client-type */\r
+    protected short _clientType;\r
+\r
+    /**\r
+        Accounting timer value (secs)\r
+     */\r
+    protected short _acctTimer;\r
+\r
+    /**\r
+        Keep-alive timer value (secs)\r
+     */\r
+    protected short _kaTimer;\r
+\r
+    /**\r
+     *  Time of the latest keep-alive received\r
+     */\r
+    protected Date _lastRecKa;\r
+\r
+    /**\r
+        Opcode of the latest message sent\r
+    */\r
+    protected byte _lastmessage;\r
+\r
+    /**\r
+        Maps a COPS Client Handle to a Request State Manager\r
+     */\r
+    protected Hashtable _managerMap;\r
+    // map < String(COPSHandle), COPSPepOSReqStateMan>;\r
+\r
+    /**\r
+        COPS error returned by PDP\r
+     */\r
+    protected COPSError _error;\r
+\r
+    /**\r
+     * Creates a new PEP connection\r
+     * @param clientType    PEP's client-type\r
+     * @param sock          Socket connected to PDP\r
+     */\r
+    public COPSPepOSConnection(short clientType, Socket sock) {\r
+        _clientType = clientType;\r
+        _sock = sock;\r
+\r
+        // Timers\r
+        _acctTimer = 0;\r
+        _kaTimer = 0;\r
+        _responseTime = 10000;\r
+        _lastmessage = COPSHeader.COPS_OP_CAT;\r
+\r
+        _managerMap = new Hashtable(20);\r
+    }\r
+\r
+    /**\r
+     * Gets the response time\r
+     * @return  Response time value (msecs)\r
+     */\r
+    public int getResponseTime() {\r
+        return _responseTime;\r
+    }\r
+\r
+    /**\r
+     * Gets the socket connected to the PDP\r
+     * @return  Socket connected to PDP\r
+     */\r
+    public Socket getSocket() {\r
+        return _sock;\r
+    }\r
+\r
+    /**\r
+     * Gets keep-alive timer\r
+     * @return  Keep-alive timer value (secs)\r
+     */\r
+    public short getKaTimer () {\r
+        return _kaTimer;\r
+    }\r
+\r
+    /**\r
+     * Gets accounting timer\r
+     * @return  Accounting timer value (secs)\r
+     */\r
+    public short getAcctTimer () {\r
+        return _acctTimer;\r
+    }\r
+\r
+    /**\r
+     * Gets active COPS handles\r
+     * @return  An <tt>Enumeration</tt> holding all active handles\r
+     */\r
+    protected Enumeration getHandles() {\r
+        return _managerMap.keys();\r
+    }\r
+\r
+    /**\r
+     * Gets all request state managers\r
+     * @return  A <tt>Hashatable</tt> holding all request state managers\r
+     */\r
+    protected Hashtable getReqStateMans() {\r
+        return _managerMap;\r
+    }\r
+\r
+    /**\r
+     * Checks whether the socket to the PDP is closed or not\r
+     * @return  <tt>true</tt> if the socket is closed, <tt>false</tt> otherwise\r
+     */\r
+    public boolean isClosed() {\r
+        return _sock.isClosed();\r
+    }\r
+\r
+    /**\r
+     * Closes the socket\r
+     *\r
+     * @throws java.io.IOException\r
+     */\r
+    protected void close() throws IOException {\r
+        _sock.close();\r
+    }\r
+\r
+    /**\r
+     * Gets the opcode of the lastest message sent\r
+     * @return  Message opcode\r
+     */\r
+    public byte getLastmessage() {\r
+        return _lastmessage;\r
+    }\r
+\r
+    /**\r
+     * Sets response time\r
+     * @param respTime  Response time value (msecs)\r
+     */\r
+    public void setResponseTime(int respTime) {\r
+        _responseTime = respTime;\r
+    };\r
+\r
+    /**\r
+     * Sets keep-alive timer\r
+     * @param kaTimer   Keep-alive timer value (secs)\r
+     */\r
+    public void setKaTimer(short kaTimer) {\r
+        _kaTimer = kaTimer;\r
+    }\r
+\r
+    /**\r
+     * Sets accounting timer\r
+     * @param acctTimer Accounting timer value (secs)\r
+     */\r
+    public void setAcctTimer(short acctTimer) {\r
+        _acctTimer = acctTimer;\r
+    }\r
+\r
+    /**\r
+     * Message-processing loop\r
+     */\r
+    public void run () {\r
+        Date _lastSendKa = new Date();\r
+        Date _lastSendAcc = new Date();\r
+        _lastRecKa = new Date();\r
+\r
+        try {\r
+            while (!_sock.isClosed()) {\r
+                if (_sock.getInputStream().available() != 0) {\r
+                    _lastmessage = processMessage(_sock);\r
+                    _lastRecKa = new Date();\r
+                }\r
+\r
+                // Keep Alive\r
+                if (_kaTimer > 0) {\r
+                    // Timeout del PDP\r
+                    int _startTime = (int) (_lastRecKa.getTime());\r
+                    int cTime = (int) (new Date().getTime());\r
+\r
+                    if ((int)(cTime - _startTime) > _kaTimer*1000) {\r
+                        _sock.close();\r
+                        // Notify all Request State Managers\r
+                        notifyNoKAAllReqStateMan();\r
+                    }\r
+\r
+                    // Send to PEP\r
+                    _startTime = (int) (_lastSendKa.getTime());\r
+                    cTime = (int) (new Date().getTime());\r
+\r
+                    if ((int)(cTime - _startTime) > ((_kaTimer*3/4) * 1000)) {\r
+                        COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_KA);\r
+                        COPSKAMsg msg = new COPSKAMsg();\r
+\r
+                        msg.add(hdr);\r
+\r
+                        COPSTransceiver.sendMsg(msg, _sock);\r
+                        _lastSendKa = new Date();\r
+                    }\r
+                }\r
+\r
+                // Accounting\r
+                if (_acctTimer > 0) {\r
+                    int _startTime = (int) (_lastSendAcc.getTime());\r
+                    int cTime = (int) (new Date().getTime());\r
+\r
+                    if ((int)(cTime - _startTime) > ((_acctTimer*3/4)*1000)) {\r
+                        // Notify all Request State Managers\r
+                        notifyAcctAllReqStateMan();\r
+                        _lastSendAcc = new Date();\r
+                    }\r
+                }\r
+\r
+                try {\r
+                    Thread.sleep(500);\r
+                } catch (Exception e) {};\r
+            }\r
+        } catch (Exception e) {\r
+            e.printStackTrace();\r
+            COPSDebug.err(getClass().getName(), COPSDebug.ERROR_SOCKET, e);\r
+        }\r
+\r
+        // connection closed by server\r
+        // COPSDebug.out(getClass().getName(),"Connection closed by server");\r
+        try {\r
+            _sock.close();\r
+        } catch (IOException e) {};\r
+\r
+        // Notify all Request State Managers\r
+        try {\r
+            notifyCloseAllReqStateMan();\r
+        } catch (COPSPepException e) {};\r
+    }\r
+\r
+    /**\r
+     * Gets a COPS message from the socket and processes it\r
+     * @param conn  Socket connected to the PDP\r
+     * @return COPS message type\r
+     * @throws COPSPepException\r
+     * @throws COPSException\r
+     * @throws IOException\r
+     */\r
+    protected byte processMessage(Socket conn) throws COPSPepException, COPSException, IOException {\r
+        COPSMsg msg = COPSTransceiver.receiveMsg(conn);\r
+\r
+        if (msg.getHeader().isAClientClose()) {\r
+            handleClientCloseMsg(conn, msg);\r
+            return COPSHeader.COPS_OP_CC;\r
+        } else if (msg.getHeader().isADecision()) {\r
+            handleDecisionMsg(/*OJO conn, */msg);\r
+            return COPSHeader.COPS_OP_DEC;\r
+        } else if (msg.getHeader().isASyncStateReq()) {\r
+            handleSyncStateReqMsg(conn, msg);\r
+            return COPSHeader.COPS_OP_SSQ;\r
+        } else if (msg.getHeader().isAKeepAlive()) {\r
+            handleKeepAliveMsg(conn, msg);\r
+            return COPSHeader.COPS_OP_KA;\r
+        } else {\r
+            throw new COPSPepException("Message not expected (" + msg.getHeader().getOpCode() + ").");\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Handle Client Close Message, close the passed connection\r
+     *\r
+     * @param    conn                a  Socket\r
+     * @param    msg                 a  COPSMsg\r
+     *\r
+     *\r
+     * <Client-Close> ::= <Common Header>\r
+     *                      <Error>\r
+     *                      [<Integrity>]\r
+     *\r
+     * Not support [<Integrity>]\r
+     *\r
+     */\r
+    private void handleClientCloseMsg(Socket conn, COPSMsg msg) {\r
+        COPSClientCloseMsg cMsg = (COPSClientCloseMsg) msg;\r
+        _error = cMsg.getError();\r
+\r
+        // COPSDebug.out(getClass().getName(),"Got close request, closing connection " +\r
+        //  conn.getInetAddress() + ":" + conn.getPort() + ":[Error " + _error.getDescription() + "]");\r
+\r
+        try {\r
+            // Support\r
+            if (cMsg.getIntegrity() != null)\r
+                COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED, "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+            conn.close();\r
+        } catch (Exception unae) { };\r
+    }\r
+\r
+    /**\r
+     * Gets the COPS error\r
+     * @return  <tt>COPSError</tt> returned by PDP\r
+     */\r
+    protected COPSError getError() {\r
+        return _error;\r
+    }\r
+\r
+    /**\r
+     * Handle Keep Alive Message\r
+     *\r
+     * <Keep-Alive> ::= <Common Header>\r
+     *                  [<Integrity>]\r
+     *\r
+     * Not support [<Integrity>]\r
+     *\r
+     * @param    conn                a  Socket\r
+     * @param    msg                 a  COPSMsg\r
+     *\r
+     */\r
+    private void handleKeepAliveMsg(Socket conn, COPSMsg msg) {\r
+        COPSKAMsg cMsg = (COPSKAMsg) msg;\r
+\r
+        // COPSDebug.out(getClass().getName(),"Get KAlive Msg");\r
+\r
+        try {\r
+            // Support\r
+            if (cMsg.getIntegrity() != null)\r
+                COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED, "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+            // must we do anything else?\r
+\r
+        } catch (Exception unae) { };\r
+    }\r
+\r
+    /**\r
+     * Method handleDecisionMsg\r
+     *\r
+     * <Decision Message> ::= <Common Header: Flag SOLICITED>\r
+     *                          <Client Handle>\r
+     *                          *(<Decision>) | <Error>\r
+     *                          [<Integrity>]\r
+     * <Decision> ::= <Context>\r
+     *                  <Decision: Flags>\r
+     *                  [<ClientSI Decision Data: Outsourcing>]\r
+     * <Decision: Flags> ::= <Command-Code> NULLFlag\r
+     * <Command-Code> ::= NULLDecision | Install | Remove\r
+     * <ClientSI Decision Data> ::= <<Install Decision> | <Remove Decision>>\r
+     * <Install Decision> ::= *(<PRID> <EPD>)\r
+     * <Remove Decision> ::= *(<PRID> | <PPRID>)\r
+     *\r
+     * @param    msg                 a  COPSMsg\r
+     *\r
+     */\r
+    private void handleDecisionMsg(/*OJO Socket conn, */COPSMsg msg) throws COPSPepException {\r
+        COPSDecisionMsg dMsg = (COPSDecisionMsg) msg;\r
+        COPSHandle handle = dMsg.getClientHandle();\r
+        COPSPepOSReqStateMan manager = (COPSPepOSReqStateMan) _managerMap.get(handle.getId().str());\r
+        manager.processDecision(dMsg);\r
+    }\r
+\r
+    /**\r
+     * Method handleSyncStateReqMsg\r
+     *\r
+     *              <Synchronize State> ::= <Common Header>\r
+     *                                      [<Client Handle>]\r
+     *                                      [<Integrity>]\r
+     *\r
+     * @param    conn                a  Socket\r
+     * @param    msg                 a  COPSMsg\r
+     *\r
+     */\r
+    private void handleSyncStateReqMsg(Socket conn, COPSMsg msg) throws COPSPepException {\r
+        COPSSyncStateMsg cMsg = (COPSSyncStateMsg) msg;\r
+        // COPSHandle handle = cMsg.getClientHandle();\r
+        // COPSHeader header = cMsg.getHeader();\r
+\r
+        // Support\r
+        if (cMsg.getIntegrity() != null)\r
+            COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOSUPPORTED,\r
+                          "Unsupported objects (Integrity) to connection " + conn.getInetAddress());\r
+\r
+        COPSPepOSReqStateMan manager = (COPSPepOSReqStateMan) _managerMap.get(cMsg.getClientHandle().getId().str());\r
+\r
+        if (manager == null)\r
+            COPSDebug.err(getClass().getName(), COPSDebug.ERROR_NOEXPECTEDMSG);\r
+        else\r
+            manager.processSyncStateRequest(cMsg);\r
+    }\r
+\r
+    /**\r
+     * Adds a new request state\r
+     * @param clientHandle  Client's handle\r
+     * @param process       Policy data processing object\r
+     * @param clientSIs     Client data from the outsourcing event\r
+     * @return              The newly created request state manager\r
+     * @throws COPSException\r
+     * @throws COPSPepException\r
+     */\r
+    protected COPSPepOSReqStateMan addRequestState(String clientHandle, COPSPepOSDataProcess process, Vector clientSIs) throws COPSException, COPSPepException {\r
+        COPSPepOSReqStateMan manager = new COPSPepOSReqStateMan(_clientType, clientHandle);\r
+        if (_managerMap.get(clientHandle) != null)\r
+            throw new COPSPepException("Duplicate Handle, rejecting " + clientHandle);\r
+\r
+        manager.setDataProcess(process);\r
+        manager.setClientSI(clientSIs);\r
+        _managerMap.put(clientHandle, manager);\r
+        manager.initRequestState(_sock);\r
+        return manager;\r
+    }\r
+\r
+    /**\r
+     * Deletes a request state\r
+     * @param manager   Request state manager\r
+     * @throws COPSException\r
+     * @throws COPSPepException\r
+     */\r
+    protected void deleteRequestState(COPSPepOSReqStateMan manager) throws COPSException, COPSPepException {\r
+        manager.finalizeRequestState();\r
+    }\r
+\r
+    private void notifyCloseAllReqStateMan() throws COPSPepException {\r
+        if (_managerMap.size() > 0) {\r
+            for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+                String handle = (String) e.nextElement();\r
+                COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+                man.processClosedConnection(_error);\r
+            }\r
+        }\r
+    }\r
+\r
+    private void notifyNoKAAllReqStateMan() throws COPSPepException {\r
+        if (_managerMap.size() > 0) {\r
+            for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+                String handle = (String) e.nextElement();\r
+                COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+                man.processNoKAConnection();\r
+            }\r
+        }\r
+    }\r
+\r
+    private void notifyAcctAllReqStateMan() throws COPSPepException {\r
+        if (_managerMap.size() > 0) {\r
+            for (Enumeration e = _managerMap.keys() ; e.hasMoreElements() ;) {\r
+                String handle = (String) e.nextElement();\r
+                COPSPepOSReqStateMan man = (COPSPepOSReqStateMan) _managerMap.get(handle);\r
+\r
+                man.processAcctReport();\r
+            }\r
+        }\r
+    }\r
+\r
+}\r