c004e827190a1bff7b132ebee290316a5f703d2f
[packetcable.git] / protocol_plugins.packetcable / src / main / java / org / umu / cops / prpep / COPSPepReqStateMan.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.net.Socket;\r
10 import java.util.Enumeration;\r
11 import java.util.Hashtable;\r
12 import java.util.Vector;\r
13 \r
14 import org.umu.cops.stack.COPSContext;\r
15 import org.umu.cops.stack.COPSData;\r
16 import org.umu.cops.stack.COPSDecision;\r
17 import org.umu.cops.stack.COPSDecisionMsg;\r
18 import org.umu.cops.stack.COPSError;\r
19 import org.umu.cops.stack.COPSHandle;\r
20 import org.umu.cops.stack.COPSPrObjBase;\r
21 import org.umu.cops.stack.COPSSyncStateMsg;\r
22 \r
23 /**\r
24  * COPSPepReqStateMan manages Request State using Client Handle (RFC 2748 pag. 21)\r
25  * in PEP.\r
26  *\r
27  *   The client handle is used to identify a unique request state for a\r
28  *   single PEP per client-type. Client handles are chosen by the PEP and\r
29  *   are opaque to the PDP. The PDP simply uses the request handle to\r
30  *   uniquely identify the request state for a particular Client-Type over\r
31  *   a particular TCP connection and generically tie its decisions to a\r
32  *   corresponding request. Client handles are initiated in request\r
33  *   messages and are then used by subsequent request, decision, and\r
34  *   report messages to reference the same request state. When the PEP is\r
35  *   ready to remove a local request state, it will issue a delete message\r
36  *   to the PDP for the corresponding client handle. A handle MUST be\r
37  *   explicitly deleted by the PEP before it can be used by the PEP to\r
38  *   identify a new request state. Handles referring to different request\r
39  *   states MUST be unique within the context of a particular TCP\r
40  *   connection and client-type.\r
41  *\r
42  * @version COPSPepReqStateMan.java, v 2.00 2004\r
43  *\r
44  */\r
45 public class COPSPepReqStateMan {\r
46 \r
47     /**\r
48      * Request State created\r
49      */\r
50     public final static short ST_CREATE = 1;\r
51     /**\r
52      * Request sent\r
53      */\r
54     public final static short ST_INIT = 2;\r
55     /**\r
56      * Decisions received\r
57      */\r
58     public final static short ST_DECS = 3;\r
59     /**\r
60      * Report sent\r
61      */\r
62     public final static short ST_REPORT = 4;\r
63     /**\r
64      * Request State finalized\r
65      */\r
66     public final static short ST_FINAL = 5;\r
67     /**\r
68      * New Request State solicited\r
69      */\r
70     public final static short ST_NEW = 6;\r
71     /**\r
72      * Delete Request State solicited\r
73      */\r
74     public final static short ST_DEL = 7;\r
75     /**\r
76      * SYNC Request received\r
77      */\r
78     public final static short ST_SYNC = 8;\r
79     /**\r
80      * SYNC Completed\r
81      */\r
82     public final static short ST_SYNCALL = 9;\r
83     /**\r
84      * Close Connection received\r
85      */\r
86     public final static short ST_CCONN = 10;\r
87     /**\r
88      * KAlive Time out\r
89      */\r
90     public final static short ST_NOKA = 11;\r
91     /**\r
92      * ACCT Time out\r
93      */\r
94     public final static short ST_ACCT = 12;\r
95 \r
96     /**\r
97      * The client-type identifies the policy client\r
98      */\r
99     protected short _clientType;\r
100 \r
101     /**\r
102      *  The client handle is used to uniquely identify a particular\r
103      *  PEP's request for a client-type\r
104      */\r
105     protected COPSHandle _handle;\r
106 \r
107     /**\r
108         The PolicyDataProcess is used to process policy data in the PEP\r
109      */\r
110     protected COPSPepDataProcess _process;\r
111 \r
112     /**\r
113      *  State Request State\r
114      */\r
115     protected short _status;\r
116 \r
117     /**\r
118         The Msg Sender is used to send COPS messages\r
119      */\r
120     protected COPSPepMsgSender _sender;\r
121 \r
122     /**\r
123      * Sync State\r
124      */\r
125     protected boolean _syncState;\r
126 \r
127     /**\r
128      * Create a State Request Manager\r
129      *\r
130      * @param    clientHandle                a Client Handle\r
131      *\r
132      */\r
133     public COPSPepReqStateMan(short clientType, String clientHandle) {\r
134         // COPS Handle\r
135         _handle = new COPSHandle();\r
136         COPSData id = new COPSData(clientHandle);\r
137         _handle.setId(id);\r
138         // client-type\r
139         _clientType = clientType;\r
140         _syncState = true;\r
141         _status = ST_CREATE;\r
142     }\r
143 \r
144     /**\r
145      * Return client handle\r
146      *\r
147      * @return   a COPSHandle\r
148      *\r
149      */\r
150     public COPSHandle getClientHandle() {\r
151         return _handle;\r
152     }\r
153 \r
154     /**\r
155      * Return client-type\r
156      *\r
157      * @return   a short\r
158      *\r
159      */\r
160     public short getClientType() {\r
161         return _clientType;\r
162     }\r
163 \r
164     /**\r
165      * Return Request State status\r
166      *\r
167      * @return      s short\r
168      */\r
169     public short getStatus() {\r
170         return _status;\r
171     }\r
172 \r
173     /**\r
174      * Return the Policy Data Process\r
175      *\r
176      * @return   a PolicyConfigure\r
177      *\r
178      */\r
179     public COPSPepDataProcess getDataProcess() {\r
180         return _process;\r
181     }\r
182 \r
183     /**\r
184      * Establish the Policy Data Process\r
185      *\r
186      * @param    process              a  PolicyConfigure\r
187      *\r
188      */\r
189     public void setDataProcess(COPSPepDataProcess process) {\r
190         _process = process;\r
191     }\r
192 \r
193     /**\r
194      * Init Request State\r
195      *\r
196      * @throws   COPSPepException\r
197      *\r
198      */\r
199     protected void initRequestState(Socket sock)\r
200     throws COPSPepException {\r
201         // Inits an object for sending COPS messages to the PDP\r
202         _sender = new COPSPepMsgSender(_clientType, _handle, sock);\r
203 \r
204         // If an object for retrieving PEP features exists,\r
205         // use it for retrieving them\r
206         Hashtable clientSIs;\r
207         if (_process != null)\r
208             clientSIs = _process.getClientData(this);\r
209         else\r
210             clientSIs = null;\r
211 \r
212         // Send the request\r
213         _sender.sendRequest(clientSIs);\r
214 \r
215         // Initial state\r
216         _status = ST_INIT;\r
217     }\r
218 \r
219     /**\r
220      * Finalize Request State\r
221      *\r
222      * @throws   COPSPepException\r
223      *\r
224      */\r
225     protected void finalizeRequestState()\r
226     throws COPSPepException {\r
227         _sender.sendDeleteRequest();\r
228         _status = ST_FINAL;\r
229     }\r
230 \r
231     /**\r
232      * Process the message Decision\r
233      *\r
234      * @param    dMsg                a  COPSDecisionMsg\r
235      *\r
236      * @throws   COPSPepException\r
237      *\r
238      */\r
239     protected void processDecision(COPSDecisionMsg dMsg)\r
240     throws COPSPepException {\r
241         // COPSDebug.out(getClass().getName(), "ClientId:" + getClientHandle().getId().str());\r
242 \r
243         // COPSHandle handle = dMsg.getClientHandle();\r
244         Hashtable decisions = dMsg.getDecisions();\r
245 \r
246         Hashtable removeDecs = new Hashtable(40);\r
247         Hashtable installDecs = new Hashtable(40);\r
248         Hashtable errorDecs = new Hashtable(40);\r
249         for (Enumeration e = decisions.keys() ; e.hasMoreElements() ;) {\r
250 \r
251             COPSContext context = (COPSContext) e.nextElement();\r
252             Vector v = (Vector) decisions.get(context);\r
253             Enumeration ee = v.elements();\r
254             COPSDecision cmddecision = (COPSDecision) ee.nextElement();\r
255 \r
256             // cmddecision --> we must check whether it is an error!\r
257 \r
258             if (cmddecision.isInstallDecision()) {\r
259                 String prid = new String();\r
260                 for (; ee.hasMoreElements() ;) {\r
261                     COPSDecision decision = (COPSDecision) ee.nextElement();\r
262 \r
263                     COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
264                     switch (obj.getSNum()) {\r
265                     case COPSPrObjBase.PR_PRID:\r
266                         prid = obj.getData().str();\r
267                         break;\r
268                     case COPSPrObjBase.PR_EPD:\r
269                         installDecs.put(prid, obj.getData().str());\r
270                         break;\r
271                     default:\r
272                         break;\r
273                     }\r
274                 }\r
275             }\r
276 \r
277             if (cmddecision.isRemoveDecision()) {\r
278 \r
279                 String prid = new String();\r
280                 for (; ee.hasMoreElements() ;) {\r
281                     COPSDecision decision = (COPSDecision) ee.nextElement();\r
282 \r
283                     COPSPrObjBase obj = new COPSPrObjBase(decision.getData().getData());\r
284                     switch (obj.getSNum()) {\r
285                     case COPSPrObjBase.PR_PRID:\r
286                         prid = obj.getData().str();\r
287                         break;\r
288                     case COPSPrObjBase.PR_EPD:\r
289                         removeDecs.put(prid, obj.getData().str());\r
290                         break;\r
291                     default:\r
292                         break;\r
293                     }\r
294                 }\r
295             }\r
296         }\r
297 \r
298         //** Apply decisions to the configuration\r
299         _process.setDecisions(this, removeDecs, installDecs, errorDecs);\r
300         _status = ST_DECS;\r
301 \r
302 \r
303         if (_process.isFailReport(this)) {\r
304             // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");\r
305             _sender.sendFailReport(_process.getReportData(this));\r
306         } else {\r
307             // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");\r
308             _sender.sendSuccessReport(_process.getReportData(this));\r
309         }\r
310         _status = ST_REPORT;\r
311 \r
312         if (!_syncState) {\r
313             _sender.sendSyncComplete();\r
314             _syncState = true;\r
315             _status = ST_SYNCALL;\r
316         }\r
317     }\r
318 \r
319     /**\r
320      * Process the message NewRequestState\r
321      *\r
322      * @throws   COPSPepException\r
323      *\r
324      */\r
325     protected void processOpenNewRequestState()\r
326     throws COPSPepException {\r
327 \r
328         if (_process != null)\r
329             _process.newRequestState(this);\r
330 \r
331         _status = ST_NEW;\r
332     }\r
333 \r
334     /**\r
335      * Process the message DeleteRequestState\r
336      *\r
337      * @param    dMsg                a  COPSDecisionMsg\r
338      *\r
339      * @throws   COPSPepException\r
340      *\r
341      */\r
342     protected void processDeleteRequestState(COPSDecisionMsg dMsg)\r
343     throws COPSPepException {\r
344         if (_process != null)\r
345             _process.closeRequestState(this);\r
346 \r
347         _status = ST_DEL;\r
348     }\r
349 \r
350     /**\r
351      * Process the message SycnStateRequest.\r
352      * The message SycnStateRequest indicates that the remote PDP\r
353      * wishes the client (which appears in the common header)\r
354      * to re-send its state.\r
355      *\r
356      * @param    ssMsg               a  COPSSyncStateMsg\r
357      *\r
358      * @throws   COPSPepException\r
359      *\r
360      */\r
361     protected void processSyncStateRequest(COPSSyncStateMsg ssMsg)\r
362     throws COPSPepException {\r
363         _syncState = false;\r
364         // If an object for retrieving PEP features exists,\r
365         // use it for retrieving them\r
366         Hashtable clientSIs;\r
367         if (_process != null)\r
368             clientSIs = _process.getClientData(this);\r
369         else\r
370             clientSIs = null;\r
371 \r
372         // Send request\r
373         _sender.sendRequest(clientSIs);\r
374 \r
375         _status = ST_SYNC;\r
376     }\r
377 \r
378     protected void processClosedConnection(COPSError error)\r
379     throws COPSPepException {\r
380         if (_process != null)\r
381             _process.notifyClosedConnection(this, error);\r
382 \r
383         _status = ST_CCONN;\r
384     }\r
385 \r
386     protected void processNoKAConnection()\r
387     throws COPSPepException {\r
388         if (_process != null)\r
389             _process.notifyNoKAliveReceived(this);\r
390 \r
391         _status = ST_NOKA;\r
392     }\r
393 \r
394     protected void processAcctReport()\r
395     throws COPSPepException {\r
396 \r
397         Hashtable report = new Hashtable();\r
398         if (_process != null)\r
399             report = _process.getAcctData(this);\r
400 \r
401         _sender.sendAcctReport(report);\r
402 \r
403         _status = ST_ACCT;\r
404     }\r
405 \r
406 }\r