blob: 13e8e1eccbab8b6eae8fbd435679ac16b99e1706 [file] [log] [blame]
/*
* 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.nan;
import android.net.wifi.nan.ConfigRequest;
import android.net.wifi.nan.PublishConfig;
import android.net.wifi.nan.SubscribeConfig;
import android.net.wifi.nan.WifiNanEventCallback;
import android.net.wifi.nan.WifiNanSessionCallback;
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 NAN HAL.
*
* Relies on WifiNative to perform the actual HAL registration.
*/
public class WifiNanNative {
private static final String TAG = "WifiNanNative";
private static final boolean DBG = false;
private static final boolean VDBG = false; // STOPSHIP if true
private static final int WIFI_SUCCESS = 0;
private static WifiNanNative sWifiNanNativeSingleton;
private boolean mNanNativeInit = false;
private static native int registerNanNatives();
/**
* Returns the singleton WifiNanNative used to manage the actual NAN HAL
* interface.
*
* @return Singleton object.
*/
public static WifiNanNative getInstance() {
// dummy reference - used to make sure that WifiNative is loaded before
// us since it is the one to load the shared library and starts its
// initialization.
WifiNative dummy = WifiNative.getWlanNativeInterface();
if (dummy == null) {
Log.w(TAG, "can't get access to WifiNative");
return null;
}
if (sWifiNanNativeSingleton == null) {
sWifiNanNativeSingleton = new WifiNanNative();
registerNanNatives();
}
return sWifiNanNativeSingleton;
}
/**
* A container class for NAN (vendor) implementation capabilities (or
* limitations). Filled-in by the firmware.
*/
public static class Capabilities {
public int maxConcurrentNanClusters;
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;
@Override
public String toString() {
return "Capabilities [maxConcurrentNanClusters=" + maxConcurrentNanClusters
+ ", 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 initNanHandlersNative(Class<WifiNative> cls, int iface);
private static native int getCapabilitiesNative(short transactionId, Class<WifiNative> cls,
int iface);
private boolean isNanInit() {
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.
*/
mNanNativeInit = false;
return false;
} else if (!mNanNativeInit) {
int ret = initNanHandlersNative(WifiNative.class, WifiNative.sWlan0Index);
if (DBG) Log.d(TAG, "initNanHandlersNative: res=" + ret);
mNanNativeInit = ret == WIFI_SUCCESS;
if (mNanNativeInit) {
ret = getCapabilitiesNative((short) 0, WifiNative.class,
WifiNative.sWlan0Index);
if (DBG) Log.d(TAG, "getCapabilitiesNative: res=" + ret);
}
return mNanNativeInit;
} else {
return true;
}
}
}
private WifiNanNative() {
// do nothing
}
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 NAN.
*
* @param transactionId Transaction ID for the transaction - used in the
* async callback to match with the original request.
* @param configRequest Requested NAN 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 (isNanInit()) {
int ret;
if (initialConfiguration) {
synchronized (WifiNative.sLock) {
ret = enableAndConfigureNative(transactionId, WifiNative.class,
WifiNative.sWlan0Index, configRequest);
}
if (DBG) Log.d(TAG, "enableAndConfigureNative: ret=" + ret);
} else {
synchronized (WifiNative.sLock) {
ret = updateConfigurationNative(transactionId, WifiNative.class,
WifiNative.sWlan0Index, configRequest);
}
if (DBG) Log.d(TAG, "updateConfigurationNative: ret=" + ret);
}
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "enableAndConfigure: NanInit fails");
return false;
}
}
private static native int disableNative(short transactionId, Class<WifiNative> cls, int iface);
/**
* Disable NAN.
*
* @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, "disableNan");
if (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = disableNative(transactionId, WifiNative.class, WifiNative.sWlan0Index);
}
if (DBG) Log.d(TAG, "disableNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "disable: cannot initialize NAN");
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 (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = publishNative(transactionId, publishId, WifiNative.class,
WifiNative.sWlan0Index, publishConfig);
}
if (DBG) Log.d(TAG, "publishNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "publish: cannot initialize NAN");
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 (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = subscribeNative(transactionId, subscribeId, WifiNative.class,
WifiNative.sWlan0Index, subscribeConfig);
}
if (DBG) Log.d(TAG, "subscribeNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "subscribe: cannot initialize NAN");
return false;
}
}
private static native int sendMessageNative(short transactionId, Class<WifiNative> cls,
int iface, int pubSubId, int requestorInstanceId, byte[] dest, byte[] message,
int messageLength);
/**
* 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 messageLength Message byte array length.
*/
public boolean sendMessage(short transactionId, int pubSubId, int requestorInstanceId,
byte[] dest, byte[] message, int messageLength) {
if (VDBG) {
Log.d(TAG,
"sendMessage: transactionId=" + transactionId + ", pubSubId=" + pubSubId
+ ", requestorInstanceId=" + requestorInstanceId + ", dest="
+ String.valueOf(HexEncoding.encode(dest)) + ", messageLength="
+ messageLength);
}
if (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = sendMessageNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
pubSubId, requestorInstanceId, dest, message, messageLength);
}
if (DBG) Log.d(TAG, "sendMessageNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "sendMessage: cannot initialize NAN");
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 (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = stopPublishNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
pubSubId);
}
if (DBG) Log.d(TAG, "stopPublishNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "stopPublish: cannot initialize NAN");
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 (isNanInit()) {
int ret;
synchronized (WifiNative.sLock) {
ret = stopSubscribeNative(transactionId, WifiNative.class, WifiNative.sWlan0Index,
pubSubId);
}
if (DBG) Log.d(TAG, "stopSubscribeNative: ret=" + ret);
return ret == WIFI_SUCCESS;
} else {
Log.w(TAG, "stopSubscribe: cannot initialize NAN");
return false;
}
}
// EVENTS
// NanResponseType for API responses: will add values as needed
public static final int NAN_RESPONSE_ENABLED = 0;
public static final int NAN_RESPONSE_PUBLISH = 2;
public static final int NAN_RESPONSE_PUBLISH_CANCEL = 3;
public static final int NAN_RESPONSE_TRANSMIT_FOLLOWUP = 4;
public static final int NAN_RESPONSE_SUBSCRIBE = 5;
public static final int NAN_RESPONSE_SUBSCRIBE_CANCEL = 6;
public static final int NAN_RESPONSE_CONFIG = 8;
public static final int NAN_RESPONSE_GET_CAPABILITIES = 12;
// direct copy from wifi_nan.h: need to keep in sync
/* NAN Protocol Response Codes */
public static final int NAN_STATUS_SUCCESS = 0;
public static final int NAN_STATUS_TIMEOUT = 1;
public static final int NAN_STATUS_DE_FAILURE = 2;
public static final int NAN_STATUS_INVALID_MSG_VERSION = 3;
public static final int NAN_STATUS_INVALID_MSG_LEN = 4;
public static final int NAN_STATUS_INVALID_MSG_ID = 5;
public static final int NAN_STATUS_INVALID_HANDLE = 6;
public static final int NAN_STATUS_NO_SPACE_AVAILABLE = 7;
public static final int NAN_STATUS_INVALID_PUBLISH_TYPE = 8;
public static final int NAN_STATUS_INVALID_TX_TYPE = 9;
public static final int NAN_STATUS_INVALID_MATCH_ALGORITHM = 10;
public static final int NAN_STATUS_DISABLE_IN_PROGRESS = 11;
public static final int NAN_STATUS_INVALID_TLV_LEN = 12;
public static final int NAN_STATUS_INVALID_TLV_TYPE = 13;
public static final int NAN_STATUS_MISSING_TLV_TYPE = 14;
public static final int NAN_STATUS_INVALID_TOTAL_TLVS_LEN = 15;
public static final int NAN_STATUS_INVALID_MATCH_HANDLE = 16;
public static final int NAN_STATUS_INVALID_TLV_VALUE = 17;
public static final int NAN_STATUS_INVALID_TX_PRIORITY = 18;
public static final int NAN_STATUS_INVALID_CONNECTION_MAP = 19;
public static final int NAN_STATUS_INVALID_TCA_ID = 20;
public static final int NAN_STATUS_INVALID_STATS_ID = 21;
public static final int NAN_STATUS_NAN_NOT_ALLOWED = 22;
public static final int NAN_STATUS_NO_OTA_ACK = 23;
public static final int NAN_STATUS_TX_FAIL = 24;
public static final int NAN_STATUS_ALREADY_ENABLED = 25;
/* NAN Configuration Response codes */
public static final int NAN_STATUS_INVALID_RSSI_CLOSE_VALUE = 4096;
public static final int NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE = 4097;
public static final int NAN_STATUS_INVALID_HOP_COUNT_LIMIT = 4098;
public static final int NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE = 4099;
public static final int NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE = 4100;
public static final int NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE = 4101;
public static final int NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD = 4102;
public static final int NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE = 4103;
public static final int NAN_STATUS_INVALID_SCAN_CHANNEL = 4104;
public static final int NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP = 4105;
public static final int NAN_STATUS_INVALID_FA_MAP_NUMCHAN_VALUE = 4106;
public static final int NAN_STATUS_INVALID_FA_MAP_DURATION_VALUE = 4107;
public static final int NAN_STATUS_INVALID_FA_MAP_CLASS_VALUE = 4108;
public static final int NAN_STATUS_INVALID_FA_MAP_CHANNEL_VALUE = 4109;
public static final int NAN_STATUS_INVALID_FA_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE = 4110;
public static final int NAN_STATUS_INVALID_FA_MAP_MAP_ID = 4111;
public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE = 4112;
public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE = 4113;
public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE = 4114;
public static final int NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE = 4115;
public static final int NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP = 4116;
public static final int NAN_STATUS_INVALID_BAND_CONFIG_FLAGS = 4117;
public static final int NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE = 4118;
public static final int NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD = 4119;
public static final int NAN_STATUS_INVALID_DW_INTERVAL_VALUE = 4120;
public static final int NAN_STATUS_INVALID_DB_INTERVAL_VALUE = 4121;
/* publish/subscribe termination reasons */
public static final int NAN_TERMINATED_REASON_INVALID = 8192;
public static final int NAN_TERMINATED_REASON_TIMEOUT = 8193;
public static final int NAN_TERMINATED_REASON_USER_REQUEST = 8194;
public static final int NAN_TERMINATED_REASON_FAILURE = 8195;
public static final int NAN_TERMINATED_REASON_COUNT_REACHED = 8196;
public static final int NAN_TERMINATED_REASON_DE_SHUTDOWN = 8197;
public static final int NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS = 8198;
public static final int NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED = 8199;
public static final int NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED = 8200;
public static final int NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY = 8201;
/* 9000-9500 NDP Status type */
public static final int NAN_STATUS_NDP_UNSUPPORTED_CONCURRENCY = 9000;
public static final int NAN_STATUS_NDP_NAN_DATA_IFACE_CREATE_FAILED = 9001;
public static final int NAN_STATUS_NDP_NAN_DATA_IFACE_DELETE_FAILED = 9002;
public static final int NAN_STATUS_NDP_DATA_INITIATOR_REQUEST_FAILED = 9003;
public static final int NAN_STATUS_NDP_DATA_RESPONDER_REQUEST_FAILED = 9004;
public static final int NAN_STATUS_NDP_INVALID_SERVICE_INSTANCE_ID = 9005;
public static final int NAN_STATUS_NDP_INVALID_NDP_INSTANCE_ID = 9006;
public static final int NAN_STATUS_NDP_INVALID_RESPONSE_CODE = 9007;
public static final int NAN_STATUS_NDP_INVALID_APP_INFO_LEN = 9008;
/* OTA failures and timeouts during negotiation */
public static final int NAN_STATUS_NDP_MGMT_FRAME_REQUEST_FAILED = 9009;
public static final int NAN_STATUS_NDP_MGMT_FRAME_RESPONSE_FAILED = 9010;
public static final int NAN_STATUS_NDP_MGMT_FRAME_CONFIRM_FAILED = 9011;
public static final int NAN_STATUS_NDP_END_FAILED = 9012;
public static final int NAN_STATUS_NDP_MGMT_FRAME_END_REQUEST_FAILED = 9013;
/* 9500 onwards vendor specific error codes */
public static final int NAN_STATUS_NDP_VENDOR_SPECIFIC_ERROR = 9500;
private static int translateHalStatusToNanEventCallbackReason(int halStatus) {
switch (halStatus) {
case NAN_STATUS_SUCCESS:
/*
* TODO: b/27914592 all of these codes will be cleaned-up/reduced.
*/
return WifiNanEventCallback.REASON_OTHER;
case NAN_STATUS_INVALID_RSSI_CLOSE_VALUE:
case NAN_STATUS_INVALID_RSSI_MIDDLE_VALUE:
case NAN_STATUS_INVALID_HOP_COUNT_LIMIT:
case NAN_STATUS_INVALID_MASTER_PREFERENCE_VALUE:
case NAN_STATUS_INVALID_LOW_CLUSTER_ID_VALUE:
case NAN_STATUS_INVALID_HIGH_CLUSTER_ID_VALUE:
case NAN_STATUS_INVALID_BACKGROUND_SCAN_PERIOD:
case NAN_STATUS_INVALID_RSSI_PROXIMITY_VALUE:
case NAN_STATUS_INVALID_SCAN_CHANNEL:
case NAN_STATUS_INVALID_POST_NAN_CONNECTIVITY_CAPABILITIES_BITMAP:
case NAN_STATUS_INVALID_FA_MAP_NUMCHAN_VALUE:
case NAN_STATUS_INVALID_FA_MAP_DURATION_VALUE:
case NAN_STATUS_INVALID_FA_MAP_CLASS_VALUE:
case NAN_STATUS_INVALID_FA_MAP_CHANNEL_VALUE:
case NAN_STATUS_INVALID_FA_MAP_AVAILABILITY_INTERVAL_BITMAP_VALUE:
case NAN_STATUS_INVALID_FA_MAP_MAP_ID:
case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_CONN_TYPE_VALUE:
case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DEVICE_ROLE_VALUE:
case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_DURATION_VALUE:
case NAN_STATUS_INVALID_POST_NAN_DISCOVERY_BITMAP_VALUE:
case NAN_STATUS_MISSING_FUTHER_AVAILABILITY_MAP:
case NAN_STATUS_INVALID_BAND_CONFIG_FLAGS:
case NAN_STATUS_INVALID_RANDOM_FACTOR_UPDATE_TIME_VALUE:
case NAN_STATUS_INVALID_ONGOING_SCAN_PERIOD:
case NAN_STATUS_INVALID_DW_INTERVAL_VALUE:
case NAN_STATUS_INVALID_DB_INTERVAL_VALUE:
return WifiNanEventCallback.REASON_INVALID_ARGS;
}
return WifiNanEventCallback.REASON_OTHER;
}
private static int translateHalStatusToNanSessionCallbackTerminate(int halStatus) {
switch (halStatus) {
case NAN_TERMINATED_REASON_TIMEOUT:
case NAN_TERMINATED_REASON_USER_REQUEST:
case NAN_TERMINATED_REASON_COUNT_REACHED:
return WifiNanSessionCallback.TERMINATE_REASON_DONE;
case NAN_TERMINATED_REASON_INVALID:
case NAN_TERMINATED_REASON_FAILURE:
case NAN_TERMINATED_REASON_DE_SHUTDOWN:
case NAN_TERMINATED_REASON_DISABLE_IN_PROGRESS:
case NAN_TERMINATED_REASON_POST_DISC_ATTR_EXPIRED:
case NAN_TERMINATED_REASON_POST_DISC_LEN_EXCEEDED:
case NAN_TERMINATED_REASON_FURTHER_AVAIL_MAP_EMPTY:
return WifiNanSessionCallback.TERMINATE_REASON_FAIL;
}
return WifiNanSessionCallback.TERMINATE_REASON_FAIL;
}
private static int translateHalStatusToNanSessionCallbackReason(int halStatus) {
switch (halStatus) {
case NAN_STATUS_TIMEOUT:
case NAN_STATUS_DE_FAILURE:
case NAN_STATUS_INVALID_MSG_VERSION:
case NAN_STATUS_INVALID_MSG_LEN:
case NAN_STATUS_INVALID_MSG_ID:
case NAN_STATUS_INVALID_HANDLE:
return WifiNanSessionCallback.REASON_OTHER;
case NAN_STATUS_NO_SPACE_AVAILABLE:
return WifiNanSessionCallback.REASON_NO_RESOURCES;
case NAN_STATUS_INVALID_PUBLISH_TYPE:
case NAN_STATUS_INVALID_TX_TYPE:
case NAN_STATUS_INVALID_MATCH_ALGORITHM:
return WifiNanSessionCallback.REASON_INVALID_ARGS;
case NAN_STATUS_DISABLE_IN_PROGRESS:
case NAN_STATUS_INVALID_TLV_LEN:
case NAN_STATUS_INVALID_TLV_TYPE:
case NAN_STATUS_MISSING_TLV_TYPE:
case NAN_STATUS_INVALID_TOTAL_TLVS_LEN:
case NAN_STATUS_INVALID_MATCH_HANDLE:
case NAN_STATUS_INVALID_TLV_VALUE:
case NAN_STATUS_INVALID_TX_PRIORITY:
case NAN_STATUS_INVALID_CONNECTION_MAP:
case NAN_STATUS_INVALID_TCA_ID:
case NAN_STATUS_INVALID_STATS_ID:
case NAN_STATUS_NAN_NOT_ALLOWED:
return WifiNanSessionCallback.REASON_OTHER;
case NAN_STATUS_NO_OTA_ACK:
case NAN_STATUS_TX_FAIL:
return WifiNanSessionCallback.REASON_TX_FAIL;
}
return WifiNanSessionCallback.REASON_OTHER;
}
// callback from native
private static void onNanNotifyResponse(short transactionId, int responseType, int status,
int value) {
if (VDBG) {
Log.v(TAG,
"onNanNotifyResponse: transactionId=" + transactionId + ", responseType="
+ responseType + ", status=" + status + ", value=" + value);
}
WifiNanStateManager stateMgr = WifiNanStateManager.getInstance();
switch (responseType) {
case NAN_RESPONSE_ENABLED:
/* fall through */
case NAN_RESPONSE_CONFIG:
if (status == NAN_STATUS_SUCCESS) {
stateMgr.onConfigSuccessResponse(transactionId);
} else {
stateMgr.onConfigFailedResponse(transactionId,
translateHalStatusToNanEventCallbackReason(status));
}
break;
case NAN_RESPONSE_PUBLISH_CANCEL:
if (status != NAN_STATUS_SUCCESS) {
Log.e(TAG, "onNanNotifyResponse: NAN_RESPONSE_PUBLISH_CANCEL error - status="
+ status + ", value=" + value);
}
break;
case NAN_RESPONSE_TRANSMIT_FOLLOWUP:
if (status == NAN_STATUS_SUCCESS) {
stateMgr.onMessageSendQueuedSuccessResponse(transactionId);
} else {
stateMgr.onMessageSendQueuedFailResponse(transactionId,
translateHalStatusToNanSessionCallbackReason(status));
}
break;
case NAN_RESPONSE_SUBSCRIBE_CANCEL:
if (status != NAN_STATUS_SUCCESS) {
Log.e(TAG, "onNanNotifyResponse: NAN_RESPONSE_PUBLISH_CANCEL error - status="
+ status + ", value=" + value);
}
break;
default:
Log.e(TAG, "onNanNotifyResponse: unclassified responseType=" + responseType);
break;
}
}
private static void onNanNotifyResponsePublishSubscribe(short transactionId, int responseType,
int status, int value, int pubSubId) {
if (VDBG) {
Log.v(TAG,
"onNanNotifyResponsePublishSubscribe: transactionId=" + transactionId
+ ", responseType=" + responseType + ", status=" + status + ", value="
+ value + ", pubSubId=" + pubSubId);
}
switch (responseType) {
case NAN_RESPONSE_PUBLISH:
if (status == NAN_STATUS_SUCCESS) {
WifiNanStateManager.getInstance().onSessionConfigSuccessResponse(transactionId,
true, pubSubId);
} else {
WifiNanStateManager.getInstance().onSessionConfigFailResponse(transactionId,
true, translateHalStatusToNanSessionCallbackReason(status));
}
break;
case NAN_RESPONSE_SUBSCRIBE:
if (status == NAN_STATUS_SUCCESS) {
WifiNanStateManager.getInstance().onSessionConfigSuccessResponse(transactionId,
false, pubSubId);
} else {
WifiNanStateManager.getInstance().onSessionConfigFailResponse(transactionId,
false, translateHalStatusToNanSessionCallbackReason(status));
}
break;
default:
Log.wtf(TAG, "onNanNotifyResponsePublishSubscribe: unclassified responseType="
+ responseType);
break;
}
}
private static void onNanNotifyResponseCapabilities(short transactionId, int status, int value,
Capabilities capabilities) {
if (VDBG) {
Log.v(TAG, "onNanNotifyResponsePublishSubscribe: transactionId=" + transactionId
+ ", status=" + status + ", value=" + value + ", capabilities=" + capabilities);
}
if (status == NAN_STATUS_SUCCESS) {
WifiNanStateManager.getInstance().onCapabilitiesUpdateNotification(capabilities);
} else {
Log.e(TAG,
"onNanNotifyResponseCapabilities: error status=" + status + ", value=" + value);
}
}
public static final int NAN_EVENT_ID_DISC_MAC_ADDR = 0;
public static final int NAN_EVENT_ID_STARTED_CLUSTER = 1;
public static final int NAN_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 == NAN_EVENT_ID_DISC_MAC_ADDR) {
WifiNanStateManager.getInstance().onInterfaceAddressChangeNotification(mac);
} else if (eventType == NAN_EVENT_ID_STARTED_CLUSTER) {
WifiNanStateManager.getInstance().onClusterChangeNotification(
WifiNanClientState.CLUSTER_CHANGE_EVENT_STARTED, mac);
} else if (eventType == NAN_EVENT_ID_JOINED_CLUSTER) {
WifiNanStateManager.getInstance().onClusterChangeNotification(
WifiNanClientState.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, int serviceSpecificInfoLength, byte[] matchFilter,
int matchFilterLength) {
if (VDBG) {
Log.v(TAG, "onMatchEvent: pubSubId=" + pubSubId + ", requestorInstanceId="
+ requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))
+ ", serviceSpecificInfo=" + Arrays.toString(serviceSpecificInfo)
+ ", matchFilterLength=" + matchFilterLength + ", matchFilter="
+ Arrays.toString(matchFilter));
}
WifiNanStateManager.getInstance().onMatchNotification(pubSubId, requestorInstanceId, mac,
serviceSpecificInfo, serviceSpecificInfoLength, matchFilter, matchFilterLength);
}
// callback from native
private static void onPublishTerminated(int publishId, int status) {
if (VDBG) Log.v(TAG, "onPublishTerminated: publishId=" + publishId + ", status=" + status);
WifiNanStateManager.getInstance().onSessionTerminatedNotification(publishId,
translateHalStatusToNanSessionCallbackTerminate(status), true);
}
// callback from native
private static void onSubscribeTerminated(int subscribeId, int status) {
if (VDBG) {
Log.v(TAG, "onSubscribeTerminated: subscribeId=" + subscribeId + ", status=" + status);
}
WifiNanStateManager.getInstance().onSessionTerminatedNotification(subscribeId,
translateHalStatusToNanSessionCallbackTerminate(status), false);
}
// callback from native
private static void onFollowupEvent(int pubSubId, int requestorInstanceId, byte[] mac,
byte[] message, int messageLength) {
if (VDBG) {
Log.v(TAG, "onFollowupEvent: pubSubId=" + pubSubId + ", requestorInstanceId="
+ requestorInstanceId + ", mac=" + String.valueOf(HexEncoding.encode(mac))
+ ", messageLength=" + messageLength);
}
WifiNanStateManager.getInstance().onMessageReceivedNotification(pubSubId,
requestorInstanceId, mac, message, messageLength);
}
// callback from native
private static void onDisabledEvent(int status) {
if (VDBG) Log.v(TAG, "onDisabledEvent: status=" + status);
WifiNanStateManager.getInstance()
.onNanDownNotification(translateHalStatusToNanEventCallbackReason(status));
}
// callback from native
private static void onTransmitFollowupEvent(short transactionId, int reason) {
if (VDBG) {
Log.v(TAG, "onTransmitFollowupEvent: transactionId=" + transactionId + ", reason="
+ reason);
}
if (reason == NAN_STATUS_SUCCESS) {
WifiNanStateManager.getInstance().onMessageSendSuccessNotification(transactionId);
} else {
WifiNanStateManager.getInstance().onMessageSendFailNotification(transactionId,
translateHalStatusToNanSessionCallbackReason(reason));
}
}
}