Merge "Remove "response" from yang."
[packetcable.git] / protocol_plugins.packetcable / src / main / java / org / umu / cops / prpep / COPSPepAgent.java
1 /*\r
2  * Copyright (c) 2004 University of Murcia.  All rights reserved.\r
3  * --------------------------------------------------------------\r
4  * For more information, please see <http://www.umu.euro6ix.org/>.\r
5  */\r
6 \r
7 package org.umu.cops.prpep;\r
8 \r
9 import java.io.IOException;\r
10 import java.net.InetAddress;\r
11 import java.net.Socket;\r
12 import java.net.UnknownHostException;\r
13 import java.util.Hashtable;\r
14 \r
15 import org.umu.cops.stack.COPSAcctTimer;\r
16 import org.umu.cops.stack.COPSClientAcceptMsg;\r
17 import org.umu.cops.stack.COPSClientCloseMsg;\r
18 import org.umu.cops.stack.COPSClientOpenMsg;\r
19 import org.umu.cops.stack.COPSData;\r
20 import org.umu.cops.stack.COPSError;\r
21 import org.umu.cops.stack.COPSException;\r
22 import org.umu.cops.stack.COPSHeader;\r
23 import org.umu.cops.stack.COPSKATimer;\r
24 import org.umu.cops.stack.COPSMsg;\r
25 import org.umu.cops.stack.COPSPepId;\r
26 import org.umu.cops.stack.COPSTransceiver;\r
27 \r
28 /**\r
29  * This is a provisioning COPS PEP. Responsible for making\r
30  * connection to the PDP and maintaining it\r
31  */\r
32 public class COPSPepAgent {\r
33 \r
34     /**\r
35         PEP's Identifier\r
36      */\r
37     private String _pepID;\r
38 \r
39     /**\r
40         PEP's client-type\r
41      */\r
42     private short _clientType;\r
43 \r
44     /**\r
45         PDP host name\r
46      */\r
47     private String _psHost;\r
48 \r
49     /**\r
50         PDP port\r
51      */\r
52     private int _psPort;\r
53 \r
54     /**\r
55         PEP-PDP connection manager\r
56      */\r
57     private COPSPepConnection _conn;\r
58 \r
59     /**\r
60         COPS error returned by PDP\r
61      */\r
62     private COPSError _error;\r
63 \r
64     /**\r
65      * Creates a PEP agent\r
66      * @param    pepID              PEP-ID\r
67      * @param    clientType         Client-type\r
68      */\r
69     public COPSPepAgent(String pepID, short clientType) {\r
70         _pepID = pepID;\r
71         _clientType = clientType;\r
72     }\r
73 \r
74     /**\r
75      * Creates a PEP agent with a PEP-ID equal to "noname"\r
76      * @param    clientType         Client-type\r
77      */\r
78     public COPSPepAgent(short clientType) {\r
79 \r
80         // PEPId\r
81         try {\r
82             _pepID = InetAddress.getLocalHost().getHostName();\r
83         } catch (Exception e) {\r
84             _pepID = "noname";\r
85         }\r
86 \r
87         _clientType = clientType;\r
88     }\r
89 \r
90     /**\r
91      * Gets the identifier of the PEP\r
92      * @return  PEP-ID\r
93      */\r
94     public String getPepID() {\r
95         return _pepID;\r
96     }\r
97 \r
98     /**\r
99      * Gets the COPS client-type\r
100      * @return  PEP's client-type\r
101      */\r
102     public short getClientType() {\r
103         return _clientType;\r
104     }\r
105 \r
106     /**\r
107      * Gets PDP host name\r
108      * @return  PDP host name\r
109      */\r
110     public String getPDPName() {\r
111         return _psHost;\r
112     }\r
113 \r
114     /**\r
115      * Gets the port of the PDP\r
116      * @return  PDP port\r
117      */\r
118     public int getPDPPort() {\r
119         return _psPort;\r
120     }\r
121 \r
122     /**\r
123      * Connects to a PDP\r
124      * @param    psHost              PDP host name\r
125      * @param    psPort              PDP port\r
126      * @return   <tt>true</tt> if PDP accepts the connection; <tt>false</tt> otherwise\r
127      * @throws   java.net.UnknownHostException\r
128      * @throws   java.io.IOException\r
129      * @throws   COPSException\r
130      * @throws   COPSPepException\r
131      */\r
132     public boolean connect(String psHost, int psPort)\r
133     throws UnknownHostException, IOException, COPSException, COPSPepException {\r
134 \r
135         // COPSDebug.out(getClass().getName(), "Thread ( " + _pepID + ") - Connecting to PDP");\r
136         _psHost = psHost;\r
137         _psPort = psPort;\r
138 \r
139         // Check whether it already exists\r
140         if (_conn == null)\r
141             _conn = processConnection(psHost,psPort);\r
142         else {\r
143             // Check if it's closed\r
144             if (_conn.isClosed()) {\r
145                 _conn = processConnection(psHost,psPort);\r
146             } else {\r
147                 disconnect(null);\r
148                 _conn = processConnection(psHost,psPort);\r
149             }\r
150         }\r
151 \r
152         return (_conn != null);\r
153     }\r
154 \r
155     /**\r
156      * Gets the connection manager\r
157      * @return  PEP-PDP connection manager object\r
158      */\r
159     public COPSPepConnection getConnection () {\r
160         return (_conn);\r
161     }\r
162 \r
163     /**\r
164      * Gets the COPS error returned by the PDP\r
165      * @return   <tt>COPSError</tt> returned by PDP\r
166      */\r
167     public COPSError getConnectionError()   {\r
168         return _error;\r
169     }\r
170 \r
171     /**\r
172      * Disconnects from the PDP\r
173      * @param error Reason\r
174      * @throws COPSException\r
175      * @throws IOException\r
176      */\r
177     public void disconnect(COPSError error)\r
178     throws COPSException, IOException {\r
179 \r
180         COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, _clientType);\r
181         COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();\r
182         closeMsg.add(cHdr);\r
183         if (error != null)\r
184             closeMsg.add(error);\r
185 \r
186         closeMsg.writeData(_conn.getSocket());\r
187         _conn.close();\r
188         _conn = null;\r
189     }\r
190 \r
191     /**\r
192      * Adds a request state to the connection manager.\r
193      * @return  The newly created connection manager\r
194      * @throws COPSPepException\r
195      * @throws COPSException\r
196      */\r
197     public COPSPepReqStateMan addRequestState (String handle, COPSPepDataProcess process)\r
198     throws COPSPepException, COPSException {\r
199         if (_conn != null) {\r
200             return _conn.addRequestState(handle, process);\r
201         }\r
202         return null;\r
203     }\r
204 \r
205 \r
206     /**\r
207      * Queries the connection manager to delete a request state\r
208      * @param man   Request state manager\r
209      * @throws COPSPepException\r
210      * @throws COPSException\r
211      */\r
212     public void deleteRequestState (COPSPepReqStateMan man)\r
213     throws COPSPepException, COPSException {\r
214         if (_conn != null)\r
215             _conn.deleteRequestState(man);\r
216     }\r
217 \r
218     /**\r
219      * Gets all the request state managers\r
220      * @return  A <tt>Hashtable</tt> holding all active request state managers\r
221      */\r
222     public Hashtable getReqStateMans() {\r
223         if (_conn != null)\r
224             return _conn.getReqStateMans();\r
225         return null;\r
226     }\r
227 \r
228     /**\r
229      * Establish connection to PDP's IP address\r
230      *\r
231      * <Client-Open> ::= <Common Header>\r
232      *                  <PEPID>\r
233      *                  [<ClientSI>]\r
234      *                  [<LastPDPAddr>]\r
235      *                  [<Integrity>]\r
236      *\r
237      * Not support [<ClientSI>], [<LastPDPAddr>], [<Integrity>]\r
238      *\r
239      * <Client-Accept> ::= <Common Header>\r
240      *                      <KA Timer>\r
241      *                      [<ACCT Timer>]\r
242      *                      [<Integrity>]\r
243      *\r
244      * Not send [<Integrity>]\r
245      *\r
246      * <Client-Close> ::= <Common Header>\r
247      *                      <Error>\r
248      *                      [<PDPRedirAddr>]\r
249      *                      [<Integrity>]\r
250      *\r
251      * Not send [<PDPRedirAddr>], [<Integrity>]\r
252      *\r
253      * @throws   UnknownHostException\r
254      * @throws   IOException\r
255      * @throws   COPSException\r
256      * @throws   COPSPepException\r
257      *\r
258      */\r
259     private COPSPepConnection processConnection(String psHost, int psPort)\r
260     throws UnknownHostException, IOException, COPSException, COPSPepException {\r
261         // Build OPN\r
262         COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, _clientType);\r
263 \r
264         COPSPepId pepId = new COPSPepId();\r
265         COPSData d = new COPSData(_pepID);\r
266         pepId.setData(d);\r
267 \r
268         COPSClientOpenMsg msg = new COPSClientOpenMsg();\r
269         msg.add(hdr);\r
270         msg.add(pepId);\r
271 \r
272         // Create Socket and send OPN\r
273         InetAddress addr = InetAddress.getByName(psHost);\r
274         Socket socket = new Socket(addr,psPort);\r
275         msg.writeData(socket);\r
276 \r
277         // Receive the response\r
278         COPSMsg recvmsg = COPSTransceiver.receiveMsg(socket);\r
279 \r
280         if (recvmsg.getHeader().isAClientAccept()) {\r
281             COPSClientAcceptMsg cMsg = (COPSClientAcceptMsg) recvmsg;\r
282 \r
283             // Support\r
284             if (cMsg.getIntegrity() != null) {\r
285                 throw new COPSPepException("Unsupported object (Integrity)");\r
286             }\r
287 \r
288             // Mandatory KATimer\r
289             COPSKATimer kt = cMsg.getKATimer();\r
290             if (kt == null)\r
291                 throw new COPSPepException ("Mandatory COPS object missing (KA Timer)");\r
292             short _kaTimeVal = kt.getTimerVal();\r
293 \r
294             // ACTimer\r
295             COPSAcctTimer at = cMsg.getAcctTimer();\r
296             short _acctTimer = 0;\r
297             if (at != null)\r
298                 _acctTimer = at.getTimerVal();\r
299 \r
300             // Create the connection manager\r
301             COPSPepConnection conn = new COPSPepConnection(_clientType, socket);\r
302             conn.setKaTimer(_kaTimeVal);\r
303             conn.setAcctTimer(_acctTimer);\r
304             new Thread(conn).start();\r
305 \r
306             return conn;\r
307         } else if (recvmsg.getHeader().isAClientClose()) {\r
308             COPSClientCloseMsg cMsg = (COPSClientCloseMsg) recvmsg;\r
309             _error = cMsg.getError();\r
310             socket.close();\r
311             return null;\r
312         } else { // messages of other types are not expected\r
313             throw new COPSPepException("Message not expected. Closing connection for " + socket.toString());\r
314         }\r
315     }\r
316 }\r
317 \r
318 \r
319 \r