Bump to odlparent 3.1.0 and yangtools 2.0.3
[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         private static final int MAX_TRANSACTION_ID = 65_536;
55         
56     protected short _transactionID;
57     protected final short _classifierID;
58
59     // XXX - this does not need to be here
60     protected IGateID _gateID;
61
62     /**
63      * Creates a PCMMPdpMsgSender
64      *
65      * @param clientType
66      *            COPS client-type
67      * @param clientHandle
68      *            Client handle
69      * @param sock
70      *            Socket to the PEP
71      */
72     public PCMMPdpMsgSender(final short clientType, final COPSHandle clientHandle, final Socket sock) {
73         this(clientType, (short)0, clientHandle, sock);
74     }
75
76     public PCMMPdpMsgSender(final short clientType, final short tID, final COPSHandle clientHandle,
77                             final Socket sock) {
78         super(clientType, clientHandle, sock);
79         _transactionID = tID == 0 ? generateNewTransactionID() : tID;
80         _classifierID = 0;
81     }
82
83     /**
84      * Gets the gate-id
85      *
86      * @return the gate-id value
87      */
88     public IGateID getGateID() {
89         return _gateID;
90     }
91
92     /**
93      * Sends a PCMM GateSet COPS Decision message
94      * @param gate - the gate
95      * @throws COPSPdpException
96      */
97     public void sendGateSet(final IPCMMGate gate) throws COPSPdpException {
98         // set transaction ID to gate set
99         // generate a new TransactionID
100         _transactionID = generateNewTransactionID();
101         final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_SET);
102         
103         gate.setTransactionID(trID);
104         // retain the transactitrIDnumonId to gate request mapping for gateID recovery after response
105         // see PCMMPdpReqStateMan.processReport()
106         final Short trIDnum = trID.getTransactionIdentifier();
107         logger.info("Adding gate to cache - " + gate + " with key - " + (int) (trIDnum & 0xffff));
108         PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
109
110         // new pcmm specific clientsi
111         final byte[] data = gate.getData();
112         // Common Header with the same ClientType as the request
113         // Client Handle with the same clientHandle as the request
114
115         final Set<COPSDecision> decisionSet = new HashSet<>();
116         decisionSet.add(new COPSDecision(CType.DEF, Command.INSTALL, DecisionFlag.REQERROR));
117         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
118         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
119
120         final COPSClientSI clientSD = new COPSClientSI(CNum.DEC, CType.CSI, new COPSData(data, 0, data.length));
121         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, _handle, decisionMap, null, clientSD);
122
123         // ** Send the GateSet Decision
124         try {
125             decisionMsg.writeData(_sock);
126         } catch (IOException e) {
127             logger.error("Failed to send the decision", e);
128         }
129
130     }
131
132     public boolean handleGateReport(final Socket socket) throws COPSPdpException {
133         try {
134             // waits for the gate-set-ack or error
135             final COPSMsg responseMsg = COPSTransceiver.receiveMsg(socket);
136             if (responseMsg.getHeader().getOpCode().equals(OPCode.RPT)) {
137                 logger.info("processing received report from CMTS");
138                 final COPSReportMsg reportMsg = (COPSReportMsg) responseMsg;
139                 if (reportMsg.getClientSI() == null) {
140                     return false;
141                 }
142                 final IPCMMGate responseGate = PCMMGateReq.parse(reportMsg.getClientSI().getData().getData());
143                 if (responseGate.getTransactionID() != null
144                         && responseGate.getTransactionID().getGateCommandType().equals(GateCommandType.GATE_SET_ACK)) {
145                     logger.info("the CMTS has sent a Gate-Set-Ack response");
146                     // here CMTS responded that he acknowledged the Gate-Set
147                     // TODO do further check of Gate-Set-Ack GateID etc...
148                     _gateID = responseGate.getGateID();
149                     return true;
150                 } else {
151                     return false;
152                 }
153             }
154             return false;
155         } catch (Exception e) { // COPSException, IOException
156             throw new COPSPdpException("Error COPSTransceiver.receiveMsg", e);
157         }
158     }
159
160
161     /**
162      * Sends a message asking that the request state be deleted
163      *
164      * @throws COPSPdpException
165      */
166     public void sendGateDelete(final IPCMMGate gate) throws COPSPdpException {
167         // set transaction ID to gate set
168         // generate a new TransactionID
169         short _transactionID = generateNewTransactionID();
170         final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_DELETE);
171         
172         gate.setTransactionID(trID);
173
174         Short trIDnum = trID.getTransactionIdentifier();
175         PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
176
177         // gateDelete only requires AMID, subscriberID, and gateID
178         // remove the gateSpec, traffic profile, and classifiers from original gate request
179         gate.setGateSpec(null);
180         gate.setTrafficProfile(null);
181         gate.setClassifiers(null);
182         // clear the error object
183         gate.setError(null);
184
185         // XXX - GateID
186         final byte[] data = gate.getData();
187         final Set<COPSDecision> decisionSet = new HashSet<>();
188         decisionSet.add(new COPSDecision(CType.DEF, Command.INSTALL, DecisionFlag.REQERROR));
189         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
190         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
191         final COPSClientSI clientSD = new COPSClientSI(CNum.DEC, CType.CSI, new COPSData(data, 0, data.length));
192
193         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
194
195         // ** Send the GateDelete Decision
196         // **
197         try {
198             decisionMsg.writeData(_sock);
199             // decisionMsg.writeData(socket_id);
200         } catch (IOException e) {
201             logger.error("Failed to send the decision", e);
202         }
203     }
204
205     /**
206      * Sends a request asking that a new request state be created
207      *
208      * @throws COPSPdpException
209      */
210     public void sendOpenNewRequestState() throws COPSPdpException {
211         /*
212          * <Decision Message> ::= <Common Header: Flag UNSOLICITED> <Client
213          * Handle> *(<Decision>) [<Integrity>] <Decision> ::= <Context>
214          * <Decision: Flags> <Decision: Flags> ::= Install Request-State
215          */
216
217         final Set<COPSDecision> decisionSet = new HashSet<>();
218         decisionSet.add(new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE));
219         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
220         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
221
222         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, null);
223
224         try {
225             decisionMsg.writeData(_sock);
226         } catch (IOException e) {
227             throw new COPSPdpException("Failed to send the open new request state", e);
228         }
229     }
230
231     /**
232      * Sends a message asking for a COPS sync operation
233      *
234      * @throws COPSPdpException
235      */
236     public void sendGateInfo(final IPCMMGate gate) throws COPSPdpException {
237         /*
238          * <Gate-Info> ::= <Common Header> [<Client Handle>] [<Integrity>]
239          */
240         
241         // added
242         // generate a new TransactionID
243         short _transactionID = generateNewTransactionID();
244         final ITransactionID trID = new TransactionID(_transactionID, GateCommandType.GATE_INFO);
245         
246         
247         gate.setTransactionID(trID);
248         // retain the transactionId to gate request mapping for gateID recovery after response
249         // see PCMMPdpReqStateMan.processReport()
250         final Short trIDnum = trID.getTransactionIdentifier();
251         logger.info("Adding gate to cache - " + gate + " with key - " + (int) (trIDnum & 0xffff));
252         PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
253         
254         // gateDelete only requires AMID, subscriberID, and gateID
255         // remove the gateSpec, traffic profile, and classifiers from original gate request
256         gate.setGateSpec(null);
257         gate.setTrafficProfile(null);
258         gate.setClassifiers(null);
259         // clear the error object
260         gate.setError(null);
261         
262         
263         // XXX - GateID
264         final byte[] data = gate.getData();
265         final Set<COPSDecision> decisionSet = new HashSet<>();
266         decisionSet.add(new COPSDecision(CType.DEF, Command.INSTALL, DecisionFlag.REQERROR));
267         final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
268         decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
269         final COPSClientSI clientSD = new COPSClientSI(CNum.DEC, CType.CSI, new COPSData(data, 0, data.length));
270         
271         //final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
272         final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
273         
274         try {
275             //msg.writeData(_sock);
276             decisionMsg.writeData(_sock);
277         } catch (IOException e) {
278             throw new COPSPdpException("Failed to send the GateInfo request", e);
279         }
280     }
281
282     /**
283      * Sends a message asking for a COPS sync operation
284      *
285      * @throws COPSPdpException
286      */
287     public void sendSyncRequest() throws COPSPdpException {
288         /*
289          * <Synchronize State Request> ::= <Common Header> [<Client Handle>]
290          * [<Integrity>]
291          */
292
293         // Client Handle with the same clientHandle as the request
294         final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
295         try {
296             msg.writeData(_sock);
297         } catch (IOException e) {
298             throw new COPSPdpException("Failed to send the sync state request", e);
299         }
300     }
301     // XXX - Temp
302     public void sendSyncRequestState() throws COPSPdpException {
303     }
304     // XXX - Temp
305     public void sendDeleteRequestState() throws COPSPdpException {
306     }
307         private static short generateNewTransactionID() {
308             return (short) (Math.random() * MAX_TRANSACTION_ID);
309         }
310 }