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

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

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

package org.pcap4j.packet;

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

/**
 * HT Control field of an IEEE802.11 frame.
 *
 * 
 *      0          1          2          3          4          5          6          7
 * +----------+----------+----------+----------+----------+----------+----------+----------+
 * |                                                                                       |
 * |                                                                                       |
 * +                              Link Adaptation Control                                  +
 * |                                                                                       |
 * |                                                                                       |
 * +----------+----------+----------+----------+----------+----------+----------+----------+
 * |    Calibration      |     Calibration     |      Reserved       |    CSI/Steering     |
 * |    Position         |     Sequence        |                     |                     |
 * +----------+----------+----------+----------+----------+----------+----------+----------+
 * |NDP Annou-|                       Reserved                       |AC        |RDG/More  |
 * |ncement   |                                                      |Constraint|PPDU      |
 * +----------+----------+----------+----------+----------+----------+----------+----------+
 * 
* * @see IEEE802.11 * @author Kaito Yamada * @since pcap4j 1.7.0 */ public final class Dot11HtControl implements Serializable { /** */ private static final long serialVersionUID = 8919536873635707080L; private final Dot11LinkAdaptationControl linkAdaptationControl; private final CalibrationPosition calibrationPosition; private final byte calibrationSequence; private final boolean bit20; private final boolean bit21; private final CsiOrSteering csiOrSteering; private final boolean ndpAnnouncement; private final boolean bit25; private final boolean bit26; private final boolean bit27; private final boolean bit28; private final boolean bit29; private final boolean acConstraint; private final boolean rdgOrMorePpdu; /** * 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 Dot11HtControl object. * @throws IllegalRawDataException if parsing the raw data fails. */ public static Dot11HtControl newInstance(byte[] rawData, int offset, int length) throws IllegalRawDataException { ByteArrays.validateBounds(rawData, offset, length); return new Dot11HtControl(rawData, offset, length); } private Dot11HtControl(byte[] rawData, int offset, int length) throws IllegalRawDataException { if (length < 4) { StringBuilder sb = new StringBuilder(200); sb.append("The data is too short to build a Dot11HtControl (") .append(2) .append(" bytes). data: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } this.linkAdaptationControl = Dot11LinkAdaptationControl.newInstance(rawData, offset, 2); byte data = rawData[offset + 2]; this.calibrationPosition = CalibrationPosition.getInstance(data & 0x03); this.calibrationSequence = (byte) ((data >> 2) & 0x03); this.bit20 = (data & 0x10) != 0; this.bit21 = (data & 0x20) != 0; this.csiOrSteering = CsiOrSteering.getInstance((data >> 6) & 0x03); data = rawData[offset + 3]; this.ndpAnnouncement = (data & 0x01) != 0; this.bit25 = (data & 0x02) != 0; this.bit26 = (data & 0x04) != 0; this.bit27 = (data & 0x08) != 0; this.bit28 = (data & 0x10) != 0; this.bit29 = (data & 0x20) != 0; this.acConstraint = (data & 0x40) != 0; this.rdgOrMorePpdu = (data & 0x80) != 0; } private Dot11HtControl(Builder builder) { if (builder == null || builder.linkAdaptationControl == null || builder.calibrationPosition == null || builder.csiOrSteering == null) { StringBuilder sb = new StringBuilder(); sb.append("builder: ") .append(builder) .append(" builder.linkAdaptationControl: ") .append(builder.linkAdaptationControl) .append(" builder.calibrationPosition: ") .append(builder.calibrationPosition) .append(" builder.csiOrSteering: ") .append(builder.csiOrSteering); throw new NullPointerException(sb.toString()); } if ((builder.calibrationSequence & 0xFC) != 0) { StringBuilder sb = new StringBuilder(150); sb.append("(builder.calibrationSequence & 0xFC) must be zero.") .append(" builder.calibrationSequence: ") .append(builder.calibrationSequence); throw new IllegalArgumentException(sb.toString()); } this.linkAdaptationControl = builder.linkAdaptationControl; this.calibrationPosition = builder.calibrationPosition; this.calibrationSequence = builder.calibrationSequence; this.bit20 = builder.bit20; this.bit21 = builder.bit21; this.csiOrSteering = builder.csiOrSteering; this.ndpAnnouncement = builder.ndpAnnouncement; this.bit25 = builder.bit25; this.bit26 = builder.bit26; this.bit27 = builder.bit27; this.bit28 = builder.bit28; this.bit29 = builder.bit29; this.acConstraint = builder.acConstraint; this.rdgOrMorePpdu = builder.rdgOrMorePpdu; } /** @return linkAdaptationControl */ public Dot11LinkAdaptationControl getLinkAdaptationControl() { return linkAdaptationControl; } /** @return calibrationPosition */ public CalibrationPosition getCalibrationPosition() { return calibrationPosition; } /** @return calibrationSequence */ public byte getCalibrationSequence() { return calibrationSequence; } /** @return calibrationSequence */ public int getCalibrationSequenceAsInt() { return calibrationSequence; } /** @return true if the bit 20 is set to 1; false otherwise. */ public boolean getBit20() { return bit20; } /** @return true if the bit 21 is set to 1; false otherwise. */ public boolean getBit21() { return bit21; } /** @return csiOrSteering */ public CsiOrSteering getCsiOrSteering() { return csiOrSteering; } /** @return true if the NDP Announcement field is set to 1; false otherwise. */ public boolean getNdpAnnouncement() { return ndpAnnouncement; } /** @return true if the bit 25 is set to 1; false otherwise. */ public boolean getBit25() { return bit25; } /** @return true if the bit 26 is set to 1; false otherwise. */ public boolean getBit26() { return bit26; } /** @return true if the bit 27 is set to 1; false otherwise. */ public boolean getBit27() { return bit27; } /** @return true if the bit 28 is set to 1; false otherwise. */ public boolean getBit28() { return bit28; } /** @return true if the bit 29 is set to 1; false otherwise. */ public boolean getBit29() { return bit29; } /** @return true if the AC Constraint field is set to 1; false otherwise. */ public boolean getAcConstraint() { return acConstraint; } /** @return true if the RDG/More PPDU field is set to 1; false otherwise. */ public boolean getRdgOrMorePpdu() { return rdgOrMorePpdu; } /** @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 = new byte[length()]; System.arraycopy(linkAdaptationControl.getRawData(), 0, data, 0, 2); data[2] = (byte) ((csiOrSteering.value << 6) | (calibrationSequence << 2) | calibrationPosition.value); if (bit20) { data[2] |= 0x10; } if (bit21) { data[2] |= 0x20; } if (ndpAnnouncement) { data[3] |= 0x01; } if (bit25) { data[3] |= 0x02; } if (bit26) { data[3] |= 0x04; } if (bit27) { data[3] |= 0x08; } if (bit28) { data[3] |= 0x10; } if (bit29) { data[3] |= 0x20; } if (acConstraint) { data[3] |= 0x40; } if (rdgOrMorePpdu) { data[3] |= 0x80; } return data; } /** @return length */ public int length() { return 4; } @Override public String toString() { return toString(""); } /** * @param indent indent * @return String representation of this object. */ public String toString(String indent) { StringBuilder sb = new StringBuilder(); String ls = System.getProperty("line.separator"); sb.append(indent) .append("Link Adaptation Control: ") .append(linkAdaptationControl) .append(ls) .append(indent) .append("Calibration Position: ") .append(calibrationPosition) .append(ls) .append(indent) .append("Calibration Sequence: ") .append(calibrationSequence) .append(ls) .append(indent) .append("Bit 20: ") .append(bit20) .append(ls) .append(indent) .append("Bit 21: ") .append(bit21) .append(ls) .append(indent) .append("CSI/Steering: ") .append(csiOrSteering) .append(ls) .append(indent) .append("NDP Announcement: ") .append(ndpAnnouncement) .append(ls) .append(indent) .append("Bit 25: ") .append(bit25) .append(ls) .append(indent) .append("Bit 26: ") .append(bit26) .append(ls) .append(indent) .append("Bit 27: ") .append(bit27) .append(ls) .append(indent) .append("Bit 28: ") .append(bit28) .append(ls) .append(indent) .append("Bit 29: ") .append(bit29) .append(ls) .append(indent) .append("AC Constraint: ") .append(acConstraint) .append(ls) .append(indent) .append("RDG/More PPDU: ") .append(rdgOrMorePpdu) .append(ls); return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (acConstraint ? 1231 : 1237); result = prime * result + (bit20 ? 1231 : 1237); result = prime * result + (bit21 ? 1231 : 1237); result = prime * result + (bit25 ? 1231 : 1237); result = prime * result + (bit26 ? 1231 : 1237); result = prime * result + (bit27 ? 1231 : 1237); result = prime * result + (bit28 ? 1231 : 1237); result = prime * result + (bit29 ? 1231 : 1237); result = prime * result + calibrationPosition.hashCode(); result = prime * result + calibrationSequence; result = prime * result + csiOrSteering.hashCode(); result = prime * result + linkAdaptationControl.hashCode(); result = prime * result + (ndpAnnouncement ? 1231 : 1237); result = prime * result + (rdgOrMorePpdu ? 1231 : 1237); return result; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Dot11HtControl other = (Dot11HtControl) obj; if (acConstraint != other.acConstraint) { return false; } if (bit20 != other.bit20) { return false; } if (bit21 != other.bit21) { return false; } if (bit25 != other.bit25) { return false; } if (bit26 != other.bit26) { return false; } if (bit27 != other.bit27) { return false; } if (bit28 != other.bit28) { return false; } if (bit29 != other.bit29) { return false; } if (calibrationPosition != other.calibrationPosition) { return false; } if (calibrationSequence != other.calibrationSequence) { return false; } if (csiOrSteering != other.csiOrSteering) { return false; } if (!linkAdaptationControl.equals(other.linkAdaptationControl)) { return false; } if (ndpAnnouncement != other.ndpAnnouncement) { return false; } if (rdgOrMorePpdu != other.rdgOrMorePpdu) { return false; } return true; } /** * Calibration Position subfield of HT Control field of an IEEE802.11 frame. * * @see IEEE802.11 * @author Kaito Yamada * @since pcap4j 1.7.0 */ public static enum CalibrationPosition { /** not a calibration frame: 0 */ NOT_CALIBRATION(0, "not a calibration frame"), /** calibration start: 1 */ CALIBRATION_START(1, "calibration start"), /** sounding response: 2 */ SOUNDING_RESPONSE(2, "sounding response"), /** sounding complete: 3 */ SOUNDING_COMPLETE(3, "sounding complete"); private final int value; private final String name; private CalibrationPosition(int value, String name) { this.value = value; this.name = name; } /** @return value */ public int getValue() { return value; } /** @return name */ public String getName() { return name; } @Override public String toString() { StringBuilder sb = new StringBuilder(50); sb.append(value).append(" (").append(name).append(")"); return sb.toString(); } /** * @param value value * @return the CalibrationPosition object the value of which is the given value. */ public static CalibrationPosition getInstance(int value) { for (CalibrationPosition cp : values()) { if (cp.value == value) { return cp; } } throw new IllegalArgumentException("Invalid value: " + value); } } /** * CSI/Steering subfield of HT Control field of an IEEE802.11 frame. * * @see IEEE802.11 * @author Kaito Yamada * @since pcap4j 1.7.0 */ public static enum CsiOrSteering { /** No feedback required: 0 */ NO_FEEDBACK_REQUIRED(0, "No feedback required"), /** CSI: 1 */ CSI(1, "CSI"), /** Noncompressed beamforming: 2 */ NONCOMPRESSED_BEAMFORMING(2, "Noncompressed beamforming"), /** Compressed beamforming: 3 */ COMPRESSED_BEAMFORMING(3, "Compressed beamforming"); private final int value; private final String name; private CsiOrSteering(int value, String name) { this.value = value; this.name = name; } /** @return value */ public int getValue() { return value; } /** @return name */ public String getName() { return name; } @Override public String toString() { StringBuilder sb = new StringBuilder(50); sb.append(value).append(" (").append(name).append(")"); return sb.toString(); } /** * @param value value * @return the CsiSteering object the value of which is the given value. */ public static CsiOrSteering getInstance(int value) { for (CsiOrSteering val : values()) { if (val.value == value) { return val; } } throw new IllegalArgumentException("Invalid value: " + value); } } /** * @author Kaito Yamada * @since pcap4j 1.7.0 */ public static final class Builder { private Dot11LinkAdaptationControl linkAdaptationControl; private CalibrationPosition calibrationPosition; private byte calibrationSequence; private boolean bit20; private boolean bit21; private CsiOrSteering csiOrSteering; private boolean ndpAnnouncement; private boolean bit25; private boolean bit26; private boolean bit27; private boolean bit28; private boolean bit29; private boolean acConstraint; private boolean rdgOrMorePpdu; /** */ public Builder() {} private Builder(Dot11HtControl obj) { this.linkAdaptationControl = obj.linkAdaptationControl; this.calibrationPosition = obj.calibrationPosition; this.calibrationSequence = obj.calibrationSequence; this.bit20 = obj.bit20; this.bit21 = obj.bit21; this.csiOrSteering = obj.csiOrSteering; this.ndpAnnouncement = obj.ndpAnnouncement; this.bit25 = obj.bit25; this.bit26 = obj.bit26; this.bit27 = obj.bit27; this.bit28 = obj.bit28; this.bit29 = obj.bit29; this.acConstraint = obj.acConstraint; this.rdgOrMorePpdu = obj.rdgOrMorePpdu; } /** * @param linkAdaptationControl linkAdaptationControl * @return this Builder object for method chaining. */ public Builder linkAdaptationControl(Dot11LinkAdaptationControl linkAdaptationControl) { this.linkAdaptationControl = linkAdaptationControl; return this; } /** * @param calibrationPosition calibrationPosition * @return this Builder object for method chaining. */ public Builder calibrationPosition(CalibrationPosition calibrationPosition) { this.calibrationPosition = calibrationPosition; return this; } /** * @param calibrationSequence calibrationSequence. The value is between 0 and 3 (inclusive). * @return this Builder object for method chaining. */ public Builder calibrationSequence(byte calibrationSequence) { this.calibrationSequence = calibrationSequence; return this; } /** * @param bit20 bit20 * @return this Builder object for method chaining. */ public Builder bit20(boolean bit20) { this.bit20 = bit20; return this; } /** * @param bit21 bit21 * @return this Builder object for method chaining. */ public Builder bit21(boolean bit21) { this.bit21 = bit21; return this; } /** * @param csiOrSteering csiOrSteering * @return this Builder object for method chaining. */ public Builder csiOrSteering(CsiOrSteering csiOrSteering) { this.csiOrSteering = csiOrSteering; return this; } /** * @param ndpAnnouncement ndpAnnouncement * @return this Builder object for method chaining. */ public Builder ndpAnnouncement(boolean ndpAnnouncement) { this.ndpAnnouncement = ndpAnnouncement; return this; } /** * @param bit25 bit25 * @return this Builder object for method chaining. */ public Builder bit25(boolean bit25) { this.bit25 = bit25; return this; } /** * @param bit26 bit26 * @return this Builder object for method chaining. */ public Builder bit26(boolean bit26) { this.bit26 = bit26; return this; } /** * @param bit27 bit27 * @return this Builder object for method chaining. */ public Builder bit27(boolean bit27) { this.bit27 = bit27; return this; } /** * @param bit28 bit28 * @return this Builder object for method chaining. */ public Builder bit28(boolean bit28) { this.bit28 = bit28; return this; } /** * @param bit29 bit29 * @return this Builder object for method chaining. */ public Builder bit29(boolean bit29) { this.bit29 = bit29; return this; } /** * @param acConstraint acConstraint * @return this Builder object for method chaining. */ public Builder acConstraint(boolean acConstraint) { this.acConstraint = acConstraint; return this; } /** * @param rdgOrMorePpdu rdgOrMorePpdu * @return this Builder object for method chaining. */ public Builder rdgOrMorePpdu(boolean rdgOrMorePpdu) { this.rdgOrMorePpdu = rdgOrMorePpdu; return this; } /** @return a new Dot11HtControl object. */ public Dot11HtControl build() { return new Dot11HtControl(this); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy