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