FileDocCategorySizeDatePackage
WifiParser.javaAPI DocAndroid 5.1 API10059Thu Mar 12 22:22:52 GMT 2015com.android.server.wifi

WifiParser

public class WifiParser extends Object
Describes information about a detected access point. In addition to the attributes described here, the supplicant keeps track of {@code quality}, {@code noise}, and {@code maxbitrate} attributes, but does not currently report them to external clients.

Fields Summary
private static final int
VENDOR_SPECIFIC_IE
private static final int
IEEE_RSN_IE
private static final int
WPA_IE_VENDOR_TYPE
Constructors Summary
public WifiParser()

Methods Summary
public static java.lang.Stringparse_akm(com.android.server.wifi.WifiParser$IE[] full_IE, java.util.BitSet ieee_cap)

 //WFA WPA vendor IE OUI/type

    /*
     * parse beacon or probe response frame and build the capabilities
     * {@hide}
     *
     * This function is called so as to build the capabilities string of the scan result, hence it is called
     * by AutoJoin controller when handling scan results that are coming from WifiScanner.
     *
     * It parses the ieee beacon's capability field, WPA and RSNE IE as per spec, but build the
     * ScanResult.capabilities String in a way that mirror the values returned by wpa_supplicant.
     *
     * Once the capabilities string is build, the ScanResult can be used be the system as if it was coming from supplicant.
     */
     /* @hide
     * */
           
        boolean privacy = false;
        boolean error = false;
        if (ieee_cap == null)
            return null;

        if (full_IE == null)
            return null;

        privacy = ieee_cap.get(4);

        String capabilities = "";
        boolean rsne_found = false;
        boolean wpa_found = false;

        for (IE ie : full_IE) {
            String security = "";
            if (ie.id == IEEE_RSN_IE) {
                rsne_found = true;
                //parsing WPA2 capabilities

                ByteBuffer buf = ByteBuffer.wrap(ie.data);

                int total_len = ie.data.length;
                int offset = 2;

                //version
                if ((total_len - offset) < 2) {
                    //not enough space for version field
                    security = "";
                    error = true;
                    break;
                }
                int val = 0;
                if (0x0100 != buf.getShort(offset)) {
                    //incorrect version
                    security = "";
                    error = true;
                    break;
                }
                offset += 2;


                //group cipher
                if ((total_len - offset) < 4) {
                    security = ""; //parse error on group cipher suite
                    error = true;
                    break;
                }
                offset += 4; //skip the group cipher

                security = "[WPA2"; //found the RSNE IE, hence start building the capability string

                //pairwise cipher
                if ((total_len - offset) < 2) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                val = buf.getShort(offset);
                if ((total_len - offset) < (2 + val * 4)) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                offset += 2 + val * 4; //skip the pairwise ciphers

                //AKM
                if ((total_len - offset) < 2) {
                    security = ""; //parse error no AKM
                    error = true;
                    break;
                }
                val = buf.getShort(offset);
                if ((total_len - offset) < (2 + val * 4)) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                offset += 2;
                if (val == 0) {
                    security += "-EAP"; //default AKM
                }
                for (int i = 0; i < val; i++) {
                    int akm = buf.getInt(offset);
                    boolean found = false;
                    switch (akm) {
                        case 0x01ac0f00:
                            security += found ? "+" : "-" + "EAP";
                            found = true;
                            break;
                        case 0x02ac0f00:
                            security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2
                            found = true;
                            break;
                        case 0x03ac0f00:
                            security += found ? "+" : "-" + "FT/EAP";
                            found = true;
                            break;
                        case 0x04ac0f00:
                            security += found ? "+" : "-" + "FT/PSK";
                            found = true;
                            break;
                        case 0x06ac0f00:
                            security += found ? "+" : "-" + "PSK-SHA256";
                            found = true;
                            break;
                        case 0x05ac0f00:
                            security += found ? "+" : "-" + "EAP-SHA256";
                            found = true;
                            break;
                    }
                    offset += 4;
                }
                //we parsed what we want at this point
                security += "]";
                capabilities += security;

            }

            if (ie.id == VENDOR_SPECIFIC_IE) {
                int total_len = ie.data.length;
                int offset = 2;

                //version
                if ((total_len - offset) < 4) {
                    //not enough space for OUI and type field
                    security = "";
                    error = true;
                    break;
                }

                ByteBuffer buf = ByteBuffer.wrap(ie.data);

                if (buf.getInt(offset) != 0x01F25000) {
                    //look for HS2.0 and WPA IE
                    security = "";
                    continue;
                }

                security = "[WPA"; //prep the string for WPA

                //version
                if ((total_len - offset) < 2) {
                    //not enough space for version field
                    security = "";
                    error = true;
                    break;
                }
                int val = 0;
                if (0x0100 != buf.getShort(offset)) {
                    //incorrect version
                    security = "";
                    error = true;
                    break;
                }
                offset += 2;


                //group cipher
                if ((total_len - offset) < 4) {
                    security = ""; //parse error on group cipher suite
                    error = true;
                    break;
                }
                offset += 4; //skip the group cipher


                //pairwise cipher
                if ((total_len - offset) < 2) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                val = buf.getShort(offset);
                if ((total_len - offset) < (2 + val * 4)) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                offset += 2 + val * 4; //skip the pairwise ciphers

                //AKM
                if ((total_len - offset) < 2) {
                    security = ""; //parse error no AKM
                    error = true;
                    break;
                }
                val = buf.getShort(offset);
                if ((total_len - offset) < (2 + val * 4)) {
                    security = ""; //parse error no pairwise cipher
                    error = true;
                    break;
                }
                offset += 2;
                if (val == 0) {
                    security += "-EAP"; //default AKM
                }
                for (int i = 0; i < val; i++) {
                    int akm = buf.getInt(offset);
                    boolean found = false;
                    switch (akm) {
                        case 0x01f25000:
                            security += found ? "+" : "-" + "EAP";
                            found = true;
                            break;
                        case 0x02f25000:
                            security += found ? "+" : "-" + "PSK"; //PSK as 802.11-2012 11.6.1.2
                            found = true;
                            break;

                    }
                    offset += 4;
                }
                //we parsed what we want at this point
                security += "]";
            }
        }

        if (rsne_found == false && wpa_found == false && privacy) {
            //private Beacon without an RSNE or WPA IE, hence WEP0
            capabilities += "[WEP]";
        }

        if (error)
            return null;
        else
            return capabilities;