2 * Copyright (c) 2014, 2015 Cable Television Laboratories, Inc. and others. All rights reserved.
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
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;
29 import java.io.IOException;
30 import java.net.Socket;
31 import java.util.HashMap;
32 import java.util.HashSet;
37 * Example of an UNSOLICITED decision
39 * <Gate Control Command> = <COPS Common Header> <Client Handle> <Context> <Decision Flags> <ClientSI Data>
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>]
49 * COPS message transceiver class for provisioning connections at the PDP side.
51 public class PCMMPdpMsgSender extends COPSMsgSender {
53 public final static Logger logger = LoggerFactory.getLogger(PCMMPdpMsgSender.class);
55 protected final short _transactionID;
56 protected final short _classifierID;
58 // XXX - this does not need to be here
59 protected IGateID _gateID;
62 * Creates a PCMMPdpMsgSender
71 public PCMMPdpMsgSender(final short clientType, final COPSHandle clientHandle, final Socket sock) {
72 this(clientType, (short)0, clientHandle, sock);
75 public PCMMPdpMsgSender(final short clientType, final short tID, final COPSHandle clientHandle,
77 super(clientType, clientHandle, sock);
78 _transactionID = tID == 0 ? (short) (Math.random() * hashCode()) : tID;
85 * @return the gate-id value
87 public IGateID getGateID() {
92 * Sends a PCMM GateSet COPS Decision message
93 * @param gate - the gate
94 * @throws COPSPdpException
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);
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);
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
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);
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);
120 // ** Send the GateSet Decision
122 decisionMsg.writeData(_sock);
123 } catch (IOException e) {
124 logger.error("Failed to send the decision", e);
129 public boolean handleGateReport(final Socket socket) throws COPSPdpException {
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) {
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();
152 } catch (Exception e) { // COPSException, IOException
153 throw new COPSPdpException("Error COPSTransceiver.receiveMsg", e);
159 * Sends a message asking that the request state be deleted
161 * @throws COPSPdpException
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);
168 Short trIDnum = trID.getTransactionIdentifier();
169 PCMMGlobalConfig.transactionGateMap.put(trIDnum, gate);
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
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));
187 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, clientSD);
189 // ** Send the GateDelete Decision
192 decisionMsg.writeData(_sock);
193 // decisionMsg.writeData(socket_id);
194 } catch (IOException e) {
195 logger.error("Failed to send the decision", e);
200 * Sends a request asking that a new request state be created
202 * @throws COPSPdpException
204 public void sendOpenNewRequestState() throws COPSPdpException {
206 * <Decision Message> ::= <Common Header: Flag UNSOLICITED> <Client
207 * Handle> *(<Decision>) [<Integrity>] <Decision> ::= <Context>
208 * <Decision: Flags> <Decision: Flags> ::= Install Request-State
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);
216 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), _handle, decisionMap, null, null);
219 decisionMsg.writeData(_sock);
220 } catch (IOException e) {
221 throw new COPSPdpException("Failed to send the open new request state", e);
226 * Sends a message asking for a COPS sync operation
228 * @throws COPSPdpException
230 public void sendGateInfo() throws COPSPdpException {
232 * <Gate-Info> ::= <Common Header> [<Client Handle>] [<Integrity>]
234 final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
236 msg.writeData(_sock);
237 } catch (IOException e) {
238 throw new COPSPdpException("Failed to send the GateInfo request", e);
243 * Sends a message asking for a COPS sync operation
245 * @throws COPSPdpException
247 public void sendSyncRequest() throws COPSPdpException {
249 * <Synchronize State Request> ::= <Common Header> [<Client Handle>]
253 // Client Handle with the same clientHandle as the request
254 final COPSSyncStateMsg msg = new COPSSyncStateMsg(getClientType(), _handle, null);
256 msg.writeData(_sock);
257 } catch (IOException e) {
258 throw new COPSPdpException("Failed to send the sync state request", e);
262 public void sendSyncRequestState() throws COPSPdpException {
265 public void sendDeleteRequestState() throws COPSPdpException {