org.pcap4j.packet.RadiotapDataChannel Maven / Gradle / Ivy
/*_##########################################################################
_##
_## Copyright (C) 2016 Pcap4J.org
_##
_##########################################################################
*/
package org.pcap4j.packet;
import java.nio.ByteOrder;
import org.pcap4j.packet.RadiotapPacket.RadiotapData;
import org.pcap4j.util.ByteArrays;
/**
* Radiotap Channel field. Tx/Rx frequency in MHz and flags.
*
* @see Radiotap
* @author Kaito Yamada
* @since pcap4j 1.6.5
*/
public final class RadiotapDataChannel implements RadiotapData {
/** */
private static final long serialVersionUID = 3645927613193110605L;
private static final int LENGTH = 4;
private final short frequency;
private final boolean lsbOfFlags;
private final boolean secondLsbOfFlags;
private final boolean thirdLsbOfFlags;
private final boolean fourthLsbOfFlags;
private final boolean turbo;
private final boolean cck;
private final boolean ofdm;
private final boolean twoGhzSpectrum;
private final boolean fiveGhzSpectrum;
private final boolean onlyPassiveScan;
private final boolean dynamicCckOfdm;
private final boolean gfsk;
private final boolean gsm;
private final boolean staticTurbo;
private final boolean halfRate;
private final boolean quarterRate;
/**
* 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 RadiotapChannel object.
* @throws IllegalRawDataException if parsing the raw data fails.
*/
public static RadiotapDataChannel newInstance(byte[] rawData, int offset, int length)
throws IllegalRawDataException {
ByteArrays.validateBounds(rawData, offset, length);
return new RadiotapDataChannel(rawData, offset, length);
}
private RadiotapDataChannel(byte[] rawData, int offset, int length)
throws IllegalRawDataException {
if (length < LENGTH) {
StringBuilder sb = new StringBuilder(200);
sb.append("The data is too short to build a RadiotapChannel (")
.append(LENGTH)
.append(" bytes). data: ")
.append(ByteArrays.toHexString(rawData, " "))
.append(", offset: ")
.append(offset)
.append(", length: ")
.append(length);
throw new IllegalRawDataException(sb.toString());
}
this.frequency = ByteArrays.getShort(rawData, offset, ByteOrder.LITTLE_ENDIAN);
this.lsbOfFlags = (rawData[offset + 2] & 0x01) != 0;
this.secondLsbOfFlags = (rawData[offset + 2] & 0x02) != 0;
this.thirdLsbOfFlags = (rawData[offset + 2] & 0x04) != 0;
this.fourthLsbOfFlags = (rawData[offset + 2] & 0x08) != 0;
this.turbo = (rawData[offset + 2] & 0x10) != 0;
this.cck = (rawData[offset + 2] & 0x20) != 0;
this.ofdm = (rawData[offset + 2] & 0x40) != 0;
this.twoGhzSpectrum = (rawData[offset + 2] & 0x80) != 0;
this.fiveGhzSpectrum = (rawData[offset + 3] & 0x01) != 0;
this.onlyPassiveScan = (rawData[offset + 3] & 0x02) != 0;
this.dynamicCckOfdm = (rawData[offset + 3] & 0x04) != 0;
this.gfsk = (rawData[offset + 3] & 0x08) != 0;
this.gsm = (rawData[offset + 3] & 0x10) != 0;
this.staticTurbo = (rawData[offset + 3] & 0x20) != 0;
this.halfRate = (rawData[offset + 3] & 0x40) != 0;
this.quarterRate = (rawData[offset + 3] & 0x80) != 0;
}
private RadiotapDataChannel(Builder builder) {
if (builder == null) {
throw new NullPointerException("builder is null.");
}
this.frequency = builder.frequency;
this.lsbOfFlags = builder.lsbOfFlags;
this.secondLsbOfFlags = builder.secondLsbOfFlags;
this.thirdLsbOfFlags = builder.thirdLsbOfFlags;
this.fourthLsbOfFlags = builder.fourthLsbOfFlags;
this.turbo = builder.turbo;
this.cck = builder.cck;
this.ofdm = builder.ofdm;
this.twoGhzSpectrum = builder.twoGhzSpectrum;
this.fiveGhzSpectrum = builder.fiveGhzSpectrum;
this.onlyPassiveScan = builder.onlyPassiveScan;
this.dynamicCckOfdm = builder.dynamicCckOfdm;
this.gfsk = builder.gfsk;
this.gsm = builder.gsm;
this.staticTurbo = builder.staticTurbo;
this.halfRate = builder.halfRate;
this.quarterRate = builder.quarterRate;
}
/**
* Tx/Rx frequency in MHz
*
* @return frequency (unit: MHz)
*/
public short getFrequency() {
return frequency;
}
/**
* Tx/Rx frequency in MHz
*
* @return frequency (unit: MHz)
*/
public int getFrequencyAsInt() {
return frequency & 0xFFFF;
}
/** @return true if the LSB of the flags field is set to 1; otherwise false. */
public boolean getLsbOfFlags() {
return lsbOfFlags;
}
/** @return true if the second LSB of the flags field is set to 1; otherwise false. */
public boolean getSecondLsbOfFlags() {
return secondLsbOfFlags;
}
/** @return true if the third LSB of the flags field is set to 1; otherwise false. */
public boolean getThirdLsbOfFlags() {
return thirdLsbOfFlags;
}
/** @return true if the fourth LSB of the flags field is set to 1; otherwise false. */
public boolean getFourthLsbOfFlags() {
return fourthLsbOfFlags;
}
/** @return turbo */
public boolean isTurbo() {
return turbo;
}
/** @return cck */
public boolean isCck() {
return cck;
}
/** @return ofdm */
public boolean isOfdm() {
return ofdm;
}
/** @return twoGhzSpectrum */
public boolean isTwoGhzSpectrum() {
return twoGhzSpectrum;
}
/** @return fiveGhzSpectrum */
public boolean isFiveGhzSpectrum() {
return fiveGhzSpectrum;
}
/** @return onlyPassiveScan */
public boolean isOnlyPassiveScan() {
return onlyPassiveScan;
}
/** @return dynamicCckOfdm */
public boolean isDynamicCckOfdm() {
return dynamicCckOfdm;
}
/** @return gfsk */
public boolean isGfsk() {
return gfsk;
}
/** @return gsm */
public boolean isGsm() {
return gsm;
}
/** @return staticTurbo */
public boolean isStaticTurbo() {
return staticTurbo;
}
/** @return halfRate */
public boolean isHalfRate() {
return halfRate;
}
/** @return quarterRate */
public boolean isQuarterRate() {
return quarterRate;
}
@Override
public int length() {
return LENGTH;
}
@Override
public byte[] getRawData() {
byte[] data = new byte[4];
System.arraycopy(
ByteArrays.toByteArray(frequency, ByteOrder.LITTLE_ENDIAN),
0,
data,
0,
ByteArrays.SHORT_SIZE_IN_BYTES);
if (lsbOfFlags) {
data[2] |= 0x01;
}
if (secondLsbOfFlags) {
data[2] |= 0x02;
}
if (thirdLsbOfFlags) {
data[2] |= 0x04;
}
if (fourthLsbOfFlags) {
data[2] |= 0x08;
}
if (turbo) {
data[2] |= 0x10;
}
if (cck) {
data[2] |= 0x20;
}
if (ofdm) {
data[2] |= 0x40;
}
if (twoGhzSpectrum) {
data[2] |= 0x80;
}
if (fiveGhzSpectrum) {
data[3] |= 0x01;
}
if (onlyPassiveScan) {
data[3] |= 0x02;
}
if (dynamicCckOfdm) {
data[3] |= 0x04;
}
if (gfsk) {
data[3] |= 0x08;
}
if (gsm) {
data[3] |= 0x10;
}
if (staticTurbo) {
data[3] |= 0x20;
}
if (halfRate) {
data[3] |= 0x40;
}
if (quarterRate) {
data[3] |= 0x80;
}
return data;
}
/** @return a new Builder object populated with this object's fields. */
public Builder getBuilder() {
return new Builder(this);
}
@Override
public String toString() {
return toString("");
}
@Override
public String toString(String indent) {
StringBuilder sb = new StringBuilder();
String ls = System.getProperty("line.separator");
sb.append(indent)
.append("Channel: ")
.append(ls)
.append(indent)
.append(" Frequency: ")
.append(getFrequencyAsInt())
.append(" MHz")
.append(ls)
.append(indent)
.append(" LSB of flags: ")
.append(lsbOfFlags)
.append(ls)
.append(indent)
.append(" 2nd LSB of flags: ")
.append(secondLsbOfFlags)
.append(ls)
.append(indent)
.append(" 3rd LSB of flags: ")
.append(thirdLsbOfFlags)
.append(ls)
.append(indent)
.append(" 4th LSB of flags: ")
.append(fourthLsbOfFlags)
.append(ls)
.append(indent)
.append(" Turbo: ")
.append(turbo)
.append(ls)
.append(indent)
.append(" CCK: ")
.append(cck)
.append(ls)
.append(indent)
.append(" OFDM: ")
.append(ofdm)
.append(ls)
.append(indent)
.append(" 2 GHz spectrum: ")
.append(twoGhzSpectrum)
.append(ls)
.append(indent)
.append(" 5 GHz spectrum: ")
.append(fiveGhzSpectrum)
.append(ls)
.append(indent)
.append(" Only passive scan: ")
.append(onlyPassiveScan)
.append(ls)
.append(indent)
.append(" Dynamic CCK-OFDM: ")
.append(dynamicCckOfdm)
.append(ls)
.append(indent)
.append(" GFSK: ")
.append(gfsk)
.append(ls)
.append(indent)
.append(" GSM: ")
.append(gsm)
.append(ls)
.append(indent)
.append(" Static Turbo: ")
.append(staticTurbo)
.append(ls)
.append(indent)
.append(" Half rate: ")
.append(halfRate)
.append(ls)
.append(indent)
.append(" Quarter rate: ")
.append(quarterRate)
.append(ls);
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (cck ? 1231 : 1237);
result = prime * result + (dynamicCckOfdm ? 1231 : 1237);
result = prime * result + (fiveGhzSpectrum ? 1231 : 1237);
result = prime * result + (fourthLsbOfFlags ? 1231 : 1237);
result = prime * result + frequency;
result = prime * result + (gfsk ? 1231 : 1237);
result = prime * result + (gsm ? 1231 : 1237);
result = prime * result + (halfRate ? 1231 : 1237);
result = prime * result + (lsbOfFlags ? 1231 : 1237);
result = prime * result + (ofdm ? 1231 : 1237);
result = prime * result + (onlyPassiveScan ? 1231 : 1237);
result = prime * result + (quarterRate ? 1231 : 1237);
result = prime * result + (secondLsbOfFlags ? 1231 : 1237);
result = prime * result + (staticTurbo ? 1231 : 1237);
result = prime * result + (thirdLsbOfFlags ? 1231 : 1237);
result = prime * result + (turbo ? 1231 : 1237);
result = prime * result + (twoGhzSpectrum ? 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;
RadiotapDataChannel other = (RadiotapDataChannel) obj;
if (cck != other.cck) return false;
if (dynamicCckOfdm != other.dynamicCckOfdm) return false;
if (fiveGhzSpectrum != other.fiveGhzSpectrum) return false;
if (fourthLsbOfFlags != other.fourthLsbOfFlags) return false;
if (frequency != other.frequency) return false;
if (gfsk != other.gfsk) return false;
if (gsm != other.gsm) return false;
if (halfRate != other.halfRate) return false;
if (lsbOfFlags != other.lsbOfFlags) return false;
if (ofdm != other.ofdm) return false;
if (onlyPassiveScan != other.onlyPassiveScan) return false;
if (quarterRate != other.quarterRate) return false;
if (secondLsbOfFlags != other.secondLsbOfFlags) return false;
if (staticTurbo != other.staticTurbo) return false;
if (thirdLsbOfFlags != other.thirdLsbOfFlags) return false;
if (turbo != other.turbo) return false;
if (twoGhzSpectrum != other.twoGhzSpectrum) return false;
return true;
}
/**
* @author Kaito Yamada
* @since pcap4j 1.6.5
*/
public static final class Builder {
private short frequency;
private boolean lsbOfFlags;
private boolean secondLsbOfFlags;
private boolean thirdLsbOfFlags;
private boolean fourthLsbOfFlags;
private boolean turbo;
private boolean cck;
private boolean ofdm;
private boolean twoGhzSpectrum;
private boolean fiveGhzSpectrum;
private boolean onlyPassiveScan;
private boolean dynamicCckOfdm;
private boolean gfsk;
private boolean gsm;
private boolean staticTurbo;
private boolean halfRate;
private boolean quarterRate;
/** */
public Builder() {}
private Builder(RadiotapDataChannel obj) {
this.frequency = obj.frequency;
this.lsbOfFlags = obj.lsbOfFlags;
this.secondLsbOfFlags = obj.secondLsbOfFlags;
this.thirdLsbOfFlags = obj.thirdLsbOfFlags;
this.fourthLsbOfFlags = obj.fourthLsbOfFlags;
this.turbo = obj.turbo;
this.cck = obj.cck;
this.ofdm = obj.ofdm;
this.twoGhzSpectrum = obj.twoGhzSpectrum;
this.fiveGhzSpectrum = obj.fiveGhzSpectrum;
this.onlyPassiveScan = obj.onlyPassiveScan;
this.dynamicCckOfdm = obj.dynamicCckOfdm;
this.gfsk = obj.gfsk;
this.gsm = obj.gsm;
this.staticTurbo = obj.staticTurbo;
this.halfRate = obj.halfRate;
this.quarterRate = obj.quarterRate;
}
/**
* @param frequency frequency
* @return this Builder object for method chaining.
*/
public Builder frequency(short frequency) {
this.frequency = frequency;
return this;
}
/**
* @param lsbOfFlags lsbOfFlags
* @return this Builder object for method chaining.
*/
public Builder lsbOfFlags(boolean lsbOfFlags) {
this.lsbOfFlags = lsbOfFlags;
return this;
}
/**
* @param secondLsbOfFlags secondLsbOfFlags
* @return this Builder object for method chaining.
*/
public Builder secondLsbOfFlags(boolean secondLsbOfFlags) {
this.secondLsbOfFlags = secondLsbOfFlags;
return this;
}
/**
* @param thirdLsbOfFlags thirdLsbOfFlags
* @return this Builder object for method chaining.
*/
public Builder thirdLsbOfFlags(boolean thirdLsbOfFlags) {
this.thirdLsbOfFlags = thirdLsbOfFlags;
return this;
}
/**
* @param fourthLsbOfFlags fourthLsbOfFlags
* @return this Builder object for method chaining.
*/
public Builder fourthLsbOfFlags(boolean fourthLsbOfFlags) {
this.fourthLsbOfFlags = fourthLsbOfFlags;
return this;
}
/**
* @param turbo turbo
* @return this Builder object for method chaining.
*/
public Builder turbo(boolean turbo) {
this.turbo = turbo;
return this;
}
/**
* @param cck cck
* @return this Builder object for method chaining.
*/
public Builder cck(boolean cck) {
this.cck = cck;
return this;
}
/**
* @param ofdm ofdm
* @return this Builder object for method chaining.
*/
public Builder ofdm(boolean ofdm) {
this.ofdm = ofdm;
return this;
}
/**
* @param twoGhzSpectrum twoGhzSpectrum
* @return this Builder object for method chaining.
*/
public Builder twoGhzSpectrum(boolean twoGhzSpectrum) {
this.twoGhzSpectrum = twoGhzSpectrum;
return this;
}
/**
* @param fiveGhzSpectrum fiveGhzSpectrum
* @return this Builder object for method chaining.
*/
public Builder fiveGhzSpectrum(boolean fiveGhzSpectrum) {
this.fiveGhzSpectrum = fiveGhzSpectrum;
return this;
}
/**
* @param onlyPassiveScan onlyPassiveScan
* @return this Builder object for method chaining.
*/
public Builder onlyPassiveScan(boolean onlyPassiveScan) {
this.onlyPassiveScan = onlyPassiveScan;
return this;
}
/**
* @param dynamicCckOfdm dynamicCckOfdm
* @return this Builder object for method chaining.
*/
public Builder dynamicCckOfdm(boolean dynamicCckOfdm) {
this.dynamicCckOfdm = dynamicCckOfdm;
return this;
}
/**
* @param gfsk gfsk
* @return this Builder object for method chaining.
*/
public Builder gfsk(boolean gfsk) {
this.gfsk = gfsk;
return this;
}
/**
* @param gsm gsm
* @return this Builder object for method chaining.
*/
public Builder gsm(boolean gsm) {
this.gsm = gsm;
return this;
}
/**
* @param staticTurbo staticTurbo
* @return this Builder object for method chaining.
*/
public Builder staticTurbo(boolean staticTurbo) {
this.staticTurbo = staticTurbo;
return this;
}
/**
* @param halfRate halfRate
* @return this Builder object for method chaining.
*/
public Builder halfRate(boolean halfRate) {
this.halfRate = halfRate;
return this;
}
/**
* @param quarterRate quarterRate
* @return this Builder object for method chaining.
*/
public Builder quarterRate(boolean quarterRate) {
this.quarterRate = quarterRate;
return this;
}
/** @return a new RadiotapChannel object. */
public RadiotapDataChannel build() {
return new RadiotapDataChannel(this);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy