Added GateInfo to Op Ds and RPCs to support gate update requests
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / gates / impl / PCMMError.java
index da686efd2f30cd10fb54642f7cc43f5e80316c74..3a550b9c93716d28284da04c7f1b8e84297d9141 100644 (file)
@@ -1,82 +1,61 @@
-/**
- @header@
+/*
+ * Copyright (c) 2015 Cable Television Laboratories, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
+
 package org.pcmm.gates.impl;
 
 import org.pcmm.base.impl.PCMMBaseObject;
 import org.pcmm.gates.IPCMMError;
+import org.umu.cops.stack.COPSMsgParser;
 
 /**
- *
+ * Implementation of the IPCMMError interface
  */
 public class PCMMError extends PCMMBaseObject implements IPCMMError {
-    /**
-     *
-     */
-    public PCMMError() {
-        this(LENGTH, STYPE, SNUM);
-    }
-
-    public PCMMError(short errorCode, short subErrCode) {
-        this();
-        setErrorCode(errorCode);
-        setErrorSubcode(subErrCode);
-    }
 
     /**
-     * @param data
+     * The error code (cannot be NA)
      */
-    public PCMMError(byte[] data) {
-        super(data);
-    }
+    private final ErrorCode errorCode;
 
     /**
-     * @param len
-     * @param sType
-     * @param sNum
+     * The error sub-code (defaults to NA)
      */
-    public PCMMError(short len, byte sType, byte sNum) {
-        super(len, sType, sNum);
-    }
+    private final short subErrCode;
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.IPCError#setErrorCode(int)
+    /**
+     * Constructor without a sub-code which will then be set to NA
+     * @param errorCode - the error code (required and not NA)
      */
-    @Override
-    public void setErrorCode(short errorCode) {
-        setShort(errorCode, (short) 0);
+    public PCMMError(final ErrorCode errorCode) {
+        this(errorCode, (short)0);
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.IPCError#getErrorCode()
+    /**
+     * Constructor with a sub-code
+     * @param errorCode - the error code (required and not NA)
+     * @param subErrCode - the sub-code (defaults to NA when null)
      */
-    @Override
-    public short getErrorCode() {
-        return getShort((short) 0);
+    public PCMMError(final ErrorCode errorCode, final short subErrCode) {
+        super(SNum.PCMM_ERROR, STYPE);
+        if (errorCode == null || errorCode.equals(ErrorCode.NA))
+            throw new IllegalArgumentException("ErrorCode is required and must not be NA");
+        this.errorCode = errorCode;
+        this.subErrCode = subErrCode;
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.IPCError#setErrorSubcode(int)
-     */
     @Override
-    public void setErrorSubcode(short errorSubcode) {
-        setShort(errorSubcode, (short) 2);
+    public ErrorCode getErrorCode() {
+        return errorCode;
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.pcmm.gates.IPCError#getErrorCode()
-     */
     @Override
     public short getErrorSubcode() {
-        return getShort((short) 2);
+        return subErrCode;
     }
 
     /*
@@ -86,13 +65,72 @@ public class PCMMError extends PCMMBaseObject implements IPCMMError {
      */
     @Override
     public String getDescription() {
-        String hex = Integer.toHexString(getErrorSubcode() & 0xFFFF);
-        return "Error Code: " + getErrorCode() + " Error Subcode : " + hex
-               + "  " + Description.valueOf(getErrorCode());
+        //Error-Subcode is a 2-byte unsigned integer field used to provide further information about the error.
+        // In the case of Error-Codes 6, 7 and 17, this 16-bit field MUST contain, as two 8-bit values the
+        // S-Num and S-Type of the object that is missing or in error.
+        String subcode;
+        switch (errorCode) {
+            case MISSING_REQ_OBJ:
+            case INVALID_OBJ:
+            case INVALID_FIELD:
+                byte[] sParts = COPSMsgParser.shortToBytes(subErrCode);
+                subcode = String.format("S-Num: %d, S-Type: %d", sParts[0], sParts[1]);
+                break;
+            default:
+                subcode = "Subcode: " + Integer.toHexString(subErrCode & 0xFFFF);
+        }
+
+        return "Error Code: " + errorCode.getCode() + " " + subcode + "  " + errorCode.getDescription();
     }
 
     @Override
     public String toString() {
         return getDescription();
     }
+
+    @Override
+    protected byte[] getBytes() {
+        final byte[] errorCodeBytes = COPSMsgParser.shortToBytes(errorCode.getCode());
+        final byte[] subErrCodeBytes = COPSMsgParser.shortToBytes(subErrCode);
+        final byte[] data = new byte[errorCodeBytes.length + subErrCodeBytes.length];
+        System.arraycopy(errorCodeBytes, 0, data, 0, errorCodeBytes.length);
+        System.arraycopy(subErrCodeBytes, 0, data, errorCodeBytes.length, subErrCodeBytes.length);
+        return data;
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof PCMMError)) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        final PCMMError pcmmError = (PCMMError) o;
+        return errorCode == pcmmError.errorCode && subErrCode == pcmmError.subErrCode;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + errorCode.hashCode();
+        result = 31 * result + subErrCode;
+        return result;
+    }
+
+    /**
+     * Returns a PCMMError object from a byte array
+     * @param data - the data to parse
+     * @return - the object
+     * TODO - make me more robust as RuntimeExceptions can be thrown here.
+     */
+    public static PCMMError parse(final byte[] data) {
+        return new PCMMError(ErrorCode.valueOf(COPSMsgParser.bytesToShort(data[0], data[1])),
+                (COPSMsgParser.bytesToShort(data[2], data[3])));
+
+    }
+
 }