All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pcap4j.packet.Dot11SequenceControl Maven / Gradle / Ivy

/*_##########################################################################
  _##
  _##  Copyright (C) 2016  Pcap4J.org
  _##
  _##########################################################################
*/

package org.pcap4j.packet;

import java.io.Serializable;
import java.nio.ByteOrder;
import org.pcap4j.util.ByteArrays;

/**
 * Sequence Control field of an IEEE802.11 frame.
 *
 * 
{@code
 *    0     1     2     3     4     5     6     7
 * +-----+-----+-----+-----+-----+-----+-----+-----+
 * |    Fragment Number    |                       |
 * +-----+-----+-----+-----+                       |
 * |               Sequence Number                 |
 * +-----+-----+-----+-----+-----+-----+-----+-----+
 * }
* * @see IEEE802.11 * @author Kaito Yamada * @since pcap4j 1.7.0 */ public final class Dot11SequenceControl implements Serializable { /** */ private static final long serialVersionUID = 8383319258993027L; private final byte fragmentNumber; private final short sequenceNumber; /** * A static factory method. This method validates the arguments by {@link * ByteArrays#validateBounds(byte[], int, int)}, which may throw exceptions undocumented here. * * @param rawData rawData * @param offset offset * @param length length * @return a new Dot11SequenceControl object. * @throws IllegalRawDataException if parsing the raw data fails. */ public static Dot11SequenceControl newInstance(byte[] rawData, int offset, int length) throws IllegalRawDataException { ByteArrays.validateBounds(rawData, offset, length); return new Dot11SequenceControl(rawData, offset, length); } private Dot11SequenceControl(byte[] rawData, int offset, int length) throws IllegalRawDataException { if (length < 2) { StringBuilder sb = new StringBuilder(200); sb.append("The data is too short to build a Dot11SequenceControl (") .append(2) .append(" bytes). data: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } this.fragmentNumber = (byte) (rawData[offset] & 0x0F); this.sequenceNumber = (short) ((ByteArrays.getShort(rawData, offset, ByteOrder.LITTLE_ENDIAN) >> 4) & 0x0FFF); } private Dot11SequenceControl(Builder builder) { if (builder == null) { throw new NullPointerException("builder is null."); } if ((builder.fragmentNumber & 0xF0) != 0) { StringBuilder sb = new StringBuilder(200); sb.append("(builder.fragmentNumber & 0xF0) must be zero. builder.fragmentNumber: ") .append(builder.fragmentNumber); throw new IllegalArgumentException(sb.toString()); } if ((builder.sequenceNumber & 0xF000) != 0) { StringBuilder sb = new StringBuilder(200); sb.append("(builder.sequenceNumber & 0xF000) must be zero. builder.sequenceNumber: ") .append(builder.sequenceNumber); throw new IllegalArgumentException(sb.toString()); } this.fragmentNumber = builder.fragmentNumber; this.sequenceNumber = builder.sequenceNumber; } /** @return fragmentNumber */ public byte getFragmentNumber() { return fragmentNumber; } /** @return fragmentNumber */ public int getFragmentNumberAsInt() { return fragmentNumber; } /** @return sequenceNumber */ public short getSequenceNumber() { return sequenceNumber; } /** @return sequenceNumber */ public int getSequenceNumberAsInt() { return sequenceNumber; } /** @return a new Builder object populated with this object's fields. */ public Builder getBuilder() { return new Builder(this); } /** @return the raw data. */ public byte[] getRawData() { byte[] data = ByteArrays.toByteArray((short) (sequenceNumber << 4), ByteOrder.LITTLE_ENDIAN); data[0] |= fragmentNumber; return data; } /** @return length */ public int length() { return 2; } @Override public String toString() { StringBuilder sb = new StringBuilder(250); sb.append("[Fragment Number: ") .append(getFragmentNumberAsInt()) .append(", Sequence Number: ") .append(getSequenceNumberAsInt()) .append("]"); return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + fragmentNumber; result = prime * result + sequenceNumber; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Dot11SequenceControl other = (Dot11SequenceControl) obj; if (fragmentNumber != other.fragmentNumber) return false; if (sequenceNumber != other.sequenceNumber) return false; return true; } /** * @author Kaito Yamada * @since pcap4j 1.7.0 */ public static final class Builder { private byte fragmentNumber; private short sequenceNumber; /** */ public Builder() {} private Builder(Dot11SequenceControl obj) { this.fragmentNumber = obj.fragmentNumber; this.sequenceNumber = obj.sequenceNumber; } /** * @param fragmentNumber fragmentNumber. The value is between 0 and 15 (inclusive). * @return this Builder object for method chaining. */ public Builder fragmentNumber(byte fragmentNumber) { this.fragmentNumber = fragmentNumber; return this; } /** * @param sequenceNumber sequenceNumber. The value is between 0 and 4095 (inclusive). * @return this Builder object for method chaining. */ public Builder sequenceNumber(short sequenceNumber) { this.sequenceNumber = sequenceNumber; return this; } /** @return a new Dot11SequenceControl object. */ public Dot11SequenceControl build() { return new Dot11SequenceControl(this); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy