Merge "Copyright"
[packetcable.git] / packetcable-driver / src / main / java / org / umu / cops / stack / COPSError.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.COPSObjHeader.CNum;
10 import org.umu.cops.stack.COPSObjHeader.CType;
11
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
15 import java.util.Map;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 /**
19  * COPS Error (RFC 2748)
20  *
21  * This object is used to identify a particular COPS protocol error.
22  * The error sub-code field contains additional detailed client specific
23  * error codes. The appropriate Error Sub-codes for a particular
24  * client-type SHOULD be specified in the relevant COPS extensions
25  * document.
26  *
27  * C-Num = 8, C-Type = 1
28  *
29  * Error-Code:
30  *
31  * 1 = Bad handle
32  * 2 = Invalid handle reference
33  * 3 = Bad message format (Malformed Message)
34  * 4 = Unable to process (server gives up on query)
35  * 5 = Mandatory client-specific info missing
36  * 6 = Unsupported client-type
37  * 7 = Mandatory COPS object missing
38  * 8 = Client Failure
39  * 9 = Communication Failure
40  * 10= Unspecified
41  * 11= Shutting down
42  * 12= Redirect to Preferred Server
43  * 13= Unknown COPS Object:
44  * Sub-code (octet 2) contains unknown object's C-Num
45  * and (octet 3) contains unknown object's C-Type.
46  * 14= Authentication Failure
47  * 15= Authentication Required
48  */
49 public class COPSError extends COPSObjBase {
50
51     public final static Map<Integer, ErrorTypes> ERROR_CODE_TO_TYPE = new ConcurrentHashMap<>();
52     static {
53         ERROR_CODE_TO_TYPE.put(ErrorTypes.NA.ordinal(), ErrorTypes.NA);
54         ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE.ordinal(), ErrorTypes.BAD_HANDLE);
55         ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_HANDLE_REF.ordinal(), ErrorTypes.BAD_HANDLE_REF);
56         ERROR_CODE_TO_TYPE.put(ErrorTypes.BAD_MSG_FORMAT.ordinal(), ErrorTypes.BAD_MSG_FORMAT);
57         ERROR_CODE_TO_TYPE.put(ErrorTypes.FAIL_PROCESS.ordinal(), ErrorTypes.FAIL_PROCESS);
58         ERROR_CODE_TO_TYPE.put(ErrorTypes.MISSING_INFO.ordinal(), ErrorTypes.MISSING_INFO);
59         ERROR_CODE_TO_TYPE.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE.ordinal(), ErrorTypes.UNSUPPORTED_CLIENT_TYPE);
60         ERROR_CODE_TO_TYPE.put(ErrorTypes.MANDATORY_OBJECT_MISSING.ordinal(), ErrorTypes.MANDATORY_OBJECT_MISSING);
61         ERROR_CODE_TO_TYPE.put(ErrorTypes.CLIENT_FAILURE.ordinal(), ErrorTypes.CLIENT_FAILURE);
62         ERROR_CODE_TO_TYPE.put(ErrorTypes.COMM_FAILURE.ordinal(), ErrorTypes.COMM_FAILURE);
63         ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN.ordinal(), ErrorTypes.UNKNOWN);
64         ERROR_CODE_TO_TYPE.put(ErrorTypes.SHUTTING_DOWN.ordinal(), ErrorTypes.SHUTTING_DOWN);
65         ERROR_CODE_TO_TYPE.put(ErrorTypes.PDP_REDIRECT.ordinal(), ErrorTypes.PDP_REDIRECT);
66         ERROR_CODE_TO_TYPE.put(ErrorTypes.UNKNOWN_OBJECT.ordinal(), ErrorTypes.UNKNOWN_OBJECT);
67         ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_FAILURE.ordinal(), ErrorTypes.AUTH_FAILURE);
68         ERROR_CODE_TO_TYPE.put(ErrorTypes.AUTH_REQUIRED.ordinal(), ErrorTypes.AUTH_REQUIRED);
69         ERROR_CODE_TO_TYPE.put(ErrorTypes.MA.ordinal(), ErrorTypes.MA);
70     }
71
72     private final static Map<ErrorTypes, String> ERROR_TYPE_TO_STRING = new ConcurrentHashMap<>();
73     static {
74         ERROR_TYPE_TO_STRING.put(ErrorTypes.NA, "Unknown.");
75         ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE, "Bad handle.");
76         ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_HANDLE_REF, "Invalid handle reference.");
77         ERROR_TYPE_TO_STRING.put(ErrorTypes.BAD_MSG_FORMAT, "Bad message format (Malformed message).");
78         ERROR_TYPE_TO_STRING.put(ErrorTypes.FAIL_PROCESS, "Unable to process.");
79         ERROR_TYPE_TO_STRING.put(ErrorTypes.MISSING_INFO, "Mandatory client-specific info missing.");
80         ERROR_TYPE_TO_STRING.put(ErrorTypes.UNSUPPORTED_CLIENT_TYPE, "Unsupported client-type");
81         ERROR_TYPE_TO_STRING.put(ErrorTypes.MANDATORY_OBJECT_MISSING, "Mandatory COPS object missing.");
82         ERROR_TYPE_TO_STRING.put(ErrorTypes.CLIENT_FAILURE, "Client failure.");
83         ERROR_TYPE_TO_STRING.put(ErrorTypes.COMM_FAILURE, "Communication failure.");
84         ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN, "Unknown.");
85         ERROR_TYPE_TO_STRING.put(ErrorTypes.SHUTTING_DOWN, "Shutting down.");
86         ERROR_TYPE_TO_STRING.put(ErrorTypes.PDP_REDIRECT, "Redirect to preferred server.");
87         ERROR_TYPE_TO_STRING.put(ErrorTypes.UNKNOWN_OBJECT, "Unknown COPS object");
88         ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_FAILURE, "Authentication failure.");
89         ERROR_TYPE_TO_STRING.put(ErrorTypes.AUTH_REQUIRED, "Authentication required.");
90         ERROR_TYPE_TO_STRING.put(ErrorTypes.MA, "Authentication required.");
91     }
92
93     /**
94      * The error code
95      */
96     private ErrorTypes _errCode;
97
98     /**
99      * Additional detailed client specific error codes
100      */
101     private ErrorTypes _errSubCode;
102
103     /**
104      * Constructor generally used for sending messages
105      * @param errCode - the error code
106      * @param subCode - the type of message
107      * @throws java.lang.IllegalArgumentException
108      */
109     public COPSError(final ErrorTypes errCode, final ErrorTypes subCode) {
110         this(new COPSObjHeader(CNum.ERROR, CType.DEF), errCode, subCode);
111     }
112
113     /**
114      * Constructor generally used when parsing the bytes of an inbound COPS message but can also be used when the
115      * COPSObjHeader information is known
116      * @param hdr - the object header
117      * @param errCode - the error code
118      * @param subCode - the type of message
119      * @throws java.lang.IllegalArgumentException
120      */
121     protected COPSError(final COPSObjHeader hdr, final ErrorTypes errCode, final ErrorTypes subCode) {
122         super(hdr);
123         if (!hdr.getCNum().equals(CNum.ERROR))
124             throw new IllegalArgumentException("Must have a CNum value of " + CNum.ERROR);
125         if (!hdr.getCType().equals(CType.DEF))
126             throw new IllegalArgumentException("Must have a CType value of " + CType.DEF);
127         if (errCode == null || subCode == null) throw new IllegalArgumentException("Error codes must not be null");
128         if (errCode.equals(ErrorTypes.NA))
129             throw new IllegalArgumentException("Error code must not be of type " + ErrorTypes.NA);
130
131         _errCode = errCode;
132         _errSubCode = subCode;
133     }
134
135     public ErrorTypes getErrCode() {
136         return _errCode;
137     }
138
139     public ErrorTypes getErrSubCode() {
140         return _errSubCode;
141     }
142
143     @Override
144     public int getDataLength() {
145         return 4;
146     }
147
148     /**
149      * Method getDescription
150      * @return   a String
151      */
152     public String getDescription() {
153         String errStr1;
154         String errStr2;
155
156         ///Get the details from the error code
157         errStr1 = ERROR_TYPE_TO_STRING.get(_errCode);
158         //TODO - define error sub-codes
159         errStr2 = "";
160         return (errStr1 + ":" + errStr2);
161     }
162
163     @Override
164     public void writeBody(final Socket socket) throws IOException {
165         final byte[] buf = new byte[4];
166
167         buf[0] = (byte) ((byte)_errCode.ordinal() >> 8);
168         buf[1] = (byte)_errCode.ordinal();
169         buf[2] = (byte) ((byte)_errSubCode.ordinal() >> 8);
170         buf[3] = (byte)_errSubCode.ordinal();
171
172         COPSUtil.writeData(socket, buf, 4);
173     }
174
175     @Override
176     public void dumpBody(final OutputStream os) throws IOException {
177         os.write(("Error Code: " + _errCode + "\n").getBytes());
178         os.write(("Error Sub Code: " + _errSubCode + "\n").getBytes());
179     }
180
181     @Override
182     public boolean equals(Object o) {
183         if (this == o) {
184             return true;
185         }
186         if (!(o instanceof COPSError)) {
187             return false;
188         }
189         if (!super.equals(o)) {
190             return false;
191         }
192
193         final COPSError copsError = (COPSError) o;
194
195         return _errCode == copsError._errCode && _errSubCode == copsError._errSubCode;
196
197     }
198
199     @Override
200     public int hashCode() {
201         int result = super.hashCode();
202         result = 31 * result + (_errCode != null ? _errCode.hashCode() : 0);
203         result = 31 * result + (_errSubCode != null ? _errSubCode.hashCode() : 0);
204         return result;
205     }
206
207     /**
208      * Creates this object from a byte array
209      * @param objHdrData - the header
210      * @param dataPtr - the data to parse
211      * @return - a new Timer
212      * @throws java.lang.IllegalArgumentException
213      */
214     public static COPSError parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
215         int errCode = 0;
216         errCode |= ((short) dataPtr[4]) << 8;
217         errCode |= ((short) dataPtr[5]) & 0xFF;
218
219         int errSubCode = 0;
220         errSubCode |= ((short) dataPtr[6]) << 8;
221         errSubCode |= ((short) dataPtr[7]) & 0xFF;
222
223         return new COPSError(objHdrData.header, ERROR_CODE_TO_TYPE.get(errCode), ERROR_CODE_TO_TYPE.get(errSubCode));
224     }
225
226     /**
227      * The different error types and the ordinal value will be serialized
228      */
229     public enum ErrorTypes {
230         NA,
231         BAD_HANDLE,
232         BAD_HANDLE_REF,
233         BAD_MSG_FORMAT,
234         FAIL_PROCESS,
235         MISSING_INFO,
236         UNSUPPORTED_CLIENT_TYPE,
237         MANDATORY_OBJECT_MISSING,
238         CLIENT_FAILURE,
239         COMM_FAILURE,
240         UNKNOWN,
241         SHUTTING_DOWN,
242         PDP_REDIRECT,
243         UNKNOWN_OBJECT,
244         AUTH_FAILURE,
245         AUTH_REQUIRED,
246         MA
247     }
248
249 }
250