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.COPSObjHeader.CNum;
10 import org.umu.cops.stack.COPSObjHeader.CType;
12 import java.io.IOException;
13 import java.io.OutputStream;
14 import java.net.Socket;
16 import java.util.concurrent.ConcurrentHashMap;
19 * COPS Error (RFC 2748)
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
27 * C-Num = 8, C-Type = 1
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
39 * 9 = Communication Failure
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
49 public class COPSError extends COPSObjBase {
51 public final static Map<Integer, ErrorTypes> ERROR_CODE_TO_TYPE = new ConcurrentHashMap<>();
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);
72 private final static Map<ErrorTypes, String> ERROR_TYPE_TO_STRING = new ConcurrentHashMap<>();
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.");
96 private ErrorTypes _errCode;
99 * Additional detailed client specific error codes
101 private ErrorTypes _errSubCode;
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
109 public COPSError(final ErrorTypes errCode, final ErrorTypes subCode) {
110 this(new COPSObjHeader(CNum.ERROR, CType.DEF), errCode, subCode);
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
121 protected COPSError(final COPSObjHeader hdr, final ErrorTypes errCode, final ErrorTypes subCode) {
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);
132 _errSubCode = subCode;
135 public ErrorTypes getErrCode() {
139 public ErrorTypes getErrSubCode() {
144 public int getDataLength() {
149 * Method getDescription
152 public String getDescription() {
156 ///Get the details from the error code
157 errStr1 = ERROR_TYPE_TO_STRING.get(_errCode);
158 //TODO - define error sub-codes
160 return (errStr1 + ":" + errStr2);
164 public void writeBody(final Socket socket) throws IOException {
165 final byte[] buf = new byte[4];
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();
172 COPSUtil.writeData(socket, buf, 4);
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());
182 public boolean equals(Object o) {
186 if (!(o instanceof COPSError)) {
189 if (!super.equals(o)) {
193 final COPSError copsError = (COPSError) o;
195 return _errCode == copsError._errCode && _errSubCode == copsError._errSubCode;
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);
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
214 public static COPSError parse(final COPSObjHeaderData objHdrData, byte[] dataPtr) {
216 errCode |= ((short) dataPtr[4]) << 8;
217 errCode |= ((short) dataPtr[5]) & 0xFF;
220 errSubCode |= ((short) dataPtr[6]) << 8;
221 errSubCode |= ((short) dataPtr[7]) & 0xFF;
223 return new COPSError(objHdrData.header, ERROR_CODE_TO_TYPE.get(errCode), ERROR_CODE_TO_TYPE.get(errSubCode));
227 * The different error types and the ordinal value will be serialized
229 public enum ErrorTypes {
236 UNSUPPORTED_CLIENT_TYPE,
237 MANDATORY_OBJECT_MISSING,