1db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen/*
2db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Copyright (C) 2016 The Android Open Source Project
3db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *
4db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Licensed under the Apache License, Version 2.0 (the "License");
5db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * you may not use this file except in compliance with the License.
6db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * You may obtain a copy of the License at
7db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *
8db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *      http://www.apache.org/licenses/LICENSE-2.0
9db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *
10db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Unless required by applicable law or agreed to in writing, software
11db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * distributed under the License is distributed on an "AS IS" BASIS,
12db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * See the License for the specific language governing permissions and
14db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * limitations under the License.
15db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen */
16db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
17db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenpackage com.android.server.wifi.aware;
18db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
19db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.IWifiNanIface;
20db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanBandIndex;
21db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanBandSpecificConfig;
2269eb934f563ac0099113bf24587c729df25b15bfEtan Cohenimport android.hardware.wifi.V1_0.NanCipherSuiteType;
23db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanConfigRequest;
242bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohenimport android.hardware.wifi.V1_0.NanDataPathSecurityType;
25db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanEnableRequest;
26db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanInitiateDataPathRequest;
27db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanMatchAlg;
28db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanPublishRequest;
29db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest;
30db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanSubscribeRequest;
31db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanTransmitFollowupRequest;
32db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanTxType;
33db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatus;
34db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatusCode;
35db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.ConfigRequest;
36db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.PublishConfig;
37db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.SubscribeConfig;
38db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.os.RemoteException;
39db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.util.Log;
40db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
41db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport libcore.util.HexEncoding;
42db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
43db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.FileDescriptor;
44db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.PrintWriter;
45db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.util.ArrayList;
46db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
47db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen/**
48db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Translates Wi-Fi Aware requests from the framework to the HAL (HIDL).
49db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *
50db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Delegates the management of the NAN interface to WifiAwareNativeManager.
51db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen */
52db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenpublic class WifiAwareNativeApi {
53db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final String TAG = "WifiAwareNativeApi";
54db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final boolean DBG = false;
55db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final boolean VDBG = false; // STOPSHIP if true
56db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
57db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private final WifiAwareNativeManager mHal;
58db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
59db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public WifiAwareNativeApi(WifiAwareNativeManager wifiAwareNativeManager) {
60db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mHal = wifiAwareNativeManager;
61db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
62db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
63db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
64db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Query the firmware's capabilities.
65db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
66db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
67db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
68db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
69db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean getCapabilities(short transactionId) {
70db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) Log.v(TAG, "getCapabilities: transactionId=" + transactionId);
71db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
72db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
73db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
74db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "getCapabilities: null interface");
75db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
76db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
77db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
78db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
79db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.getCapabilitiesRequest(transactionId);
80db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
81db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
82db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
83db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "getCapabilities: error: " + statusString(status));
84db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
85db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
86db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
87db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "getCapabilities: exception: " + e);
88db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
89db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
90db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
91db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
92db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
93db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Enable and configure Aware.
94db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
95db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the
96db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            async callback to match with the original request.
97db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param configRequest Requested Aware configuration.
98db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param notifyIdentityChange Indicates whether or not to get address change callbacks.
99db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param initialConfiguration Specifies whether initial configuration
100db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            (true) or an update (false) to the configuration.
101db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
102db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
103db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            boolean notifyIdentityChange, boolean initialConfiguration) {
104db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
105db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "enableAndConfigure: transactionId=" + transactionId + ", configRequest="
106db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + configRequest + ", notifyIdentityChange=" + notifyIdentityChange
107db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", initialConfiguration=" + initialConfiguration);
108db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
109db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
110db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
111db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
112db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "enableAndConfigure: null interface");
113db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
114db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
115db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
116db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
117db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status;
118db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (initialConfiguration) {
119db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                // translate framework to HIDL configuration
120db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanEnableRequest req = new NanEnableRequest();
121db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
122db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
123db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
124db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.hopCountMax = 2;
125db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.masterPref = (byte) configRequest.mMasterPreference;
126db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
127db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
128db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
1291e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.configParams.includePublishServiceIdsInBeacon = true;
1301e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.configParams.numberOfPublishServiceIdsInBeacon = 0;
131cb1a42a285106e31790297b5427024f43307d457Etan Cohen                req.configParams.includeSubscribeServiceIdsInBeacon = true;
132cb1a42a285106e31790297b5427024f43307d457Etan Cohen                req.configParams.numberOfSubscribeServiceIdsInBeacon = 0;
133db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.rssiWindowSize = 8;
134db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.macAddressRandomizationIntervalSec = 1800;
135db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
136db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config24 = new NanBandSpecificConfig();
137db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiClose = 60;
138db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiMiddle = 70;
1391e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                config24.rssiCloseProximity = 60;
140db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.dwellTimeMs = (byte) 200;
141db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.scanPeriodSec = 20;
14249a847941e08faec5901d4824040a522b773ef83Etan Cohen                if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]
14349a847941e08faec5901d4824040a522b773ef83Etan Cohen                        == ConfigRequest.DW_INTERVAL_NOT_INIT) {
14449a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.validDiscoveryWindowIntervalVal = false;
14549a847941e08faec5901d4824040a522b773ef83Etan Cohen                } else {
14649a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.validDiscoveryWindowIntervalVal = true;
14749a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.discoveryWindowIntervalVal =
14849a847941e08faec5901d4824040a522b773ef83Etan Cohen                            (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
14949a847941e08faec5901d4824040a522b773ef83Etan Cohen                                    .NAN_BAND_24GHZ];
15049a847941e08faec5901d4824040a522b773ef83Etan Cohen                }
151db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
152db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
153db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config5 = new NanBandSpecificConfig();
154db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiClose = 60;
155db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiMiddle = 75;
1561e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                config5.rssiCloseProximity = 60;
157db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.dwellTimeMs = (byte) 200;
158db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.scanPeriodSec = 20;
15949a847941e08faec5901d4824040a522b773ef83Etan Cohen                if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]
16049a847941e08faec5901d4824040a522b773ef83Etan Cohen                        == ConfigRequest.DW_INTERVAL_NOT_INIT) {
16149a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.validDiscoveryWindowIntervalVal = false;
16249a847941e08faec5901d4824040a522b773ef83Etan Cohen                } else {
16349a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.validDiscoveryWindowIntervalVal = true;
16449a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.discoveryWindowIntervalVal =
16549a847941e08faec5901d4824040a522b773ef83Etan Cohen                            (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
16649a847941e08faec5901d4824040a522b773ef83Etan Cohen                                    .NAN_BAND_5GHZ];
16749a847941e08faec5901d4824040a522b773ef83Etan Cohen                }
168db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
169db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
170db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validClusterIdVals = true;
1711e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.debugConfigs.clusterIdTopRangeVal = (short) configRequest.mClusterHigh;
1721e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.debugConfigs.clusterIdBottomRangeVal = (short) configRequest.mClusterLow;
173db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validIntfAddrVal = false;
174db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validOuiVal = false;
175db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.ouiVal = 0;
176db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validRandomFactorForceVal = false;
177db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.randomFactorForceVal = 0;
178db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validHopCountForceVal = false;
179db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.hopCountForceVal = 0;
180db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validDiscoveryChannelVal = false;
181db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
182db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
183db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validUseBeaconsInBandVal = false;
184db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
185db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
186db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validUseSdfInBandVal = false;
187db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
188db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
189db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
190db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                status = iface.enableRequest(transactionId, req);
191db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
192db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanConfigRequest req = new NanConfigRequest();
193db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.masterPref = (byte) configRequest.mMasterPreference;
194db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
195db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableStartedClusterIndication = !notifyIdentityChange;
196db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableJoinedClusterIndication = !notifyIdentityChange;
1971e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.includePublishServiceIdsInBeacon = true;
1981e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                req.numberOfPublishServiceIdsInBeacon = 0;
199cb1a42a285106e31790297b5427024f43307d457Etan Cohen                req.includeSubscribeServiceIdsInBeacon = true;
200cb1a42a285106e31790297b5427024f43307d457Etan Cohen                req.numberOfSubscribeServiceIdsInBeacon = 0;
201db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.rssiWindowSize = 8;
202db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.macAddressRandomizationIntervalSec = 1800;
203db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
204db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config24 = new NanBandSpecificConfig();
205db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiClose = 60;
206db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiMiddle = 70;
2071e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                config24.rssiCloseProximity = 60;
208db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.dwellTimeMs = (byte) 200;
209db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.scanPeriodSec = 20;
21049a847941e08faec5901d4824040a522b773ef83Etan Cohen                if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]
21149a847941e08faec5901d4824040a522b773ef83Etan Cohen                        == ConfigRequest.DW_INTERVAL_NOT_INIT) {
21249a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.validDiscoveryWindowIntervalVal = false;
21349a847941e08faec5901d4824040a522b773ef83Etan Cohen                } else {
21449a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.validDiscoveryWindowIntervalVal = true;
21549a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config24.discoveryWindowIntervalVal =
21649a847941e08faec5901d4824040a522b773ef83Etan Cohen                            (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
21749a847941e08faec5901d4824040a522b773ef83Etan Cohen                                    .NAN_BAND_24GHZ];
21849a847941e08faec5901d4824040a522b773ef83Etan Cohen                }
219db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
220db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
221db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config5 = new NanBandSpecificConfig();
222db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiClose = 60;
223db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiMiddle = 75;
2241e7386343d09cb5b63661d52732999f8626ba140Etan Cohen                config5.rssiCloseProximity = 60;
225db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.dwellTimeMs = (byte) 200;
226db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.scanPeriodSec = 20;
22749a847941e08faec5901d4824040a522b773ef83Etan Cohen                if (configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]
22849a847941e08faec5901d4824040a522b773ef83Etan Cohen                        == ConfigRequest.DW_INTERVAL_NOT_INIT) {
22949a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.validDiscoveryWindowIntervalVal = false;
23049a847941e08faec5901d4824040a522b773ef83Etan Cohen                } else {
23149a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.validDiscoveryWindowIntervalVal = true;
23249a847941e08faec5901d4824040a522b773ef83Etan Cohen                    config5.discoveryWindowIntervalVal =
23349a847941e08faec5901d4824040a522b773ef83Etan Cohen                            (byte) configRequest.mDiscoveryWindowInterval[ConfigRequest
23449a847941e08faec5901d4824040a522b773ef83Etan Cohen                                    .NAN_BAND_5GHZ];
23549a847941e08faec5901d4824040a522b773ef83Etan Cohen                }
236db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
237db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
238db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                status = iface.configRequest(transactionId, req);
239db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
240db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
241db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
242db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
243db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "enableAndConfigure: error: " + statusString(status));
244db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
245db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
246db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
247db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "enableAndConfigure: exception: " + e);
248db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
249db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
250db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
251db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
252db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
253db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Disable Aware.
254db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
255db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
256db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
257db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
258db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean disable(short transactionId) {
259db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) Log.d(TAG, "disable");
260db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
261db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
262db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
263db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "disable: null interface");
264db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
265db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
266db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
267db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
268db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.disableRequest(transactionId);
269db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
270db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
271db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
272db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "disable: error: " + statusString(status));
273db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
274db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
275db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
276db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "disable: exception: " + e);
277db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
278db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
279db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
280db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
281db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
282db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Start or modify a service publish session.
283db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
284db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
285db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
286db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param publishId ID of the requested session - 0 to request a new publish
287db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            session.
288db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param publishConfig Configuration of the discovery session.
289db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
290db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean publish(short transactionId, int publishId, PublishConfig publishConfig) {
291db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
292db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "publish: transactionId=" + transactionId + ", config=" + publishConfig);
293db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
294db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
295db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
296db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
297db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "publish: null interface");
298db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
299db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
300db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
301db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanPublishRequest req = new NanPublishRequest();
302db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.sessionId = 0;
303db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
304db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryWindowPeriod = 1;
3050b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen        req.baseConfigs.discoveryCount = 0;
3062bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(publishConfig.mServiceName, req.baseConfigs.serviceName);
307db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        // TODO: what's the right value on publish?
308db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
3092bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(publishConfig.mServiceSpecificInfo,
310db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.baseConfigs.serviceSpecificInfo);
3112bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(publishConfig.mMatchFilter,
312db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
313db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                        ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
314db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.useRssiThreshold = false;
315db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableDiscoveryTerminationIndication =
316db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                !publishConfig.mEnableTerminateNotification;
317db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableMatchExpirationIndication = true;
318db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableFollowupReceivedIndication = false;
319db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
320db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        // TODO: configure ranging and security
3212bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
322db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.rangingRequired = false;
32386e4c343394565f8e59e02d25334589f96de38f0Etan Cohen        req.autoAcceptDataPathRequests = false;
324db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
325db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.publishType = publishConfig.mPublishType;
326db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.txType = NanTxType.BROADCAST;
327db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
328db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
329db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.startPublishRequest(transactionId, req);
330db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
331db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
332db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
333db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "publish: error: " + statusString(status));
334db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
335db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
336db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
337db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "publish: exception: " + e);
338db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
339db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
340db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
341db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
342db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
343db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Start or modify a service subscription session.
344db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
345db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
346db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
347db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param subscribeId ID of the requested session - 0 to request a new
348db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            subscribe session.
349db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param subscribeConfig Configuration of the discovery session.
350db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
351db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean subscribe(short transactionId, int subscribeId,
352db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            SubscribeConfig subscribeConfig) {
353db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
354db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "subscribe: transactionId=" + transactionId + ", config=" + subscribeConfig);
355db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
356db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
357db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
358db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
359db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "subscribe: null interface");
360db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
361db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
362db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
363db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanSubscribeRequest req = new NanSubscribeRequest();
364db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.sessionId = 0;
365db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.ttlSec = (short) subscribeConfig.mTtlSec;
366db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryWindowPeriod = 1;
3670b74b795587b6aada97c7c63f0febf94c76633e2Etan Cohen        req.baseConfigs.discoveryCount = 0;
3682bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(subscribeConfig.mServiceName,
3692bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen                req.baseConfigs.serviceName);
37049f29f155e729fd02eeae18b98cfc6ee4910ad3fEtan Cohen        req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
3712bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(subscribeConfig.mServiceSpecificInfo,
372db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.baseConfigs.serviceSpecificInfo);
3732bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(subscribeConfig.mMatchFilter,
374db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
375db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                        ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
376db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.useRssiThreshold = false;
377db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableDiscoveryTerminationIndication =
378db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                !subscribeConfig.mEnableTerminateNotification;
379db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableMatchExpirationIndication = true;
380db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableFollowupReceivedIndication = false;
381afd0fa5167ae4e0eb3e7d0f3e1a011ebccef5f80Etan Cohen
382afd0fa5167ae4e0eb3e7d0f3e1a011ebccef5f80Etan Cohen        // TODO: configure ranging and security
3832bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        req.baseConfigs.securityConfig.securityType = NanDataPathSecurityType.OPEN;
384afd0fa5167ae4e0eb3e7d0f3e1a011ebccef5f80Etan Cohen        req.baseConfigs.rangingRequired = false;
385afd0fa5167ae4e0eb3e7d0f3e1a011ebccef5f80Etan Cohen
386db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.subscribeType = subscribeConfig.mSubscribeType;
387db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
388db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
389db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.startSubscribeRequest(transactionId, req);
390db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
391db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
392db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
393db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "subscribe: error: " + statusString(status));
394db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
395db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
396db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
397db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "subscribe: exception: " + e);
398db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
399db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
400db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
401db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
402db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
403db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Send a message through an existing discovery session.
404db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
405db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
406db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
407db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the existing publish/subscribe session.
408db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param requestorInstanceId ID of the peer to communicate with - obtained
409db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            through a previous discovery (match) operation with that peer.
410db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param dest MAC address of the peer to communicate with - obtained
411db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            together with requestorInstanceId.
412db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param message Message.
413db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param messageId Arbitary integer from host (not sent to HAL - useful for
414db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                  testing/debugging at this level)
415db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
416db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId,
417db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            byte[] dest, byte[] message, int messageId) {
418db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
419db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG,
420db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId
421db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + ", requestorInstanceId=" + requestorInstanceId + ", dest="
422db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + String.valueOf(HexEncoding.encode(dest)) + ", messageId="
423db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + messageId);
424db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
425db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
426db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
427db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
428db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "sendMessage: null interface");
429db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
430db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
431db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
432db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanTransmitFollowupRequest req = new NanTransmitFollowupRequest();
43326ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen        req.discoverySessionId = (byte) pubSubId;
434db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.peerId = requestorInstanceId;
435db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        copyArray(dest, req.addr);
436db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.isHighPriority = false;
437db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.shouldUseDiscoveryWindow = true;
4382bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        convertNativeByteArrayToArrayList(message, req.serviceSpecificInfo);
439db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.disableFollowupResultIndication = false;
440db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
441db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
442db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.transmitFollowupRequest(transactionId, req);
443db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
444db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
445db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
446db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "sendMessage: error: " + statusString(status));
447db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
448db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
449db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
450db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "sendMessage: exception: " + e);
451db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
452db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
453db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
454db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
455db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
456db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate a publish discovery session.
457db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
458db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
459db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
460db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the publish/subscribe session - obtained when
461db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            creating a session.
462db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
463db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean stopPublish(short transactionId, int pubSubId) {
464db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
465db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
466db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
467db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
468db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
469db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
470db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopPublish: null interface");
471db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
472db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
473db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
474db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
47526ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen            WifiStatus status = iface.stopPublishRequest(transactionId, (byte) pubSubId);
476db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
477db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
478db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
479db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "stopPublish: error: " + statusString(status));
480db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
481db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
482db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
483db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopPublish: exception: " + e);
484db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
485db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
486db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
487db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
488db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
489db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate a subscribe discovery session.
490db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
491db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
492db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
493db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the publish/subscribe session - obtained when
494db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            creating a session.
495db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
496db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean stopSubscribe(short transactionId, int pubSubId) {
497db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
498db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
499db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
500db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
501db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
502db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
503db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopSubscribe: null interface");
504db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
505db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
506db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
507db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
50826ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen            WifiStatus status = iface.stopSubscribeRequest(transactionId, (byte) pubSubId);
509db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
510db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
511db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
512db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "stopSubscribe: error: " + statusString(status));
513db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
514db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
515db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
516db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopSubscribe: exception: " + e);
517db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
518db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
519db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
520db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
521db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
522db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Create a Aware network interface. This only creates the Linux interface - it doesn't actually
523db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * create the data connection.
524db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
525db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
526db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
527db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The name of the interface, e.g. "aware0".
528db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
529db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean createAwareNetworkInterface(short transactionId, String interfaceName) {
530db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
531db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "createAwareNetworkInterface: transactionId=" + transactionId + ", "
532db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + "interfaceName=" + interfaceName);
533db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
534db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
535db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
536db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
537db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "createAwareNetworkInterface: null interface");
538db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
539db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
540db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
541db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
542db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.createDataInterfaceRequest(transactionId, interfaceName);
543db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
544db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
545db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
546db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "createAwareNetworkInterface: error: " + statusString(status));
547db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
548db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
549db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
550db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "createAwareNetworkInterface: exception: " + e);
551db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
552db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
553db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
554db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
555db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
556db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Deletes a Aware network interface. The data connection can (should?) be torn down previously.
557db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
558db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
559db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
560db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The name of the interface, e.g. "aware0".
561db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
562db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) {
563db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
564db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "deleteAwareNetworkInterface: transactionId=" + transactionId + ", "
565db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + "interfaceName=" + interfaceName);
566db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
567db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
568db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
569db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
570db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "deleteAwareNetworkInterface: null interface");
571db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
572db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
573db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
574db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
575db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.deleteDataInterfaceRequest(transactionId, interfaceName);
576db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
577db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
578db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
579db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "deleteAwareNetworkInterface: error: " + statusString(status));
580db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
581db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
582db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
583db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "deleteAwareNetworkInterface: exception: " + e);
584db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
585db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
586db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
587db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
588db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
58931389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen     * Initiates setting up a data-path between device and peer. Security is provided by either
5902bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen     * PMK or Passphrase (not both) - if both are null then an open (unencrypted) link is set up.
591db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
592db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId      Transaction ID for the transaction - used in the async callback to
593db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           match with the original request.
594db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param peerId             ID of the peer ID to associate the data path with. A value of 0
595db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           indicates that not associated with an existing session.
596db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param channelRequestType Indicates whether the specified channel is available, if available
597db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           requested or forced (resulting in failure if cannot be
598db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           accommodated).
599db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param channel            The channel on which to set up the data-path.
600db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param peer               The MAC address of the peer to create a connection with.
601db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName      The interface on which to create the data connection.
60231389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen     * @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
60331389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen     * @param passphrase  Passphrase for the data-path.
60469eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     * @param capabilities The capabilities of the firmware.
605db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
606db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
60731389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen            int channel, byte[] peer, String interfaceName, byte[] pmk, String passphrase,
60831389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen            Capabilities capabilities) {
609db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
610db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId
611db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", channelRequestType=" + channelRequestType + ", channel=" + channel
612db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName="
613db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + interfaceName);
614db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
615db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
616db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
617db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
618db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "initiateDataPath: null interface");
619db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
620db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
621db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
62269eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        if (capabilities == null) {
62369eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            Log.e(TAG, "initiateDataPath: null capabilities");
62469eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            return false;
62569eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
62669eb934f563ac0099113bf24587c729df25b15bfEtan Cohen
627db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanInitiateDataPathRequest req = new NanInitiateDataPathRequest();
628db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.peerId = peerId;
629db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        copyArray(peer, req.peerDiscMacAddr);
630db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.channelRequestType = channelRequestType;
631db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.channel = channel;
632db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ifaceName = interfaceName;
6332bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
6342bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        if (pmk != null && pmk.length != 0) {
6352bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.cipherType = getStrongestCipherSuiteType(
6362bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen                    capabilities.supportedCipherSuites);
6372bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.securityType = NanDataPathSecurityType.PMK;
6382bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            copyArray(pmk, req.securityConfig.pmk);
6392bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        }
6402bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        if (passphrase != null && passphrase.length() != 0) {
6412bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.cipherType = getStrongestCipherSuiteType(
6422bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen                    capabilities.supportedCipherSuites);
6432bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
6442bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            convertNativeByteArrayToArrayList(passphrase.getBytes(), req.securityConfig.passphrase);
64569eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
646db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
647db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
648db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.initiateDataPathRequest(transactionId, req);
649db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
650db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
651db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
652db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "initiateDataPath: error: " + statusString(status));
653db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
654db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
655db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
656db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "initiateDataPath: exception: " + e);
657db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
658db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
659db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
660db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
661db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
6622bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen     * Responds to a data request from a peer. Security is provided by either PMK or Passphrase (not
6632bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen     * both) - if both are null then an open (unencrypted) link is set up.
664db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
665db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
666db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
667db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param accept Accept (true) or reject (false) the original call.
668db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param ndpId The NDP (Aware data path) ID. Obtained from the request callback.
669db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The interface on which the data path will be setup. Obtained from the
670db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      request callback.
67131389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen     * @param pmk Pairwise master key (PMK - see IEEE 802.11i) for the data-path.
67231389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen     * @param passphrase  Passphrase for the data-path.
67369eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     * @param capabilities The capabilities of the firmware.
674db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
675db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
67631389a22a6f12b12cca89d53b5f9f80fdcd76385Etan Cohen            String interfaceName, byte[] pmk, String passphrase, Capabilities capabilities) {
677db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
678db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept="
679db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName);
680db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
681db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
682db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
683db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
684db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "respondToDataPathRequest: null interface");
685db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
686db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
687db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
68869eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        if (capabilities == null) {
68969eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            Log.e(TAG, "initiateDataPath: null capabilities");
69069eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            return false;
69169eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
69269eb934f563ac0099113bf24587c729df25b15bfEtan Cohen
693db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest();
694db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.acceptRequest = accept;
695db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ndpInstanceId = ndpId;
696db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ifaceName = interfaceName;
6972bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        req.securityConfig.securityType = NanDataPathSecurityType.OPEN;
6982bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        if (pmk != null && pmk.length != 0) {
6992bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.cipherType = getStrongestCipherSuiteType(
7002bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen                    capabilities.supportedCipherSuites);
7012bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.securityType = NanDataPathSecurityType.PMK;
7022bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            copyArray(pmk, req.securityConfig.pmk);
7032bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        }
7042bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen        if (passphrase != null && passphrase.length() != 0) {
7052bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.cipherType = getStrongestCipherSuiteType(
7062bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen                    capabilities.supportedCipherSuites);
7072bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            req.securityConfig.securityType = NanDataPathSecurityType.PASSPHRASE;
7082bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen            convertNativeByteArrayToArrayList(passphrase.getBytes(), req.securityConfig.passphrase);
70969eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
710db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
711db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
712db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req);
713db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
714db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
715db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
716db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "respondToDataPathRequest: error: " + statusString(status));
717db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
718db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
719db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
720db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "respondToDataPathRequest: exception: " + e);
721db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
722db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
723db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
724db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
725db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
726db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate an existing data-path (does not delete the interface).
727db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
728db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
729db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
730db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param ndpId The NDP (Aware data path) ID to be terminated.
731db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
732db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean endDataPath(short transactionId, int ndpId) {
733db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
734db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "endDataPath: transactionId=" + transactionId + ", ndpId=" + ndpId);
735db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
736db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
737db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
738db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
739db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "endDataPath: null interface");
740db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
741db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
742db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
743db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
744db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.terminateDataPathRequest(transactionId, ndpId);
745db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
746db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
747db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
748db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "endDataPath: error: " + statusString(status));
749db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
750db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
751db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
752db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "endDataPath: exception: " + e);
753db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
754db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
755db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
756db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
757db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
758db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    // utilities
759db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
760db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
76169eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     * Returns the strongest supported cipher suite.
76269eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     *
76369eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     * Baseline is very simple: 256 > 128 > 0.
76469eb934f563ac0099113bf24587c729df25b15bfEtan Cohen     */
76569eb934f563ac0099113bf24587c729df25b15bfEtan Cohen    private int getStrongestCipherSuiteType(int supportedCipherSuites) {
76669eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        if ((supportedCipherSuites & NanCipherSuiteType.SHARED_KEY_256_MASK) != 0) {
76769eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            return NanCipherSuiteType.SHARED_KEY_256_MASK;
76869eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
76969eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        if ((supportedCipherSuites & NanCipherSuiteType.SHARED_KEY_128_MASK) != 0) {
77069eb934f563ac0099113bf24587c729df25b15bfEtan Cohen            return NanCipherSuiteType.SHARED_KEY_128_MASK;
77169eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        }
77269eb934f563ac0099113bf24587c729df25b15bfEtan Cohen        return NanCipherSuiteType.NONE;
77369eb934f563ac0099113bf24587c729df25b15bfEtan Cohen    }
77469eb934f563ac0099113bf24587c729df25b15bfEtan Cohen
77569eb934f563ac0099113bf24587c729df25b15bfEtan Cohen    /**
776db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Converts a byte[] to an ArrayList<Byte>. Fills in the entries of the 'to' array if
777db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * provided (non-null), otherwise creates and returns a new ArrayList<>.
778db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
779db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param from The input byte[] to convert from.
780db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param to An optional ArrayList<> to fill in from 'from'.
781db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
782db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @return A newly allocated ArrayList<> if 'to' is null, otherwise null.
783db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
7842bce4620efc197b7423b842dbb8884ccecf76a1fEtan Cohen    private ArrayList<Byte> convertNativeByteArrayToArrayList(byte[] from, ArrayList<Byte> to) {
785db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (from == null) {
786db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            from = new byte[0];
787db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
788db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
789db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (to == null) {
790db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to = new ArrayList<>(from.length);
791db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } else {
792db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to.ensureCapacity(from.length);
793db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
794db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        for (int i = 0; i < from.length; ++i) {
795db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to.add(from[i]);
796db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
797db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        return to;
798db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
799db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
800db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private void copyArray(byte[] from, byte[] to) {
801db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (from == null || to == null || from.length != to.length) {
802db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "copyArray error: from=" + from + ", to=" + to);
803db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return;
804db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
805db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        for (int i = 0; i < from.length; ++i) {
806db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to[i] = from[i];
807db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
808db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
809db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
810db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static String statusString(WifiStatus status) {
811db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (status == null) {
812db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return "status=null";
813db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
814db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        StringBuilder sb = new StringBuilder();
815db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        sb.append(status.code).append(" (").append(status.description).append(")");
816db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        return sb.toString();
817db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
818db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
819db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
820db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Dump the internal state of the class.
821db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
822db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
823db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mHal.dump(fd, pw, args);
824db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
825db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen}
826