diff options
Diffstat (limited to 'service')
14 files changed, 1365 insertions, 993 deletions
diff --git a/service/Android.mk b/service/Android.mk index 4de32d2d5..82f6d5d6e 100644 --- a/service/Android.mk +++ b/service/Android.mk @@ -37,8 +37,7 @@ LOCAL_SHARED_LIBRARIES += \ LOCAL_SRC_FILES := \ jni/com_android_server_wifi_WifiNative.cpp \ - jni/jni_helper.cpp \ - jni/com_android_server_wifi_aware_WifiAwareNative.cpp + jni/jni_helper.cpp LOCAL_MODULE := libwifi-service diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index 9d8a6b597..274b0e59f 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -416,7 +416,7 @@ public class WifiInjector { * * TODO: share worker thread with other Wi-Fi handlers (b/27924886) */ - public HandlerThread getmWifiAwareHandlerThread() { + public HandlerThread getWifiAwareHandlerThread() { if (mWifiAwareHandlerThread == null) { // lazy initialization mWifiAwareHandlerThread = new HandlerThread("wifiAwareService"); mWifiAwareHandlerThread.start(); diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 541e42341..3562768d8 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -76,7 +76,6 @@ import android.net.wifi.WifiSsid; import android.net.wifi.WpsInfo; import android.net.wifi.WpsResult; import android.net.wifi.WpsResult.Status; -import android.net.wifi.aware.WifiAwareManager; import android.net.wifi.p2p.IWifiP2pManager; import android.os.BatteryStats; import android.os.Binder; @@ -209,7 +208,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss private WifiApConfigStore mWifiApConfigStore; private final boolean mP2pSupported; private final AtomicBoolean mP2pConnected = new AtomicBoolean(false); - private final boolean mAwareSupported; private boolean mTemporarilyDisconnectWifi = false; private final String mPrimaryDeviceType; private final Clock mClock; @@ -431,8 +429,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss // Channel for sending replies. private AsyncChannel mReplyChannel = new AsyncChannel(); - private WifiAwareManager mWifiAwareManager; - // Used to initiate a connection with WifiP2pService private AsyncChannel mWifiP2pChannel; @@ -873,8 +869,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mP2pSupported = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_DIRECT); - mAwareSupported = mContext.getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE); mWifiConfigManager = mWifiInjector.getWifiConfigManager(); mWifiApConfigStore = mWifiInjector.getWifiApConfigStore(); @@ -4277,24 +4271,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss } } - if (mAwareSupported) { - if (mWifiAwareManager == null) { - mWifiAwareManager = mContext.getSystemService(WifiAwareManager.class); - } - if (mWifiAwareManager == null) { - Log.e(TAG, "Can't get WifiAwareManager to enable usage!"); - } else { - if (mOperationalMode == CONNECT_MODE) { - mWifiAwareManager.enableUsage(); - } else { - /* - * Aware state machine starts in disabled state. Nothing - * needed to keep it disabled. - */ - } - } - } - final Intent intent = new Intent(WifiManager.WIFI_SCAN_AVAILABLE); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); intent.putExtra(WifiManager.EXTRA_SCAN_AVAILABLE, WIFI_STATE_ENABLED); @@ -4459,17 +4435,6 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); mBufferedScanMsg.clear(); - if (mAwareSupported) { - if (mWifiAwareManager == null) { - mWifiAwareManager = mContext.getSystemService(WifiAwareManager.class); - } - if (mWifiAwareManager == null) { - Log.e(TAG, "Can't get WifiAwareManager (to disable usage)!"); - } else { - mWifiAwareManager.disableUsage(); - } - } - mNetworkInfo.setIsAvailable(false); if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo); mCountryCode.setReadyForChange(false); diff --git a/service/java/com/android/server/wifi/aware/Capabilities.java b/service/java/com/android/server/wifi/aware/Capabilities.java new file mode 100644 index 000000000..635eed6dd --- /dev/null +++ b/service/java/com/android/server/wifi/aware/Capabilities.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi.aware; + +import android.net.wifi.aware.Characteristics; +import android.os.Bundle; + +/** + * A container class for Aware (vendor) implementation capabilities (or + * limitations). Filled-in by the firmware. + */ +public class Capabilities { + public int maxConcurrentAwareClusters; + public int maxPublishes; + public int maxSubscribes; + public int maxServiceNameLen; + public int maxMatchFilterLen; + public int maxTotalMatchFilterLen; + public int maxServiceSpecificInfoLen; + public int maxVsaDataLen; + public int maxNdiInterfaces; + public int maxNdpSessions; + public int maxAppInfoLen; + public int maxQueuedTransmitMessages; + public int maxSubscribeInterfaceAddresses; + public int supportedCipherSuites; + + /** + * Converts the internal capabilities to a parcelable & potentially app-facing + * characteristics bundle. Only some of the information is exposed. + */ + public Characteristics toPublicCharacteristics() { + Bundle bundle = new Bundle(); + bundle.putInt(Characteristics.KEY_MAX_SERVICE_NAME_LENGTH, maxServiceNameLen); + bundle.putInt(Characteristics.KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH, + maxServiceSpecificInfoLen); + bundle.putInt(Characteristics.KEY_MAX_MATCH_FILTER_LENGTH, maxMatchFilterLen); + return new Characteristics(bundle); + } + + @Override + public String toString() { + return "Capabilities [maxConcurrentAwareClusters=" + maxConcurrentAwareClusters + + ", maxPublishes=" + maxPublishes + ", maxSubscribes=" + maxSubscribes + + ", maxServiceNameLen=" + maxServiceNameLen + ", maxMatchFilterLen=" + + maxMatchFilterLen + ", maxTotalMatchFilterLen=" + maxTotalMatchFilterLen + + ", maxServiceSpecificInfoLen=" + maxServiceSpecificInfoLen + + ", maxVsaDataLen=" + maxVsaDataLen + + ", maxNdiInterfaces=" + maxNdiInterfaces + ", maxNdpSessions=" + + maxNdpSessions + ", maxAppInfoLen=" + maxAppInfoLen + + ", maxQueuedTransmitMessages=" + maxQueuedTransmitMessages + + ", maxSubscribeInterfaceAddresses=" + maxSubscribeInterfaceAddresses + + ", supportedCipherSuites=" + supportedCipherSuites + + "]"; + } +} diff --git a/service/java/com/android/server/wifi/aware/WifiAwareClientState.java b/service/java/com/android/server/wifi/aware/WifiAwareClientState.java index fca3d835b..9745b1006 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareClientState.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareClientState.java @@ -105,6 +105,10 @@ public class WifiAwareClientState { return mUid; } + public boolean getNotifyIdentityChange() { + return mNotifyIdentityChange; + } + /** * Searches the discovery sessions of this client and returns the one * corresponding to the publish/subscribe ID. Used on callbacks from HAL to diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java index b947163a5..2f8c299fc 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareDataPathStateManager.java @@ -17,6 +17,7 @@ package com.android.server.wifi.aware; import android.content.Context; +import android.hardware.wifi.V1_0.NanDataPathChannelCfg; import android.net.ConnectivityManager; import android.net.IpPrefix; import android.net.LinkAddress; @@ -79,7 +80,7 @@ public class WifiAwareDataPathStateManager { private static final boolean DBG = false; private static final boolean VDBG = false; // STOPSHIP if true - private static final String AWARE_INTERFACE_PREFIX = "aware"; + private static final String AWARE_INTERFACE_PREFIX = "aware_data"; private static final String NETWORK_TAG = "WIFI_AWARE_FACTORY"; private static final String AGENT_TAG_PREFIX = "WIFI_AWARE_AGENT_"; private static final int NETWORK_FACTORY_SCORE_AVAIL = 1; @@ -595,9 +596,8 @@ public class WifiAwareDataPathStateManager { nnri.interfaceName = selectInterfaceForRequest(nnri); mMgr.initiateDataPathSetup(networkSpecifier, nnri.peerId, - WifiAwareNative.CHANNEL_REQUEST_TYPE_REQUESTED, - selectChannelForRequest(nnri), nnri.peerDiscoveryMac, nnri.interfaceName, - nnri.token); + NanDataPathChannelCfg.REQUEST_CHANNEL_SETUP, selectChannelForRequest(nnri), + nnri.peerDiscoveryMac, nnri.interfaceName, nnri.token); nnri.state = AwareNetworkRequestInformation.STATE_INITIATOR_WAIT_FOR_REQUEST_RESPONSE; } else { diff --git a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java index 97df1f05d..f0170c695 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareDiscoverySessionState.java @@ -16,6 +16,7 @@ package com.android.server.wifi.aware; +import android.hardware.wifi.V1_0.NanStatusType; import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback; import android.net.wifi.aware.PublishConfig; import android.net.wifi.aware.SubscribeConfig; @@ -39,7 +40,7 @@ public class WifiAwareDiscoverySessionState { private static final boolean DBG = false; private static final boolean VDBG = false; // STOPSHIP if true - private final WifiAwareNative mWifiAwareNative; + private final WifiAwareNativeApi mWifiAwareNativeApi; private int mSessionId; private int mPubSubId; private IWifiAwareDiscoverySessionCallback mCallback; @@ -47,9 +48,9 @@ public class WifiAwareDiscoverySessionState { private final SparseArray<String> mMacByRequestorInstanceId = new SparseArray<>(); - public WifiAwareDiscoverySessionState(WifiAwareNative wifiAwareNative, int sessionId, + public WifiAwareDiscoverySessionState(WifiAwareNativeApi wifiAwareNativeApi, int sessionId, int pubSubId, IWifiAwareDiscoverySessionCallback callback, boolean isPublishSession) { - mWifiAwareNative = wifiAwareNative; + mWifiAwareNativeApi = wifiAwareNativeApi; mSessionId = sessionId; mPubSubId = pubSubId; mCallback = callback; @@ -93,9 +94,9 @@ public class WifiAwareDiscoverySessionState { mCallback = null; if (mIsPublishSession) { - mWifiAwareNative.stopPublish((short) 0, mPubSubId); + mWifiAwareNativeApi.stopPublish((short) 0, mPubSubId); } else { - mWifiAwareNative.stopSubscribe((short) 0, mPubSubId); + mWifiAwareNativeApi.stopSubscribe((short) 0, mPubSubId); } } @@ -121,14 +122,14 @@ public class WifiAwareDiscoverySessionState { if (!mIsPublishSession) { Log.e(TAG, "A SUBSCRIBE session is being used to publish"); try { - mCallback.onSessionConfigFail(WifiAwareNative.AWARE_STATUS_ERROR); + mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE); } catch (RemoteException e) { Log.e(TAG, "updatePublish: RemoteException=" + e); } return false; } - return mWifiAwareNative.publish(transactionId, mPubSubId, config); + return mWifiAwareNativeApi.publish(transactionId, mPubSubId, config); } /** @@ -142,14 +143,14 @@ public class WifiAwareDiscoverySessionState { if (mIsPublishSession) { Log.e(TAG, "A PUBLISH session is being used to subscribe"); try { - mCallback.onSessionConfigFail(WifiAwareNative.AWARE_STATUS_ERROR); + mCallback.onSessionConfigFail(NanStatusType.INTERNAL_FAILURE); } catch (RemoteException e) { Log.e(TAG, "updateSubscribe: RemoteException=" + e); } return false; } - return mWifiAwareNative.subscribe(transactionId, mPubSubId, config); + return mWifiAwareNativeApi.subscribe(transactionId, mPubSubId, config); } /** @@ -169,7 +170,7 @@ public class WifiAwareDiscoverySessionState { Log.e(TAG, "sendMessage: attempting to send a message to an address which didn't " + "match/contact us"); try { - mCallback.onMessageSendFail(messageId, WifiAwareNative.AWARE_STATUS_ERROR); + mCallback.onMessageSendFail(messageId, NanStatusType.INTERNAL_FAILURE); } catch (RemoteException e) { Log.e(TAG, "sendMessage: RemoteException=" + e); } @@ -177,7 +178,7 @@ public class WifiAwareDiscoverySessionState { } byte[] peerMac = HexEncoding.decode(peerMacStr.toCharArray(), false); - return mWifiAwareNative.sendMessage(transactionId, mPubSubId, peerId, peerMac, message, + return mWifiAwareNativeApi.sendMessage(transactionId, mPubSubId, peerId, peerMac, message, messageId); } diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNative.java b/service/java/com/android/server/wifi/aware/WifiAwareNative.java deleted file mode 100644 index 90663d1f2..000000000 --- a/service/java/com/android/server/wifi/aware/WifiAwareNative.java +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.wifi.aware; - -import android.net.wifi.aware.Characteristics; -import android.net.wifi.aware.ConfigRequest; -import android.net.wifi.aware.PublishConfig; -import android.net.wifi.aware.SubscribeConfig; -import android.os.Bundle; -import android.util.Log; - -import com.android.server.wifi.WifiNative; - -import libcore.util.HexEncoding; - -import java.util.Arrays; - -/** - * Native calls to access the Wi-Fi Aware HAL. - * - * Relies on WifiNative to perform the actual HAL registration. - */ -public class WifiAwareNative { - private static final String TAG = "WifiAwareNative"; - private static final boolean DBG = false; - private static final boolean VDBG = false; // STOPSHIP if true - - private static final int WIFI_SUCCESS = 0; - - private static WifiAwareStateManager sWifiAwareStateManager; - private boolean mNativeHandlersIsInitialized = false; - - private static native int registerAwareNatives(); - - /** - * A container class for Aware (vendor) implementation capabilities (or - * limitations). Filled-in by the firmware. - */ - public static class Capabilities { - public int maxConcurrentAwareClusters; - public int maxPublishes; - public int maxSubscribes; - public int maxServiceNameLen; - public int maxMatchFilterLen; - public int maxTotalMatchFilterLen; - public int maxServiceSpecificInfoLen; - public int maxVsaDataLen; - public int maxMeshDataLen; - public int maxNdiInterfaces; - public int maxNdpSessions; - public int maxAppInfoLen; - public int maxQueuedTransmitMessages; - - /** - * Converts the internal capabilities to a parcelable & potentially app-facing - * characteristics bundle. Only some of the information is exposed. - */ - public Characteristics toPublicCharacteristics() { - Bundle bundle = new Bundle(); - bundle.putInt(Characteristics.KEY_MAX_SERVICE_NAME_LENGTH, maxServiceNameLen); - bundle.putInt(Characteristics.KEY_MAX_SERVICE_SPECIFIC_INFO_LENGTH, - maxServiceSpecificInfoLen); - bundle.putInt(Characteristics.KEY_MAX_MATCH_FILTER_LENGTH, maxMatchFilterLen); - return new Characteristics(bundle); - } - - @Override - public String toString() { - return "Capabilities [maxConcurrentAwareClusters=" + maxConcurrentAwareClusters - + ", maxPublishes=" + maxPublishes + ", maxSubscribes=" + maxSubscribes - + ", maxServiceNameLen=" + maxServiceNameLen + ", maxMatchFilterLen=" - + maxMatchFilterLen + ", maxTotalMatchFilterLen=" + maxTotalMatchFilterLen - + ", maxServiceSpecificInfoLen=" + maxServiceSpecificInfoLen - + ", maxVsaDataLen=" + maxVsaDataLen + ", maxMeshDataLen=" + maxMeshDataLen - + ", maxNdiInterfaces=" + maxNdiInterfaces + ", maxNdpSessions=" - + maxNdpSessions + ", maxAppInfoLen=" + maxAppInfoLen - + ", maxQueuedTransmitMessages=" + maxQueuedTransmitMessages + "]"; - } - } - - /* package */ static native int initAwareHandlersNative(Class<WifiNative> cls, int iface); - - private boolean isAwareInit() { - synchronized (WifiNative.sLock) { - if (!WifiNative.getWlanNativeInterface().isHalStarted()) { - /* - * We should never start the HAL - that's done at a higher level - * by the Wi-Fi state machine. - */ - mNativeHandlersIsInitialized = false; - return false; - } else if (!mNativeHandlersIsInitialized) { - int ret = initAwareHandlersNative(WifiNative.class, WifiNative.sWlan0Index); - if (DBG) Log.d(TAG, "initAwareHandlersNative: res=" + ret); - mNativeHandlersIsInitialized = ret == WIFI_SUCCESS; - - return mNativeHandlersIsInitialized; - } else { - return true; - } - } - } - - /** - * Tell the Aware JNI to re-initialize the Aware callback pointers next time it starts up. - */ - public void deInitAware() { - if (VDBG) { - Log.v(TAG, "deInitAware: mNativeHandlersIsInitialized=" + mNativeHandlersIsInitialized); - } - mNativeHandlersIsInitialized = false; - } - - public WifiAwareNative(boolean doRegistration) { - if (doRegistration) { - registerAwareNatives(); - } - } - - public void setStateManager(WifiAwareStateManager awareStateManager) { - sWifiAwareStateManager = awareStateManager; - } - - private static native int getCapabilitiesNative(short transactionId, Class<WifiNative> cls, - int iface); - - /** - * Query the Aware firmware's capabilities. - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - */ - public boolean getCapabilities(short transactionId) { - if (VDBG) Log.d(TAG, "getCapabilities"); - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = getCapabilitiesNative(transactionId, WifiNative.class, - WifiNative.sWlan0Index); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "getCapabilities: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "getCapabilities: cannot initialize Aware"); - return false; - } - } - - private static native int enableAndConfigureNative(short transactionId, Class<WifiNative> cls, - int iface, ConfigRequest configRequest); - - private static native int updateConfigurationNative(short transactionId, Class<WifiNative> cls, - int iface, ConfigRequest configRequest); - - /** - * Enable and configure Aware. - * - * @param transactionId Transaction ID for the transaction - used in the - * async callback to match with the original request. - * @param configRequest Requested Aware configuration. - * @param initialConfiguration Specifies whether initial configuration - * (true) or an update (false) to the configuration. - */ - public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest, - boolean initialConfiguration) { - if (VDBG) Log.d(TAG, "enableAndConfigure: configRequest=" + configRequest); - if (isAwareInit()) { - int ret; - if (initialConfiguration) { - synchronized (WifiNative.sLock) { - ret = enableAndConfigureNative(transactionId, WifiNative.class, - WifiNative.sWlan0Index, configRequest); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "enableAndConfigureNative: HAL API returned non-success -- " + ret); - } - } else { - synchronized (WifiNative.sLock) { - ret = updateConfigurationNative(transactionId, WifiNative.class, - WifiNative.sWlan0Index, configRequest); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "updateConfigurationNative: HAL API returned non-success -- " + ret); - } - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "enableAndConfigure: AwareInit fails"); - return false; - } - } - - private static native int disableNative(short transactionId, Class<WifiNative> cls, int iface); - - /** - * Disable Aware. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - */ - public boolean disable(short transactionId) { - if (VDBG) Log.d(TAG, "disableAware"); - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = disableNative(transactionId, WifiNative.class, WifiNative.sWlan0Index); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "disableNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "disable: cannot initialize Aware"); - return false; - } - } - - private static native int publishNative(short transactionId, int publishId, - Class<WifiNative> cls, int iface, PublishConfig publishConfig); - - /** - * Start or modify a service publish session. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - * @param publishId ID of the requested session - 0 to request a new publish - * session. - * @param publishConfig Configuration of the discovery session. - */ - public boolean publish(short transactionId, int publishId, PublishConfig publishConfig) { - if (VDBG) { - Log.d(TAG, "publish: transactionId=" + transactionId + ", config=" + publishConfig); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = publishNative(transactionId, publishId, WifiNative.class, - WifiNative.sWlan0Index, publishConfig); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "publishNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "publish: cannot initialize Aware"); - return false; - } - } - - private static native int subscribeNative(short transactionId, int subscribeId, - Class<WifiNative> cls, int iface, SubscribeConfig subscribeConfig); - - /** - * Start or modify a service subscription session. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - * @param subscribeId ID of the requested session - 0 to request a new - * subscribe session. - * @param subscribeConfig Configuration of the discovery session. - */ - public boolean subscribe(short transactionId, int subscribeId, - SubscribeConfig subscribeConfig) { - if (VDBG) { - Log.d(TAG, "subscribe: transactionId=" + transactionId + ", config=" + subscribeConfig); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = subscribeNative(transactionId, subscribeId, WifiNative.class, - WifiNative.sWlan0Index, subscribeConfig); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "subscribeNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "subscribe: cannot initialize Aware"); - return false; - } - } - - private static native int sendMessageNative(short transactionId, Class<WifiNative> cls, - int iface, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message); - - /** - * Send a message through an existing discovery session. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - * @param pubSubId ID of the existing publish/subscribe session. - * @param requestorInstanceId ID of the peer to communicate with - obtained - * through a previous discovery (match) operation with that peer. - * @param dest MAC address of the peer to communicate with - obtained - * together with requestorInstanceId. - * @param message Message. - * @param messageId Arbitary integer from host (not sent to HAL - useful for - * testing/debugging at this level) - */ - public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId, - byte[] dest, byte[] message, int messageId) { - if (VDBG) { - Log.d(TAG, - "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId - + ", requestorInstanceId=" + requestorInstanceId + ", dest=" - + String.valueOf(HexEncoding.encode(dest)) + ", messageId=" - + messageId); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = sendMessageNative(transactionId, WifiNative.class, WifiNative.sWlan0Index, - pubSubId, requestorInstanceId, dest, message); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "sendMessageNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "sendMessage: cannot initialize Aware"); - return false; - } - } - - private static native int stopPublishNative(short transactionId, Class<WifiNative> cls, - int iface, int pubSubId); - - /** - * Terminate a publish discovery session. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - * @param pubSubId ID of the publish/subscribe session - obtained when - * creating a session. - */ - public boolean stopPublish(short transactionId, int pubSubId) { - if (VDBG) { - Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = stopPublishNative(transactionId, WifiNative.class, WifiNative.sWlan0Index, - pubSubId); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "stopPublishNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "stopPublish: cannot initialize Aware"); - return false; - } - } - - private static native int stopSubscribeNative(short transactionId, Class<WifiNative> cls, - int iface, int pubSubId); - - /** - * Terminate a subscribe discovery session. - * - * @param transactionId transactionId Transaction ID for the transaction - - * used in the async callback to match with the original request. - * @param pubSubId ID of the publish/subscribe session - obtained when - * creating a session. - */ - public boolean stopSubscribe(short transactionId, int pubSubId) { - if (VDBG) { - Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = stopSubscribeNative(transactionId, WifiNative.class, WifiNative.sWlan0Index, - pubSubId); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "stopSubscribeNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "stopSubscribe: cannot initialize Aware"); - return false; - } - } - - private static native int createAwareNetworkInterfaceNative(short transactionId, - Class<WifiNative> cls, int iface, - String interfaceName); - - /** - * Create a Aware network interface. This only creates the Linux interface - it doesn't actually - * create the data connection. - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - * @param interfaceName The name of the interface, e.g. "aware0". - */ - public boolean createAwareNetworkInterface(short transactionId, String interfaceName) { - if (VDBG) { - Log.v(TAG, "createAwareNetworkInterface: transactionId=" + transactionId + ", " - + "interfaceName=" + interfaceName); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = createAwareNetworkInterfaceNative(transactionId, WifiNative.class, WifiNative - .sWlan0Index, interfaceName); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "createAwareNetworkInterfaceNative: HAL API returned non-success -- " - + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "createAwareNetworkInterface: cannot initialize Aware"); - return false; - } - } - - private static native int deleteAwareNetworkInterfaceNative(short transactionId, - Class<WifiNative> cls, int iface, - String interfaceName); - - /** - * Deletes a Aware network interface. The data connection can (should?) be torn down previously. - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - * @param interfaceName The name of the interface, e.g. "aware0". - */ - public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) { - if (VDBG) { - Log.v(TAG, "deleteAwareNetworkInterface: transactionId=" + transactionId + ", " - + "interfaceName=" + interfaceName); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = deleteAwareNetworkInterfaceNative(transactionId, WifiNative.class, WifiNative - .sWlan0Index, interfaceName); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "deleteAwareNetworkInterfaceNative: HAL API returned non-success -- " - + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "deleteAwareNetworkInterface: cannot initialize Aware"); - return false; - } - } - - private static native int initiateDataPathNative(short transactionId, Class<WifiNative> cls, - int iface, int peerId, int channelRequestType, int channel, byte[] peer, - String interfaceName, byte[] message); - - public static final int CHANNEL_REQUEST_TYPE_NONE = 0; - public static final int CHANNEL_REQUEST_TYPE_REQUESTED = 1; - public static final int CHANNEL_REQUEST_TYPE_REQUIRED = 2; - - /** - * Initiates setting up a data-path between device and peer. - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - * @param peerId ID of the peer ID to associate the data path with. A value of 0 - * indicates that not associated with an existing session. - * @param channelRequestType Indicates whether the specified channel is available, if available - * requested or forced (resulting in failure if cannot be - * accommodated). - * @param channel The channel on which to set up the data-path. - * @param peer The MAC address of the peer to create a connection with. - * @param interfaceName The interface on which to create the data connection. - * @param message An arbitrary byte array to forward to the peer as part of the data path - * request. - */ - public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType, - int channel, byte[] peer, String interfaceName, byte[] message) { - if (VDBG) { - Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId - + ", channelRequestType=" + channelRequestType + ", channel=" + channel - + ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName=" - + interfaceName); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = initiateDataPathNative(transactionId, WifiNative.class, WifiNative - .sWlan0Index, peerId, channelRequestType, channel, peer, interfaceName, - message); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "initiateDataPathNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "initiateDataPath: cannot initialize Aware"); - return false; - } - } - - private static native int respondToDataPathRequestNative(short transactionId, - Class<WifiNative> cls, int iface, boolean accept, int ndpId, String interfaceName, - byte[] message); - - /** - * Responds to a data request from a peer. - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - * @param accept Accept (true) or reject (false) the original call. - * @param ndpId The NDP (Aware data path) ID. Obtained from the request callback. - * @param interfaceName The interface on which the data path will be setup. Obtained from the - * request callback. - * @param message An arbitrary byte array to forward to the peer in the respond message. - */ - public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId, - String interfaceName, byte[] message) { - if (VDBG) { - Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept=" - + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = respondToDataPathRequestNative(transactionId, WifiNative.class, WifiNative - .sWlan0Index, accept, ndpId, interfaceName, message); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, - "respondToDataPathRequestNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "respondToDataPathRequest: cannot initialize Aware"); - return false; - } - } - - private static native int endDataPathNative(short transactionId, Class<WifiNative> cls, - int iface, int ndpId); - - /** - * Terminate an existing data-path (does not delete the interface). - * - * @param transactionId Transaction ID for the transaction - used in the async callback to - * match with the original request. - * @param ndpId The NDP (Aware data path) ID to be terminated. - */ - public boolean endDataPath(short transactionId, int ndpId) { - if (VDBG) { - Log.v(TAG, "endDataPath: transactionId=" + transactionId + ", ndpId=" + ndpId); - } - - if (isAwareInit()) { - int ret; - synchronized (WifiNative.sLock) { - ret = endDataPathNative(transactionId, WifiNative.class, WifiNative.sWlan0Index, - ndpId); - } - if (ret != WIFI_SUCCESS) { - Log.w(TAG, "endDataPathNative: HAL API returned non-success -- " + ret); - } - return ret == WIFI_SUCCESS; - } else { - Log.w(TAG, "endDataPath: cannot initialize Aware"); - return false; - } - } - - // EVENTS - - // AwareResponseType for API responses: will add values as needed - public static final int AWARE_RESPONSE_ENABLED = 0; - public static final int AWARE_RESPONSE_PUBLISH = 2; - public static final int AWARE_RESPONSE_PUBLISH_CANCEL = 3; - public static final int AWARE_RESPONSE_TRANSMIT_FOLLOWUP = 4; - public static final int AWARE_RESPONSE_SUBSCRIBE = 5; - public static final int AWARE_RESPONSE_SUBSCRIBE_CANCEL = 6; - public static final int AWARE_RESPONSE_CONFIG = 8; - public static final int AWARE_RESPONSE_GET_CAPABILITIES = 12; - public static final int AWARE_RESPONSE_DP_INTERFACE_CREATE = 13; - public static final int AWARE_RESPONSE_DP_INTERFACE_DELETE = 14; - public static final int AWARE_RESPONSE_DP_INITIATOR_RESPONSE = 15; - public static final int AWARE_RESPONSE_DP_RESPONDER_RESPONSE = 16; - public static final int AWARE_RESPONSE_DP_END = 17; - - // TODO: place-holder until resolve error codes/feedback to user b/29443148 - public static final int AWARE_STATUS_ERROR = -1; - - // direct copy from wifi_nan.h: need to keep in sync - /* Aware HAL Status Codes */ - public static final int AWARE_STATUS_SUCCESS = 0; - public static final int AWARE_STATUS_INTERNAL_FAILURE = 1; - public static final int AWARE_STATUS_PROTOCOL_FAILURE = 2; - public static final int AWARE_STATUS_INVALID_PUBLISH_SUBSCRIBE_ID = 3; - public static final int AWARE_STATUS_NO_RESOURCE_AVAILABLE = 4; - public static final int AWARE_STATUS_INVALID_PARAM = 5; - public static final int AWARE_STATUS_INVALID_REQUESTOR_INSTANCE_ID = 6; - public static final int AWARE_STATUS_INVALID_SERVICE_INSTANCE_ID = 7; - public static final int AWARE_STATUS_INVALID_NDP_ID = 8; - public static final int AWARE_STATUS_NAN_NOT_ALLOWED = 9; - public static final int AWARE_STATUS_NO_OTA_ACK = 10; - public static final int AWARE_STATUS_ALREADY_ENABLED = 11; - public static final int AWARE_STATUS_FOLLOWUP_QUEUE_FULL = 12; - public static final int AWARE_STATUS_UNSUPPORTED_CONCURRENCY_NAN_DISABLED = 13; - - // callback from native - private static void onAwareNotifyResponse(short transactionId, int responseType, int status, - String nanError) { - if (VDBG) { - Log.v(TAG, - "onAwareNotifyResponse: transactionId=" + transactionId + ", responseType=" - + responseType + ", status=" + status + ", nanError=" + nanError); - } - - switch (responseType) { - case AWARE_RESPONSE_ENABLED: - /* fall through */ - case AWARE_RESPONSE_CONFIG: - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onConfigSuccessResponse(transactionId); - } else { - sWifiAwareStateManager.onConfigFailedResponse(transactionId, status); - } - break; - case AWARE_RESPONSE_PUBLISH_CANCEL: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, - "onAwareNotifyResponse: AWARE_RESPONSE_PUBLISH_CANCEL error - status=" - + status + ", nanError=" + nanError); - } - break; - case AWARE_RESPONSE_TRANSMIT_FOLLOWUP: - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onMessageSendQueuedSuccessResponse(transactionId); - } else { - sWifiAwareStateManager.onMessageSendQueuedFailResponse(transactionId, status); - } - break; - case AWARE_RESPONSE_SUBSCRIBE_CANCEL: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, - "onAwareNotifyResponse: AWARE_RESPONSE_PUBLISH_CANCEL error - status=" - + status + ", nanError=" + nanError); - } - break; - case AWARE_RESPONSE_DP_INTERFACE_CREATE: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, - "onAwareNotifyResponse: AWARE_RESPONSE_DP_INTERFACE_CREATE error - " - + "status=" - + status + ", nanError=" + nanError); - } - sWifiAwareStateManager.onCreateDataPathInterfaceResponse(transactionId, - status == AWARE_STATUS_SUCCESS, status); - break; - case AWARE_RESPONSE_DP_INTERFACE_DELETE: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, - "onAwareNotifyResponse: AWARE_RESPONSE_DP_INTERFACE_DELETE error - " - + "status=" - + status + ", nanError=" + nanError); - } - sWifiAwareStateManager.onDeleteDataPathInterfaceResponse(transactionId, - status == AWARE_STATUS_SUCCESS, status); - break; - case AWARE_RESPONSE_DP_RESPONDER_RESPONSE: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, - "onAwareNotifyResponse: AWARE_RESPONSE_DP_RESPONDER_RESPONSE error - " - + "status=" + status + ", nanError=" + nanError); - } - sWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(transactionId, - status == AWARE_STATUS_SUCCESS, status); - break; - case AWARE_RESPONSE_DP_END: - if (status != AWARE_STATUS_SUCCESS) { - Log.e(TAG, "onAwareNotifyResponse: AWARE_RESPONSE_DP_END error - status=" - + status + ", nanError=" + nanError); - } - sWifiAwareStateManager.onEndDataPathResponse(transactionId, - status == AWARE_STATUS_SUCCESS, status); - break; - default: - Log.e(TAG, "onAwareNotifyResponse: unclassified responseType=" + responseType); - break; - } - } - - private static void onAwareNotifyResponsePublishSubscribe(short transactionId, int responseType, - int status, String nanError, int pubSubId) { - if (VDBG) { - Log.v(TAG, - "onAwareNotifyResponsePublishSubscribe: transactionId=" + transactionId - + ", responseType=" + responseType + ", status=" + status - + ", nanError=" + nanError + ", pubSubId=" + pubSubId); - } - - switch (responseType) { - case AWARE_RESPONSE_PUBLISH: - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onSessionConfigSuccessResponse(transactionId, true, - pubSubId); - } else { - sWifiAwareStateManager.onSessionConfigFailResponse(transactionId, true, status); - } - break; - case AWARE_RESPONSE_SUBSCRIBE: - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onSessionConfigSuccessResponse(transactionId, false, - pubSubId); - } else { - sWifiAwareStateManager.onSessionConfigFailResponse(transactionId, false, - status); - } - break; - default: - Log.wtf(TAG, "onAwareNotifyResponsePublishSubscribe: unclassified responseType=" - + responseType); - break; - } - } - - private static void onAwareNotifyResponseCapabilities(short transactionId, int status, - String nanError, Capabilities capabilities) { - if (VDBG) { - Log.v(TAG, "onAwareNotifyResponseCapabilities: transactionId=" + transactionId - + ", status=" + status + ", nanError=" + nanError + ", capabilities=" - + capabilities); - } - - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onCapabilitiesUpdateResponse(transactionId, capabilities); - } else { - Log.e(TAG, "onAwareNotifyResponseCapabilities: error status=" + status - + ", nanError=" + nanError); - } - } - - private static void onAwareNotifyResponseDataPathInitiate(short transactionId, int status, - String nanError, int ndpId) { - if (VDBG) { - Log.v(TAG, - "onAwareNotifyResponseDataPathInitiate: transactionId=" + transactionId - + ", status=" + status + ", nanError=" + nanError + ", ndpId=" + ndpId); - } - if (status == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onInitiateDataPathResponseSuccess(transactionId, ndpId); - } else { - sWifiAwareStateManager.onInitiateDataPathResponseFail(transactionId, status); - } - } - - public static final int AWARE_EVENT_ID_DISC_MAC_ADDR = 0; - public static final int AWARE_EVENT_ID_STARTED_CLUSTER = 1; - public static final int AWARE_EVENT_ID_JOINED_CLUSTER = 2; - - // callback from native - private static void onDiscoveryEngineEvent(int eventType, byte[] mac) { - if (VDBG) { - Log.v(TAG, "onDiscoveryEngineEvent: eventType=" + eventType + ", mac=" - + String.valueOf(HexEncoding.encode(mac))); - } - - if (eventType == AWARE_EVENT_ID_DISC_MAC_ADDR) { - sWifiAwareStateManager.onInterfaceAddressChangeNotification(mac); - } else if (eventType == AWARE_EVENT_ID_STARTED_CLUSTER) { - sWifiAwareStateManager.onClusterChangeNotification( - WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, mac); - } else if (eventType == AWARE_EVENT_ID_JOINED_CLUSTER) { - sWifiAwareStateManager.onClusterChangeNotification( - WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, mac); - } else { - Log.w(TAG, "onDiscoveryEngineEvent: invalid eventType=" + eventType); - } - } - - // callback from native - private static void onMatchEvent(int pubSubId, int requestorInstanceId, byte[] mac, - byte[] serviceSpecificInfo, byte[] matchFilter) { - if (VDBG) { - Log.v(TAG, "onMatchEvent: pubSubId=" + pubSubId + ", requestorInstanceId=" - + requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac)) - + ", serviceSpecificInfo=" + Arrays.toString(serviceSpecificInfo) - + ", matchFilter=" + Arrays.toString(matchFilter)); - } - - sWifiAwareStateManager.onMatchNotification(pubSubId, requestorInstanceId, mac, - serviceSpecificInfo, matchFilter); - } - - // callback from native - private static void onPublishTerminated(int publishId, int status) { - if (VDBG) Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status); - - sWifiAwareStateManager.onSessionTerminatedNotification(publishId, status, true); - } - - // callback from native - private static void onSubscribeTerminated(int subscribeId, int status) { - if (VDBG) { - Log.v(TAG, "onSubscribeTerminated: subscribeId=" + subscribeId + ", status=" + status); - } - - sWifiAwareStateManager.onSessionTerminatedNotification(subscribeId, status, false); - } - - // callback from native - private static void onFollowupEvent(int pubSubId, int requestorInstanceId, byte[] mac, - byte[] message) { - if (VDBG) { - Log.v(TAG, "onFollowupEvent: pubSubId=" + pubSubId + ", requestorInstanceId=" - + requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))); - } - - sWifiAwareStateManager.onMessageReceivedNotification(pubSubId, requestorInstanceId, mac, - message); - } - - // callback from native - private static void onDisabledEvent(int status) { - if (VDBG) Log.v(TAG, "onDisabledEvent: status=" + status); - - sWifiAwareStateManager.onAwareDownNotification(status); - } - - // callback from native - private static void onTransmitFollowupEvent(short transactionId, int reason) { - if (VDBG) { - Log.v(TAG, "onTransmitFollowupEvent: transactionId=" + transactionId + ", reason=" - + reason); - } - - if (reason == AWARE_STATUS_SUCCESS) { - sWifiAwareStateManager.onMessageSendSuccessNotification(transactionId); - } else { - sWifiAwareStateManager.onMessageSendFailNotification(transactionId, reason); - } - } - - private static void onDataPathRequest(int pubSubId, byte[] mac, int ndpId, byte[] message) { - if (VDBG) { - Log.v(TAG, "onDataPathRequest: pubSubId=" + pubSubId + ", mac=" + String.valueOf( - HexEncoding.encode(mac)) + ", ndpId=" + ndpId); - } - - sWifiAwareStateManager.onDataPathRequestNotification(pubSubId, mac, ndpId, message); - } - - private static void onDataPathConfirm(int ndpId, byte[] mac, boolean accept, int reason, - byte[] message) { - if (VDBG) { - Log.v(TAG, "onDataPathConfirm: ndpId=" + ndpId + ", mac=" + String.valueOf(HexEncoding - .encode(mac)) + ", accept=" + accept + ", reason=" + reason); - } - - sWifiAwareStateManager.onDataPathConfirmNotification(ndpId, mac, accept, reason, message); - } - - private static void onDataPathEnd(int ndpId) { - if (VDBG) { - Log.v(TAG, "onDataPathEndNotification: ndpId=" + ndpId); - } - - sWifiAwareStateManager.onDataPathEndNotification(ndpId); - } -} diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java new file mode 100644 index 000000000..e446feb5f --- /dev/null +++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeApi.java @@ -0,0 +1,730 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi.aware; + +import android.hardware.wifi.V1_0.IWifiNanIface; +import android.hardware.wifi.V1_0.NanBandIndex; +import android.hardware.wifi.V1_0.NanBandSpecificConfig; +import android.hardware.wifi.V1_0.NanConfigRequest; +import android.hardware.wifi.V1_0.NanEnableRequest; +import android.hardware.wifi.V1_0.NanInitiateDataPathRequest; +import android.hardware.wifi.V1_0.NanMatchAlg; +import android.hardware.wifi.V1_0.NanPublishRequest; +import android.hardware.wifi.V1_0.NanRespondToDataPathIndicationRequest; +import android.hardware.wifi.V1_0.NanSubscribeRequest; +import android.hardware.wifi.V1_0.NanTransmitFollowupRequest; +import android.hardware.wifi.V1_0.NanTxType; +import android.hardware.wifi.V1_0.WifiStatus; +import android.hardware.wifi.V1_0.WifiStatusCode; +import android.net.wifi.aware.ConfigRequest; +import android.net.wifi.aware.PublishConfig; +import android.net.wifi.aware.SubscribeConfig; +import android.os.RemoteException; +import android.util.Log; + +import libcore.util.HexEncoding; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; + +/** + * Translates Wi-Fi Aware requests from the framework to the HAL (HIDL). + * + * Delegates the management of the NAN interface to WifiAwareNativeManager. + */ +public class WifiAwareNativeApi { + private static final String TAG = "WifiAwareNativeApi"; + private static final boolean DBG = false; + private static final boolean VDBG = false; // STOPSHIP if true + + private final WifiAwareNativeManager mHal; + + public WifiAwareNativeApi(WifiAwareNativeManager wifiAwareNativeManager) { + mHal = wifiAwareNativeManager; + } + + /** + * Query the firmware's capabilities. + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + */ + public boolean getCapabilities(short transactionId) { + if (VDBG) Log.v(TAG, "getCapabilities: transactionId=" + transactionId); + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "getCapabilities: null interface"); + return false; + } + + try { + WifiStatus status = iface.getCapabilitiesRequest(transactionId); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "getCapabilities: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "getCapabilities: exception: " + e); + return false; + } + } + + /** + * Enable and configure Aware. + * + * @param transactionId Transaction ID for the transaction - used in the + * async callback to match with the original request. + * @param configRequest Requested Aware configuration. + * @param notifyIdentityChange Indicates whether or not to get address change callbacks. + * @param initialConfiguration Specifies whether initial configuration + * (true) or an update (false) to the configuration. + */ + public boolean enableAndConfigure(short transactionId, ConfigRequest configRequest, + boolean notifyIdentityChange, boolean initialConfiguration) { + if (VDBG) { + Log.v(TAG, "enableAndConfigure: transactionId=" + transactionId + ", configRequest=" + + configRequest + ", notifyIdentityChange=" + notifyIdentityChange + + ", initialConfiguration=" + initialConfiguration); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "enableAndConfigure: null interface"); + return false; + } + + try { + WifiStatus status; + if (initialConfiguration) { + // translate framework to HIDL configuration + NanEnableRequest req = new NanEnableRequest(); + + req.operateInBand[NanBandIndex.NAN_BAND_24GHZ] = true; + req.operateInBand[NanBandIndex.NAN_BAND_5GHZ] = configRequest.mSupport5gBand; + req.hopCountMax = 2; + req.configParams.masterPref = (byte) configRequest.mMasterPreference; + req.configParams.disableDiscoveryAddressChangeIndication = !notifyIdentityChange; + req.configParams.disableStartedClusterIndication = !notifyIdentityChange; + req.configParams.disableJoinedClusterIndication = !notifyIdentityChange; + req.configParams.includeServiceIdsInBeacon = true; + req.configParams.numberOfServiceIdsInBeacon = 0; + req.configParams.rssiWindowSize = 8; + req.configParams.macAddressRandomizationIntervalSec = 1800; + req.configParams.acceptRangingRequests = true; + + NanBandSpecificConfig config24 = new NanBandSpecificConfig(); + config24.rssiClose = 60; + config24.rssiMiddle = 70; + config24.rssiProximity = 60; + config24.dwellTimeMs = (byte) 200; + config24.scanPeriodSec = 20; + config24.validDiscoveryWindowIntervalVal = false; + req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24; + + NanBandSpecificConfig config5 = new NanBandSpecificConfig(); + config5.rssiClose = 60; + config5.rssiMiddle = 75; + config5.rssiProximity = 60; + config5.dwellTimeMs = (byte) 200; + config5.scanPeriodSec = 20; + config5.validDiscoveryWindowIntervalVal = false; + req.configParams.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5; + + req.debugConfigs.validClusterIdVals = true; + req.debugConfigs.clusterIdHighVal = (short) configRequest.mClusterHigh; + req.debugConfigs.clusterIdLowVal = (short) configRequest.mClusterLow; + req.debugConfigs.validIntfAddrVal = false; + req.debugConfigs.validOuiVal = false; + req.debugConfigs.ouiVal = 0; + req.debugConfigs.validRandomFactorForceVal = false; + req.debugConfigs.randomFactorForceVal = 0; + req.debugConfigs.validHopCountForceVal = false; + req.debugConfigs.hopCountForceVal = 0; + req.debugConfigs.validDiscoveryChannelVal = false; + req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_24GHZ] = 0; + req.debugConfigs.discoveryChannelMhzVal[NanBandIndex.NAN_BAND_5GHZ] = 0; + req.debugConfigs.validUseBeaconsInBandVal = false; + req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true; + req.debugConfigs.useBeaconsInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true; + req.debugConfigs.validUseSdfInBandVal = false; + req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_24GHZ] = true; + req.debugConfigs.useSdfInBandVal[NanBandIndex.NAN_BAND_5GHZ] = true; + + status = iface.enableRequest(transactionId, req); + } else { + NanConfigRequest req = new NanConfigRequest(); + req.masterPref = (byte) configRequest.mMasterPreference; + req.disableDiscoveryAddressChangeIndication = !notifyIdentityChange; + req.disableStartedClusterIndication = !notifyIdentityChange; + req.disableJoinedClusterIndication = !notifyIdentityChange; + req.includeServiceIdsInBeacon = true; + req.numberOfServiceIdsInBeacon = 0; + req.rssiWindowSize = 8; + req.macAddressRandomizationIntervalSec = 1800; + req.acceptRangingRequests = true; + + NanBandSpecificConfig config24 = new NanBandSpecificConfig(); + config24.rssiClose = 60; + config24.rssiMiddle = 70; + config24.rssiProximity = 60; + config24.dwellTimeMs = (byte) 200; + config24.scanPeriodSec = 20; + config24.validDiscoveryWindowIntervalVal = false; + req.bandSpecificConfig[NanBandIndex.NAN_BAND_24GHZ] = config24; + + NanBandSpecificConfig config5 = new NanBandSpecificConfig(); + config5.rssiClose = 60; + config5.rssiMiddle = 75; + config5.rssiProximity = 60; + config5.dwellTimeMs = (byte) 200; + config5.scanPeriodSec = 20; + config5.validDiscoveryWindowIntervalVal = false; + req.bandSpecificConfig[NanBandIndex.NAN_BAND_5GHZ] = config5; + + status = iface.configRequest(transactionId, req); + } + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "enableAndConfigure: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "enableAndConfigure: exception: " + e); + return false; + } + } + + /** + * Disable Aware. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + */ + public boolean disable(short transactionId) { + if (VDBG) Log.d(TAG, "disable"); + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "disable: null interface"); + return false; + } + + try { + WifiStatus status = iface.disableRequest(transactionId); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "disable: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "disable: exception: " + e); + return false; + } + } + + /** + * Start or modify a service publish session. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + * @param publishId ID of the requested session - 0 to request a new publish + * session. + * @param publishConfig Configuration of the discovery session. + */ + public boolean publish(short transactionId, int publishId, PublishConfig publishConfig) { + if (VDBG) { + Log.d(TAG, "publish: transactionId=" + transactionId + ", config=" + publishConfig); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "publish: null interface"); + return false; + } + + NanPublishRequest req = new NanPublishRequest(); + req.baseConfigs.sessionId = 0; + req.baseConfigs.ttlSec = (short) publishConfig.mTtlSec; + req.baseConfigs.discoveryWindowPeriod = 1; + req.baseConfigs.discoveryCount = (byte) publishConfig.mPublishCount; + convertLcByteToUcByteArray(publishConfig.mServiceName, req.baseConfigs.serviceName); + // TODO: what's the right value on publish? + req.baseConfigs.discoveryMatchIndicator = NanMatchAlg.MATCH_ONCE; + convertLcByteToUcByteArray(publishConfig.mServiceSpecificInfo, + req.baseConfigs.serviceSpecificInfo); + convertLcByteToUcByteArray(publishConfig.mMatchFilter, + publishConfig.mPublishType == PublishConfig.PUBLISH_TYPE_UNSOLICITED + ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter); + req.baseConfigs.useRssiThreshold = false; + req.baseConfigs.disableDiscoveryTerminationIndication = + !publishConfig.mEnableTerminateNotification; + req.baseConfigs.disableMatchExpirationIndication = true; + req.baseConfigs.disableFollowupReceivedIndication = false; + + // TODO: configure ranging and security + req.baseConfigs.securityEnabledInNdp = false; + req.baseConfigs.rangingRequired = false; + + req.publishType = publishConfig.mPublishType; + req.txType = NanTxType.BROADCAST; + + try { + WifiStatus status = iface.startPublishRequest(transactionId, req); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "publish: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "publish: exception: " + e); + return false; + } + } + + /** + * Start or modify a service subscription session. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + * @param subscribeId ID of the requested session - 0 to request a new + * subscribe session. + * @param subscribeConfig Configuration of the discovery session. + */ + public boolean subscribe(short transactionId, int subscribeId, + SubscribeConfig subscribeConfig) { + if (VDBG) { + Log.d(TAG, "subscribe: transactionId=" + transactionId + ", config=" + subscribeConfig); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "subscribe: null interface"); + return false; + } + + NanSubscribeRequest req = new NanSubscribeRequest(); + req.baseConfigs.sessionId = 0; + req.baseConfigs.ttlSec = (short) subscribeConfig.mTtlSec; + req.baseConfigs.discoveryWindowPeriod = 1; + req.baseConfigs.discoveryCount = (byte) subscribeConfig.mSubscribeCount; + convertLcByteToUcByteArray(subscribeConfig.mServiceName, req.baseConfigs.serviceName); + req.baseConfigs.discoveryMatchIndicator = subscribeConfig.mMatchStyle; + convertLcByteToUcByteArray(subscribeConfig.mServiceSpecificInfo, + req.baseConfigs.serviceSpecificInfo); + convertLcByteToUcByteArray(subscribeConfig.mMatchFilter, + subscribeConfig.mSubscribeType == SubscribeConfig.SUBSCRIBE_TYPE_ACTIVE + ? req.baseConfigs.txMatchFilter : req.baseConfigs.rxMatchFilter); + req.baseConfigs.useRssiThreshold = false; + req.baseConfigs.disableDiscoveryTerminationIndication = + !subscribeConfig.mEnableTerminateNotification; + req.baseConfigs.disableMatchExpirationIndication = true; + req.baseConfigs.disableFollowupReceivedIndication = false; + req.subscribeType = subscribeConfig.mSubscribeType; + + try { + WifiStatus status = iface.startSubscribeRequest(transactionId, req); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "subscribe: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "subscribe: exception: " + e); + return false; + } + } + + /** + * Send a message through an existing discovery session. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + * @param pubSubId ID of the existing publish/subscribe session. + * @param requestorInstanceId ID of the peer to communicate with - obtained + * through a previous discovery (match) operation with that peer. + * @param dest MAC address of the peer to communicate with - obtained + * together with requestorInstanceId. + * @param message Message. + * @param messageId Arbitary integer from host (not sent to HAL - useful for + * testing/debugging at this level) + */ + public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId, + byte[] dest, byte[] message, int messageId) { + if (VDBG) { + Log.d(TAG, + "sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId + + ", requestorInstanceId=" + requestorInstanceId + ", dest=" + + String.valueOf(HexEncoding.encode(dest)) + ", messageId=" + + messageId); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "sendMessage: null interface"); + return false; + } + + NanTransmitFollowupRequest req = new NanTransmitFollowupRequest(); + req.discoverySessionId = (short) pubSubId; + req.peerId = requestorInstanceId; + copyArray(dest, req.addr); + req.isHighPriority = false; + req.shouldUseDiscoveryWindow = true; + convertLcByteToUcByteArray(message, req.message); + req.disableFollowupResultIndication = false; + + try { + WifiStatus status = iface.transmitFollowupRequest(transactionId, req); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "sendMessage: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "sendMessage: exception: " + e); + return false; + } + } + + /** + * Terminate a publish discovery session. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + * @param pubSubId ID of the publish/subscribe session - obtained when + * creating a session. + */ + public boolean stopPublish(short transactionId, int pubSubId) { + if (VDBG) { + Log.d(TAG, "stopPublish: transactionId=" + transactionId + ", pubSubId=" + pubSubId); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "stopPublish: null interface"); + return false; + } + + try { + WifiStatus status = iface.stopPublishRequest(transactionId, (short) pubSubId); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "stopPublish: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "stopPublish: exception: " + e); + return false; + } + } + + /** + * Terminate a subscribe discovery session. + * + * @param transactionId transactionId Transaction ID for the transaction - + * used in the async callback to match with the original request. + * @param pubSubId ID of the publish/subscribe session - obtained when + * creating a session. + */ + public boolean stopSubscribe(short transactionId, int pubSubId) { + if (VDBG) { + Log.d(TAG, "stopSubscribe: transactionId=" + transactionId + ", pubSubId=" + pubSubId); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "stopSubscribe: null interface"); + return false; + } + + try { + WifiStatus status = iface.stopSubscribeRequest(transactionId, (short) pubSubId); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "stopSubscribe: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "stopSubscribe: exception: " + e); + return false; + } + } + + /** + * Create a Aware network interface. This only creates the Linux interface - it doesn't actually + * create the data connection. + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + * @param interfaceName The name of the interface, e.g. "aware0". + */ + public boolean createAwareNetworkInterface(short transactionId, String interfaceName) { + if (VDBG) { + Log.v(TAG, "createAwareNetworkInterface: transactionId=" + transactionId + ", " + + "interfaceName=" + interfaceName); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "createAwareNetworkInterface: null interface"); + return false; + } + + try { + WifiStatus status = iface.createDataInterfaceRequest(transactionId, interfaceName); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "createAwareNetworkInterface: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "createAwareNetworkInterface: exception: " + e); + return false; + } + } + + /** + * Deletes a Aware network interface. The data connection can (should?) be torn down previously. + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + * @param interfaceName The name of the interface, e.g. "aware0". + */ + public boolean deleteAwareNetworkInterface(short transactionId, String interfaceName) { + if (VDBG) { + Log.v(TAG, "deleteAwareNetworkInterface: transactionId=" + transactionId + ", " + + "interfaceName=" + interfaceName); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "deleteAwareNetworkInterface: null interface"); + return false; + } + + try { + WifiStatus status = iface.deleteDataInterfaceRequest(transactionId, interfaceName); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "deleteAwareNetworkInterface: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "deleteAwareNetworkInterface: exception: " + e); + return false; + } + } + + /** + * Initiates setting up a data-path between device and peer. + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + * @param peerId ID of the peer ID to associate the data path with. A value of 0 + * indicates that not associated with an existing session. + * @param channelRequestType Indicates whether the specified channel is available, if available + * requested or forced (resulting in failure if cannot be + * accommodated). + * @param channel The channel on which to set up the data-path. + * @param peer The MAC address of the peer to create a connection with. + * @param interfaceName The interface on which to create the data connection. + * @param message An arbitrary byte array to forward to the peer as part of the data path + * request. + */ + public boolean initiateDataPath(short transactionId, int peerId, int channelRequestType, + int channel, byte[] peer, String interfaceName, byte[] message) { + if (VDBG) { + Log.v(TAG, "initiateDataPath: transactionId=" + transactionId + ", peerId=" + peerId + + ", channelRequestType=" + channelRequestType + ", channel=" + channel + + ", peer=" + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName=" + + interfaceName); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "initiateDataPath: null interface"); + return false; + } + + NanInitiateDataPathRequest req = new NanInitiateDataPathRequest(); + req.peerId = peerId; + copyArray(peer, req.peerDiscMacAddr); + req.channelRequestType = channelRequestType; + req.channel = channel; + req.ifaceName = interfaceName; + req.securityRequired = false; + convertLcByteToUcByteArray(message, req.appInfo); + + try { + WifiStatus status = iface.initiateDataPathRequest(transactionId, req); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "initiateDataPath: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "initiateDataPath: exception: " + e); + return false; + } + } + + /** + * Responds to a data request from a peer. + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + * @param accept Accept (true) or reject (false) the original call. + * @param ndpId The NDP (Aware data path) ID. Obtained from the request callback. + * @param interfaceName The interface on which the data path will be setup. Obtained from the + * request callback. + * @param message An arbitrary byte array to forward to the peer in the respond message. + */ + public boolean respondToDataPathRequest(short transactionId, boolean accept, int ndpId, + String interfaceName, byte[] message) { + if (VDBG) { + Log.v(TAG, "respondToDataPathRequest: transactionId=" + transactionId + ", accept=" + + accept + ", int ndpId=" + ndpId + ", interfaceName=" + interfaceName); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "respondToDataPathRequest: null interface"); + return false; + } + + NanRespondToDataPathIndicationRequest req = new NanRespondToDataPathIndicationRequest(); + req.acceptRequest = accept; + req.ndpInstanceId = ndpId; + req.ifaceName = interfaceName; + req.securityRequired = false; + convertLcByteToUcByteArray(message, req.appInfo); + + try { + WifiStatus status = iface.respondToDataPathIndicationRequest(transactionId, req); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "respondToDataPathRequest: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "respondToDataPathRequest: exception: " + e); + return false; + } + } + + /** + * Terminate an existing data-path (does not delete the interface). + * + * @param transactionId Transaction ID for the transaction - used in the async callback to + * match with the original request. + * @param ndpId The NDP (Aware data path) ID to be terminated. + */ + public boolean endDataPath(short transactionId, int ndpId) { + if (VDBG) { + Log.v(TAG, "endDataPath: transactionId=" + transactionId + ", ndpId=" + ndpId); + } + + IWifiNanIface iface = mHal.getWifiNanIface(); + if (iface == null) { + Log.e(TAG, "endDataPath: null interface"); + return false; + } + + try { + WifiStatus status = iface.terminateDataPathRequest(transactionId, ndpId); + if (status.code == WifiStatusCode.SUCCESS) { + return true; + } else { + Log.e(TAG, "endDataPath: error: " + statusString(status)); + return false; + } + } catch (RemoteException e) { + Log.e(TAG, "endDataPath: exception: " + e); + return false; + } + } + + + // utilities + + /** + * Converts a byte[] to an ArrayList<Byte>. Fills in the entries of the 'to' array if + * provided (non-null), otherwise creates and returns a new ArrayList<>. + * + * @param from The input byte[] to convert from. + * @param to An optional ArrayList<> to fill in from 'from'. + * + * @return A newly allocated ArrayList<> if 'to' is null, otherwise null. + */ + private ArrayList<Byte> convertLcByteToUcByteArray(byte[] from, ArrayList<Byte> to) { + if (from == null) { + from = new byte[0]; + } + + if (to == null) { + to = new ArrayList<>(from.length); + } else { + to.ensureCapacity(from.length); + } + for (int i = 0; i < from.length; ++i) { + to.add(from[i]); + } + return to; + } + + private void copyArray(byte[] from, byte[] to) { + if (from == null || to == null || from.length != to.length) { + Log.e(TAG, "copyArray error: from=" + from + ", to=" + to); + return; + } + for (int i = 0; i < from.length; ++i) { + to[i] = from[i]; + } + } + + private static String statusString(WifiStatus status) { + if (status == null) { + return "status=null"; + } + StringBuilder sb = new StringBuilder(); + sb.append(status.code).append(" (").append(status.description).append(")"); + return sb.toString(); + } + + + /** + * Dump the internal state of the class. + */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + mHal.dump(fd, pw, args); + } +} diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java new file mode 100644 index 000000000..24e2c689c --- /dev/null +++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeCallback.java @@ -0,0 +1,429 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi.aware; + +import android.hardware.wifi.V1_0.IWifiNanIfaceEventCallback; +import android.hardware.wifi.V1_0.NanBeaconSdfPayloadInd; +import android.hardware.wifi.V1_0.NanCapabilities; +import android.hardware.wifi.V1_0.NanClusterEventInd; +import android.hardware.wifi.V1_0.NanClusterEventType; +import android.hardware.wifi.V1_0.NanDataPathConfirmInd; +import android.hardware.wifi.V1_0.NanDataPathRequestInd; +import android.hardware.wifi.V1_0.NanFollowupReceivedInd; +import android.hardware.wifi.V1_0.NanMatchInd; +import android.hardware.wifi.V1_0.NanStatusType; +import android.hardware.wifi.V1_0.WifiNanStatus; +import android.util.Log; + +import libcore.util.HexEncoding; + +import java.util.ArrayList; +import java.util.Arrays; + +/** + * Manages the callbacks from Wi-Fi Aware HIDL (HAL). + */ +public class WifiAwareNativeCallback extends IWifiNanIfaceEventCallback.Stub { + private static final String TAG = "WifiAwareNativeCallback"; + private static final boolean DBG = false; + private static final boolean VDBG = false; + + private final WifiAwareStateManager mWifiAwareStateManager; + + public WifiAwareNativeCallback(WifiAwareStateManager wifiAwareStateManager) { + mWifiAwareStateManager = wifiAwareStateManager; + } + + @Override + public void notifyCapabilitiesResponse(short id, WifiNanStatus status, + NanCapabilities capabilities) { + if (VDBG) { + Log.v(TAG, "notifyCapabilitiesResponse: id=" + id + ", status=" + statusString(status) + + ", capabilities=" + capabilities); + } + + if (status.status == NanStatusType.SUCCESS) { + Capabilities frameworkCapabilities = new Capabilities(); + frameworkCapabilities.maxConcurrentAwareClusters = capabilities.maxConcurrentClusters; + frameworkCapabilities.maxPublishes = capabilities.maxPublishes; + frameworkCapabilities.maxSubscribes = capabilities.maxSubscribes; + frameworkCapabilities.maxServiceNameLen = capabilities.maxServiceNameLen; + frameworkCapabilities.maxMatchFilterLen = capabilities.maxMatchFilterLen; + frameworkCapabilities.maxTotalMatchFilterLen = capabilities.maxTotalMatchFilterLen; + frameworkCapabilities.maxServiceSpecificInfoLen = + capabilities.maxServiceSpecificInfoLen; + frameworkCapabilities.maxVsaDataLen = capabilities.maxVsaDataLen; + frameworkCapabilities.maxNdiInterfaces = capabilities.maxNdiInterfaces; + frameworkCapabilities.maxNdpSessions = capabilities.maxNdpSessions; + frameworkCapabilities.maxAppInfoLen = capabilities.maxAppInfoLen; + frameworkCapabilities.maxQueuedTransmitMessages = + capabilities.maxQueuedTransmitFollowupMsgs; + frameworkCapabilities.maxSubscribeInterfaceAddresses = + capabilities.maxSubscribeInterfaceAddresses; + frameworkCapabilities.supportedCipherSuites = capabilities.supportedCipherSuites; + + mWifiAwareStateManager.onCapabilitiesUpdateResponse(id, frameworkCapabilities); + } else { + Log.e(TAG, "notifyCapabilitiesResponse: error code=" + status.status + " (" + + status.description + ")"); + } + } + + @Override + public void notifyEnableResponse(short id, WifiNanStatus status) { + if (VDBG) Log.v(TAG, "notifyEnableResponse: id=" + id + ", status=" + statusString(status)); + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onConfigSuccessResponse(id); + } else { + mWifiAwareStateManager.onConfigFailedResponse(id, status.status); + } + } + + @Override + public void notifyConfigResponse(short id, WifiNanStatus status) { + if (VDBG) Log.v(TAG, "notifyConfigResponse: id=" + id + ", status=" + statusString(status)); + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onConfigSuccessResponse(id); + } else { + mWifiAwareStateManager.onConfigFailedResponse(id, status.status); + } + } + + @Override + public void notifyDisableResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyDisableResponse: id=" + id + ", status=" + statusString(status)); + } + + if (status.status == NanStatusType.SUCCESS) { + // NOP + } else { + Log.e(TAG, "notifyDisableResponse: failure - code=" + status.status + " (" + + status.description + ")"); + } + } + + @Override + public void notifyStartPublishResponse(short id, WifiNanStatus status, short publishId) { + if (VDBG) { + Log.v(TAG, "notifyStartPublishResponse: id=" + id + ", status=" + statusString(status) + + ", publishId=" + publishId); + } + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onSessionConfigSuccessResponse(id, true, publishId); + } else { + mWifiAwareStateManager.onSessionConfigFailResponse(id, true, status.status); + } + } + + @Override + public void notifyStopPublishResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyStopPublishResponse: id=" + id + ", status=" + statusString(status)); + } + + if (status.status == NanStatusType.SUCCESS) { + // NOP + } else { + Log.e(TAG, "notifyStopPublishResponse: failure - code=" + status.status + " (" + + status.description + ")"); + } + } + + @Override + public void notifyStartSubscribeResponse(short id, WifiNanStatus status, short subscribeId) { + if (VDBG) { + Log.v(TAG, "notifyStartSubscribeResponse: id=" + id + ", status=" + statusString(status) + + ", subscribeId=" + subscribeId); + } + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onSessionConfigSuccessResponse(id, false, subscribeId); + } else { + mWifiAwareStateManager.onSessionConfigFailResponse(id, false, status.status); + } + } + + @Override + public void notifyStopSubscribeResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyStopSubscribeResponse: id=" + id + ", status=" + + statusString(status)); + } + + if (status.status == NanStatusType.SUCCESS) { + // NOP + } else { + Log.e(TAG, "notifyStopSubscribeResponse: failure - code=" + status.status + " (" + + status.description + ")"); + } + } + + @Override + public void notifyTransmitFollowupResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyTransmitFollowupResponse: id=" + id + ", status=" + + statusString(status)); + } + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onMessageSendQueuedSuccessResponse(id); + } else { + mWifiAwareStateManager.onMessageSendQueuedFailResponse(id, status.status); + } + } + + @Override + public void notifyCreateDataInterfaceResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyCreateDataInterfaceResponse: id=" + id + ", status=" + + statusString(status)); + } + + mWifiAwareStateManager.onCreateDataPathInterfaceResponse(id, + status.status == NanStatusType.SUCCESS, status.status); + } + + @Override + public void notifyDeleteDataInterfaceResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyDeleteDataInterfaceResponse: id=" + id + ", status=" + + statusString(status)); + } + + mWifiAwareStateManager.onDeleteDataPathInterfaceResponse(id, + status.status == NanStatusType.SUCCESS, status.status); + } + + @Override + public void notifyInitiateDataPathResponse(short id, WifiNanStatus status, + int ndpInstanceId) { + if (VDBG) { + Log.v(TAG, "notifyInitiateDataPathResponse: id=" + id + ", status=" + + statusString(status) + ", ndpInstanceId=" + ndpInstanceId); + } + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onInitiateDataPathResponseSuccess(id, ndpInstanceId); + } else { + mWifiAwareStateManager.onInitiateDataPathResponseFail(id, status.status); + } + } + + @Override + public void notifyRespondToDataPathIndicationResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyRespondToDataPathIndicationResponse: id=" + id + + ", status=" + statusString(status)); + } + + mWifiAwareStateManager.onRespondToDataPathSetupRequestResponse(id, + status.status == NanStatusType.SUCCESS, status.status); + } + + @Override + public void notifyTerminateDataPathResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyTerminateDataPathResponse: id=" + id + ", status=" + + statusString(status)); + } + + mWifiAwareStateManager.onEndDataPathResponse(id, status.status == NanStatusType.SUCCESS, + status.status); + } + + @Override + public void notifyBeaconSdfPayloadResponse(short id, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "notifyBeaconSdfPayloadResponse: id=" + id + ", status=" + + statusString(status)); + } + + // NOP + } + + @Override + public void eventClusterEvent(NanClusterEventInd event) { + if (VDBG) { + Log.v(TAG, "eventClusterEvent: eventType=" + event.eventType + ", addr=" + + String.valueOf(HexEncoding.encode(event.addr))); + } + + if (event.eventType == NanClusterEventType.DISCOVERY_MAC_ADDRESS_CHANGED) { + mWifiAwareStateManager.onInterfaceAddressChangeNotification(event.addr); + } else if (event.eventType == NanClusterEventType.STARTED_CLUSTER) { + mWifiAwareStateManager.onClusterChangeNotification( + WifiAwareClientState.CLUSTER_CHANGE_EVENT_STARTED, event.addr); + } else if (event.eventType == NanClusterEventType.JOINED_CLUSTER) { + mWifiAwareStateManager.onClusterChangeNotification( + WifiAwareClientState.CLUSTER_CHANGE_EVENT_JOINED, event.addr); + } else { + Log.e(TAG, "eventClusterEvent: invalid eventType=" + event.eventType); + } + } + + @Override + public void eventDisabled(WifiNanStatus status) { + if (VDBG) Log.v(TAG, "eventDisabled: status=" + statusString(status)); + + mWifiAwareStateManager.onAwareDownNotification(status.status); + } + + @Override + public void eventPublishTerminated(short sessionId, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "eventPublishTerminated: sessionId=" + sessionId + ", status=" + + statusString(status)); + } + + mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, true); + } + + @Override + public void eventSubscribeTerminated(short sessionId, WifiNanStatus status) { + if (VDBG) { + Log.v(TAG, "eventSubscribeTerminated: sessionId=" + sessionId + ", status=" + + statusString(status)); + } + + mWifiAwareStateManager.onSessionTerminatedNotification(sessionId, status.status, false); + } + + @Override + public void eventMatch(NanMatchInd event) { + if (VDBG) { + Log.v(TAG, "eventMatch: discoverySessionId=" + event.discoverySessionId + ", peerId=" + + event.peerId + ", addr=" + String.valueOf(HexEncoding.encode(event.addr)) + + ", serviceSpecificInfo=" + Arrays.toString( + convertUcByteToLcByteArray(event.serviceSpecificInfo)) + ", matchFilter=" + + Arrays.toString(convertUcByteToLcByteArray(event.matchFilter))); + } + + mWifiAwareStateManager.onMatchNotification(event.discoverySessionId, event.peerId, + event.addr, convertUcByteToLcByteArray(event.serviceSpecificInfo), + convertUcByteToLcByteArray(event.matchFilter)); + } + + @Override + public void eventMatchExpired(short discoverySessionId, int peerId) { + if (VDBG) { + Log.v(TAG, "eventMatchExpired: discoverySessionId=" + discoverySessionId + + ", peerId=" + peerId); + } + + // NOP + } + + @Override + public void eventFollowupReceived(NanFollowupReceivedInd event) { + if (VDBG) { + Log.v(TAG, "eventFollowupReceived: discoverySessionId=" + event.discoverySessionId + + ", peerId=" + event.peerId + ", addr=" + String.valueOf( + HexEncoding.encode(event.addr))); + } + + mWifiAwareStateManager.onMessageReceivedNotification(event.discoverySessionId, event.peerId, + event.addr, convertUcByteToLcByteArray(event.message)); + } + + @Override + public void eventTransmitFollowup(short id, WifiNanStatus status) { + Log.v(TAG, "eventTransmitFollowup: id=" + id + ", status=" + statusString(status)); + + if (status.status == NanStatusType.SUCCESS) { + mWifiAwareStateManager.onMessageSendSuccessNotification(id); + } else { + mWifiAwareStateManager.onMessageSendFailNotification(id, status.status); + } + } + + @Override + public void eventDataPathRequest(NanDataPathRequestInd event) { + if (VDBG) { + Log.v(TAG, "eventDataPathRequest: discoverySessionId=" + event.discoverySessionId + + ", peerDiscMacAddr=" + String.valueOf( + HexEncoding.encode(event.peerDiscMacAddr)) + ", ndpInstanceId=" + + event.ndpInstanceId); + } + + mWifiAwareStateManager.onDataPathRequestNotification(event.discoverySessionId, + event.peerDiscMacAddr, event.ndpInstanceId, + convertUcByteToLcByteArray(event.appInfo)); + } + + @Override + public void eventDataPathConfirm(NanDataPathConfirmInd event) { + if (VDBG) { + Log.v(TAG, "onDataPathConfirm: ndpInstanceId=" + event.ndpInstanceId + + ", peerNdiMacAddr=" + String.valueOf(HexEncoding.encode(event.peerNdiMacAddr)) + + ", dataPathSetupSuccess=" + event.dataPathSetupSuccess + ", reason=" + + event.status.status); + } + + mWifiAwareStateManager.onDataPathConfirmNotification(event.ndpInstanceId, + event.peerNdiMacAddr, event.dataPathSetupSuccess, event.status.status, + convertUcByteToLcByteArray(event.appInfo)); + } + + @Override + public void eventDataPathTerminated(int ndpInstanceId) { + if (VDBG) Log.v(TAG, "eventDataPathTerminated: ndpInstanceId=" + ndpInstanceId); + + mWifiAwareStateManager.onDataPathEndNotification(ndpInstanceId); + } + + @Override + public void eventBeaconSdfPayload(NanBeaconSdfPayloadInd event) { + if (VDBG) Log.v(TAG, "eventBeaconSdfPayload"); + + // NOP + Log.e(TAG, "eventBeaconSdfPayload: not configured - should not happen!"); + } + + // utilities + + /** + * Converts an ArrayList<Byte> to a byte[]. + * + * @param from The input ArrayList<Byte></Byte> to convert from. + * + * @return A newly allocated byte[]. + */ + private byte[] convertUcByteToLcByteArray(ArrayList<Byte> from) { + if (from == null) { + return null; + } + + byte[] to = new byte[from.size()]; + for (int i = 0; i < from.size(); ++i) { + to[i] = from.get(i); + } + return to; + } + + private static String statusString(WifiNanStatus status) { + if (status == null) { + return "status=null"; + } + StringBuilder sb = new StringBuilder(); + sb.append(status.status).append(" (").append(status.description).append(")"); + return sb.toString(); + } +} diff --git a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java index deb6f01a3..22f13851f 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareNativeManager.java @@ -18,10 +18,16 @@ package com.android.server.wifi.aware; import android.hardware.wifi.V1_0.IWifiNanIface; import android.hardware.wifi.V1_0.IfaceType; +import android.hardware.wifi.V1_0.WifiStatus; +import android.hardware.wifi.V1_0.WifiStatusCode; +import android.os.RemoteException; import android.util.Log; import com.android.server.wifi.HalDeviceManager; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * Manages the interface to Wi-Fi Aware HIDL (HAL). */ @@ -34,6 +40,7 @@ class WifiAwareNativeManager { private WifiAwareStateManager mWifiAwareStateManager; private HalDeviceManager mHalDeviceManager; + private WifiAwareNativeCallback mWifiAwareNativeCallback; private IWifiNanIface mWifiNanIface = null; private InterfaceDestroyedListener mInterfaceDestroyedListener = new InterfaceDestroyedListener(); @@ -41,9 +48,11 @@ class WifiAwareNativeManager { new InterfaceAvailableForRequestListener(); WifiAwareNativeManager(WifiAwareStateManager awareStateManager, - HalDeviceManager halDeviceManager) { + HalDeviceManager halDeviceManager, + WifiAwareNativeCallback wifiAwareNativeCallback) { mWifiAwareStateManager = awareStateManager; mHalDeviceManager = halDeviceManager; + mWifiAwareNativeCallback = wifiAwareNativeCallback; mHalDeviceManager.registerStatusListener( new HalDeviceManager.ManagerStatusListener() { @Override @@ -86,6 +95,19 @@ class WifiAwareNativeManager { } else { if (DBG) Log.d(TAG, "Obtained an IWifiNanIface"); + try { + WifiStatus status = iface.registerEventCallback(mWifiAwareNativeCallback); + if (status.code != WifiStatusCode.SUCCESS) { + Log.e(TAG, "IWifiNanIface.registerEventCallback error: " + statusString( + status)); + mHalDeviceManager.removeIface(iface); + return; + } + } catch (RemoteException e) { + Log.e(TAG, "IWifiNanIface.registerEventCallback exception: " + e); + mHalDeviceManager.removeIface(iface); + return; + } mWifiNanIface = iface; mWifiAwareStateManager.enableUsage(); } @@ -119,4 +141,22 @@ class WifiAwareNativeManager { tryToGetAware(); } } + + private static String statusString(WifiStatus status) { + if (status == null) { + return "status=null"; + } + StringBuilder sb = new StringBuilder(); + sb.append(status.code).append(" (").append(status.description).append(")"); + return sb.toString(); + } + + /** + * Dump the internal state of the class. + */ + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("WifiAwareNativeManager:"); + pw.println(" mWifiNanIface: " + mWifiNanIface); + mHalDeviceManager.dump(fd, pw, args); + } } diff --git a/service/java/com/android/server/wifi/aware/WifiAwareService.java b/service/java/com/android/server/wifi/aware/WifiAwareService.java index dde3f162a..75efa0296 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareService.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareService.java @@ -21,6 +21,7 @@ import android.os.HandlerThread; import android.util.Log; import com.android.server.SystemService; +import com.android.server.wifi.HalDeviceManager; import com.android.server.wifi.WifiInjector; /** @@ -51,13 +52,19 @@ public final class WifiAwareService extends SystemService { return; } - HandlerThread awareHandlerThread = wifiInjector.getmWifiAwareHandlerThread(); - WifiAwareStateManager awareStateManager = new WifiAwareStateManager(); - WifiAwareNative awareNative = new WifiAwareNative(true); - awareStateManager.setNative(awareNative); - awareNative.setStateManager(awareStateManager); + HalDeviceManager halDeviceManager = wifiInjector.getHalDeviceManager(); + halDeviceManager.initialize(); - mImpl.start(awareHandlerThread, awareStateManager); + WifiAwareStateManager wifiAwareStateManager = new WifiAwareStateManager(); + WifiAwareNativeCallback wifiAwareNativeCallback = new WifiAwareNativeCallback( + wifiAwareStateManager); + WifiAwareNativeManager wifiAwareNativeManager = new WifiAwareNativeManager( + wifiAwareStateManager, halDeviceManager, wifiAwareNativeCallback); + WifiAwareNativeApi wifiAwareNativeApi = new WifiAwareNativeApi(wifiAwareNativeManager); + wifiAwareStateManager.setNative(wifiAwareNativeApi); + + HandlerThread awareHandlerThread = wifiInjector.getWifiAwareHandlerThread(); + mImpl.start(awareHandlerThread, wifiAwareStateManager); } else if (phase == SystemService.PHASE_BOOT_COMPLETED) { mImpl.startLate(); } diff --git a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java index 74e8e34b9..4f6a6198c 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareServiceImpl.java @@ -18,6 +18,7 @@ package com.android.server.wifi.aware; import android.content.Context; import android.content.pm.PackageManager; +import android.hardware.wifi.V1_0.NanStatusType; import android.net.wifi.RttManager; import android.net.wifi.aware.Characteristics; import android.net.wifi.aware.ConfigRequest; @@ -190,7 +191,7 @@ public class WifiAwareServiceImpl extends IWifiAwareManager.Stub { } catch (RemoteException e) { Log.e(TAG, "Error on linkToDeath - " + e); try { - callback.onConnectFail(WifiAwareNative.AWARE_STATUS_ERROR); + callback.onConnectFail(NanStatusType.INTERNAL_FAILURE); } catch (RemoteException e1) { Log.e(TAG, "Error on onConnectFail()"); } diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java index ac3594ba1..2cb2355d6 100644 --- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java +++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java @@ -18,6 +18,7 @@ package com.android.server.wifi.aware; import android.content.Context; import android.content.Intent; +import android.hardware.wifi.V1_0.NanStatusType; import android.net.wifi.RttManager; import android.net.wifi.aware.Characteristics; import android.net.wifi.aware.ConfigRequest; @@ -168,7 +169,7 @@ public class WifiAwareStateManager { private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ = "message_arrival_seq"; private static final String MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE = "notify_identity_chg"; - private WifiAwareNative mWifiAwareNative; + private WifiAwareNativeApi mWifiAwareNativeApi; /* * Asynchronous access with no lock @@ -180,7 +181,7 @@ public class WifiAwareStateManager { * handler thread: no need to use a lock. */ private Context mContext; - private volatile WifiAwareNative.Capabilities mCapabilities; + private volatile Capabilities mCapabilities; private volatile Characteristics mCharacteristics = null; private WifiAwareStateMachine mSm; private WifiAwareRttStateManager mRtt; @@ -188,6 +189,7 @@ public class WifiAwareStateManager { private final SparseArray<WifiAwareClientState> mClients = new SparseArray<>(); private ConfigRequest mCurrentAwareConfiguration = null; + private boolean mCurrentIdentityNotification = false; private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0}; private byte[] mCurrentDiscoveryInterfaceMac = ALL_ZERO_MAC; @@ -196,8 +198,8 @@ public class WifiAwareStateManager { // empty } - public void setNative(WifiAwareNative awareNative) { - mWifiAwareNative = awareNative; + public void setNative(WifiAwareNativeApi wifiAwareNativeApi) { + mWifiAwareNativeApi = wifiAwareNativeApi; } /** @@ -236,7 +238,7 @@ public class WifiAwareStateManager { /** * Get the capabilities. */ - public WifiAwareNative.Capabilities getCapabilities() { + public Capabilities getCapabilities() { return mCapabilities; } @@ -593,7 +595,7 @@ public class WifiAwareStateManager { * capabilities of the Aware stack. */ public void onCapabilitiesUpdateResponse(short transactionId, - WifiAwareNative.Capabilities capabilities) { + Capabilities capabilities) { Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); msg.arg1 = RESPONSE_TYPE_ON_CAPABILITIES_UPDATED; msg.arg2 = transactionId; @@ -1099,7 +1101,7 @@ public class WifiAwareStateManager { int retryCount = sentMessage.getData() .getInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT); - if (retryCount > 0 && reason == WifiAwareNative.AWARE_STATUS_NO_OTA_ACK) { + if (retryCount > 0 && reason == NanStatusType.NO_OTA_ACK) { if (DBG) { Log.d(TAG, "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: transactionId=" @@ -1330,7 +1332,8 @@ public class WifiAwareStateManager { } case COMMAND_TYPE_GET_CAPABILITIES: if (mCapabilities == null) { - waitForResponse = mWifiAwareNative.getCapabilities(mCurrentTransactionId); + waitForResponse = mWifiAwareNativeApi.getCapabilities( + mCurrentTransactionId); } else { if (VDBG) { Log.v(TAG, "COMMAND_TYPE_GET_CAPABILITIES: already have capabilities - " @@ -1348,11 +1351,11 @@ public class WifiAwareStateManager { waitForResponse = false; break; case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE: - waitForResponse = mWifiAwareNative.createAwareNetworkInterface( + waitForResponse = mWifiAwareNativeApi.createAwareNetworkInterface( mCurrentTransactionId, (String) msg.obj); break; case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE: - waitForResponse = mWifiAwareNative.deleteAwareNetworkInterface( + waitForResponse = mWifiAwareNativeApi.deleteAwareNetworkInterface( mCurrentTransactionId, (String) msg.obj); break; case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP: { @@ -1487,7 +1490,7 @@ public class WifiAwareStateManager { break; } case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED: { - onCapabilitiesUpdatedResponseLocal((WifiAwareNative.Capabilities) msg.obj); + onCapabilitiesUpdatedResponseLocal((Capabilities) msg.obj); break; } case RESPONSE_TYPE_ON_CREATE_INTERFACE: @@ -1543,7 +1546,7 @@ public class WifiAwareStateManager { */ switch (msg.arg1) { case COMMAND_TYPE_CONNECT: { - onConfigFailedLocal(mCurrentCommand, WifiAwareNative.AWARE_STATUS_ERROR); + onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_DISCONNECT: { @@ -1551,7 +1554,7 @@ public class WifiAwareStateManager { * Will only get here on DISCONNECT if was downgrading. The * callback will do a NOP - but should still call it. */ - onConfigFailedLocal(mCurrentCommand, WifiAwareNative.AWARE_STATUS_ERROR); + onConfigFailedLocal(mCurrentCommand, NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_TERMINATE_SESSION: { @@ -1559,23 +1562,21 @@ public class WifiAwareStateManager { break; } case COMMAND_TYPE_PUBLISH: { - onSessionConfigFailLocal(mCurrentCommand, true, - WifiAwareNative.AWARE_STATUS_ERROR); + onSessionConfigFailLocal(mCurrentCommand, true, NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_UPDATE_PUBLISH: { - onSessionConfigFailLocal(mCurrentCommand, true, - WifiAwareNative.AWARE_STATUS_ERROR); + onSessionConfigFailLocal(mCurrentCommand, true, NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_SUBSCRIBE: { onSessionConfigFailLocal(mCurrentCommand, false, - WifiAwareNative.AWARE_STATUS_ERROR); + NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_UPDATE_SUBSCRIBE: { onSessionConfigFailLocal(mCurrentCommand, false, - WifiAwareNative.AWARE_STATUS_ERROR); + NanStatusType.INTERNAL_FAILURE); break; } case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: { @@ -1585,7 +1586,7 @@ public class WifiAwareStateManager { case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: { Message sentMessage = mCurrentCommand.getData().getParcelable( MESSAGE_BUNDLE_KEY_SENT_MESSAGE); - onMessageSendFailLocal(sentMessage, WifiAwareNative.AWARE_STATUS_ERROR); + onMessageSendFailLocal(sentMessage, NanStatusType.INTERNAL_FAILURE); mSendQueueBlocked = false; transmitNextMessage(); break; @@ -1694,7 +1695,7 @@ public class WifiAwareStateManager { + ", due to messageEnqueueTime=" + messageEnqueueTime + ", currentTime=" + currentTime); } - onMessageSendFailLocal(message, WifiAwareNative.AWARE_STATUS_ERROR); + onMessageSendFailLocal(message, NanStatusType.INTERNAL_FAILURE); it.remove(); first = false; } else { @@ -1768,15 +1769,21 @@ public class WifiAwareStateManager { if (mCurrentAwareConfiguration != null && !mCurrentAwareConfiguration.equals(configRequest)) { try { - callback.onConnectFail(WifiAwareNative.AWARE_STATUS_ERROR); + callback.onConnectFail(NanStatusType.INTERNAL_FAILURE); } catch (RemoteException e) { Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e); } return false; } + if (VDBG) { + Log.v(TAG, "mCurrentAwareConfiguration=" + mCurrentAwareConfiguration + + ", mCurrentIdentityNotification=" + mCurrentIdentityNotification); + } + ConfigRequest merged = mergeConfigRequests(configRequest); - if (mCurrentAwareConfiguration != null && mCurrentAwareConfiguration.equals(merged)) { + if (mCurrentAwareConfiguration != null && mCurrentAwareConfiguration.equals(merged) + && mCurrentIdentityNotification == notifyIdentityChange) { try { callback.onConnectSuccess(clientId); } catch (RemoteException e) { @@ -1788,8 +1795,10 @@ public class WifiAwareStateManager { mClients.append(clientId, client); return false; } + boolean notificationRequired = + doesAnyClientNeedIdentityChangeNotifications() || notifyIdentityChange; - return mWifiAwareNative.enableAndConfigure(transactionId, merged, + return mWifiAwareNativeApi.enableAndConfigure(transactionId, merged, notificationRequired, mCurrentAwareConfiguration == null); } @@ -1809,16 +1818,19 @@ public class WifiAwareStateManager { if (mClients.size() == 0) { mCurrentAwareConfiguration = null; - mWifiAwareNative.disable((short) 0); + mWifiAwareNativeApi.disable((short) 0); return false; } ConfigRequest merged = mergeConfigRequests(null); - if (merged.equals(mCurrentAwareConfiguration)) { + boolean notificationReqs = doesAnyClientNeedIdentityChangeNotifications(); + if (merged.equals(mCurrentAwareConfiguration) + && mCurrentIdentityNotification == notificationReqs) { return false; } - return mWifiAwareNative.enableAndConfigure(transactionId, merged, false); + return mWifiAwareNativeApi.enableAndConfigure(transactionId, merged, notificationReqs, + false); } private void terminateSessionLocal(int clientId, int sessionId) { @@ -1849,7 +1861,7 @@ public class WifiAwareStateManager { return false; } - return mWifiAwareNative.publish(transactionId, 0, publishConfig); + return mWifiAwareNativeApi.publish(transactionId, 0, publishConfig); } private boolean updatePublishLocal(short transactionId, int clientId, int sessionId, @@ -1888,7 +1900,7 @@ public class WifiAwareStateManager { return false; } - return mWifiAwareNative.subscribe(transactionId, 0, subscribeConfig); + return mWifiAwareNativeApi.subscribe(transactionId, 0, subscribeConfig); } private boolean updateSubscribeLocal(short transactionId, int clientId, int sessionId, @@ -1948,8 +1960,6 @@ public class WifiAwareStateManager { return; } - mWifiAwareNative.deInitAware(); // force a re-init of Aware HAL - mUsageEnabled = true; queryCapabilities(); createAllDataPathInterfaces(); @@ -1967,8 +1977,7 @@ public class WifiAwareStateManager { deleteAllDataPathInterfaces(); mUsageEnabled = false; - mWifiAwareNative.disable((short) 0); - mWifiAwareNative.deInitAware(); + mWifiAwareNativeApi.disable((short) 0); sendAwareStateChangedBroadcast(false); } @@ -2023,7 +2032,7 @@ public class WifiAwareStateManager { + ", interfaceName=" + interfaceName + ", token=" + token); } - return mWifiAwareNative.initiateDataPath(transactionId, peerId, + return mWifiAwareNativeApi.initiateDataPath(transactionId, peerId, channelRequestType, channel, peer, interfaceName, token); } @@ -2038,7 +2047,7 @@ public class WifiAwareStateManager { byte[] tokenBytes = token.getBytes(); - return mWifiAwareNative.respondToDataPathRequest(transactionId, accept, ndpId, + return mWifiAwareNativeApi.respondToDataPathRequest(transactionId, accept, ndpId, interfaceName, tokenBytes); } @@ -2048,7 +2057,7 @@ public class WifiAwareStateManager { "endDataPathLocal: transactionId=" + transactionId + ", ndpId=" + ndpId); } - return mWifiAwareNative.endDataPath(transactionId, ndpId); + return mWifiAwareNativeApi.endDataPath(transactionId, ndpId); } /* @@ -2093,6 +2102,7 @@ public class WifiAwareStateManager { } mCurrentAwareConfiguration = mergeConfigRequests(null); + mCurrentIdentityNotification = doesAnyClientNeedIdentityChangeNotifications(); } private void onConfigFailedLocal(Message failedCommand, int reason) { @@ -2151,7 +2161,7 @@ public class WifiAwareStateManager { } WifiAwareDiscoverySessionState session = new WifiAwareDiscoverySessionState( - mWifiAwareNative, sessionId, pubSubId, callback, isPublish); + mWifiAwareNativeApi, sessionId, pubSubId, callback, isPublish); client.addSession(session); } else if (completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH || completedCommand.arg1 == COMMAND_TYPE_UPDATE_SUBSCRIBE) { @@ -2286,7 +2296,7 @@ public class WifiAwareStateManager { } } - private void onCapabilitiesUpdatedResponseLocal(WifiAwareNative.Capabilities capabilities) { + private void onCapabilitiesUpdatedResponseLocal(Capabilities capabilities) { if (VDBG) { Log.v(TAG, "onCapabilitiesUpdatedResponseLocal: capabilites=" + capabilities); } @@ -2548,6 +2558,15 @@ public class WifiAwareStateManager { .setClusterHigh(clusterHigh).build(); } + private boolean doesAnyClientNeedIdentityChangeNotifications() { + for (int i = 0; i < mClients.size(); ++i) { + if (mClients.valueAt(i).getNotifyIdentityChange()) { + return true; + } + } + return false; + } + private static String messageToString(Message msg) { StringBuilder sb = new StringBuilder(); @@ -2588,5 +2607,6 @@ public class WifiAwareStateManager { mSm.dump(fd, pw, args); mRtt.dump(fd, pw, args); mDataPathMgr.dump(fd, pw, args); + mWifiAwareNativeApi.dump(fd, pw, args); } } |