Home | History | Annotate | Download | only in anqp
      1 package com.android.server.wifi.hotspot2.anqp;
      2 
      3 import com.android.internal.annotations.VisibleForTesting;
      4 
      5 import java.net.ProtocolException;
      6 import java.nio.ByteBuffer;
      7 import java.util.HashSet;
      8 import java.util.Set;
      9 
     10 /**
     11  * The IP Address Type availability ANQP Element, IEEE802.11-2012 section 8.4.4.9
     12  *
     13  * Format:
     14  *
     15  * | IP Address |
     16  *       1
     17  * b0                           b7
     18  * | IPv6 Address | IPv4 Address |
     19  *     2 bits          6 bits
     20  *
     21  * IPv4 Address field values:
     22  * 0 - Address type not available
     23  * 1 - Public IPv4 address available
     24  * 2 - Port-restricted IPv4 address available
     25  * 3 - Single NATed private IPv4 address available
     26  * 4 - Single NATed private IPv4 address available
     27  * 5 - Port-restricted IPv4 address and single NATed IPv4 address available
     28  * 6 - Port-restricted IPv4 address and double NATed IPv4 address available
     29  * 7 - Availability of the address type is not known
     30  *
     31  * IPv6 Address field values:
     32  * 0 - Address type not available
     33  * 1 - Address type not available
     34  * 2 - Availability of the address type not known
     35  *
     36  */
     37 public class IPAddressTypeAvailabilityElement extends ANQPElement {
     38     @VisibleForTesting
     39     public static final int EXPECTED_BUFFER_LENGTH = 1;
     40 
     41     /**
     42      * Constants for IPv4 availability.
     43      */
     44     public static final int IPV4_NOT_AVAILABLE = 0;
     45     public static final int IPV4_PUBLIC = 1;
     46     public static final int IPV4_PORT_RESTRICTED = 2;
     47     public static final int IPV4_SINGLE_NAT = 3;
     48     public static final int IPV4_DOUBLE_NAT = 4;
     49     public static final int IPV4_PORT_RESTRICTED_AND_SINGLE_NAT = 5;
     50     public static final int IPV4_PORT_RESTRICTED_AND_DOUBLE_NAT = 6;
     51     public static final int IPV4_UNKNOWN = 7;
     52     private static final Set<Integer> IPV4_AVAILABILITY = new HashSet<Integer>();
     53     static {
     54         IPV4_AVAILABILITY.add(IPV4_NOT_AVAILABLE);
     55         IPV4_AVAILABILITY.add(IPV4_PUBLIC);
     56         IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED);
     57         IPV4_AVAILABILITY.add(IPV4_SINGLE_NAT);
     58         IPV4_AVAILABILITY.add(IPV4_DOUBLE_NAT);
     59         IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED_AND_SINGLE_NAT);
     60         IPV4_AVAILABILITY.add(IPV4_PORT_RESTRICTED_AND_DOUBLE_NAT);
     61     }
     62 
     63     /**
     64      * Constants for IPv6 availability.
     65      */
     66     public static final int IPV6_NOT_AVAILABLE = 0;
     67     public static final int IPV6_AVAILABLE = 1;
     68     public static final int IPV6_UNKNOWN = 2;
     69     private static final Set<Integer> IPV6_AVAILABILITY = new HashSet<Integer>();
     70     static {
     71         IPV6_AVAILABILITY.add(IPV6_NOT_AVAILABLE);
     72         IPV6_AVAILABILITY.add(IPV6_AVAILABLE);
     73         IPV6_AVAILABILITY.add(IPV6_UNKNOWN);
     74     }
     75 
     76     private static final int IPV4_AVAILABILITY_MASK = 0x3F;
     77     private static final int IPV6_AVAILABILITY_MASK = 0x3;
     78 
     79     private final int mV4Availability;
     80     private final int mV6Availability;
     81 
     82     @VisibleForTesting
     83     public IPAddressTypeAvailabilityElement(int v4Availability, int v6Availability) {
     84         super(Constants.ANQPElementType.ANQPIPAddrAvailability);
     85         mV4Availability = v4Availability;
     86         mV6Availability = v6Availability;
     87     }
     88 
     89     /**
     90      * Parse an IPAddressTypeAvailabilityElement from the given buffer.
     91      *
     92      * @param payload The byte buffer to read from
     93      * @return {@link IPAddressTypeAvailabilityElement}
     94      * @throws ProtocolException
     95      */
     96     public static IPAddressTypeAvailabilityElement parse(ByteBuffer payload)
     97             throws ProtocolException {
     98         if (payload.remaining() != EXPECTED_BUFFER_LENGTH) {
     99             throw new ProtocolException("Unexpected buffer length: " + payload.remaining());
    100         }
    101 
    102         int ipField = payload.get() & 0xFF;
    103 
    104         int v6Availability = ipField & IPV6_AVAILABILITY_MASK;
    105         if (!IPV6_AVAILABILITY.contains(v6Availability)) {
    106             v6Availability = IPV6_UNKNOWN;
    107         }
    108 
    109         int v4Availability = (ipField >> 2) & IPV4_AVAILABILITY_MASK;
    110         if (!IPV4_AVAILABILITY.contains(v4Availability)) {
    111             v4Availability = IPV4_UNKNOWN;
    112         }
    113 
    114         return new IPAddressTypeAvailabilityElement(v4Availability, v6Availability);
    115     }
    116 
    117     public int getV4Availability() {
    118         return mV4Availability;
    119     }
    120 
    121     public int getV6Availability() {
    122         return mV6Availability;
    123     }
    124 
    125     @Override
    126     public boolean equals(Object thatObject) {
    127         if (this == thatObject) {
    128             return true;
    129         }
    130         if (!(thatObject instanceof IPAddressTypeAvailabilityElement)) {
    131             return false;
    132         }
    133         IPAddressTypeAvailabilityElement that = (IPAddressTypeAvailabilityElement) thatObject;
    134         return mV4Availability == that.mV4Availability && mV6Availability == that.mV6Availability;
    135     }
    136 
    137     @Override
    138     public int hashCode() {
    139         return mV4Availability << 2 + mV6Availability;
    140     }
    141 
    142     @Override
    143     public String toString() {
    144         return "IPAddressTypeAvailability{" +
    145                 "mV4Availability=" + mV4Availability +
    146                 ", mV6Availability=" + mV6Availability +
    147                 '}';
    148     }
    149 }
    150