1d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski/*
2d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * Copyright (C) 2017 The Android Open Source Project
3d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski *
4d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * Licensed under the Apache License, Version 2.0 (the "License");
5d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * you may not use this file except in compliance with the License.
6d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * You may obtain a copy of the License at
7d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski *
8d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski *      http://www.apache.org/licenses/LICENSE-2.0
9d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski *
10d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * Unless required by applicable law or agreed to in writing, software
11d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * distributed under the License is distributed on an "AS IS" BASIS,
12d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * See the License for the specific language governing permissions and
14d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski * limitations under the License.
15d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski */
16d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
17163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Piuspackage com.android.server.wifi.p2p;
18d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
19d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.hardware.wifi.supplicant.V1_0.ISupplicantP2pIfaceCallback;
207f7b374b3e75a929ab0d46426daf9a5e92c2d85bRoshan Piusimport android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
21d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.WpsInfo;
22d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pConfig;
23d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pDevice;
24d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pGroup;
25d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pProvDiscEvent;
26d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.WifiP2pWfdInfo;
27d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
28d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport android.util.Log;
29d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
30d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport com.android.server.wifi.p2p.WifiP2pServiceImpl.P2pStatus;
31d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport com.android.server.wifi.util.NativeUtil;
32d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
33d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport java.util.ArrayList;
347e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhneimport java.util.Arrays;
35d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskiimport java.util.List;
36d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
37163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius/**
38163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius * Class used for processing all P2P callbacks.
39163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius */
40d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowskipublic class SupplicantP2pIfaceCallback extends ISupplicantP2pIfaceCallback.Stub {
41d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private static final String TAG = "SupplicantP2pIfaceCallback";
42d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private static final boolean DBG = true;
43d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
44d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private final String mInterface;
45163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    private final WifiP2pMonitor mMonitor;
46d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
47163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius    public SupplicantP2pIfaceCallback(String iface, WifiP2pMonitor monitor) {
48d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mInterface = iface;
49d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor = monitor;
50d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
51d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
52d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
53d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    protected static void logd(String s) {
54d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (DBG) Log.d(TAG, s);
55d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
56d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
57d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
58d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate that a new network has been added.
59d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
60163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param networkId Network ID allocated to the corresponding network.
61d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
62d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onNetworkAdded(int networkId) {
63d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
64d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
65d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
66d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
67d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate that a network has been removed.
68d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
69163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param networkId Network ID allocated to the corresponding network.
70d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
71d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onNetworkRemoved(int networkId) {
72d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
73d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
74d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
75d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
76d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate that a P2P device has been found.
77d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
78d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device found. This must either
79d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        be the P2P device address or the P2P interface address.
80d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param p2pDeviceAddress P2P device address.
81d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param primaryDeviceType Type of device. Refer to section B.1 of Wifi P2P
82d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        Technical specification v1.2.
83d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param deviceName Name of the device.
84d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param configMethods Mask of WPS configuration methods supported by the
85d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        device.
86d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param deviceCapabilities Refer to section 4.1.4 of Wifi P2P Technical
87d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        specification v1.2.
88163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param groupCapabilities Refer to section 4.1.4 of Wifi P2P Technical
89d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        specification v1.2.
90d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param wfdDeviceInfo WFD device info as described in section 5.1.2 of WFD
91d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        technical specification v1.0.0.
92d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
93d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onDeviceFound(byte[] srcAddress, byte[] p2pDeviceAddress, byte[] primaryDeviceType,
94d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            String deviceName, short configMethods, byte deviceCapabilities, int groupCapabilities,
95d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            byte[] wfdDeviceInfo) {
96d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pDevice device = new WifiP2pDevice();
97d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.deviceName = deviceName;
98d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (deviceName == null) {
99d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Missing device name.");
100d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
101d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
102d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
103d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
104d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
105d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
106d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode device address.", e);
107d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
108d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
109d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
110d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
1115bf1c66cfc5099801abe53fd54cef661740b24b5Glen Kuhne            device.primaryDeviceType = NativeUtil.wpsDevTypeStringFromByteArray(primaryDeviceType);
112d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
113d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not encode device primary type.", e);
114d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
115d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
116d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
117d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.deviceCapability = deviceCapabilities;
118d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.groupCapability = groupCapabilities;
119d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.wpsConfigMethodsSupported = configMethods;
120d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.status = WifiP2pDevice.AVAILABLE;
121d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
122d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (wfdDeviceInfo != null && wfdDeviceInfo.length >= 6) {
123d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            device.wfdInfo = new WifiP2pWfdInfo(
124d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                    (wfdDeviceInfo[0] << 8) + wfdDeviceInfo[1],
125d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                    (wfdDeviceInfo[2] << 8) + wfdDeviceInfo[3],
126d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                    (wfdDeviceInfo[4] << 8) + wfdDeviceInfo[5]);
127d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
128d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
129d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Device discovered on " + mInterface + ": " + device);
130d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pDeviceFound(mInterface, device);
131d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
132d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
133d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
134d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate that a P2P device has been lost.
135d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
136d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param p2pDeviceAddress P2P device address.
137d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
138d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onDeviceLost(byte[] p2pDeviceAddress) {
139d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pDevice device = new WifiP2pDevice();
140d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
141d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
142d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
143d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
144d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode device address.", e);
145d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
146d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
147d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
148d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        device.status = WifiP2pDevice.UNAVAILABLE;
149d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
150d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Device lost on " + mInterface + ": " + device);
151d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pDeviceLost(mInterface, device);
152d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
153d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
154d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
155d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
156d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the termination of P2P find operation.
157d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
158d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onFindStopped() {
159d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Search stopped on " + mInterface);
160d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pFindStopped(mInterface);
161d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
162d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
163d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
164d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
165d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the reception of a P2P Group Owner negotiation request.
166d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
167d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device that initiated the GO
168d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        negotiation request.
169d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param passwordId Type of password.
170d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
171d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGoNegotiationRequest(byte[] srcAddress, short passwordId) {
172d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pConfig config = new WifiP2pConfig();
173d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
174d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
175d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            config.deviceAddress = NativeUtil.macAddressFromByteArray(srcAddress);
176d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
177d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode device address.", e);
178d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
179d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
180d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
181d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        config.wps = new WpsInfo();
182d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
183d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        switch (passwordId) {
184d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case WpsDevPasswordId.USER_SPECIFIED:
185d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                config.wps.setup = WpsInfo.DISPLAY;
186d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
187d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
188d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case WpsDevPasswordId.PUSHBUTTON:
189d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                config.wps.setup = WpsInfo.PBC;
190d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
191d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
192d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case WpsDevPasswordId.REGISTRAR_SPECIFIED:
193d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                config.wps.setup = WpsInfo.KEYPAD;
194d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
195d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
196d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            default:
197d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                config.wps.setup = WpsInfo.PBC;
198d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
199d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
200d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
201d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group Owner negotiation initiated on " + mInterface + ": " + config);
202d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pGoNegotiationRequest(mInterface, config);
203d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
204d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
205d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
206d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
207d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the completion of a P2P Group Owner negotiation request.
208d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
209d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param status Status of the GO negotiation.
210d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
211d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGoNegotiationCompleted(int status) {
212d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group Owner negotiation completed with status: " + status);
213d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        P2pStatus result = halStatusToP2pStatus(status);
214d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
215d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (result == P2pStatus.SUCCESS) {
216d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mMonitor.broadcastP2pGoNegotiationSuccess(mInterface);
217d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } else {
218d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mMonitor.broadcastP2pGoNegotiationFailure(mInterface, result);
219d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
220d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
221d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
222d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
223d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
224d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate a successful formation of a P2P group.
225d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
226d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGroupFormationSuccess() {
227d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group formation successful on " + mInterface);
228d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pGroupFormationSuccess(mInterface);
229d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
230d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
231d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
232d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
233d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate a failure to form a P2P group.
234d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
235d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param failureReason Failure reason string for debug purposes.
236d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
237d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGroupFormationFailure(String failureReason) {
238d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        // TODO(ender): failureReason should probably be an int (P2pStatusCode).
239d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group formation failed on " + mInterface + ": " + failureReason);
240d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pGroupFormationFailure(mInterface, failureReason);
241d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
242d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
243d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
244d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
245d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the start of a P2P group.
246d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
247d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
248d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param isGo Whether this device is owner of the group.
249d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param ssid SSID of the group.
250d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param frequency Frequency on which this group is created.
251d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param psk PSK used to secure the group.
252d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param passphrase PSK passphrase used to secure the group.
253d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param goDeviceAddress MAC Address of the owner of this group.
254d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param isPersistent Whether this group is persisted or not.
255d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
256d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGroupStarted(String groupIfName, boolean isGo, ArrayList<Byte> ssid,
257d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            int frequency, byte[] psk, String passphrase, byte[] goDeviceAddress,
258d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            boolean isPersistent) {
259d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (groupIfName == null) {
260d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Missing group interface name.");
261d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
262d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
263d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
264d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group " + groupIfName + " started on " + mInterface);
265d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
266d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pGroup group = new WifiP2pGroup();
267d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setInterface(groupIfName);
268d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
269d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
270d5a56317c4697aab6fc8c277ba33dbce6542db79Roshan Pius            String quotedSsid = NativeUtil.encodeSsid(ssid);
271d5a56317c4697aab6fc8c277ba33dbce6542db79Roshan Pius            group.setNetworkName(NativeUtil.removeEnclosingQuotes(quotedSsid));
272d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
273d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not encode SSID.", e);
274d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
275d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
276d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
277d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setIsGroupOwner(isGo);
278d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setPassphrase(passphrase);
279d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
280d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (isPersistent) {
281d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            group.setNetworkId(WifiP2pGroup.PERSISTENT_NET_ID);
282d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } else {
283d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            group.setNetworkId(WifiP2pGroup.TEMPORARY_NET_ID);
284d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
285d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
286d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pDevice owner = new WifiP2pDevice();
287d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
288d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
289d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            owner.deviceAddress = NativeUtil.macAddressFromByteArray(goDeviceAddress);
290d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
291d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode Group Owner address.", e);
292d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
293d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
294d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
295d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setOwner(owner);
296d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pGroupStarted(mInterface, group);
297d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
298d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
299d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
300d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
301d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the removal of a P2P group.
302d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
303d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param groupIfName Interface name of the group. (For ex: p2p-p2p0-1)
304d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param isGo Whether this device is owner of the group.
305d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
306d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onGroupRemoved(String groupIfName, boolean isGo) {
307d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        if (groupIfName == null) {
308d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Missing group name.");
309d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
310d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
311d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
312d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Group " + groupIfName + " removed from " + mInterface);
313d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pGroup group = new WifiP2pGroup();
314d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setInterface(groupIfName);
315d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setIsGroupOwner(isGo);
316d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pGroupRemoved(mInterface, group);
317d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
318d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
319d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
320d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
321d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the reception of a P2P invitation.
322d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
323d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device that sent the invitation.
324d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param goDeviceAddress MAC Address of the owner of this group.
325163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param bssid Bssid of the group.
326d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param persistentNetworkId Persistent network Id of the group.
327d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param operatingFrequency Frequency on which the invitation was received.
328d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
329d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onInvitationReceived(byte[] srcAddress, byte[] goDeviceAddress,
330d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            byte[] bssid, int persistentNetworkId, int operatingFrequency) {
331d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pGroup group = new WifiP2pGroup();
332d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setNetworkId(persistentNetworkId);
333d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
334d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pDevice client = new WifiP2pDevice();
335d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
336d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
337d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            client.deviceAddress = NativeUtil.macAddressFromByteArray(srcAddress);
338d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
339d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode MAC address.", e);
340d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
341d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
342d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
343d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.addClient(client);
344d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
345d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pDevice owner = new WifiP2pDevice();
346d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
347d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
348d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            owner.deviceAddress = NativeUtil.macAddressFromByteArray(goDeviceAddress);
349d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
350d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode Group Owner MAC address.", e);
351d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
352d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
353d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
354d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        group.setOwner(owner);
355d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
356d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Invitation received on " + mInterface + ": " + group);
357d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pInvitationReceived(mInterface, group);
358d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
359d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
360d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
361d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
362d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the result of the P2P invitation request.
363d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
364163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius     * @param bssid Bssid of the group.
365d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param status Status of the invitation.
366d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
367d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onInvitationResult(byte[] bssid, int status) {
368d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Invitation completed with status: " + status);
369d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pInvitationResult(mInterface, halStatusToP2pStatus(status));
370d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
371d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
372d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
373d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
374d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the completion of a P2P provision discovery request.
375d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
376d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param p2pDeviceAddress P2P device address.
377d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param isRequest Whether we received or sent the provision discovery.
378d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param status Status of the provision discovery (SupplicantStatusCode).
379d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param configMethods Mask of WPS configuration methods supported.
380d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *                      Only one configMethod bit should be set per call.
381d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param generatedPin 8 digit pin generated.
382d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
383d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onProvisionDiscoveryCompleted(byte[] p2pDeviceAddress, boolean isRequest,
384d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            byte status, short configMethods, String generatedPin) {
3857f7b374b3e75a929ab0d46426daf9a5e92c2d85bRoshan Pius        if (status != ISupplicantP2pIfaceCallback.P2pProvDiscStatusCode.SUCCESS) {
386d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Provision discovery failed: " + status);
387d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mMonitor.broadcastP2pProvisionDiscoveryFailure(mInterface);
388d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
389d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
390d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
391163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        logd("Provision discovery " + (isRequest ? "request" : "response")
392163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius                + " for WPS Config method: " + configMethods);
393d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
394d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        WifiP2pProvDiscEvent event = new WifiP2pProvDiscEvent();
395d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        event.device = new WifiP2pDevice();
396d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
397d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
398d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            event.device.deviceAddress = NativeUtil.macAddressFromByteArray(p2pDeviceAddress);
399d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
400d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not decode MAC address.", e);
401d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
402d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
403d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
4047f7b374b3e75a929ab0d46426daf9a5e92c2d85bRoshan Pius        if ((configMethods & WpsConfigMethods.PUSHBUTTON) != 0) {
405d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            if (isRequest) {
406d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                event.event = WifiP2pProvDiscEvent.PBC_REQ;
407d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                mMonitor.broadcastP2pProvisionDiscoveryPbcRequest(mInterface, event);
408d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            } else {
409d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                event.event = WifiP2pProvDiscEvent.PBC_RSP;
410d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                mMonitor.broadcastP2pProvisionDiscoveryPbcResponse(mInterface, event);
411d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            }
4125a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne        } else if (!isRequest && (configMethods & WpsConfigMethods.KEYPAD) != 0) {
413d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            event.event = WifiP2pProvDiscEvent.SHOW_PIN;
414d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            event.pin = generatedPin;
415d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mMonitor.broadcastP2pProvisionDiscoveryShowPin(mInterface, event);
4165a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne        } else if (!isRequest && (configMethods & WpsConfigMethods.DISPLAY) != 0) {
4175a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            event.event = WifiP2pProvDiscEvent.ENTER_PIN;
4185a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            mMonitor.broadcastP2pProvisionDiscoveryEnterPin(mInterface, event);
4195a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne        } else if (isRequest && (configMethods & WpsConfigMethods.DISPLAY) != 0) {
4205a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            event.event = WifiP2pProvDiscEvent.SHOW_PIN;
4215a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            event.pin = generatedPin;
4225a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne            mMonitor.broadcastP2pProvisionDiscoveryShowPin(mInterface, event);
4235a843c0d793abf48de2c77e0b1a54fded88bb018Glen Kuhne        } else if (isRequest && (configMethods & WpsConfigMethods.KEYPAD) != 0) {
424d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            event.event = WifiP2pProvDiscEvent.ENTER_PIN;
425d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            mMonitor.broadcastP2pProvisionDiscoveryEnterPin(mInterface, event);
426d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } else {
427d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Unsupported config methods: " + configMethods);
428d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
429d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
430d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
431d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
432d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
433d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate the reception of a P2P service discovery response.
434d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
435d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device that sent the service discovery.
436d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param updateIndicator Service update indicator. Refer to section 3.1.3 of
437d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *        Wifi P2P Technical specification v1.2.
438d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param tlvs Refer to section 3.1.3.1 of Wifi P2P Technical specification v1.2.
439d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
440d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onServiceDiscoveryResponse(byte[] srcAddress, short updateIndicator,
441d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            ArrayList<Byte> tlvs) {
442d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        List<WifiP2pServiceResponse> response = null;
443d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
444d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("Service discovery response received on " + mInterface);
445d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        try {
446c5f4b2597df6284d35d2f3af8fb35f72e140c5a7Glen Kuhne            String srcAddressStr = NativeUtil.macAddressFromByteArray(srcAddress);
447c5f4b2597df6284d35d2f3af8fb35f72e140c5a7Glen Kuhne            // updateIndicator is not used
448c5f4b2597df6284d35d2f3af8fb35f72e140c5a7Glen Kuhne            response = WifiP2pServiceResponse.newInstance(srcAddressStr,
449c5f4b2597df6284d35d2f3af8fb35f72e140c5a7Glen Kuhne                    NativeUtil.byteArrayFromArrayList(tlvs));
450d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        } catch (Exception e) {
451d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            Log.e(TAG, "Could not process service discovery response.", e);
452d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            return;
453d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        }
454d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        mMonitor.broadcastP2pServiceDiscoveryResponse(mInterface, response);
455d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
456d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
4577e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne    private WifiP2pDevice createStaEventDevice(byte[] srcAddress, byte[] p2pDeviceAddress) {
4587e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        WifiP2pDevice device = new WifiP2pDevice();
4597e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        byte[] deviceAddressBytes;
4607e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        // Legacy STAs may not supply a p2pDeviceAddress (signaled by a zero'd p2pDeviceAddress)
4617e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        // In this case, use srcAddress instead
4627e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        if (!Arrays.equals(NativeUtil.ANY_MAC_BYTES, p2pDeviceAddress)) {
4637e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne            deviceAddressBytes = p2pDeviceAddress;
4647e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        } else {
4657e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne            deviceAddressBytes = srcAddress;
4667e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        }
4677e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        try {
4687e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne            device.deviceAddress = NativeUtil.macAddressFromByteArray(deviceAddressBytes);
4697e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        } catch (Exception e) {
4707e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne            Log.e(TAG, "Could not decode MAC address", e);
4717e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne            return null;
4727e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        }
4737e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        return device;
4747e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne    }
475d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
476d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
477d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate when a STA device is connected to this device.
478d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
479d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device that was authorized.
480d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param p2pDeviceAddress P2P device address.
481d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
482d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onStaAuthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
483d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("STA authorized on " + mInterface);
4847e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
4857e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        if (device == null) {
4861555c030405df64cb4c52cff44598e678045b82bRoshan Pius            return;
4871555c030405df64cb4c52cff44598e678045b82bRoshan Pius        }
4881555c030405df64cb4c52cff44598e678045b82bRoshan Pius        mMonitor.broadcastP2pApStaConnected(mInterface, device);
489d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
490d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
491d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
492d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    /**
493d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * Used to indicate when a STA device is disconnected from this device.
494d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     *
495d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param srcAddress MAC address of the device that was deauthorized.
496d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     * @param p2pDeviceAddress P2P device address.
497d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski     */
498d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    public void onStaDeauthorized(byte[] srcAddress, byte[] p2pDeviceAddress) {
499d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        logd("STA deauthorized on " + mInterface);
5007e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        WifiP2pDevice device = createStaEventDevice(srcAddress, p2pDeviceAddress);
5017e9eafab778c3920732a965ca9a0b330c6c676d6Glen Kuhne        if (device == null) {
5021555c030405df64cb4c52cff44598e678045b82bRoshan Pius            return;
5031555c030405df64cb4c52cff44598e678045b82bRoshan Pius        }
5041555c030405df64cb4c52cff44598e678045b82bRoshan Pius        mMonitor.broadcastP2pApStaDisconnected(mInterface, device);
505d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
506d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
507d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
508d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    private static P2pStatus halStatusToP2pStatus(int status) {
509d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        P2pStatus result = P2pStatus.UNKNOWN;
510d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
511d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        switch (status) {
512d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.SUCCESS:
513d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.SUCCESS_DEFERRED:
514d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.SUCCESS;
515d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
516d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
517d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_INFO_CURRENTLY_UNAVAILABLE:
518d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE;
519d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
520d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
521d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_INCOMPATIBLE_PARAMS:
522d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.INCOMPATIBLE_PARAMETERS;
523d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
524d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
525d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_LIMIT_REACHED:
526d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.LIMIT_REACHED;
527d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
528d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
529d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_INVALID_PARAMS:
530d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.INVALID_PARAMETER;
531d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
532d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
533d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_UNABLE_TO_ACCOMMODATE:
534d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.UNABLE_TO_ACCOMMODATE_REQUEST;
535d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
536d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
537d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_PREV_PROTOCOL_ERROR:
538d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.PREVIOUS_PROTOCOL_ERROR;
539d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
540d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
541d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_NO_COMMON_CHANNELS:
542d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.NO_COMMON_CHANNEL;
543d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
544d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
545d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_UNKNOWN_GROUP:
546d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.UNKNOWN_P2P_GROUP;
547d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
548d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
549d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_BOTH_GO_INTENT_15:
550d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.BOTH_GO_INTENT_15;
551d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
552d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
553d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_INCOMPATIBLE_PROV_METHOD:
554d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.INCOMPATIBLE_PROVISIONING_METHOD;
555d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
556d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
557d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski            case P2pStatusCode.FAIL_REJECTED_BY_USER:
558d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                result = P2pStatus.REJECTED_BY_USER;
559d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski                break;
560163f9765f9e4c3f868b1e0d630b6adeaa115fb4aRoshan Pius        }
561d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski        return result;
562d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski    }
563d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski}
564d3c761e72a5f89c81bd74889a9fec663adcc491eTomasz Wiszkowski
565