| 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 + |
| '}'; |
| } |
| } |