/**
 *    Copyright 2012, Big Switch Networks, Inc.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *    License for the specific language governing permissions and limitations
 *    under the License.
 **/

/**
 *
 */
package net.onrc.onos.core.packet;

import java.nio.ByteBuffer;
import java.util.Arrays;

import org.openflow.util.HexString;

/**
 * @author Shudong Zhou (shudong.zhou@bigswitch.com)
 */
public class BSNPROBE extends BasePacket {
    protected long controllerId;
    protected int sequenceId;
    protected byte[] srcMac;
    protected byte[] dstMac;
    protected long srcSwDpid;
    protected int srcPortNo;

    public BSNPROBE() {
        srcMac = new byte[6];
        dstMac = new byte[6];
    }


    public long getControllerId() {
        return this.controllerId;
    }

    public BSNPROBE setControllerId(long controllerId) {
        this.controllerId = controllerId;
        return this;
    }

    public int getSequenceId() {
        return sequenceId;
    }

    public BSNPROBE setSequenceId(int sequenceId) {
        this.sequenceId = sequenceId;
        return this;
    }

    public byte[] getSrcMac() {
        return this.srcMac;
    }

    public BSNPROBE setSrcMac(byte[] srcMac) {
        this.srcMac = srcMac;
        return this;
    }

    public byte[] getDstMac() {
        return dstMac;
    }

    public BSNPROBE setDstMac(byte[] dstMac) {
        this.dstMac = dstMac;
        return this;
    }

    public long getSrcSwDpid() {
        return srcSwDpid;
    }

    public BSNPROBE setSrcSwDpid(long srcSwDpid) {
        this.srcSwDpid = srcSwDpid;
        return this;
    }

    public int getSrcPortNo() {
        return srcPortNo;
    }

    public BSNPROBE setSrcPortNo(int srcPortNo) {
        this.srcPortNo = srcPortNo;
        return this;
    }

    @Override
    public byte[] serialize() {
        short length = 8 /* controllerId */ + 4 /* seqId */
                + 12 /* srcMac dstMac */ + 8 /* srcSwDpid */ + 4 /* srcPortNo */;

        byte[] payloadData = null;
        if (this.payload != null) {
            payload.setParent(this);
            payloadData = payload.serialize();
            length += payloadData.length;
        }

        byte[] data = new byte[length];
        ByteBuffer bb = ByteBuffer.wrap(data);
        bb.putLong(this.controllerId);
        bb.putInt(this.sequenceId);
        bb.put(this.srcMac);
        bb.put(this.dstMac);
        bb.putLong(this.srcSwDpid);
        bb.putInt(this.srcPortNo);
        if (payloadData != null)
            bb.put(payloadData);

        if (this.parent != null && this.parent instanceof BSN)
            ((BSN) this.parent).setType(BSN.BSN_TYPE_PROBE);

        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

        controllerId = bb.getLong();
        sequenceId = bb.getInt();
        bb.get(this.srcMac, 0, 6);
        bb.get(this.dstMac, 0, 6);
        this.srcSwDpid = bb.getLong();
        this.srcPortNo = bb.getInt();

        if (bb.hasRemaining()) {
            this.payload = new Data();
            this.payload = payload.deserialize(data, bb.position(), bb.limit() - bb.position());
            this.payload.setParent(this);
        }

        return this;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 883;
        int result = super.hashCode();
        result = prime * result + srcMac.hashCode();
        result = prime * result + dstMac.hashCode();
        result = prime * result + (int) (srcSwDpid >> 32) + (int) srcSwDpid;
        result = prime * result + srcPortNo;
        return result;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (!(obj instanceof BSNPROBE))
            return false;
        BSNPROBE other = (BSNPROBE) obj;
        if (!Arrays.equals(srcMac, other.srcMac))
            return false;
        if (!Arrays.equals(dstMac, other.dstMac))
            return false;
        return (sequenceId == other.sequenceId &&
                srcSwDpid == other.srcSwDpid &&
                srcPortNo == other.srcPortNo
        );
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("\n");
        sb.append("BSN Probe packet");
        sb.append("\nSource Mac: ");
        sb.append(HexString.toHexString(srcMac));
        sb.append("\nDestination Mac: ");
        sb.append(HexString.toHexString(dstMac));
        sb.append("\nSource Switch: ");
        sb.append(HexString.toHexString(srcSwDpid));
        sb.append(" port: " + srcPortNo);
        sb.append("\nSequence No.:" + sequenceId);

        return sb.toString();
    }
}

@@ -3980,22 +3980,22 @@
 esult + 
-srcMac
+Arrays
 .hashCod
@@ -3988,32 +3988,38 @@
 Arrays.hashCode(
+srcMac
 );%0A        resul
@@ -4039,22 +4039,22 @@
 esult + 
-dstMac
+Arrays
 .hashCod
@@ -4047,32 +4047,38 @@
 Arrays.hashCode(
+dstMac
 );%0A        resul

Fix issues found by FindBugs: DMI_INVOKING_HASHCODE_ON_ARRAY