Merge "Changed tests to leverage a dynamic port for testing COPS message marshalling...
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / prpdp / COPSPdpReqStateMan.java
1 /*
2  * Copyright (c) 2004 University of Murcia.  All rights reserved.
3  * --------------------------------------------------------------
4  * For more information, please see <http://www.umu.euro6ix.org/>.
5  */
6
7 package org.umu.cops.prpdp;
8
9 import org.umu.cops.stack.*;
10
11 import java.net.Socket;
12 import java.util.HashMap;
13 import java.util.Map;
14
15 /**
16  * State manager class for provisioning requests, at the PDP side.
17  */
18 public class COPSPdpReqStateMan {
19
20     /**
21      * Request State created
22      */
23     public final static short ST_CREATE = 1;
24     /**
25      * Request received
26      */
27     public final static short ST_INIT = 2;
28     /**
29      * Decisions sent
30      */
31     public final static short ST_DECS = 3;
32     /**
33      * Report received
34      */
35     public final static short ST_REPORT = 4;
36     /**
37      * Request State finalized
38      */
39     public final static short ST_FINAL = 5;
40     /**
41      * New Request State solicited
42      */
43     public final static short ST_NEW = 6;
44     /**
45      * Delete Request State solicited
46      */
47     public final static short ST_DEL = 7;
48     /**
49      * SYNC request sent
50      */
51     public final static short ST_SYNC = 8;
52     /**
53      * SYNC completed
54      */
55     public final static short ST_SYNCALL = 9;
56     /**
57      * Close connection received
58      */
59     public final static short ST_CCONN = 10;
60     /**
61      * Keep-alive timeout
62      */
63     public final static short ST_NOKA = 11;
64     /**
65      * Accounting timeout
66      */
67     public final static short ST_ACCT = 12;
68
69     /**
70      * COPS client-type that identifies the policy client
71      */
72     protected short _clientType;
73
74     /**
75      *  COPS client handle used to uniquely identify a particular
76      *  PEP's request for a client-type
77      */
78     protected COPSHandle _handle;
79
80     /**
81      * Object for performing policy data processing
82      */
83     protected COPSPdpDataProcess _process;
84
85     /**
86      *  Current state of the request being managed
87      */
88     protected short _status;
89
90     /** COPS message transceiver used to send COPS messages */
91     protected COPSPdpMsgSender _sender;
92
93     /**
94      * Creates a request state manager
95      * @param clientType    Client-type
96      * @param clientHandle  Client handle
97      */
98     public COPSPdpReqStateMan(short clientType, String clientHandle) {
99         _handle = new COPSHandle(new COPSData(clientHandle));
100         _clientType = clientType;
101         _status = ST_CREATE;
102     }
103
104     /**
105      * Gets the client handle
106      * @return   Client's <tt>COPSHandle</tt>
107      */
108     public COPSHandle getClientHandle() {
109         return _handle;
110     }
111
112     /**
113      * Gets the client-type
114      * @return   Client-type value
115      */
116     public int getClientType() {
117         return _clientType;
118     }
119
120     /**
121      * Gets the status of the request
122      * @return      Request state value
123      */
124     public short getStatus() {
125         return _status;
126     }
127
128     /**
129      * Gets the policy data processing object
130      * @return   Policy data processing object
131      */
132     public COPSPdpDataProcess getDataProcess() {
133         return _process;
134     }
135
136     /**
137      * Sets the policy data processing object
138      * @param   process Policy data processing object
139      */
140     public void setDataProcess(COPSPdpDataProcess process) {
141         _process = process;
142     }
143
144     /**
145      * Called when COPS sync is completed
146      * @param    repMsg              COPS sync message
147      * @throws   COPSPdpException
148      */
149     protected void processSyncComplete(COPSSyncStateMsg repMsg)
150     throws COPSPdpException {
151
152         _status = ST_SYNCALL;
153
154         // maybe we should notifySyncComplete ...
155     }
156
157     /**
158      * Initializes a new request state over a socket
159      * @param sock  Socket to the PEP
160      * @throws COPSPdpException
161      */
162     protected void initRequestState(Socket sock)
163     throws COPSPdpException {
164         // Inits an object for sending COPS messages to the PEP
165         _sender = new COPSPdpMsgSender(_clientType, _handle, sock);
166
167         // Initial state
168         _status = ST_INIT;
169     }
170
171     /**
172      * Processes a COPS request
173      * @param msg   COPS request received from the PEP
174      * @throws COPSPdpException
175      */
176     protected void processRequest(COPSReqMsg msg)
177     throws COPSPdpException {
178
179         COPSHeader hdrmsg = msg.getHeader();
180         COPSHandle handlemsg = msg.getClientHandle();
181         COPSContext contextmsg = msg.getContext();
182
183         //** Analyze the request
184         //**
185
186         /* <Request> ::= <Common Header>
187         *                   <Client Handle>
188         *                   <Context>
189         *                   *(<Named ClientSI>)
190         *                   [<Integrity>]
191         * <Named ClientSI> ::= <*(<PRID> <EPD>)>
192         *
193         * Very important, this is actually being treated like this:
194         * <Named ClientSI> ::= <PRID> | <EPD>
195         *
196
197         // Named ClientSI
198         Vector clientSIs = msg.getClientSI();
199         Hashtable reqSIs = new Hashtable(40);
200         String strobjprid = new String();
201         for (Enumeration e = clientSIs.elements() ; e.hasMoreElements() ;) {
202             COPSClientSI clientSI = (COPSClientSI) e.nextElement();
203
204             COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
205             switch (obj.getSNum())
206             {
207                 case COPSPrObjBase.PR_PRID:
208                     strobjprid = obj.getData().str();
209                     break;
210                 case COPSPrObjBase.PR_EPD:
211                     reqSIs.put(strobjprid, obj.getData().str());
212                     // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
213                     // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
214                     break;
215                 default:
216                     break;
217             }
218         }
219
220         //** Here we must retrieve a decision depending on
221         //** the supplied ClientSIs
222         // reqSIs is a hashtable with the prid and epds
223
224         // ................
225         //
226         Hashtable removeDecs = new Hashtable();
227         Hashtable installDecs = new Hashtable();
228         _process.setClientData(this, reqSIs);
229
230         removeDecs = _process.getRemovePolicy(this);
231         installDecs = _process.getInstallPolicy(this);
232
233         //** We create the SOLICITED decision
234         //**
235         _sender.sendDecision(removeDecs, installDecs);
236         _status = ST_DECS;
237         */
238     }
239
240     /**
241      * Processes a report
242      * @param msg   Report message from the PEP
243      * @throws COPSPdpException
244      */
245     protected void processReport(final COPSReportMsg msg) throws COPSPdpException {
246
247         //** Analyze the report
248         //**
249
250         /*
251          * <Report State> ::= <Common Header>
252          *                      <Client Handle>
253          *                      <Report Type>
254          *                      *(<Named ClientSI>)
255          *                      [<Integrity>]
256          * <Named ClientSI: Report> ::= <[<GPERR>] *(<report>)>
257          * <report> ::= <ErrorPRID> <CPERR> *(<PRID><EPD>)
258          *
259          * Important, <Named ClientSI> is not parsed
260         */
261
262         // COPSHeader hdrmsg = msg.getHeader();
263         // COPSHandle handlemsg = msg.getClientHandle();
264
265         if (msg.getClientSI() != null) {
266             // Report Type
267             final COPSReportType rtypemsg = msg.getReport();
268
269             // Named ClientSI
270             //        final Set<COPSClientSI> clientSIs = msg.getClientSI();
271             final Map<String, String> repSIs = new HashMap<>();
272             String strobjprid = "";
273             //        for (final COPSClientSI clientSI : clientSIs) {
274             final COPSPrObjBase obj = new COPSPrObjBase(msg.getClientSI().getData().getData());
275             switch (obj.getSNum()) {
276                 case COPSPrObjBase.PR_PRID:
277                     strobjprid = obj.getData().str();
278                     break;
279                 case COPSPrObjBase.PR_EPD:
280                     repSIs.put(strobjprid, obj.getData().str());
281                     // COPSDebug.out(getClass().getName(),"PRID: " + strobjprid);
282                     // COPSDebug.out(getClass().getName(),"EPD: " + obj.getData().str());
283                     break;
284                 default:
285                     break;
286             }
287             //        }
288
289             //** Here we must act in accordance with
290             //** the report received
291             switch (rtypemsg.getReportType()) {
292                 case SUCCESS:
293                     _status = ST_REPORT;
294                     _process.successReport(this, repSIs);
295                     break;
296                 case FAILURE:
297                     _status = ST_REPORT;
298                     _process.failReport(this, repSIs);
299                     break;
300                 case ACCOUNTING:
301                     _status = ST_ACCT;
302                     _process.acctReport(this, repSIs);
303                     break;
304             }
305         }
306
307
308     }
309
310     /**
311      * Called when connection is closed
312      * @param error Reason
313      * @throws COPSPdpException
314      */
315     protected void processClosedConnection(COPSError error)
316     throws COPSPdpException {
317         if (_process != null)
318             _process.notifyClosedConnection(this, error);
319
320         _status = ST_CCONN;
321     }
322
323     /**
324      * Called when no keep-alive is received
325      * @throws COPSPdpException
326      */
327     protected void processNoKAConnection()
328     throws COPSPdpException {
329         if (_process != null)
330             _process.notifyNoKAliveReceived(this);
331
332         _status = ST_NOKA;
333     }
334
335     /**
336      * Deletes the request state
337      * @throws COPSPdpException
338      */
339     protected void finalizeRequestState()
340     throws COPSPdpException {
341         _sender.sendDeleteRequestState();
342         _status = ST_FINAL;
343     }
344
345     /**
346      * Asks for a COPS sync
347      * @throws COPSPdpException
348      */
349     protected void syncRequestState()
350     throws COPSPdpException {
351         _sender.sendSyncRequestState();
352         _status = ST_SYNC;
353     }
354
355     /**
356      * Opens a new request state
357      * @throws COPSPdpException
358      */
359     protected void openNewRequestState()
360     throws COPSPdpException {
361         _sender.sendOpenNewRequestState();
362         _status = ST_NEW;
363     }
364
365     /**
366      * Processes a COPS delete message
367      * @param dMsg  <tt>COPSDeleteMsg</tt> received from the PEP
368      * @throws COPSPdpException
369      */
370     protected void processDeleteRequestState(COPSDeleteMsg dMsg)
371     throws COPSPdpException {
372         if (_process != null)
373             _process.closeRequestState(this);
374
375         _status = ST_DEL;
376     }
377
378 }