Merge "Completed COPS Message refactoring. Was planning on one additional patch start...
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / PCMMPepAgent.java
1 /**
2  @header@
3  */
4
5 package org.pcmm;
6
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import org.umu.cops.prpep.COPSPepAgent;
10 import org.umu.cops.prpep.COPSPepConnection;
11 import org.umu.cops.prpep.COPSPepException;
12 import org.umu.cops.stack.*;
13 import org.umu.cops.stack.COPSHeader.ClientType;
14 import org.umu.cops.stack.COPSHeader.OPCode;
15
16 import java.io.IOException;
17 import java.net.ServerSocket;
18 import java.net.Socket;
19
20 /**
21  * This is a provisioning COPS PEP. Responsible for making connection to the PDP
22  * and maintaining it
23  */
24 public class PCMMPepAgent extends COPSPepAgent implements Runnable {
25
26     public final static Logger logger = LoggerFactory.getLogger(PCMMPepAgent.class);
27
28     /** Well-known port for COPS */
29     public static final int WELL_KNOWN_CMTS_PORT = 3918;
30
31     /**
32      * PDP host IP
33      */
34     private ServerSocket serverSocket;
35
36     /**
37      * PDP host port
38      */
39     private int serverPort;
40
41     /**
42      * COPS error returned by PDP
43      */
44     private COPSError error;
45
46     /**
47      * Creates a PEP agent
48      *
49      * @param pepID
50      *            PEP-ID
51      * @param clientType
52      *            Client-type
53      */
54     public PCMMPepAgent(final String pepID, final ClientType clientType) {
55         super(pepID, clientType);
56         serverPort = WELL_KNOWN_CMTS_PORT;
57     }
58
59     /**
60      * Creates a PEP agent with a PEP-ID equal to "noname"
61      *
62      * @param clientType
63      *            Client-type
64      */
65     public PCMMPepAgent(final ClientType clientType) {
66         super(clientType);
67         serverPort = WELL_KNOWN_CMTS_PORT;
68     }
69
70     /**
71      * Runs the PEP process XXX - not sure of the exception throwing
72      */
73     public void run() {
74         try {
75
76             logger.info("Create Server Socket on Port " + serverPort);
77
78             serverSocket = new ServerSocket(serverPort);
79             // Loop through for Incoming messages
80
81             // server infinite loop
82             while (true) {
83
84                 // Wait for an incoming connection from a PEP
85                 Socket socket = serverSocket.accept();
86
87                 logger.info("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
88
89                 processConnection(socket);
90                 /**
91                  * XXX - processConnection handles the open request from PEP And
92                  * a thread is created for conn = new
93                  * COPSPepConnection(_clientType, socket); the main processing
94                  * loop for PEP
95                  */
96
97             }
98         } catch (Exception e) {
99             logger.error("Error while processing the socket connection", e);
100         }
101     }
102
103     /**
104      * Establish connection to PDP's IP address
105      *
106      * <Client-Open> ::= <Common Header> <PEPID> [<ClientSI>] [<LastPDPAddr>]
107      * [<Integrity>]
108      *
109      * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]
110      *
111      * <Client-Accept> ::= <Common Header> <KA Timer> [<ACCT Timer>]
112      * [<Integrity>]
113      *
114      * Not send [<Integrity>]
115      *
116      * <Client-Close> ::= <Common Header> <Error> [<PDPRedirAddr>] [<Integrity>]
117      *
118      * Not send [<PDPRedirAddr>], [<Integrity>]
119      *
120      * @throws IOException
121      * @throws COPSException
122      * @throws COPSPepException
123      *
124      */
125     private COPSPepConnection processConnection(Socket socket) throws IOException, COPSException, COPSPepException {
126         // Build OPN
127         final COPSPepId pepId = new COPSPepId(new COPSData(getPepID()));
128         final COPSClientOpenMsg msg = new COPSClientOpenMsg(getClientType(), pepId, null, null, null);
129
130         // Create Socket and send OPN
131         /*
132          * InetAddress addr = InetAddress.getByName(psHost); Socket socket = new
133          * Socket(addr,psPort);
134          */
135         logger.info("Send COPSClientOpenMsg to PDP");
136         msg.writeData(socket);
137
138         // Receive the response
139         logger.info("Receive the resposne from PDP");
140         COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);
141
142         if (recvmsg.getHeader().getOpCode().equals(OPCode.CAT)) {
143             logger.info("isAClientAccept from PDP");
144             COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;
145
146             // Support
147             if (cMsg.getIntegrity() != null) {
148                 throw new COPSPepException("Unsupported object (Integrity)");
149             }
150
151             // Mandatory KATimer
152             COPSKATimer kt = cMsg.getKATimer();
153             if (kt == null)
154                 throw new COPSPepException(
155                     "Mandatory COPS object missing (KA Timer)");
156             short _kaTimeVal = kt.getTimerVal();
157
158             // ACTimer
159             COPSAcctTimer at = cMsg.getAcctTimer();
160             short _acctTimer = 0;
161             if (at != null)
162                 _acctTimer = at.getTimerVal();
163
164             // Create the connection manager
165             COPSPepConnection conn = new COPSPepConnection(getClientType(),
166                     socket);
167             conn.setKaTimer(_kaTimeVal);
168             conn.setAcctTimer(_acctTimer);
169             logger.info("Thread(conn).start");
170             new Thread(conn).start();
171
172             return conn;
173         } else if (recvmsg.getHeader().getOpCode().equals(OPCode.CC)) {
174             logger.info("isAClientClose from PDP");
175             COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;
176             error = cMsg.getError();
177             socket.close();
178             return null;
179         } else { // messages of other types are not expected
180             throw new COPSPepException(
181                 "Message not expected. Closing connection for "
182                 + socket.toString());
183         }
184     }
185
186     /**
187      * Gets the COPS error returned by the PDP
188      *
189      * @return <tt>COPSError</tt> returned by PDP
190      */
191     public COPSError getConnectionError() {
192         return error;
193     }
194
195     public void setConnectionError(COPSError _error) {
196         this.error = _error;
197     }
198
199     /**
200      * @return the serverSocket
201      */
202     public ServerSocket getServerSocket() {
203         return serverSocket;
204     }
205
206     /**
207      * @param serverSocket
208      *            the serverSocket to set
209      */
210     public void setServerSocket(ServerSocket serverSocket) {
211         this.serverSocket = serverSocket;
212     }
213
214     /**
215      * @return the serverPort
216      */
217     public int getServerPort() {
218         return serverPort;
219     }
220
221     /**
222      * @param serverPort
223      *            the serverPort to set
224      */
225     public void setServerPort(int serverPort) {
226         this.serverPort = serverPort;
227     }
228
229 }