2 * Copyright (c) 2004 University of Murcia. All rights reserved.
3 * --------------------------------------------------------------
4 * For more information, please see <http://www.umu.euro6ix.org/>.
7 package org.umu.cops.prpdp;
9 import org.umu.cops.stack.*;
10 import org.umu.cops.stack.COPSContext.RType;
11 import org.umu.cops.stack.COPSDecision.Command;
12 import org.umu.cops.stack.COPSDecision.DecisionFlag;
13 import org.umu.cops.stack.COPSObjHeader.CType;
15 import java.io.IOException;
16 import java.net.Socket;
17 import java.util.HashMap;
18 import java.util.HashSet;
23 * COPS message transceiver class for provisioning connections at the PDP side.
25 * TODO - Need to continue refactoring by removing all instances of Hashtable (change to Map<>)
27 public class COPSPdpMsgSender {
30 * Socket connected to PEP
32 protected final Socket _sock;
35 * COPS client-type that identifies the policy client
37 protected final short _clientType;
40 * COPS client handle used to uniquely identify a particular
41 * PEP's request for a client-type
43 protected final COPSHandle _handle;
46 * Creates a COPSPepMsgSender
48 * @param clientType COPS client-type
49 * @param clientHandle Client handle
50 * @param sock Socket to the PEP
52 public COPSPdpMsgSender (final short clientType, final COPSHandle clientHandle, final Socket sock) {
54 _handle = clientHandle;
55 _clientType = clientType;
61 * Gets the client handle
62 * @return Client's <tt>COPSHandle</tt>
64 public COPSHandle getClientHandle() {
69 * Gets the client-type
70 * @return Client-type value
72 public short getClientType() {
77 * Sends a decision message
78 * @param removeDecs Decisions to be removed
79 * @param installDecs Decisions to be installed
80 * @throws COPSPdpException
82 public void sendDecision(final Map<String, String> removeDecs, Map<String, String> installDecs)
83 throws COPSPdpException {
84 /* <Decision Message> ::= <Common Header: Flag SOLICITED>
86 * *(<Decision>) | <Error>
88 * <Decision> ::= <Context>
90 * [<Named Decision Data: Provisioning>]
91 * <Decision: Flags> ::= <Command-Code> NULLFlag
92 * <Command-Code> ::= NULLDecision | Install | Remove
93 * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>
94 * <Install Decision> ::= *(<PRID> <EPD>)
95 * <Remove Decision> ::= *(<PRID> | <PPRID>)
97 * Very important, this is actually being treated like this:
98 * <Install Decision> ::= <PRID> | <EPD>
99 * <Remove Decision> ::= <PRID> | <PPRID>
103 final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
105 // Decisions (no flags supplied)
107 final COPSContext cntxt = new COPSContext(RType.CONFIG, (short)0);
111 final COPSDecision rdec1 = new COPSDecision(Command.REMOVE);
113 final Set<COPSDecision> decisionSet = new HashSet<>();
114 decisionSet.add(rdec1);
115 decisionMap.put(cntxt, decisionSet);
117 for (final Map.Entry<String, String> entry : removeDecs.entrySet()) {
118 // <Named Decision Data: Provisioning> (PRID)
119 final COPSPrID prid = new COPSPrID();
120 prid.setData(new COPSData(entry.getKey()));
121 final COPSDecision decisionPrid = new COPSDecision(CType.NAMED,
122 new COPSData(prid.getDataRep(), 0, prid.getDataLength()));
124 decisionMap.get(cntxt).add(decisionPrid);
126 final COPSPrEPD epd = new COPSPrEPD();
127 final COPSDecision decisionPrepd = new COPSDecision(CType.NAMED,
128 new COPSData(epd.getDataRep(), 0, epd.getDataLength()));
130 decisionMap.get(cntxt).add(decisionPrepd);
135 final COPSDecision idec1 = new COPSDecision(Command.INSTALL);
136 decisionMap.get(cntxt).add(idec1);
138 for (final Map.Entry<String, String> entry : installDecs.entrySet()) {
139 // <Named Decision Data: Provisioning> (PRID)
140 final COPSPrID prid = new COPSPrID();
141 prid.setData(new COPSData(entry.getKey()));
142 final COPSDecision decisionPrid2 = new COPSDecision(CType.NAMED,
143 new COPSData(prid.getDataRep(), 0, prid.getDataLength()));
145 decisionMap.get(cntxt).add(decisionPrid2);
148 // Common Header with the same ClientType as the request
149 // Client Handle with the same clientHandle as the request
150 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
153 //** Send the decision
156 decisionMsg.writeData(_sock);
157 } catch (IOException e) {
158 throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());
163 * Sends a decision message which was not requested by the PEP
164 * @param removeDecs Decisions to be removed
165 * @param installDecs Decisions to be installed
166 * @throws COPSPdpException
168 public void sendUnsolicitedDecision(final Map<String, String> removeDecs, final Map<String, String> installDecs)
169 throws COPSPdpException {
170 //** Example of an UNSOLICITED decision
173 /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
175 * *(<Decision>) | <Error>
177 * <Decision> ::= <Context>
179 * [<Named Decision Data: Provisioning>]
180 * <Decision: Flags> ::= <Command-Code> NULLFlag
181 * <Command-Code> ::= NULLDecision | Install | Remove
182 * <Named Decision Data> ::= <<Install Decision> | <Remove Decision>>
183 * <Install Decision> ::= *(<PRID> <EPD>)
184 * <Remove Decision> ::= *(<PRID> | <PPRID>)
186 * Very important, this is actually being treated like this:
187 * <Install Decision> ::= <PRID> | <EPD>
188 * <Remove Decision> ::= <PRID> | <PPRID>
192 // Common Header with the same ClientType as the request
193 // Client Handle with the same clientHandle as the request
194 final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
195 // Decisions (no flags supplied)
197 final COPSContext cntxt = new COPSContext(RType.CONFIG, (short)0);
201 final Set<COPSDecision> decisionSet = new HashSet<>();
202 decisionSet.add(new COPSDecision(Command.REMOVE));
203 decisionMap.put(cntxt, decisionSet);
205 for (final Map.Entry<String, String> entry : removeDecs.entrySet()) {
206 // <Named Decision Data: Provisioning> (PRID)
207 final COPSPrID prid = new COPSPrID();
208 prid.setData(new COPSData(entry.getKey()));
209 decisionMap.get(cntxt).add(new COPSDecision(CType.NAMED,
210 new COPSData(prid.getDataRep(), 0, prid.getDataLength())));
212 // <Named Decision Data: Provisioning> (EPD)
213 final COPSPrEPD epd = new COPSPrEPD();
214 epd.setData(new COPSData(entry.getValue()));
215 decisionMap.get(cntxt).add(
216 new COPSDecision(CType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())));
221 decisionMap.get(cntxt).add(new COPSDecision(Command.INSTALL));
223 for (final Map.Entry<String, String> entry : installDecs.entrySet()) {
224 // <Named Decision Data: Provisioning> (PRID)
225 final COPSPrID prid = new COPSPrID();
226 prid.setData(new COPSData(entry.getKey()));
227 decisionMap.get(cntxt).add(new COPSDecision(CType.NAMED,
228 new COPSData(prid.getDataRep(), 0, prid.getDataLength())));
230 final COPSPrEPD epd = new COPSPrEPD();
231 epd.setData(new COPSData(entry.getValue()));
232 decisionMap.get(cntxt).add(
233 new COPSDecision(CType.NAMED, new COPSData(epd.getDataRep(), 0, epd.getDataLength())));
237 COPSIntegrity intr = new COPSIntegrity();
240 intr.setKeyDigest(new COPSData("KEY DIGEST"));
241 decisionMsg.add(intr);
244 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(getClientHandle().getId()),
247 //** Send the decision
250 decisionMsg.writeData(_sock);
251 } catch (IOException e) {
252 throw new COPSPdpException("Failed to send the decision, reason: " + e.getMessage());
257 * Sends a message asking that the request state be deleted
258 * @throws COPSPdpException
260 public void sendDeleteRequestState() throws COPSPdpException {
261 /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
265 * <Decision> ::= <Context>
267 * <Decision: Flags> ::= Remove Request-State
274 final COPSDecision dec = new COPSDecision(Command.REMOVE, DecisionFlag.REQSTATE);
275 final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
276 final Set<COPSDecision> decisionSet = new HashSet<>();
277 decisionSet.add(dec);
278 decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
280 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(getClientType(), new COPSHandle(_handle.getId()),
283 decisionMsg.writeData(_sock);
284 } catch (IOException e) {
285 throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
290 * Sends a request asking that a new request state be created
291 * @throws COPSPdpException
293 public void sendOpenNewRequestState()
294 throws COPSPdpException {
295 /* <Decision Message> ::= <Common Header: Flag UNSOLICITED>
299 * <Decision> ::= <Context>
301 * <Decision: Flags> ::= Install Request-State
306 final COPSDecision dec = new COPSDecision(Command.INSTALL, DecisionFlag.REQSTATE);
307 final Map<COPSContext, Set<COPSDecision>> decisionMap = new HashMap<>();
308 final Set<COPSDecision> decisionSet = new HashSet<>();
309 decisionSet.add(dec);
310 decisionMap.put(new COPSContext(RType.CONFIG, (short)0), decisionSet);
312 final COPSDecisionMsg decisionMsg = new COPSDecisionMsg(_clientType, new COPSHandle(_handle.getId()),
316 decisionMsg.writeData(_sock);
317 } catch (IOException e) {
318 throw new COPSPdpException("Failed to send the open new request state, reason: " + e.getMessage());
323 * Sends a message asking for a COPS sync operation
324 * @throws COPSPdpException
326 public void sendSyncRequestState()
327 throws COPSPdpException {
328 /* <Synchronize State Request> ::= <Common Header>
333 final COPSSyncStateMsg msg = new COPSSyncStateMsg(_clientType, new COPSHandle(_handle.getId()), null);
335 msg.writeData(_sock);
336 } catch (IOException e) {
337 throw new COPSPdpException("Failed to send the sync state request, reason: " + e.getMessage());