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