2 * Copyright (c) 2003 University of Murcia. All rights reserved.
\r
3 * --------------------------------------------------------------
\r
4 * For more information, please see <http://www.umu.euro6ix.org/>.
\r
7 package org.umu.cops.stack;
\r
9 import java.io.IOException;
\r
10 import java.io.OutputStream;
\r
11 import java.net.Socket;
\r
12 import java.util.Enumeration;
\r
13 import java.util.Vector;
\r
16 * COPS Report Message (RFC 2748 pag. 25)
\r
18 * The RPT message is used by the PEP to communicate to the PDP its
\r
19 * success or failure in carrying out the PDP's decision, or to report
\r
20 * an accounting related change in state. The Report-Type specifies the
\r
21 * kind of report and the optional ClientSI can carry additional
\r
22 * information per Client-Type.
\r
24 * For every DEC message containing a configuration context that is
\r
25 * received by a PEP, the PEP MUST generate a corresponding Report State
\r
26 * message with the Solicited Message flag set describing its success or
\r
27 * failure in applying the configuration decision. In addition,
\r
28 * outsourcing decisions from the PDP MAY result in a corresponding
\r
29 * solicited Report State from the PEP depending on the context and the
\r
30 * type of client. RPT messages solicited by decisions for a given
\r
31 * Client Handle MUST set the Solicited Message flag and MUST be sent in
\r
32 * the same order as their corresponding Decision messages were
\r
33 * received. There MUST never be more than one Report State message
\r
34 * generated with the Solicited Message flag set per Decision.
\r
36 * The Report State may also be used to provide periodic updates of
\r
37 * client specific information for accounting and state monitoring
\r
38 * purposes depending on the type of the client. In such cases the
\r
39 * accounting report type should be specified utilizing the appropriate
\r
40 * client specific information object.
\r
42 * <Report State> ::== <Common Header>
\r
48 * @version COPSReportMsg.java, v 1.00 2003
\r
51 public class COPSReportMsg extends COPSMsg {
\r
52 /* COPSHeader coming from base class */
\r
53 private COPSHandle _clientHandle;
\r
54 private COPSReportType _report;
\r
55 private Vector _clientSI;
\r
56 private COPSIntegrity _integrity;
\r
58 public COPSReportMsg() {
\r
59 _clientHandle = null;
\r
62 _clientSI = new Vector(20);
\r
66 Parse data and create COPSReportMsg object
\r
68 protected COPSReportMsg (byte[] data) throws COPSException {
\r
69 _clientHandle = null;
\r
76 * Checks the sanity of COPS message and throw an
\r
77 * COPSException when data is bad.
\r
79 public void checkSanity() throws COPSException {
\r
80 if ((_hdr == null) || (_clientHandle == null) || (_report == null))
\r
81 throw new COPSException("Bad message format");
\r
85 * Add message header
\r
87 * @param hdr a COPSHeader
\r
89 * @throws COPSException
\r
92 public void add (COPSHeader hdr) throws COPSException {
\r
94 throw new COPSException ("Null Header");
\r
95 if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)
\r
96 throw new COPSException ("Error Header (no COPS_OP_REQ)");
\r
102 * Add Report object to the message
\r
104 * @param report a COPSReportType
\r
106 * @throws COPSException
\r
109 public void add (COPSReportType report) throws COPSException {
\r
110 if (report == null)
\r
111 throw new COPSException ("Null Handle");
\r
113 //Message integrity object should be the very last one
\r
114 //If it is already added
\r
115 if (_integrity != null)
\r
116 throw new COPSException ("No null Handle");
\r
123 * Add client handle to the message
\r
125 * @param handle a COPSHandle
\r
127 * @throws COPSException
\r
130 public void add (COPSHandle handle) throws COPSException {
\r
131 if (handle == null)
\r
132 throw new COPSException ("Null Handle");
\r
134 //Message integrity object should be the very last one
\r
135 //If it is already added
\r
136 if (_integrity != null)
\r
137 throw new COPSException ("No null Handle");
\r
139 _clientHandle = handle;
\r
144 * Add one or more clientSI objects
\r
146 * @param clientSI a COPSClientSI
\r
148 * @throws COPSException
\r
151 public void add (COPSClientSI clientSI) throws COPSException {
\r
152 if (clientSI == null)
\r
153 throw new COPSException ("Null ClientSI");
\r
154 _clientSI.add(clientSI);
\r
159 * Add integrity object
\r
161 * @param integrity a COPSIntegrity
\r
163 * @throws COPSException
\r
166 public void add (COPSIntegrity integrity) throws COPSException {
\r
167 if (integrity == null)
\r
168 throw new COPSException ("Null Integrity");
\r
169 if (!integrity.isMessageIntegrity())
\r
170 throw new COPSException ("Error Integrity");
\r
171 _integrity = integrity;
\r
176 * Get client Handle
\r
178 * @return a COPSHandle
\r
181 public COPSHandle getClientHandle() {
\r
182 return _clientHandle;
\r
188 * @return a COPSReportType
\r
191 public COPSReportType getReport() {
\r
201 public Vector getClientSI() {
\r
206 * Returns true if it has Integrity object
\r
208 * @return a boolean
\r
211 public boolean hasIntegrity() {
\r
212 return (_integrity != null);
\r
217 * Get Integrity. Should check hasIntegrity() before calling
\r
219 * @return a COPSIntegrity
\r
222 public COPSIntegrity getIntegrity() {
\r
223 return (_integrity);
\r
227 * Writes data to given network socket
\r
229 * @param id a Socket
\r
231 * @throws IOException
\r
234 public void writeData(Socket id) throws IOException {
\r
236 if (_hdr != null) _hdr.writeData(id);
\r
237 if (_clientHandle != null) _clientHandle.writeData(id);
\r
238 if (_report != null) _report.writeData(id);
\r
240 for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {
\r
241 COPSClientSI clientSI = (COPSClientSI) e.nextElement();
\r
242 clientSI.writeData(id);
\r
245 if (_integrity != null) _integrity.writeData(id);
\r
251 * @param data a byte[]
\r
253 * @throws COPSException
\r
256 protected void parse(byte[] data) throws COPSException {
\r
257 super.parseHeader(data);
\r
259 while (_dataStart < _dataLength) {
\r
260 byte[] buf = new byte[data.length - _dataStart];
\r
261 System.arraycopy(data,_dataStart,buf,0,data.length - _dataStart);
\r
263 COPSObjHeader objHdr = new COPSObjHeader (buf);
\r
264 switch (objHdr.getCNum()) {
\r
265 case COPSObjHeader.COPS_HANDLE: {
\r
266 _clientHandle = new COPSHandle(buf);
\r
267 _dataStart += _clientHandle.getDataLength();
\r
270 case COPSObjHeader.COPS_RPT: {
\r
271 _report = new COPSReportType(buf);
\r
272 _dataStart += _report.getDataLength();
\r
275 case COPSObjHeader.COPS_CSI: {
\r
276 COPSClientSI csi = new COPSClientSI(buf);
\r
277 _dataStart += csi.getDataLength();
\r
278 _clientSI.add(csi);
\r
282 case COPSObjHeader.COPS_MSG_INTEGRITY: {
\r
283 _integrity = new COPSIntegrity(buf);
\r
284 _dataStart += _integrity.getDataLength();
\r
289 throw new COPSException("Bad Message format, unknown object type");
\r
299 * @param hdr a COPSHeader
\r
300 * @param data a byte[]
\r
302 * @throws COPSException
\r
305 protected void parse(COPSHeader hdr, byte[] data) throws COPSException {
\r
306 if (hdr.getOpCode() != COPSHeader.COPS_OP_RPT)
\r
307 throw new COPSException ("Null Header");
\r
314 * Set the message length, base on the set of objects it contains
\r
316 * @throws COPSException
\r
319 protected void setMsgLength() throws COPSException {
\r
321 if (_clientHandle != null) len += _clientHandle.getDataLength();
\r
322 if (_report != null) len += _report.getDataLength();
\r
324 for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {
\r
325 COPSClientSI clientSI = (COPSClientSI) e.nextElement();
\r
326 len += clientSI.getDataLength();
\r
329 if (_integrity != null) len += _integrity.getDataLength();
\r
330 _hdr.setMsgLength(len);
\r
334 * Write an object textual description in the output stream
\r
336 * @param os an OutputStream
\r
338 * @throws IOException
\r
341 public void dump(OutputStream os) throws IOException {
\r
344 if (_clientHandle != null)
\r
345 _clientHandle.dump(os);
\r
347 if (_report != null)
\r
350 for (Enumeration e = _clientSI.elements() ; e.hasMoreElements() ;) {
\r
351 COPSClientSI clientSI = (COPSClientSI) e.nextElement();
\r
355 if (_integrity != null) {
\r
356 _integrity.dump(os);
\r