blob: ed8f8c19f15595c5f83c7bc77ebda8e1b8928812 [file] [log] [blame]
package com.android.server.wifi.hotspot2.anqp;
import com.android.internal.annotations.VisibleForTesting;
import java.net.ProtocolException;
import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Set;
/**
* The IP Address Type availability ANQP Element, IEEE802.11-2012 section 8.4.4.9
*
* Format:
*
* | IP Address |
* 1
* b0 b7
* | IPv6 Address | IPv4 Address |
* 2 bits 6 bits
*
* IPv4 Address field values:
* 0 - Address type not available
* 1 - Public IPv4 address available
* 2 - Port-restricted IPv4 address available
* 3 - Single NATed private IPv4 address available
* 4 - Single NATed private IPv4 address available
* 5 - Port-restricted IPv4 address and single NATed IPv4 address available
* 6 - Port-restricted IPv4 address and double NATed IPv4 address available
* 7 - Availability of the address type is not known
*
* IPv6 Address field values:
* 0 - Address type not available
* 1 - Address type not available
* 2 - Availability of the address type not known
*
*/
public class IPAddressTypeAvailabilityElement extends ANQPElement {
@VisibleForTesting
public static final int EXPECTED_BUFFER_LENGTH = 1;
/**
* Constants for IPv4 availability.
*/
public static final int IPV4_NOT_AVAILABLE = 0;
public static final int IPV4_PUBLIC = 1;
public static final int IPV4_PORT_RESTRICTED = 2;
public static final int IPV4_SINGLE_NAT = 3;
public static final int IPV4_DOUBLE_NAT = 4;
public static final int IPV4_PORT_RESTRICTED_AND_SINGLE_NAT = 5;
public static final int IPV4_PORT_RESTRICTED_AND_DOUBLE_NAT = 6;
public static final int IPV4_UNKNOWN = 7;
private static final Set<Integer> IPV4_AVAILABILITY = new HashSet<Integer>();
static {
IPV4_AVAILABILITY.add(IPV4_NOT_AVAILABLE);
IPV4_AVAILABILITY.add(IPV4_PUBLIC);
IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED);
IPV4_AVAILABILITY.add(IPV4_SINGLE_NAT);
IPV4_AVAILABILITY.add(IPV4_DOUBLE_NAT);
IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED_AND_SINGLE_NAT);
IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED_AND_DOUBLE_NAT);
}
/**
* Constants for IPv6 availability.
*/
public static final int IPV6_NOT_AVAILABLE = 0;
public static final int IPV6_AVAILABLE = 1;
public static final int IPV6_UNKNOWN = 2;
private static final Set<Integer> IPV6_AVAILABILITY = new HashSet<Integer>();
static {
IPV6_AVAILABILITY.add(IPV6_NOT_AVAILABLE);
IPV6_AVAILABILITY.add(IPV6_AVAILABLE);
IPV6_AVAILABILITY.add(IPV6_UNKNOWN);
}
private static final int IPV4_AVAILABILITY_MASK = 0x3F;
private static final int IPV6_AVAILABILITY_MASK = 0x3;
private final int mV4Availability;
private final int mV6Availability;
@VisibleForTesting
public IPAddressTypeAvailabilityElement(int v4Availability, int v6Availability) {
super(Constants.ANQPElementType.ANQPIPAddrAvailability);
mV4Availability = v4Availability;
mV6Availability = v6Availability;
}
/**
* Parse an IPAddressTypeAvailabilityElement from the given buffer.
*
* @param payload The byte buffer to read from
* @return {@link IPAddressTypeAvailabilityElement}
* @throws ProtocolException
*/
public static IPAddressTypeAvailabilityElement parse(ByteBuffer payload)
throws ProtocolException {
if (payload.remaining() != EXPECTED_BUFFER_LENGTH) {
throw new ProtocolException("Unexpected buffer length: " + payload.remaining());
}
int ipField = payload.get() & 0xFF;
int v6Availability = ipField & IPV6_AVAILABILITY_MASK;
if (!IPV6_AVAILABILITY.contains(v6Availability)) {
v6Availability = IPV6_UNKNOWN;
}
int v4Availability = (ipField >> 2) & IPV4_AVAILABILITY_MASK;
if (!IPV4_AVAILABILITY.contains(v4Availability)) {
v4Availability = IPV4_UNKNOWN;
}
return new IPAddressTypeAvailabilityElement(v4Availability, v6Availability);
}
public int getV4Availability() {
return mV4Availability;
}
public int getV6Availability() {
return mV6Availability;
}
@Override
public boolean equals(Object thatObject) {
if (this == thatObject) {
return true;
}
if (!(thatObject instanceof IPAddressTypeAvailabilityElement)) {
return false;
}
IPAddressTypeAvailabilityElement that = (IPAddressTypeAvailabilityElement) thatObject;
return mV4Availability == that.mV4Availability && mV6Availability == that.mV6Availability;
}
@Override
public int hashCode() {
return mV4Availability << 2 + mV6Availability;
}
@Override
public String toString() {
return "IPAddressTypeAvailability{" +
"mV4Availability=" + mV4Availability +
", mV6Availability=" + mV6Availability +
'}';
}
}