Add missing license headers to packetcable-driver gates
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / PCMMPdpMsgSender.java
1 /*
2  * (c) 2015 Cable Television Laboratories, Inc.  All rights reserved.
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.ITransactionID.GateCommandType;
11 import org.pcmm.gates.impl.PCMMGateReq;
12 import org.pcmm.gates.impl.TransactionID;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.umu.cops.COPSMsgSender;
16 import org.umu.cops.prpdp.COPSPdpException;
17 import org.umu.cops.stack.*;
18 import org.umu.cops.stack.COPSContext.RType;
19 import org.umu.cops.stack.COPSDecision.Command;
20 import org.umu.cops.stack.COPSDecision.DecisionFlag;
21 import org.umu.cops.stack.COPSHeader.OPCode;
22 import org.umu.cops.stack.COPSObjHeader.CNum;
23 import org.umu.cops.stack.COPSObjHeader.CType;
24
25 import java.io.IOException;
26 import java.net.Socket;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Set;
31
32 /*
33  * Example of an UNSOLICITED decision
34  *
35  * <Gate Control Command> = <COPS Common Header> <Client Handle> <Context> <Decision Flags> <ClientSI Data>
36  *
37  * <ClientSI Data> = <Gate-Set> | <Gate-Info> | <Gate-Delete> |
38  *                   <PDP-Config> | <Synch-Request> | <Msg-Receipt>
39  * <Gate-Set>      = <Decision Header> <TransactionID> <AMID> <SubscriberID> [<GateID>] <GateSpec>
40  *                   <Traffic Profile> <classifier> [<classifier...>] [<Event Generation Info>]
41  *                   [<Volume-Based Usage Limit>] [<Time-Based Usage Limit>][<Opaque Data>] [<UserID>]
42  */
43
44 /**
45  * COPS message transceiver class for provisioning connections at the PDP side.
46  */
47 public class PCMMPdpMsgSender extends COPSMsgSender {
48
49     public final static Logger logger = LoggerFactory.getLogger(PCMMPdpMsgSender.class);
50
51     protected final short _transactionID;
52     protected final short _classifierID;
53
54     // XXX - this does not need to be here
55     protected IGateID _gateID;
56
57     /**
58      * Creates a PCMMPdpMsgSender
59      *
60      * @param clientType
61      *            COPS client-type
62      * @param clientHandle
63      *            Client handle
64      * @param sock
65      *            Socket to the PEP
66      */
67     public PCMMPdpMsgSender(final short clientType, final COPSHandle clientHandle, final Socket sock) {
68         this(clientType, (short)0, clientHandle, sock);
69     }
70
71     public PCMMPdpMsgSender(final short clientType, final short tID, final COPSHandle clientHandle,
72                             final Socket sock) {
73         super(clientType, clientHandle, sock);
74         _transactionID = tID == 0 ? (short) (Math.random() * hashCode()) : tID;
75         _classifierID = 0;
76     }
77
78     /**
79      * Gets the gate-id
80      *
81      * @return the gate-id value
82      */
83     public IGateID getGateID() {
84         return _gateID;
85     }
86
87     /**
88      * Sends a PCMM GateSet COPS Decision message
89      * @param gate - the gate
90      * @throws COPSPdpException
91      */
92     public void sendGateSet(final IPCMMGate gate) throws COPSPdpException {
93         // set transaction ID to gate set
94         final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_SET);
95
96         gate.setTransactionID(trID);
97         // retain the transactionId to gate request mapping for gateID recovery after response
98         // see PCMMPdpReqStateMan.processReport()
99         final Short trIDnum = trID.getTransactionIdentifier();
100         logger.info("Adding gate to cache - " + gate + " with key - " + trIDnum);
101         PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
102
103         // new pcmm specific clientsi
104         final byte[] data = gate.getData();
105         // Common Header with the same ClientType as the request
106         // Client Handle with the same clientHandle as the request
107
108         final Set<COPSDecision> decisionSet = new HashSet<>();
109         decisionSet.add(new COPSDecision(CType.DEF, Command.INSTALL, DecisionFlag.REQERROR));
110         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
111         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
112
113         final COPSClientSI clientSD = new COPSClientSI(CNum.DEC, CType.CSI, new COPSData(data, 0, data.length));
114         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, _handle, decisionMap, null, clientSD);
115
116         // ** Send the GateSet Decision
117         try {
118             decisionMsg.writeData(_sock);
119         } catch (IOException e) {
120             logger.error("Failed to send the decision", e);
121         }
122
123     }
124
125     public boolean handleGateReport(final Socket socket) throws COPSPdpException {
126         try {
127             // waits for the gate-set-ack or error
128             final COPSMsg responseMsg = COPSTransceiver.receiveMsg(socket);
129             if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
130                 logger.info("processing received report from CMTS");
131                 final COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
132                 if (reportMsg.getClientSI() == null) {
133                     return false;
134                 }
135                 final IPCMMGate responseGate = PCMMGateReq.parse(reportMsg.getClientSI().getData().getData());
136                 if (responseGate.getTransactionID() != null
137                         && responseGate.getTransactionID().getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
138                     logger.info("the CMTS has sent a Gate-Set-Ack response");
139                     // here CMTS responded that he acknowledged the Gate-Set
140                     // TODO do further check of Gate-Set-Ack GateID etc...
141                     _gateID = responseGate.getGateID();
142                     return true;
143                 } else {
144                     return false;
145                 }
146             }
147             return false;
148         } catch (Exception e) { // COPSException, IOException
149             throw new COPSPdpException("Error COPSTransceiver.receiveMsg", e);
150         }
151     }
152
153
154     /**
155      * Sends a message asking that the request state be deleted
156      *
157      * @throws COPSPdpException
158      */
159     public void sendGateDelete(final IPCMMGate gate) throws COPSPdpException {
160         // set transaction ID to gate set
161         final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_DELETE);
162         gate.setTransactionID(trID);
163
164         Short trIDnum = trID.getTransactionIdentifier();
165         PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
166
167         // gateDelete only requires AMID, subscriberID, and gateID
168         // remove the gateSpec, traffic profile, and classifiers from original gate request
169         gate.setGateSpec(null);
170         gate.setTrafficProfile(null);
171         gate.setClassifiers(null);
172         // clear the error object
173         gate.setError(null);
174
175         // XXX - GateID
176         final byte[] data = gate.getData();
177         final Set<COPSDecision> decisionSet = new HashSet<>();
178         decisionSet.add(new COPSDecision(CType.DEF, Command.INSTALL, DecisionFlag.REQERROR));
179         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
180         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
181         final COPSClientSI clientSD = new COPSClientSI(CNum.DEC, CType.CSI, new COPSData(data, 0, data.length));
182
183         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
184
185         // ** Send the GateDelete Decision
186         // **
187         try {
188             decisionMsg.writeData(_sock);
189             // decisionMsg.writeData(socket_id);
190         } catch (IOException e) {
191             logger.error("Failed to send the decision", e);
192         }
193     }
194
195     /**
196      * Sends a request asking that a new request state be created
197      *
198      * @throws COPSPdpException
199      */
200     public void sendOpenNewRequestState() throws COPSPdpException {
201         /*
202          * <Decision Message> ::= <Common Header: Flag UNSOLICITED> <Client
203          * Handle> *(<Decision>) [<Integrity>] <Decision> ::= <Context>
204          * <Decision: Flags> <Decision: Flags> ::= Install Request-State
205          */
206
207         final Set<COPSDecision> decisionSet = new HashSet<>();
208         decisionSet.add(new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE));
209         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
210         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
211
212         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, null);
213
214         try {
215             decisionMsg.writeData(_sock);
216         } catch (IOException e) {
217             throw new COPSPdpException("Failed to send the open new request state", e);
218         }
219     }
220
221     /**
222      * Sends a message asking for a COPS sync operation
223      *
224      * @throws COPSPdpException
225      */
226     public void sendGateInfo() throws COPSPdpException {
227         /*
228          * <Gate-Info> ::= <Common Header> [<Client Handle>] [<Integrity>]
229          */
230         final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
231         try {
232             msg.writeData(_sock);
233         } catch (IOException e) {
234             throw new COPSPdpException("Failed to send the GateInfo request", e);
235         }
236     }
237
238     /**
239      * Sends a message asking for a COPS sync operation
240      *
241      * @throws COPSPdpException
242      */
243     public void sendSyncRequest() throws COPSPdpException {
244         /*
245          * <Synchronize State Request> ::= <Common Header> [<Client Handle>]
246          * [<Integrity>]
247          */
248
249         // Client Handle with the same clientHandle as the request
250         final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
251         try {
252             msg.writeData(_sock);
253         } catch (IOException e) {
254             throw new COPSPdpException("Failed to send the sync state request", e);
255         }
256     }
257     // XXX - Temp
258     public void sendSyncRequestState() throws COPSPdpException {
259     }
260     // XXX - Temp
261     public void sendDeleteRequestState() throws COPSPdpException {
262     }
263 }