5e5f6300d9f86a0cdaa44778fe2166de1893b5d0
[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.IGateID;
8 import org.pcmm.gates.IPCMMGate;
9 import org.pcmm.gates.ITransactionID;
10 import org.pcmm.gates.impl.PCMMGateReq;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.umu.cops.prpdp.COPSPdpException;
14 import org.umu.cops.prpdp.COPSPdpReqStateMan;
15 import org.umu.cops.stack.*;
16 import org.umu.cops.stack.COPSReportType.ReportType;
17
18 import java.net.Socket;
19 import java.util.Arrays;
20 import java.util.HashMap;
21 import java.util.Map;
22
23 /**
24  * State manager class for provisioning requests, at the PDP side.
25  */
26 public class PCMMPdpReqStateMan extends COPSPdpReqStateMan {
27
28     private final static Logger logger = LoggerFactory.getLogger(PCMMPdpReqStateMan.class);
29
30     /**
31      * Object for performing policy data processing
32      */
33     protected final PCMMPdpDataProcess _thisProcess;
34
35     /** COPS message transceiver used to send COPS messages */
36     protected transient PCMMPdpMsgSender _sender;
37
38     /**
39      * Creates a request state manager
40      * @param clientType    Client-type
41      * @param clientHandle  Client handle
42      */
43     // TODO - consider sending in the COPSHandle object instead
44     public PCMMPdpReqStateMan(final short clientType, final COPSHandle clientHandle, final PCMMPdpDataProcess process) {
45         super(clientType, clientHandle, process);
46         this._thisProcess = process;
47     }
48
49     @Override
50     protected void initRequestState(final Socket sock) throws COPSPdpException {
51         // Inits an object for sending COPS messages to the PEP
52         _sender = new PCMMPdpMsgSender(_clientType, _handle, sock);
53
54         // Initial state
55         _status = Status.ST_INIT;
56     }
57
58     /**
59      * Processes a COPS request
60      * @param msg   COPS request received from the PEP
61      * @throws COPSPdpException
62      */
63     public void processRequest(final COPSReqMsg msg) throws COPSPdpException {
64         // TODO - Implement me - see commented out code from history prior to May 4, 2015...
65     }
66
67     /**
68      * Processes a report
69      * @param msg   Report message from the PEP
70      * @throws COPSPdpException
71      * TODO - break apart this method
72      */
73     protected void processReport(final COPSReportMsg msg) throws COPSPdpException {
74         // Report Type
75         final COPSReportType rtypemsg = msg.getReport();
76
77         if (msg.getClientSI() != null) {
78             final COPSClientSI clientSI = msg.getClientSI();
79             // Named ClientSI
80             final byte[] data = Arrays.copyOfRange(clientSI.getData().getData(), 0, clientSI.getData().getData().length);
81
82             // PCMMUtils.WriteBinaryDump("COPSReportClientSI", data);
83             logger.info("PCMMGateReq Parse Gate Message");
84             final PCMMGateReq gateMsg = new PCMMGateReq(data);
85
86             // TODO FIXME - Why is this Map being filled but never used???
87             final Map<String, String> repSIs = new HashMap<>();
88             String strobjprid = "";
89             final COPSPrObjBase obj = new COPSPrObjBase(clientSI.getData().getData());
90             switch (obj.getSNum()) {
91                 case COPSPrObjBase.PR_PRID:
92                     logger.info("COPSPrObjBase.PR_PRID");
93                     // TODO FIXME - this value is never used
94                     strobjprid = obj.getData().str();
95                     break;
96                 case COPSPrObjBase.PR_EPD:
97                     logger.info("COPSPrObjBase.PR_EPD");
98                     // TODO FIXME - strobjprid is always empty
99                     repSIs.put(strobjprid, obj.getData().str());
100                     logger.info("PRID: " + strobjprid);
101                     logger.info("EPD: " + obj.getData().str());
102                     break;
103                 default:
104                     logger.error("Object s-num: " + obj.getSNum() + "stype " + obj.getSType());
105                     logger.error("PRID: " + strobjprid);
106                     logger.error("EPD: " + obj.getData().str());
107                     break;
108             }
109
110             logger.info("rtypemsg process");
111             //** Here we must act in accordance with
112             //** the report received
113
114             // retrieve and remove the transactionId to gate request map entry
115             // see PCMMPdpMsgSender.sendGateSet(IPCMMGate gate)
116             final ITransactionID trID = gateMsg.getTransactionID();
117             final Short trIDnum = trID.getTransactionIdentifier();
118
119             logger.info("Removing gate from cache with key - " + trIDnum);
120             final IPCMMGate gate = PCMMGlobalConfig.transactionGateMap.remove(trIDnum);
121             if (gate != null) {
122                 // capture the "error" message if any
123                 gate.setError(gateMsg.getError());
124                 logger.info("Setting error on gate - " + gateMsg.getError());
125             }else {
126                 logger.error("processReport(): gateReq not found for transactionID {}", trIDnum);
127                 return;
128             }
129
130             if (rtypemsg.getReportType().equals(ReportType.SUCCESS)) {
131                 logger.info("rtypemsg success");
132                 _status = Status.ST_REPORT;
133                 final IGateID gateID = gateMsg.getGateID();
134                 logger.info("Setting gate ID on gate object - " + gateID);
135                 gate.setGateID(gateID);
136                 if (_thisProcess != null)
137                     _thisProcess.successReport(this, gateMsg);
138             } else {
139                 final String cmdType;
140                 if ( trID.getGateCommandType() == ITransactionID.GateDeleteAck ) {
141                     cmdType = "GateDeleteAck";
142                 } else if ( trID.getGateCommandType() == ITransactionID.GateSetAck ) {
143                     cmdType = "GateSetAck";
144                 } else cmdType = null;
145                 // capture the gateId from the response message
146                 final IGateID gateID = gateMsg.getGateID();
147                 logger.info("Setting gate ID on gate object - " + gateID);
148                 gate.setGateID(gateID);
149                 int gateIdInt = gateID.getGateID();
150                 String gateIdHex = String.format("%08x", gateIdInt);
151                 logger.info(getClass().getName() + ": " + cmdType + ": GateID = " + gateIdHex);
152             }
153             if (rtypemsg.getReportType().equals(ReportType.FAILURE)) {
154                 logger.info("rtypemsg failure");
155                 _status = Status.ST_REPORT;
156                 if (_thisProcess != null)
157                     _thisProcess.failReport(this, gateMsg);
158                 else
159                     logger.info("Gate message error - " + gateMsg.getError().toString());
160             } else if (rtypemsg.getReportType().equals(ReportType.ACCOUNTING)) {
161                     logger.info("rtypemsg account");
162                     _status = Status.ST_ACCT;
163                     if (_thisProcess != null)
164                         _thisProcess.acctReport(this, gateMsg);
165             }
166
167             // let the waiting gateSet/gateDelete sender proceed
168             // TODO - see PCMMService#processReport() gate.notify(). Should determine a better means to
169             // TODO - handle this synchronization.
170             logger.info("Notify gate request has been updated with ID - " + gate.getGateID());
171             synchronized(gate) {
172                 gate.notify();
173             }
174             logger.info("Out processReport");
175         }
176     }
177
178 }