2 * (c) 2015 Cable Television Laboratories, Inc. All rights reserved.
5 package org.pcmm.rcd.impl;
7 import org.pcmm.gates.IGateSpec.Direction;
8 import org.pcmm.gates.IPCMMError;
9 import org.pcmm.gates.IPCMMError.ErrorCode;
10 import org.pcmm.gates.impl.GateID;
11 import org.pcmm.gates.impl.PCMMError;
12 import org.pcmm.gates.impl.PCMMGateReq;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15 import org.umu.cops.prpep.COPSPepException;
16 import org.umu.cops.prpep.COPSPepMsgSender;
17 import org.umu.cops.prpep.COPSPepReqStateMan;
18 import org.umu.cops.stack.*;
19 import org.umu.cops.stack.COPSDecision.DecisionFlag;
20 import org.umu.cops.stack.COPSObjHeader.CNum;
21 import org.umu.cops.stack.COPSObjHeader.CType;
22 import org.umu.cops.stack.COPSReportType.ReportType;
24 import java.io.IOException;
25 import java.net.Socket;
29 * PEP State manager implementation for use in a CMTS.
31 public class CmtsPepReqStateMan extends COPSPepReqStateMan {
33 private final static Logger logger = LoggerFactory.getLogger(CmtsPepReqStateMan.class);
36 * The configured gates
38 private final Map<Direction, Set<String>> gateConfig;
41 * The connected CMTSs and whether or not they are up
43 private final Map<String, Boolean> cmStatus;
46 * Contains the gates that have been set where the key is the gate name and the value is a Set of subIds
47 * that are using this gate
49 private final Map<String, Set<String>> gatesSetMap;
52 * Create a State Request Manager
54 * @param clientType - the client type for this connection
55 * @param clientHandle - the client-handle for this connection
56 * @param process - the data processor
57 * @param socket - the socket connection
58 * @param gateConfig - the configured service class names (gates)
60 public CmtsPepReqStateMan(final short clientType, final COPSHandle clientHandle, final CmtsDataProcessor process,
61 final Socket socket, final Map<Direction, Set<String>> gateConfig,
62 final Map<String, Boolean> cmStatus) {
63 super(clientType, clientHandle, process, socket, new COPSPepMsgSender(clientType, clientHandle, socket));
64 this.gateConfig = Collections.unmodifiableMap(gateConfig);
65 this.cmStatus = Collections.unmodifiableMap(cmStatus);
67 this.gatesSetMap = new HashMap<>();
68 for (final Set<String> gateIdSet: gateConfig.values()) {
69 for (final String gateId : gateIdSet) {
70 gatesSetMap.put(gateId, new HashSet<String>());
76 protected void processDecision(final COPSDecisionMsg dMsg) throws COPSException {
77 logger.info("Processing decision message - " + dMsg);
78 final Map<COPSContext, Set<COPSDecision>> decisions = dMsg.getDecisions();
80 final Map<String, String> removeDecs = new HashMap<>();
81 final Map<String, String> installDecs = new HashMap<>();
83 for (final Set<COPSDecision> copsDecisions: decisions.values()) {
84 final COPSDecision cmddecision = copsDecisions.iterator().next();
85 switch (cmddecision.getCommand()) {
87 for (final COPSDecision decision : copsDecisions) {
88 if (decision.getFlag().equals(DecisionFlag.REQERROR)) {
89 logger.info("processing decision");
90 // This is assuming a gate set right or wrong
91 if (dMsg.getDecisions().size() == 1 && dMsg.getDecSI() != null) {
92 final PCMMGateReq gateReq = PCMMGateReq.parse(dMsg.getDecSI().getData().getData());
93 if (gateReq.getGateSpec() != null) {
94 processGateReq(gateReq, _socket);
101 for (final COPSDecision decision : copsDecisions) {
102 // TODO - implement gate delete
109 //** Apply decisions to the configuration
110 // TODO - why is this collection never getting populated???
111 final Map<String, String> errorDecs = new HashMap<>();
112 _process.setDecisions(this, removeDecs, installDecs, errorDecs);
113 _status = Status.ST_DECS;
116 if (_process.isFailReport(this)) {
117 // COPSDebug.out(getClass().getName(),"Sending FAIL Report\n");
118 _sender.sendFailReport(_process.getReportData(this));
120 // COPSDebug.out(getClass().getName(),"Sending SUCCESS Report\n");
121 _sender.sendSuccessReport(_process.getReportData(this));
123 _status = Status.ST_REPORT;
126 _sender.sendSyncComplete();
128 _status = Status.ST_SYNCALL;
132 private void processGateReq(final PCMMGateReq gateReq, final Socket socket) throws COPSException {
133 // TODO - Check and/or Set state here
134 // Gate ADD gateReq.getTrafficProfile() != null
135 // Gate REMOVE gateReq.getTrafficProfile() == null
136 final String subId = gateReq.getSubscriberID().getSourceIPAddress().getHostAddress();
138 // Get direction here
139 final Direction gateDir = gateReq.getGateSpec().getDirection();
140 final Set<String> gateNames = gateConfig.get(gateDir);
141 // TODO - Determine if this is the best means to derive the gate name???
142 final String gateName = new String(gateReq.getTrafficProfile().getAsBinaryArray());
144 final IPCMMError error;
145 if (subId == null || gateDir == null || gateNames == null) {
146 // Missing required object
147 // TODO - Determine if this is the correct code. 3 was being used previously and I don't see any corresponding code.
148 error = new PCMMError(ErrorCode.UNK_GATE_ID);
149 } else if (!cmStatus.keySet().contains(subId)
150 || (cmStatus.keySet().contains(subId) && !cmStatus.get(subId))) {
152 // TODO - Determine if this code is correct
153 error = new PCMMError(ErrorCode.INVALID_SUB_ID);
154 } else if (!gateNames.contains(gateName.trim())) {
155 // TODO - Determine if this code is correct
156 error = new PCMMError(ErrorCode.UNDEF_SCN_NAME);
159 gatesSetMap.get(gateName.trim()).add(subId);
161 gateReq.setError(error);
163 logger.info("Processing gate request [" + gateName + "] with direction [" + gateDir + ']');
168 final List<Byte> data = new ArrayList<>();
169 for (final byte val : gateReq.getTransactionID().getAsBinaryArray())
171 for (final byte val : gateReq.getAMID().getAsBinaryArray())
173 for (final byte val : gateReq.getSubscriberID().getAsBinaryArray())
175 if (error != null) for (final byte val : gateReq.getError().getAsBinaryArray())
179 final GateID gateID = new GateID(UUID.randomUUID().hashCode());
180 for (final byte val : gateID.getAsBinaryArray())
184 final byte[] csiArr = new byte[data.size()];
185 for (int i = 0; i < data.size(); i++) {
186 csiArr[i] = data.get(i);
188 final COPSClientSI si = new COPSClientSI(CNum.CSI, CType.DEF, new COPSData(csiArr, 0, csiArr.length));
190 final ReportType reportType;
191 if (gateReq.getError() == null) reportType = ReportType.SUCCESS; else reportType = ReportType.FAILURE;
193 logger.info("Returning " + reportType + " for gate request [" + gateName + "] direction [" + gateDir
194 + "] for host - " + subId);
195 final COPSReportMsg reportMsg = new COPSReportMsg(_clientType, getClientHandle(),
196 new COPSReportType(reportType), si, null);
198 reportMsg.writeData(socket);
199 } catch (IOException e) {
200 throw new COPSPepException("Error writing gate set SUCCESS Report", e);