WifiAwareNativeApi.java revision 26ac163a1f95188ea00314e07ba52574aadfb726
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;
22db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanConfigRequest;
23db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanEnableRequest;
24db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanInitiateDataPathRequest;
25db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanMatchAlg;
26db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanPublishRequest;
27db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest;
28db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanSubscribeRequest;
29db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanTransmitFollowupRequest;
30db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.NanTxType;
31db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatus;
32db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.hardware.wifi.V1_0.WifiStatusCode;
33db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.ConfigRequest;
34db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.PublishConfig;
35db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.net.wifi.aware.SubscribeConfig;
36db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.os.RemoteException;
37db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport android.util.Log;
38db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
39db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport libcore.util.HexEncoding;
40db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
41db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.FileDescriptor;
42db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.io.PrintWriter;
43db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenimport java.util.ArrayList;
44db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
45db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen/**
46db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Translates Wi-Fi Aware requests from the framework to the HAL (HIDL).
47db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen *
48db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen * Delegates the management of the NAN interface to WifiAwareNativeManager.
49db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen */
50db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohenpublic class WifiAwareNativeApi {
51db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final String TAG = "WifiAwareNativeApi";
52db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final boolean DBG = false;
53db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static final boolean VDBG = false; // STOPSHIP if true
54db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
55db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private final WifiAwareNativeManager mHal;
56db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
57db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public WifiAwareNativeApi(WifiAwareNativeManager wifiAwareNativeManager) {
58db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mHal = wifiAwareNativeManager;
59db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
60db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
61db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
62db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Query the firmware's capabilities.
63db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
64db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
65db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
66db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
67db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean getCapabilities(short transactionId) {
68db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) Log.v(TAG, "getCapabilities: transactionId=" + transactionId);
69db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
70db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
71db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
72db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "getCapabilities: null interface");
73db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
74db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
75db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
76db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
77db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.getCapabilitiesRequest(transactionId);
78db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
79db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
80db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
81db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "getCapabilities: error: " + statusString(status));
82db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
83db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
84db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
85db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "getCapabilities: exception: " + e);
86db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
87db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
88db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
89db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
90db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
91db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Enable and configure Aware.
92db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
93db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the
94db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            async callback to match with the original request.
95db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param configRequest Requested Aware configuration.
96db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param notifyIdentityChange Indicates whether or not to get address change callbacks.
97db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param initialConfiguration Specifies whether initial configuration
98db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            (true) or an update (false) to the configuration.
99db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
100db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest,
101db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            boolean notifyIdentityChange, boolean initialConfiguration) {
102db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
103db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "enableAndConfigure: transactionId=" + transactionId + ", configRequest="
104db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + configRequest + ", notifyIdentityChange=" + notifyIdentityChange
105db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", initialConfiguration=" + initialConfiguration);
106db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
107db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
108db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
109db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
110db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "enableAndConfigure: null interface");
111db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
112db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
113db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
114db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
115db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status;
116db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (initialConfiguration) {
117db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                // translate framework to HIDL configuration
118db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanEnableRequest req = new NanEnableRequest();
119db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
120db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true;
121db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand;
122db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.hopCountMax = 2;
123db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.masterPref = (byte) configRequest.mMasterPreference;
124db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
125db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableStartedClusterIndication = !notifyIdentityChange;
126db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.disableJoinedClusterIndication = !notifyIdentityChange;
127db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.includeServiceIdsInBeacon = true;
128db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.numberOfServiceIdsInBeacon = 0;
129db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.rssiWindowSize = 8;
130db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.macAddressRandomizationIntervalSec = 1800;
131db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.acceptRangingRequests = true;
132db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
133db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config24 = new NanBandSpecificConfig();
134db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiClose = 60;
135db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiMiddle = 70;
136db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiProximity = 60;
137db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.dwellTimeMs = (byte) 200;
138db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.scanPeriodSec = 20;
139db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.validDiscoveryWindowIntervalVal = false;
140db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
141db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
142db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config5 = new NanBandSpecificConfig();
143db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiClose = 60;
144db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiMiddle = 75;
145db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiProximity = 60;
146db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.dwellTimeMs = (byte) 200;
147db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.scanPeriodSec = 20;
148db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.validDiscoveryWindowIntervalVal = false;
149db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
150db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
151db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validClusterIdVals = true;
152db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.clusterIdHighVal = (short) configRequest.mClusterHigh;
153db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.clusterIdLowVal = (short) configRequest.mClusterLow;
154db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validIntfAddrVal = false;
155db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validOuiVal = false;
156db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.ouiVal = 0;
157db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validRandomFactorForceVal = false;
158db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.randomFactorForceVal = 0;
159db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validHopCountForceVal = false;
160db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.hopCountForceVal = 0;
161db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validDiscoveryChannelVal = false;
162db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0;
163db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0;
164db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validUseBeaconsInBandVal = false;
165db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
166db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
167db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.validUseSdfInBandVal = false;
168db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true;
169db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true;
170db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
171db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                status = iface.enableRequest(transactionId, req);
172db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
173db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanConfigRequest req = new NanConfigRequest();
174db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.masterPref = (byte) configRequest.mMasterPreference;
175db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange;
176db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableStartedClusterIndication = !notifyIdentityChange;
177db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.disableJoinedClusterIndication = !notifyIdentityChange;
178db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.includeServiceIdsInBeacon = true;
179db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.numberOfServiceIdsInBeacon = 0;
180db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.rssiWindowSize = 8;
181db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.macAddressRandomizationIntervalSec = 1800;
182db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.acceptRangingRequests = true;
183db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
184db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config24 = new NanBandSpecificConfig();
185db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiClose = 60;
186db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiMiddle = 70;
187db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.rssiProximity = 60;
188db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.dwellTimeMs = (byte) 200;
189db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.scanPeriodSec = 20;
190db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config24.validDiscoveryWindowIntervalVal = false;
191db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24;
192db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
193db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                NanBandSpecificConfig config5 = new NanBandSpecificConfig();
194db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiClose = 60;
195db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiMiddle = 75;
196db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.rssiProximity = 60;
197db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.dwellTimeMs = (byte) 200;
198db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.scanPeriodSec = 20;
199db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                config5.validDiscoveryWindowIntervalVal = false;
200db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5;
201db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
202db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                status = iface.configRequest(transactionId, req);
203db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
204db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
205db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
206db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
207db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "enableAndConfigure: error: " + statusString(status));
208db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
209db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
210db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
211db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "enableAndConfigure: exception: " + e);
212db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
213db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
214db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
215db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
216db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
217db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Disable Aware.
218db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
219db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
220db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
221db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
222db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean disable(short transactionId) {
223db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) Log.d(TAG, "disable");
224db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
225db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
226db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
227db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "disable: null interface");
228db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
229db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
230db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
231db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
232db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.disableRequest(transactionId);
233db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
234db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
235db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
236db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "disable: error: " + statusString(status));
237db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
238db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
239db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
240db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "disable: exception: " + e);
241db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
242db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
243db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
244db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
245db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
246db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Start or modify a service publish session.
247db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
248db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
249db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
250db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param publishId ID of the requested session - 0 to request a new publish
251db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            session.
252db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param publishConfig Configuration of the discovery session.
253db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
254db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean publish(short transactionId, int publishId, PublishConfig publishConfig) {
255db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
256db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "publish: transactionId=" + transactionId + ", config=" + publishConfig);
257db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
258db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
259db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
260db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
261db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "publish: null interface");
262db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
263db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
264db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
265db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanPublishRequest req = new NanPublishRequest();
266db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.sessionId = 0;
267db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec;
268db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryWindowPeriod = 1;
269db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryCount = (byte) publishConfig.mPublishCount;
270db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(publishConfig.mServiceName, req.baseConfigs.serviceName);
271db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        // TODO: what's the right value on publish?
272db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE;
273db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(publishConfig.mServiceSpecificInfo,
274db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.baseConfigs.serviceSpecificInfo);
275db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(publishConfig.mMatchFilter,
276db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED
277db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                        ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
278db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.useRssiThreshold = false;
279db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableDiscoveryTerminationIndication =
280db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                !publishConfig.mEnableTerminateNotification;
281db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableMatchExpirationIndication = true;
282db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableFollowupReceivedIndication = false;
283db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
284db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        // TODO: configure ranging and security
285db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.securityEnabledInNdp = false;
286db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.rangingRequired = false;
287db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
288db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.publishType = publishConfig.mPublishType;
289db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.txType = NanTxType.BROADCAST;
290db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
291db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
292db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.startPublishRequest(transactionId, req);
293db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
294db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
295db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
296db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "publish: error: " + statusString(status));
297db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
298db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
299db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
300db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "publish: exception: " + e);
301db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
302db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
303db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
304db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
305db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
306db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Start or modify a service subscription session.
307db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
308db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
309db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
310db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param subscribeId ID of the requested session - 0 to request a new
311db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            subscribe session.
312db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param subscribeConfig Configuration of the discovery session.
313db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
314db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean subscribe(short transactionId, int subscribeId,
315db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            SubscribeConfig subscribeConfig) {
316db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
317db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "subscribe: transactionId=" + transactionId + ", config=" + subscribeConfig);
318db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
319db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
320db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
321db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
322db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "subscribe: null interface");
323db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
324db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
325db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
326db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanSubscribeRequest req = new NanSubscribeRequest();
327db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.sessionId = 0;
328db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.ttlSec = (short) subscribeConfig.mTtlSec;
329db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryWindowPeriod = 1;
330db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryCount = (byte) subscribeConfig.mSubscribeCount;
331db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(subscribeConfig.mServiceName, req.baseConfigs.serviceName);
332db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.discoveryMatchIndicator = subscribeConfig.mMatchStyle;
333db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(subscribeConfig.mServiceSpecificInfo,
334db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                req.baseConfigs.serviceSpecificInfo);
335db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(subscribeConfig.mMatchFilter,
336db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE
337db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                        ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter);
338db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.useRssiThreshold = false;
339db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableDiscoveryTerminationIndication =
340db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                !subscribeConfig.mEnableTerminateNotification;
341db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableMatchExpirationIndication = true;
342db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.baseConfigs.disableFollowupReceivedIndication = false;
343db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.subscribeType = subscribeConfig.mSubscribeType;
344db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
345db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
346db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.startSubscribeRequest(transactionId, req);
347db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
348db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
349db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
350db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "subscribe: error: " + statusString(status));
351db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
352db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
353db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
354db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "subscribe: exception: " + e);
355db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
356db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
357db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
358db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
359db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
360db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Send a message through an existing discovery session.
361db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
362db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
363db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
364db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the existing publish/subscribe session.
365db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param requestorInstanceId ID of the peer to communicate with - obtained
366db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            through a previous discovery (match) operation with that peer.
367db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param dest MAC address of the peer to communicate with - obtained
368db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            together with requestorInstanceId.
369db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param message Message.
370db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param messageId Arbitary integer from host (not sent to HAL - useful for
371db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                  testing/debugging at this level)
372db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
373db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId,
374db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            byte[] dest, byte[] message, int messageId) {
375db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
376db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG,
377db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId
378db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + ", requestorInstanceId=" + requestorInstanceId + ", dest="
379db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + String.valueOf(HexEncoding.encode(dest)) + ", messageId="
380db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                            + messageId);
381db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
382db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
383db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
384db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
385db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "sendMessage: null interface");
386db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
387db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
388db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
389db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanTransmitFollowupRequest req = new NanTransmitFollowupRequest();
39026ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen        req.discoverySessionId = (byte) pubSubId;
391db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.peerId = requestorInstanceId;
392db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        copyArray(dest, req.addr);
393db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.isHighPriority = false;
394db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.shouldUseDiscoveryWindow = true;
395db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(message, req.message);
396db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.disableFollowupResultIndication = false;
397db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
398db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
399db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.transmitFollowupRequest(transactionId, req);
400db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
401db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
402db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
403db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "sendMessage: error: " + statusString(status));
404db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
405db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
406db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
407db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "sendMessage: exception: " + e);
408db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
409db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
410db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
411db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
412db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
413db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate a publish discovery session.
414db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
415db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
416db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
417db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the publish/subscribe session - obtained when
418db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            creating a session.
419db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
420db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean stopPublish(short transactionId, int pubSubId) {
421db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
422db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
423db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
424db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
425db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
426db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
427db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopPublish: null interface");
428db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
429db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
430db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
431db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
43226ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen            WifiStatus status = iface.stopPublishRequest(transactionId, (byte) pubSubId);
433db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
434db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
435db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
436db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "stopPublish: error: " + statusString(status));
437db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
438db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
439db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
440db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopPublish: exception: " + e);
441db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
442db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
443db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
444db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
445db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
446db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate a subscribe discovery session.
447db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
448db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId transactionId Transaction ID for the transaction -
449db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            used in the async callback to match with the original request.
450db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param pubSubId ID of the publish/subscribe session - obtained when
451db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *            creating a session.
452db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
453db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean stopSubscribe(short transactionId, int pubSubId) {
454db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
455db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId);
456db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
457db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
458db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
459db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
460db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopSubscribe: null interface");
461db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
462db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
463db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
464db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
46526ac163a1f95188ea00314e07ba52574aadfb726Etan Cohen            WifiStatus status = iface.stopSubscribeRequest(transactionId, (byte) pubSubId);
466db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
467db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
468db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
469db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "stopSubscribe: error: " + statusString(status));
470db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
471db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
472db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
473db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "stopSubscribe: exception: " + e);
474db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
475db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
476db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
477db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
478db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
479db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Create a Aware network interface. This only creates the Linux interface - it doesn't actually
480db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * create the data connection.
481db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
482db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
483db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
484db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The name of the interface, e.g. "aware0".
485db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
486db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean createAwareNetworkInterface(short transactionId, String interfaceName) {
487db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
488db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "createAwareNetworkInterface: transactionId=" + transactionId + ", "
489db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + "interfaceName=" + interfaceName);
490db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
491db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
492db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
493db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
494db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "createAwareNetworkInterface: null interface");
495db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
496db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
497db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
498db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
499db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.createDataInterfaceRequest(transactionId, interfaceName);
500db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
501db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
502db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
503db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "createAwareNetworkInterface: error: " + statusString(status));
504db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
505db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
506db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
507db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "createAwareNetworkInterface: exception: " + e);
508db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
509db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
510db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
511db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
512db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
513db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Deletes a Aware network interface. The data connection can (should?) be torn down previously.
514db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
515db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
516db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
517db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The name of the interface, e.g. "aware0".
518db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
519db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) {
520db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
521db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "deleteAwareNetworkInterface: transactionId=" + transactionId + ", "
522db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + "interfaceName=" + interfaceName);
523db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
524db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
525db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
526db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
527db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "deleteAwareNetworkInterface: null interface");
528db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
529db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
530db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
531db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
532db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.deleteDataInterfaceRequest(transactionId, interfaceName);
533db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
534db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
535db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
536db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "deleteAwareNetworkInterface: error: " + statusString(status));
537db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
538db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
539db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
540db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "deleteAwareNetworkInterface: exception: " + e);
541db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
542db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
543db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
544db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
545db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
546db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Initiates setting up a data-path between device and peer.
547db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
548db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId      Transaction ID for the transaction - used in the async callback to
549db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           match with the original request.
550db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param peerId             ID of the peer ID to associate the data path with. A value of 0
551db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           indicates that not associated with an existing session.
552db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param channelRequestType Indicates whether the specified channel is available, if available
553db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           requested or forced (resulting in failure if cannot be
554db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                           accommodated).
555db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param channel            The channel on which to set up the data-path.
556db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param peer               The MAC address of the peer to create a connection with.
557db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName      The interface on which to create the data connection.
558db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param message An arbitrary byte array to forward to the peer as part of the data path
559db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                request.
560db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
561db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType,
562db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            int channel, byte[] peer, String interfaceName, byte[] message) {
563db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
564db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId
565db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", channelRequestType=" + channelRequestType + ", channel=" + channel
566db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName="
567db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + interfaceName);
568db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
569db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
570db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
571db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
572db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "initiateDataPath: null interface");
573db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
574db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
575db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
576db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanInitiateDataPathRequest req = new NanInitiateDataPathRequest();
577db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.peerId = peerId;
578db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        copyArray(peer, req.peerDiscMacAddr);
579db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.channelRequestType = channelRequestType;
580db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.channel = channel;
581db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ifaceName = interfaceName;
582db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.securityRequired = false;
583db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(message, req.appInfo);
584db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
585db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
586db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.initiateDataPathRequest(transactionId, req);
587db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
588db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
589db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
590db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "initiateDataPath: error: " + statusString(status));
591db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
592db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
593db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
594db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "initiateDataPath: exception: " + e);
595db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
596db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
597db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
598db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
599db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
600db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Responds to a data request from a peer.
601db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
602db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
603db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
604db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param accept Accept (true) or reject (false) the original call.
605db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param ndpId The NDP (Aware data path) ID. Obtained from the request callback.
606db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param interfaceName The interface on which the data path will be setup. Obtained from the
607db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      request callback.
608db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param message An arbitrary byte array to forward to the peer in the respond message.
609db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
610db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId,
611db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            String interfaceName, byte[] message) {
612db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
613db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept="
614db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                    + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName);
615db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
616db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
617db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
618db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
619db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "respondToDataPathRequest: null interface");
620db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
621db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
622db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
623db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest();
624db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.acceptRequest = accept;
625db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ndpInstanceId = ndpId;
626db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.ifaceName = interfaceName;
627db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        req.securityRequired = false;
628db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        convertLcByteToUcByteArray(message, req.appInfo);
629db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
630db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
631db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req);
632db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
633db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
634db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
635db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "respondToDataPathRequest: error: " + statusString(status));
636db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
637db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
638db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
639db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "respondToDataPathRequest: exception: " + e);
640db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
641db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
642db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
643db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
644db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
645db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Terminate an existing data-path (does not delete the interface).
646db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
647db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param transactionId Transaction ID for the transaction - used in the async callback to
648db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *                      match with the original request.
649db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param ndpId The NDP (Aware data path) ID to be terminated.
650db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
651db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public boolean endDataPath(short transactionId, int ndpId) {
652db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (VDBG) {
653db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.v(TAG, "endDataPath: transactionId=" + transactionId + ", ndpId=" + ndpId);
654db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
655db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
656db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        IWifiNanIface iface = mHal.getWifiNanIface();
657db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (iface == null) {
658db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "endDataPath: null interface");
659db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
660db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
661db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
662db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        try {
663db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            WifiStatus status = iface.terminateDataPathRequest(transactionId, ndpId);
664db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            if (status.code == WifiStatusCode.SUCCESS) {
665db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return true;
666db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            } else {
667db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                Log.e(TAG, "endDataPath: error: " + statusString(status));
668db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen                return false;
669db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            }
670db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } catch (RemoteException e) {
671db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "endDataPath: exception: " + e);
672db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return false;
673db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
674db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
675db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
676db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
677db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    // utilities
678db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
679db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
680db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Converts a byte[] to an ArrayList<Byte>. Fills in the entries of the 'to' array if
681db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * provided (non-null), otherwise creates and returns a new ArrayList<>.
682db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
683db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param from The input byte[] to convert from.
684db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @param to An optional ArrayList<> to fill in from 'from'.
685db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     *
686db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * @return A newly allocated ArrayList<> if 'to' is null, otherwise null.
687db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
688db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private ArrayList<Byte> convertLcByteToUcByteArray(byte[] from, ArrayList<Byte> to) {
689db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (from == null) {
690db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            from = new byte[0];
691db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
692db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
693db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (to == null) {
694db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to = new ArrayList<>(from.length);
695db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        } else {
696db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to.ensureCapacity(from.length);
697db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
698db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        for (int i = 0; i < from.length; ++i) {
699db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to.add(from[i]);
700db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
701db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        return to;
702db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
703db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
704db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private void copyArray(byte[] from, byte[] to) {
705db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (from == null || to == null || from.length != to.length) {
706db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            Log.e(TAG, "copyArray error: from=" + from + ", to=" + to);
707db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return;
708db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
709db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        for (int i = 0; i < from.length; ++i) {
710db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            to[i] = from[i];
711db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
712db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
713db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
714db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    private static String statusString(WifiStatus status) {
715db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        if (status == null) {
716db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen            return "status=null";
717db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        }
718db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        StringBuilder sb = new StringBuilder();
719db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        sb.append(status.code).append(" (").append(status.description).append(")");
720db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        return sb.toString();
721db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
722db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
723db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen
724db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    /**
725db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     * Dump the internal state of the class.
726db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen     */
727db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
728db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen        mHal.dump(fd, pw, args);
729db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen    }
730db3c9d35a7f08de03beec81e801d917a5375f63eEtan Cohen}
731