2 * Copyright (c) 2003 University of Murcia. All rights reserved.
3 * --------------------------------------------------------------
4 * For more information, please see <http://www.umu.euro6ix.org/>.
7 package org.umu.cops.stack;
9 import org.umu.cops.stack.COPSHeader.Flag;
10 import org.umu.cops.stack.COPSHeader.OPCode;
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
17 * Client-Accept (CAT) PDP -> PEP (RFC 2748 pag. 26)
19 * The Client-Accept message is used to positively respond to the
20 * Client-Open message. This message will return to the PEP a timer
21 * object indicating the maximum time interval between keep-alive
22 * messages. Optionally, a timer specifying the minimum allowed interval
23 * between accounting report messages may be included when applicable.
25 * <Client-Accept> ::= <Common Header>
30 * If the PDP refuses the client, it will instead issue a Client-Close
33 * The KA Timer corresponds to maximum acceptable intermediate time
34 * between the generation of messages by the PDP and PEP. The timer
35 * value is determined by the PDP and is specified in seconds. A timer
36 * value of 0 implies no secondary connection verification is necessary.
38 * The optional ACCT Timer allows the PDP to indicate to the PEP that
39 * periodic accounting reports SHOULD NOT exceed the specified timer
40 * interval per client handle. This allows the PDP to control the rate
41 * at which accounting reports are sent by the PEP (when applicable).
43 * In general, accounting type Report messages are sent to the PDP when
44 * determined appropriate by the PEP. The accounting timer merely is
45 * used by the PDP to keep the rate of such updates in check (i.e.
46 * Preventing the PEP from blasting the PDP with accounting reports).
47 * Not including this object implies there are no PDP restrictions on
48 * the rate at which accounting updates are generated.
50 * If the PEP receives a malformed Client-Accept message it MUST
51 * generate a Client-Close message specifying the appropriate error
54 public class COPSClientAcceptMsg extends COPSMsg {
57 private final COPSKATimer _kaTimer;
60 private final COPSAcctTimer _acctTimer;
61 private final COPSIntegrity _integrity;
64 * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
65 * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
66 * @param clientType - the type of client that created the message (required)
67 * @param kaTimer - the Keep alive timer (required)
68 * @param acctTimer - the account timer (optional)
69 * @param integrity - the integrity (optional)
70 * @throws java.lang.IllegalArgumentException
73 public COPSClientAcceptMsg(final short clientType, final COPSKATimer kaTimer, final COPSAcctTimer acctTimer,
74 final COPSIntegrity integrity) {
75 this(new COPSHeader(OPCode.CAT, clientType), kaTimer, acctTimer, integrity);
79 * Constructor (generally used for sending messages).
80 * @param version - the supported PCMM Version
81 * @param flag - the flag...
82 * @param clientType - the type of client that created the message (required)
83 * @param kaTimer - the Keep alive timer (required)
84 * @param acctTimer - the account timer (optional)
85 * @param integrity - the integrity (optional)
86 * @throws java.lang.IllegalArgumentException
88 public COPSClientAcceptMsg(final int version, final Flag flag, final short clientType,
89 final COPSKATimer kaTimer, final COPSAcctTimer acctTimer, final COPSIntegrity integrity) {
90 this(new COPSHeader(version, flag, OPCode.CAT, clientType), kaTimer, acctTimer, integrity);
94 * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
95 * COPSHeader information is known.
96 * @param hdr - COPS Header
97 * @param kaTimer - the Keep alive timer (required)
98 * @param acctTimer - the account timer (optional)
99 * @param integrity - the integrity (optional)
100 * @throws java.lang.IllegalArgumentException
102 protected COPSClientAcceptMsg(final COPSHeader hdr, final COPSKATimer kaTimer, final COPSAcctTimer acctTimer,
103 final COPSIntegrity integrity) {
105 if (!hdr.getOpCode().equals(OPCode.CAT))
106 throw new IllegalArgumentException("OPCode must be of type - " + OPCode.CAT);
107 if (kaTimer == null) throw new IllegalArgumentException("Keep alive timer must not be null");
109 _acctTimer = acctTimer;
110 _integrity = integrity;
114 public COPSKATimer getKATimer() {
117 public COPSAcctTimer getAcctTimer() {
120 public COPSIntegrity getIntegrity() {
125 protected void writeBody(final Socket socket) throws IOException {
126 _kaTimer.writeData(socket);
127 if (_acctTimer != null) _acctTimer.writeData(socket);
128 if (_integrity != null) _integrity.writeData(socket);
132 protected int getDataLength() {
133 int out = _kaTimer.getDataLength() + _kaTimer.getHeader().getHdrLength();
134 if (_acctTimer != null) out += _acctTimer.getDataLength() + _acctTimer.getHeader().getHdrLength();
135 if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
139 protected void dumpBody(final OutputStream os) throws IOException {
141 if (_acctTimer != null) _acctTimer.dump(os);
142 if (_integrity != null) _integrity.dump(os);
146 public boolean equals(final Object o) {
150 if (!(o instanceof COPSClientAcceptMsg)) {
153 if (!super.equals(o)) {
157 final COPSClientAcceptMsg acceptMsg = (COPSClientAcceptMsg) o;
159 return !(_acctTimer != null ? !_acctTimer.equals(acceptMsg._acctTimer) : acceptMsg._acctTimer != null) &&
160 !(_integrity != null ? !_integrity.equals(acceptMsg._integrity) : acceptMsg._integrity != null) &&
161 _kaTimer.equals(acceptMsg._kaTimer);
166 public int hashCode() {
167 int result = super.hashCode();
168 result = 31 * result + _kaTimer.hashCode();
169 result = 31 * result + (_acctTimer != null ? _acctTimer.hashCode() : 0);
170 result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
175 * Responsible for parsing a byte array to create a COPSDecisionMsg object
176 * @param hdrData - the object's header data
177 * @param data - the byte array to parse
178 * @return - the message object
179 * @throws COPSException
181 public static COPSClientAcceptMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
182 // Variables for constructor
183 COPSKATimer kaTimer = null;
184 COPSAcctTimer acctTimer = null;
185 COPSIntegrity integrity = null;
188 while (dataStart < data.length) {
189 final byte[] buf = new byte[data.length - dataStart];
190 System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
192 final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
193 switch (objHdrData.header.getCNum()) {
195 kaTimer = COPSKATimer.parse(objHdrData, buf);
198 acctTimer = COPSAcctTimer.parse(objHdrData, buf);
201 integrity = COPSIntegrity.parse(objHdrData, buf);
204 throw new COPSException("Bad Message format, unknown object type");
206 dataStart += objHdrData.msgByteCount;
209 return new COPSClientAcceptMsg(hdrData.header, kaTimer, acctTimer, integrity);