155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/*
255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Copyright (C) 2011 The Android Open Source Project
355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Licensed under the Apache License, Version 2.0 (the "License");
555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * you may not use this file except in compliance with the License.
655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * You may obtain a copy of the License at
755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *      http://www.apache.org/licenses/LICENSE-2.0
955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync *
1055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * Unless required by applicable law or agreed to in writing, software
1155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * distributed under the License is distributed on an "AS IS" BASIS,
1255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * See the License for the specific language governing permissions and
1455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * limitations under the License.
1555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
1655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpackage android.net.wifi.p2p;
1855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
1955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Parcelable;
2055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.os.Parcel;
2155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport android.util.Log;
2255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncimport java.util.regex.Pattern;
2461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenagaimport java.util.regex.Matcher;
2555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync/**
2755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync * A class representing a Wi-Fi p2p device
286f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff *
293a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff * Note that the operations are not thread safe
306f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff * {@see WifiP2pManager}
3155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync */
3255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo syncpublic class WifiP2pDevice implements Parcelable {
3355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
3455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final String TAG = "WifiP2pDevice";
356f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff
3655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
376f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * The device name is a user friendly string to identify a Wi-Fi p2p device
3855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
39bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    public String deviceName = "";
4055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
426f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * The device MAC address uniquely identifies a Wi-Fi p2p device
4355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
44bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff    public String deviceAddress = "";
4555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
4655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
476f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * Primary device type identifies the type of device. For example, an application
486f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * could filter the devices discovered to only display printers if the purpose is to
496f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * enable a printing action from the user. See the Wi-Fi Direct technical specification
506f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * for the full list of standard device types supported.
5155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
5255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public String primaryDeviceType;
5355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
5455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
556f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * Secondary device type is an optional attribute that can be provided by a device in
566f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * addition to the primary device type.
5755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
5855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public String secondaryDeviceType;
5955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
6055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
6155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    // These definitions match the ones in wpa_supplicant
6255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* WPS config methods supported */
6355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int WPS_CONFIG_DISPLAY         = 0x0008;
6455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int WPS_CONFIG_PUSHBUTTON      = 0x0080;
6555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int WPS_CONFIG_KEYPAD          = 0x0100;
6655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
6755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Device Capability bitmap */
6855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_SERVICE_DISCOVERY         = 1;
6955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_CLIENT_DISCOVERABILITY    = 1<<1;
7055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_CONCURRENT_OPER           = 1<<2;
7155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_INFRA_MANAGED             = 1<<3;
7255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_DEVICE_LIMIT              = 1<<4;
7355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int DEVICE_CAPAB_INVITATION_PROCEDURE      = 1<<5;
7455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
7555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /* Group Capability bitmap */
7655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_GROUP_OWNER                = 1;
7755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_PERSISTENT_GROUP           = 1<<1;
7855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_GROUP_LIMIT                = 1<<2;
7955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_INTRA_BSS_DIST             = 1<<3;
8055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_CROSS_CONN                 = 1<<4;
8155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_PERSISTENT_RECONN          = 1<<5;
8255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private static final int GROUP_CAPAB_GROUP_FORMATION            = 1<<6;
8355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
8455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
8555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * WPS config methods supported
866f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * @hide
8755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
8855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public int wpsConfigMethodsSupported;
8955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
9055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
9155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Device capability
926f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * @hide
9355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
9455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public int deviceCapability;
9555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
9655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
9755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * Group capability
986f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * @hide
9955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
10055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public int groupCapability;
10155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
102651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static final int CONNECTED   = 0;
103651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static final int INVITED     = 1;
104651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static final int FAILED      = 2;
105651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static final int AVAILABLE   = 3;
106651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public static final int UNAVAILABLE = 4;
10755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
108651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /** Device connection status */
109651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public int status = UNAVAILABLE;
11055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
111ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    /** @hide */
112ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    public WifiP2pWfdInfo wfdInfo;
113ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber
114ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber    /** Detailed device string pattern with WFD info
11561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     * Example:
116ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber     *  P2P-DEVICE-FOUND 00:18:6b:de:a3:6e p2p_dev_addr=00:18:6b:de:a3:6e
117ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber     *  pri_dev_type=1-0050F204-1 name='DWD-300-DEA36E' config_methods=0x188
118ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber     *  dev_capab=0x21 group_capab=0x9
11961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     */
12061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    private static final Pattern detailedDevicePattern = Pattern.compile(
12161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
12261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "(\\d+ )?" +
12361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) " +
12461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "pri_dev_type=(\\d+-[0-9a-fA-F]+-\\d+) " +
12561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "name='(.*)' " +
12661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "config_methods=(0x[0-9a-fA-F]+) " +
12761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "dev_capab=(0x[0-9a-fA-F]+) " +
1281f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff        "group_capab=(0x[0-9a-fA-F]+)" +
1293af71e6dcf078ad50c9d074e08b5b04311971f35Dmitry Shmidt        "( wfd_dev_info=0x([0-9a-fA-F]{12}))?"
13061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    );
13161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga
13261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    /** 2 token device address pattern
13361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     * Example:
13461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
13561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09
13661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     */
13761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    private static final Pattern twoTokenPattern = Pattern.compile(
13861472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "(p2p_dev_addr=)?((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
13961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    );
14061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga
14161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    /** 3 token device address pattern
14261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     * Example:
14361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
14461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=fa:7b:7a:42:02:13
14561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     */
14661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    private static final Pattern threeTokenPattern = Pattern.compile(
14761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        "(?:[0-9a-f]{2}:){5}[0-9a-f]{2} p2p_dev_addr=((?:[0-9a-f]{2}:){5}[0-9a-f]{2})"
14861472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga    );
14961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga
15061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga
151651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    public WifiP2pDevice() {
15255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
15355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
15455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    /**
15555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     * @param string formats supported include
15655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *  P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13
15755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *  pri_dev_type=1-0050F204-1 name='p2p-TEST1' config_methods=0x188 dev_capab=0x27
1581f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff     *  group_capab=0x0 wfd_dev_info=000006015d022a0032
15955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *
16055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *  P2P-DEVICE-LOST p2p_dev_addr=fa:7b:7a:42:02:13
16155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *
16261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  AP-STA-CONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
16361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *
16461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *  AP-STA-DISCONNECTED 42:fc:89:a8:96:09 [p2p_dev_addr=02:90:4c:a0:92:54]
16561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga     *
16655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *  fa:7b:7a:42:02:13
16755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *
16855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     *  Note: The events formats can be looked up in the wpa_supplicant code
1696f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff     * @hide
17055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync     */
17155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pDevice(String string) throws IllegalArgumentException {
172bfed2d6c618e0bf2c271dad1f4acf6d29ebbea51Irfan Sheriff        String[] tokens = string.split("[ \n]");
17361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        Matcher match;
17455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (tokens.length < 1) {
17655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            throw new IllegalArgumentException("Malformed supplicant event");
17755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
17855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
17961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga        switch (tokens.length) {
18061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            case 1:
18161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                /* Just a device address */
18261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceAddress = string;
18361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                return;
18461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            case 2:
18561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                match = twoTokenPattern.matcher(string);
18661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                if (!match.find()) {
18761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    throw new IllegalArgumentException("Malformed supplicant event");
18861472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                }
18961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceAddress = match.group(2);
19061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                return;
19161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            case 3:
19261472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                match = threeTokenPattern.matcher(string);
19361472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                if (!match.find()) {
19461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    throw new IllegalArgumentException("Malformed supplicant event");
19561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                }
19661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceAddress = match.group(1);
19761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                return;
19861472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga            default:
19961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                match = detailedDevicePattern.matcher(string);
20061472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                if (!match.find()) {
20161472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                    throw new IllegalArgumentException("Malformed supplicant event");
202618455f7e7255019c8cc08a734ba7c52b67a7dc8Irfan Sheriff                }
20355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
20461472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceAddress = match.group(3);
20561472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                primaryDeviceType = match.group(4);
20661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceName = match.group(5);
20761472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                wpsConfigMethodsSupported = parseHex(match.group(6));
20861472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                deviceCapability = parseHex(match.group(7));
20961472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                groupCapability = parseHex(match.group(8));
2101f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                if (match.group(9) != null) {
2111f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                    String str = match.group(10);
2121f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                    wfdInfo = new WifiP2pWfdInfo(parseHex(str.substring(0,4)),
2131f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                            parseHex(str.substring(4,8)),
2141f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                            parseHex(str.substring(8,12)));
2151f6d8706918ddb277cad5fc8a006cc56ea7dbf69Irfan Sheriff                }
21661472a8314e6716f231ec1c0aba73e005935829bYoshihiko Ikenaga                break;
21755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
21855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
21955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (tokens[0].startsWith("P2P-DEVICE-FOUND")) {
220651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff            status = AVAILABLE;
22155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
22255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
22355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2246f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    /** Returns true if WPS push button configuration is supported */
2256f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    public boolean wpsPbcSupported() {
2266f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        return (wpsConfigMethodsSupported & WPS_CONFIG_PUSHBUTTON) != 0;
2276f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    }
2286f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff
2296f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    /** Returns true if WPS keypad configuration is supported */
2306f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    public boolean wpsKeypadSupported() {
2316f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        return (wpsConfigMethodsSupported & WPS_CONFIG_KEYPAD) != 0;
2326f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    }
2336f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff
2346f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    /** Returns true if WPS display configuration is supported */
2356f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    public boolean wpsDisplaySupported() {
2366f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        return (wpsConfigMethodsSupported & WPS_CONFIG_DISPLAY) != 0;
2376f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    }
2386f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff
2396f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    /** Returns true if the device is capable of service discovery */
2406f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    public boolean isServiceDiscoveryCapable() {
2416f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff        return (deviceCapability & DEVICE_CAPAB_SERVICE_DISCOVERY) != 0;
2426f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    }
2436f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff
2440879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /** Returns true if the device is capable of invitation {@hide}*/
2450879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public boolean isInvitationCapable() {
2460879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return (deviceCapability & DEVICE_CAPAB_INVITATION_PROCEDURE) != 0;
2470879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
2480879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2490879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /** Returns true if the device reaches the limit. {@hide}*/
2500879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public boolean isDeviceLimit() {
2510879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return (deviceCapability & DEVICE_CAPAB_DEVICE_LIMIT) != 0;
2520879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
2530879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2546f7d385d964949e507dcc9c88012372f48d0bce7Irfan Sheriff    /** Returns true if the device is a group owner */
25555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public boolean isGroupOwner() {
25655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return (groupCapability & GROUP_CAPAB_GROUP_OWNER) != 0;
25755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
25855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
2590879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    /** Returns true if the group reaches the limit. {@hide}*/
2600879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    public boolean isGroupLimit() {
2610879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga        return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0;
2620879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga    }
2630879d03f0a5caa108a0a7320442d57629f9ced81Yoshihiko Ikenaga
2643a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff    /**
2653a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     * Update device details. This will be throw an exception if the device address
2663a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     * does not match.
2673a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     * @param device to be updated
2683a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     * @throws IllegalArgumentException if the device is null or device address does not match
2693a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     * @hide
2703a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff     */
271c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    public void update(WifiP2pDevice device) {
2723a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        updateSupplicantDetails(device);
2733a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        status = device.status;
2743a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff    }
2753a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff
2763a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff    /** Updates details obtained from supplicant @hide */
277ffadfb9ffdced62db215319d3edc7717802088fbVinit Deshapnde    public void updateSupplicantDetails(WifiP2pDevice device) {
2783a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        if (device == null) {
2793a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff            throw new IllegalArgumentException("device is null");
2803a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        }
2813a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        if (device.deviceAddress == null) {
2823a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff            throw new IllegalArgumentException("deviceAddress is null");
2833a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        }
2843a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        if (!deviceAddress.equals(device.deviceAddress)) {
2853a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff            throw new IllegalArgumentException("deviceAddress does not match");
2863a67e2515bff73fab57621b1f9966662e83b7881Irfan Sheriff        }
287c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        deviceName = device.deviceName;
288c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        primaryDeviceType = device.primaryDeviceType;
289c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        secondaryDeviceType = device.secondaryDeviceType;
290c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
291c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        deviceCapability = device.deviceCapability;
292c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        groupCapability = device.groupCapability;
293c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff        wfdInfo = device.wfdInfo;
294c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff    }
295c41096e1b4bf453c195c8c46c5d296f2125d31f6Irfan Sheriff
29655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    @Override
29755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public boolean equals(Object obj) {
29855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (this == obj) return true;
29955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (!(obj instanceof WifiP2pDevice)) return false;
30055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        WifiP2pDevice other = (WifiP2pDevice) obj;
30255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (other == null || other.deviceAddress == null) {
30355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            return (deviceAddress == null);
30455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
3058c57bcdbc6b360ee27d59b957a53e64c03257c9drepo sync        return other.deviceAddress.equals(deviceAddress);
30655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
30755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
30855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public String toString() {
30955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        StringBuffer sbuf = new StringBuffer();
31055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("Device: ").append(deviceName);
31155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n deviceAddress: ").append(deviceAddress);
31255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n primary type: ").append(primaryDeviceType);
31355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n secondary type: ").append(secondaryDeviceType);
31455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n wps: ").append(wpsConfigMethodsSupported);
31555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n grpcapab: ").append(groupCapability);
31655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n devcapab: ").append(deviceCapability);
31755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        sbuf.append("\n status: ").append(status);
318ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        sbuf.append("\n wfdInfo: ").append(wfdInfo);
31955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return sbuf.toString();
32055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
32155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
322651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /** Implement the Parcelable interface */
32355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public int describeContents() {
32455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return 0;
32555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
32655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
327651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /** copy constructor */
32855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public WifiP2pDevice(WifiP2pDevice source) {
32955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (source != null) {
33055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            deviceName = source.deviceName;
33155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            deviceAddress = source.deviceAddress;
33255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            primaryDeviceType = source.primaryDeviceType;
33355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            secondaryDeviceType = source.secondaryDeviceType;
33455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            wpsConfigMethodsSupported = source.wpsConfigMethodsSupported;
33555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            deviceCapability = source.deviceCapability;
33655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            groupCapability = source.groupCapability;
33755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            status = source.status;
338ab3b9fbfa0523e036ec71888d0da5dc55cd3301bIrfan Sheriff            wfdInfo = new WifiP2pWfdInfo(source.wfdInfo);
33955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
34055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
34155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
342651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /** Implement the Parcelable interface */
34355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public void writeToParcel(Parcel dest, int flags) {
34455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeString(deviceName);
34555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeString(deviceAddress);
34655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeString(primaryDeviceType);
34755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeString(secondaryDeviceType);
34855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeInt(wpsConfigMethodsSupported);
34955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeInt(deviceCapability);
35055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        dest.writeInt(groupCapability);
351651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff        dest.writeInt(status);
352ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        if (wfdInfo != null) {
353ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            dest.writeInt(1);
354ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            wfdInfo.writeToParcel(dest, flags);
355ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        } else {
356ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber            dest.writeInt(0);
357ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber        }
35855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
35955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
360651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff    /** Implement the Parcelable interface */
36155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    public static final Creator<WifiP2pDevice> CREATOR =
36255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        new Creator<WifiP2pDevice>() {
36355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            public WifiP2pDevice createFromParcel(Parcel in) {
36455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                WifiP2pDevice device = new WifiP2pDevice();
36555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.deviceName = in.readString();
36655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.deviceAddress = in.readString();
36755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.primaryDeviceType = in.readString();
36855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.secondaryDeviceType = in.readString();
36955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.wpsConfigMethodsSupported = in.readInt();
37055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.deviceCapability = in.readInt();
37155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                device.groupCapability = in.readInt();
372651cdfcbac6245f570475991588ddc2d30265e8dIrfan Sheriff                device.status = in.readInt();
373ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                if (in.readInt() == 1) {
374ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                    device.wfdInfo = WifiP2pWfdInfo.CREATOR.createFromParcel(in);
375ab4cd45133ccea6a66fb081f9b2a8d14eb3e4f1dAndreas Huber                }
37655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                return device;
37755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
37855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
37955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            public WifiP2pDevice[] newArray(int size) {
38055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync                return new WifiP2pDevice[size];
38155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            }
38255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        };
38355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
38455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    //supported formats: 0x1abc, 0X1abc, 1abc
38555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    private int parseHex(String hexString) {
38655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        int num = 0;
38755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        if (hexString.startsWith("0x") || hexString.startsWith("0X")) {
38855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            hexString = hexString.substring(2);
38955bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
39055bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync
39155bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        try {
39255bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            num = Integer.parseInt(hexString, 16);
39355bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        } catch(NumberFormatException e) {
39455bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync            Log.e(TAG, "Failed to parse hex string " + hexString);
39555bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        }
39655bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync        return num;
39755bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync    }
39855bc5f3e0408bcb5a39a6732de0b2d1aa99a55berepo sync}
399