Added new constructor. May need to tighten down interfaces in the future.
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / stack / COPSClientCloseMsg.java
1 /*
2  * Copyright (c) 2003 University of Murcia.  All rights reserved.
3  * --------------------------------------------------------------
4  * For more information, please see <http://www.umu.euro6ix.org/>.
5  */
6
7 package org.umu.cops.stack;
8
9 import org.umu.cops.stack.COPSHeader.Flag;
10 import org.umu.cops.stack.COPSHeader.OPCode;
11
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
15
16 /**
17  * COPS Client Close Message (RFC 2748 pg. 27)
18  *
19  * The Client-Close message can be issued by either the PDP or PEP to
20  * notify the other that a particular type of client is no longer being
21  * supported.
22  *
23  * <Client-Close>  ::= <Common Header>
24  * <Error>
25  * [<PDPRedirAddr>]
26  * [<Integrity>]
27  *
28  * The Error object is included to describe the reason for the close
29  * (e.g. the requested client-type is not supported by the remote PDP or
30  * client failure).
31  *
32  * A PDP MAY optionally include a PDP Redirect Address object in order
33  * to inform the PEP of the alternate PDP it SHOULD use for the client-
34  * type specified in the common header.
35  */
36 public class COPSClientCloseMsg extends COPSMsg {
37
38     // Required
39     private final COPSError _error;
40
41     // Optional
42     private final COPSPdpAddress _redirAddr;
43     private final COPSIntegrity _integrity;
44
45     /**
46      * Constructor (generally used for sending messages) which probably should not be used as the PCMM version and
47      * Flag values on the header are being hardcoded to 1 and UNSOLICITED respectively. Use the next one below instead
48      * @param clientType - the type of client that created the message (required)
49      * @param error - the error (required)
50      * @param redirAddr - the redirect address (optional)
51      * @param integrity - the integrity (optional)
52      * @throws java.lang.IllegalArgumentException
53      */
54     @Deprecated
55     public COPSClientCloseMsg(final short clientType, final COPSError error, final COPSPdpAddress redirAddr,
56                               final COPSIntegrity integrity) {
57         this(new COPSHeader(OPCode.CC, clientType), error, redirAddr, integrity);
58     }
59
60     /**
61      * Constructor (generally used for sending messages).
62      * @param version - the supported PCMM Version
63      * @param flag - the flag...
64      * @param clientType - the type of client that created the message (required)
65      * @param error - the error (required)
66      * @param redirAddr - the redirect address (optional)
67      * @param integrity - the integrity (optional)
68      * @throws java.lang.IllegalArgumentException
69      */
70     public COPSClientCloseMsg(final int version, final Flag flag, final short clientType, final COPSError error,
71                               final COPSPdpAddress redirAddr, final COPSIntegrity integrity) {
72         this(new COPSHeader(version, flag, OPCode.CC, clientType), error, redirAddr, integrity);
73     }
74
75     /**
76      * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
77      * COPSHeader information is known.
78      * @param hdr - COPS Header
79      * @param error - the error (required)
80      * @param redirAddr - the redirect address (optional)
81      * @param integrity - the integrity (optional)
82      * @throws java.lang.IllegalArgumentException
83      */
84     public COPSClientCloseMsg(final COPSHeader hdr, final COPSError error, final COPSPdpAddress redirAddr,
85                               final COPSIntegrity integrity) {
86         super(hdr);
87         if (!hdr.getOpCode().equals(OPCode.CC))
88             throw new IllegalArgumentException("OPCode must be of type - " + OPCode.CAT);
89         if (error == null) throw new IllegalArgumentException("Error object must not be null");
90         this._error = error;
91         this._redirAddr = redirAddr;
92         this._integrity = integrity;
93     }
94
95     // Getters
96     public COPSError getError() {
97         return (_error);
98     }
99     public COPSPdpAddress getRedirAddr() {
100         return (_redirAddr);
101     }
102     public COPSIntegrity getIntegrity() {
103         return (_integrity);
104     }
105
106     @Override
107     protected void writeBody(final Socket socket) throws IOException {
108         _error.writeData(socket);
109         if (_redirAddr != null) _redirAddr.writeData(socket);
110         if (_integrity != null) _integrity.writeData(socket);
111     }
112
113     @Override
114     protected int getDataLength() {
115         int out = _error.getDataLength() + _error.getHeader().getHdrLength();
116         if (_redirAddr != null) out += _redirAddr.getDataLength() + _redirAddr.getHeader().getHdrLength();
117         if (_integrity != null) out += _integrity.getDataLength() + _integrity.getHeader().getHdrLength();
118         return out;
119     }
120
121     @Override
122     protected void dumpBody(OutputStream os) throws IOException {
123         _error.dump(os);
124         if (_redirAddr != null) _redirAddr.dump(os);
125         if (_integrity != null) _integrity.dump(os);
126     }
127
128     @Override
129     public boolean equals(final Object o) {
130         if (this == o) {
131             return true;
132         }
133         if (!(o instanceof COPSClientCloseMsg)) {
134             return false;
135         }
136         if (!super.equals(o)) {
137             return false;
138         }
139
140         final COPSClientCloseMsg closeMsg = (COPSClientCloseMsg) o;
141
142         return _error.equals(closeMsg._error) &&
143                 !(_integrity != null ? !_integrity.equals(closeMsg._integrity) : closeMsg._integrity != null) &&
144                 !(_redirAddr != null ? !_redirAddr.equals(closeMsg._redirAddr) : closeMsg._redirAddr != null);
145
146     }
147
148     @Override
149     public int hashCode() {
150         int result = super.hashCode();
151         result = 31 * result + _error.hashCode();
152         result = 31 * result + (_redirAddr != null ? _redirAddr.hashCode() : 0);
153         result = 31 * result + (_integrity != null ? _integrity.hashCode() : 0);
154         return result;
155     }
156
157     /**
158      * Responsible for parsing a byte array to create a COPSDecisionMsg object
159      * @param hdrData - the object's header data
160      * @param data - the byte array to parse
161      * @return - the message object
162      * @throws COPSException
163      */
164     public static COPSClientCloseMsg parse(final COPSHeaderData hdrData, final byte[] data) throws COPSException {
165         // Variables for constructor
166         COPSError error = null;
167         COPSPdpAddress redirAddr = null;
168         COPSIntegrity integrity = null;
169
170         int dataStart = 0;
171         while (dataStart < data.length) {
172             final byte[] buf = new byte[data.length - dataStart];
173             System.arraycopy(data, dataStart, buf, 0, data.length - dataStart);
174
175             final COPSObjHeaderData objHdrData = COPSObjectParser.parseObjHeader(buf);
176             switch (objHdrData.header.getCNum()) {
177                 case ERROR:
178                     error = COPSError.parse(objHdrData, buf);
179                     break;
180                 case PDP_REDIR:
181                     redirAddr = COPSPdpAddress.parse(objHdrData, buf);
182                     break;
183                 case MSG_INTEGRITY:
184                     integrity = COPSIntegrity.parse(objHdrData, buf);
185                     break;
186                 default:
187                     throw new COPSException("Bad Message format, unknown object type");
188             }
189             dataStart += objHdrData.msgByteCount;
190         }
191
192         return new COPSClientCloseMsg(hdrData.header, error, redirAddr, integrity);
193     }
194
195 }
196