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