1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.wifi.aware; 18 19 import static android.Manifest.permission.ACCESS_WIFI_STATE; 20 import static android.net.wifi.WifiAvailableChannel.OP_MODE_WIFI_AWARE; 21 import static android.net.wifi.aware.Characteristics.WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128; 22 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_RESUME_INTERNAL_ERROR; 23 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_RESUME_INVALID_SESSION; 24 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_RESUME_REDUNDANT_REQUEST; 25 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_SUSPEND_CANNOT_SUSPEND; 26 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_SUSPEND_INTERNAL_ERROR; 27 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_SUSPEND_INVALID_SESSION; 28 import static android.net.wifi.aware.WifiAwareManager.WIFI_AWARE_SUSPEND_REDUNDANT_REQUEST; 29 30 import static com.android.server.wifi.WifiSettingsConfigStore.D2D_ALLOWED_WHEN_INFRA_STA_DISABLED; 31 import static com.android.server.wifi.aware.WifiAwareMetrics.convertNanStatusCodeToWifiStatsLogEnum; 32 import static com.android.server.wifi.hal.WifiNanIface.NanStatusCode.NOT_SUPPORTED; 33 import static com.android.server.wifi.hal.WifiNanIface.NanStatusCode.NO_CONNECTION; 34 import static com.android.server.wifi.hal.WifiNanIface.NanStatusCode.REDUNDANT_REQUEST; 35 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_CAPABILITIES; 36 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED; 37 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_API_UNKNOWN; 38 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_CONFIG_REQUEST; 39 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_CREATE_DATA_INTERFACE_REQUEST; 40 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_DELETE_DATA_INTERFACE_REQUEST; 41 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_DISABLE_REQUEST; 42 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_ENABLE_REQUEST; 43 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_GET_CAPABILITIES_REQUEST; 44 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_BOOTSTRAPPING_REQUEST; 45 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_DATA_PATH_REQUEST; 46 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_PAIRING_REQUEST; 47 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_BOOTSTRAPPING_INDICATION_REQUEST; 48 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_DATA_PATH_INDICATION_REQUEST; 49 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_PAIRING_INDICATION_REQUEST; 50 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESUME_REQUEST; 51 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_START_PUBLISH_REQUEST; 52 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_START_SUBSCRIBE_REQUEST; 53 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_SUSPEND_REQUEST; 54 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TERMINATE_DATA_PATH_REQUEST; 55 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TERMINATE_PAIRING_REQUEST; 56 import static com.android.server.wifi.proto.WifiStatsLog.WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TRANSMIT_FOLLOW_UP_REQUEST; 57 58 import android.annotation.NonNull; 59 import android.annotation.Nullable; 60 import android.app.StatsManager; 61 import android.content.AttributionSource; 62 import android.content.BroadcastReceiver; 63 import android.content.Context; 64 import android.content.Intent; 65 import android.content.IntentFilter; 66 import android.hardware.wifi.V1_0.WifiStatusCode; 67 import android.location.LocationManager; 68 import android.net.MacAddress; 69 import android.net.wifi.IBooleanListener; 70 import android.net.wifi.IIntegerListener; 71 import android.net.wifi.IListListener; 72 import android.net.wifi.OuiKeyedData; 73 import android.net.wifi.WifiAvailableChannel; 74 import android.net.wifi.WifiManager; 75 import android.net.wifi.WifiScanner; 76 import android.net.wifi.aware.AwarePairingConfig; 77 import android.net.wifi.aware.AwareParams; 78 import android.net.wifi.aware.AwareResources; 79 import android.net.wifi.aware.Characteristics; 80 import android.net.wifi.aware.ConfigRequest; 81 import android.net.wifi.aware.IWifiAwareDiscoverySessionCallback; 82 import android.net.wifi.aware.IWifiAwareEventCallback; 83 import android.net.wifi.aware.IWifiAwareMacAddressProvider; 84 import android.net.wifi.aware.IdentityChangedListener; 85 import android.net.wifi.aware.MacAddrMapping; 86 import android.net.wifi.aware.PublishConfig; 87 import android.net.wifi.aware.SubscribeConfig; 88 import android.net.wifi.aware.WifiAwareChannelInfo; 89 import android.net.wifi.aware.WifiAwareDataPathSecurityConfig; 90 import android.net.wifi.aware.WifiAwareManager; 91 import android.net.wifi.aware.WifiAwareNetworkSpecifier; 92 import android.net.wifi.rtt.RangingResult; 93 import android.net.wifi.util.HexEncoding; 94 import android.os.Bundle; 95 import android.os.Handler; 96 import android.os.Looper; 97 import android.os.Message; 98 import android.os.PowerManager; 99 import android.os.Process; 100 import android.os.RemoteException; 101 import android.os.SystemClock; 102 import android.os.UserHandle; 103 import android.os.WorkSource; 104 import android.text.TextUtils; 105 import android.util.ArraySet; 106 import android.util.Log; 107 import android.util.Pair; 108 import android.util.SparseArray; 109 import android.util.StatsEvent; 110 111 import com.android.internal.annotations.VisibleForTesting; 112 import com.android.internal.util.MessageUtils; 113 import com.android.internal.util.StateMachine; 114 import com.android.internal.util.WakeupMessage; 115 import com.android.modules.utils.BasicShellCommandHandler; 116 import com.android.modules.utils.HandlerExecutor; 117 import com.android.modules.utils.build.SdkLevel; 118 import com.android.server.wifi.Clock; 119 import com.android.server.wifi.HalDeviceManager; 120 import com.android.server.wifi.InterfaceConflictManager; 121 import com.android.server.wifi.RunnerState; 122 import com.android.server.wifi.WifiGlobals; 123 import com.android.server.wifi.WifiInjector; 124 import com.android.server.wifi.WifiSettingsConfigStore; 125 import com.android.server.wifi.aware.PairingConfigManager.PairingSecurityAssociationInfo; 126 import com.android.server.wifi.hal.WifiNanIface.NanStatusCode; 127 import com.android.server.wifi.proto.WifiStatsLog; 128 import com.android.server.wifi.util.NetdWrapper; 129 import com.android.server.wifi.util.WaitingState; 130 import com.android.server.wifi.util.WifiPermissionsUtil; 131 import com.android.server.wifi.util.WifiPermissionsWrapper; 132 import com.android.wifi.flags.FeatureFlags; 133 import com.android.wifi.resources.R; 134 135 import org.json.JSONException; 136 import org.json.JSONObject; 137 138 import java.io.FileDescriptor; 139 import java.io.PrintWriter; 140 import java.util.ArrayList; 141 import java.util.Arrays; 142 import java.util.HashMap; 143 import java.util.Iterator; 144 import java.util.LinkedHashMap; 145 import java.util.List; 146 import java.util.Map; 147 import java.util.Set; 148 import java.util.concurrent.Executor; 149 import java.util.function.Consumer; 150 151 /** 152 * Manages the state of the Wi-Fi Aware system service. 153 */ 154 public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShellCommand { 155 private static final String TAG = "WifiAwareStateManager"; 156 private boolean mVdbg = false; // STOPSHIP if true - for detailed state machine 157 private boolean mVerboseLoggingEnabled = false; 158 private static final short NUM_LOG_RECS = 256; 159 private static final short NUM_LOG_RECS_VERBOSE = 1024; 160 161 @VisibleForTesting 162 public static final String HAL_COMMAND_TIMEOUT_TAG = TAG + " HAL Command Timeout"; 163 164 @VisibleForTesting 165 public static final String HAL_SEND_MESSAGE_TIMEOUT_TAG = TAG + " HAL Send Message Timeout"; 166 167 @VisibleForTesting 168 public static final String HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG = 169 TAG + " HAL Data Path Confirm Timeout"; 170 @VisibleForTesting 171 public static final String HAL_PAIRING_CONFIRM_TIMEOUT_TAG = 172 TAG + " HAL Pairing Confirm Timeout"; 173 @VisibleForTesting 174 public static final String HAL_BOOTSTRAPPING_CONFIRM_TIMEOUT_TAG = 175 TAG + " HAL Bootstrapping Confirm Timeout"; 176 177 public static final int NAN_PAIRING_REQUEST_TYPE_SETUP = 0; 178 public static final int NAN_PAIRING_REQUEST_TYPE_VERIFICATION = 1; 179 public static final int NAN_PAIRING_AKM_SAE = 0; 180 public static final int NAN_PAIRING_AKM_PASN = 1; 181 public static final int NAN_BOOTSTRAPPING_ACCEPT = 0; 182 public static final int NAN_BOOTSTRAPPING_REJECT = 1; 183 public static final int NAN_BOOTSTRAPPING_COMEBACK = 2; 184 185 186 public static final int NAN_PARAM_NOT_SET = -1; 187 188 public static final int INSTANT_MODE_DISABLED = 0; 189 public static final int INSTANT_MODE_24GHZ = 1; 190 public static final int INSTANT_MODE_5GHZ = 3; 191 192 /* 193 * State machine message types. There are sub-types for the messages (except for TIMEOUTs). 194 * Format: 195 * - Message.arg1: contains message sub-type 196 * - Message.arg2: contains transaction ID for RESPONSE & RESPONSE_TIMEOUT 197 */ 198 private static final int MESSAGE_TYPE_COMMAND = 1; 199 private static final int MESSAGE_TYPE_RESPONSE = 2; 200 private static final int MESSAGE_TYPE_NOTIFICATION = 3; 201 private static final int MESSAGE_TYPE_RESPONSE_TIMEOUT = 4; 202 private static final int MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT = 5; 203 private static final int MESSAGE_TYPE_DATA_PATH_TIMEOUT = 6; 204 private static final int MESSAGE_TYPE_PAIRING_TIMEOUT = 7; 205 private static final int MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT = 8; 206 207 /* 208 * Message sub-types: 209 */ 210 private static final int COMMAND_TYPE_CONNECT = 100; 211 private static final int COMMAND_TYPE_DISCONNECT = 101; 212 private static final int COMMAND_TYPE_TERMINATE_SESSION = 102; 213 private static final int COMMAND_TYPE_PUBLISH = 103; 214 private static final int COMMAND_TYPE_UPDATE_PUBLISH = 104; 215 private static final int COMMAND_TYPE_SUBSCRIBE = 105; 216 private static final int COMMAND_TYPE_UPDATE_SUBSCRIBE = 106; 217 private static final int COMMAND_TYPE_ENQUEUE_SEND_MESSAGE = 107; 218 private static final int COMMAND_TYPE_ENABLE_USAGE = 108; 219 private static final int COMMAND_TYPE_DISABLE_USAGE = 109; 220 private static final int COMMAND_TYPE_GET_CAPABILITIES = 111; 221 private static final int COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES = 113; 222 private static final int COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE = 114; 223 private static final int COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE = 115; 224 private static final int COMMAND_TYPE_INITIATE_DATA_PATH_SETUP = 116; 225 private static final int COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST = 117; 226 private static final int COMMAND_TYPE_END_DATA_PATH = 118; 227 private static final int COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE = 119; 228 private static final int COMMAND_TYPE_RECONFIGURE = 120; 229 private static final int COMMAND_TYPE_DELAYED_INITIALIZATION = 121; 230 private static final int COMMAND_TYPE_GET_AWARE = 122; 231 private static final int COMMAND_TYPE_RELEASE_AWARE = 123; 232 private static final int COMMAND_TYPE_DISABLE = 124; 233 private static final int COMMAND_TYPE_INITIATE_PAIRING_REQUEST = 125; 234 private static final int COMMAND_TYPE_RESPONSE_PAIRING_REQUEST = 126; 235 private static final int COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST = 127; 236 private static final int COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST = 128; 237 private static final int COMMAND_TYPE_SUSPEND_SESSION = 129; 238 private static final int COMMAND_TYPE_RESUME_SESSION = 130; 239 private static final int COMMAND_TYPE_END_PAIRING = 131; 240 241 private static final int RESPONSE_TYPE_ON_CONFIG_SUCCESS = 200; 242 private static final int RESPONSE_TYPE_ON_CONFIG_FAIL = 201; 243 private static final int RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS = 202; 244 private static final int RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL = 203; 245 private static final int RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS = 204; 246 private static final int RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL = 205; 247 private static final int RESPONSE_TYPE_ON_CAPABILITIES_UPDATED = 206; 248 private static final int RESPONSE_TYPE_ON_CREATE_INTERFACE = 207; 249 private static final int RESPONSE_TYPE_ON_DELETE_INTERFACE = 208; 250 private static final int RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS = 209; 251 private static final int RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL = 210; 252 private static final int RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST = 211; 253 private static final int RESPONSE_TYPE_ON_END_DATA_PATH = 212; 254 private static final int RESPONSE_TYPE_ON_DISABLE = 213; 255 private static final int RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS = 214; 256 private static final int RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL = 215; 257 private static final int RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS = 216; 258 private static final int RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL = 217; 259 private static final int RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS = 218; 260 private static final int RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL = 219; 261 private static final int RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS = 220; 262 private static final int RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL = 221; 263 private static final int RESPONSE_TYPE_ON_SUSPEND = 222; 264 private static final int RESPONSE_TYPE_ON_RESUME = 223; 265 private static final int RESPONSE_TYPE_ON_END_PAIRING = 224; 266 267 private static final int NOTIFICATION_TYPE_INTERFACE_CHANGE = 301; 268 private static final int NOTIFICATION_TYPE_CLUSTER_CHANGE = 302; 269 private static final int NOTIFICATION_TYPE_MATCH = 303; 270 private static final int NOTIFICATION_TYPE_SESSION_TERMINATED = 304; 271 private static final int NOTIFICATION_TYPE_MESSAGE_RECEIVED = 305; 272 private static final int NOTIFICATION_TYPE_AWARE_DOWN = 306; 273 private static final int NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS = 307; 274 private static final int NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL = 308; 275 private static final int NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST = 309; 276 private static final int NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM = 310; 277 private static final int NOTIFICATION_TYPE_ON_DATA_PATH_END = 311; 278 private static final int NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE = 312; 279 private static final int NOTIFICATION_TYPE_MATCH_EXPIRED = 313; 280 private static final int NOTIFICATION_TYPE_ON_PAIRING_REQUEST = 314; 281 private static final int NOTIFICATION_TYPE_ON_PAIRING_CONFIRM = 315; 282 private static final int NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST = 316; 283 private static final int NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM = 317; 284 private static final int NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED = 318; 285 private static final int NOTIFICATION_TYPE_RANGING_RESULTS = 319; 286 287 private static final SparseArray<String> sSmToString = MessageUtils.findMessageNames( 288 new Class[]{WifiAwareStateManager.class}, 289 new String[]{"MESSAGE_TYPE", "COMMAND_TYPE", "RESPONSE_TYPE", "NOTIFICATION_TYPE"}); 290 291 /* 292 * Keys used when passing (some) arguments to the Handler thread (too many 293 * arguments to pass in the short-cut Message members). 294 */ 295 private static final String MESSAGE_BUNDLE_KEY_SESSION_TYPE = "session_type"; 296 private static final String MESSAGE_BUNDLE_KEY_SESSION_ID = "session_id"; 297 private static final String MESSAGE_BUNDLE_KEY_CONFIG = "config"; 298 private static final String MESSAGE_BUNDLE_KEY_MESSAGE = "message"; 299 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID = "message_peer_id"; 300 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ID = "message_id"; 301 private static final String MESSAGE_BUNDLE_KEY_SSI_DATA = "ssi_data"; 302 private static final String MESSAGE_BUNDLE_KEY_FILTER_DATA = "filter_data"; 303 private static final String MESSAGE_BUNDLE_KEY_MAC_ADDRESS = "mac_address"; 304 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_DATA = "message_data"; 305 private static final String MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID = "req_instance_id"; 306 private static final String MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME = "message_queue_time"; 307 private static final String MESSAGE_BUNDLE_KEY_RETRY_COUNT = "retry_count"; 308 private static final String MESSAGE_BUNDLE_KEY_SUCCESS_FLAG = "success_flag"; 309 private static final String MESSAGE_BUNDLE_KEY_STATUS_CODE = "status_code"; 310 private static final String MESSAGE_BUNDLE_KEY_INTERFACE_NAME = "interface_name"; 311 private static final String MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE = "channel_request_type"; 312 private static final String MESSAGE_BUNDLE_KEY_CHANNEL = "channel"; 313 private static final String MESSAGE_BUNDLE_KEY_PEER_ID = "peer_id"; 314 private static final String MESSAGE_BUNDLE_KEY_UID = "uid"; 315 private static final String MESSAGE_BUNDLE_KEY_PID = "pid"; 316 private static final String MESSAGE_BUNDLE_KEY_CALLING_PACKAGE = "calling_package"; 317 private static final String MESSAGE_BUNDLE_KEY_CALLING_FEATURE_ID = "calling_feature_id"; 318 private static final String MESSAGE_BUNDLE_KEY_SENT_MESSAGE = "send_message"; 319 private static final String MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ = "message_arrival_seq"; 320 private static final String MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE = "notify_identity_chg"; 321 private static final String MESSAGE_BUNDLE_KEY_SCID = "scid"; 322 private static final String MESSAGE_BUNDLE_KEY_CIPHER_SUITE = "cipher_suite"; 323 private static final String MESSAGE_BUNDLE_KEY_OOB = "out_of_band"; 324 private static final String MESSAGE_RANGING_INDICATION = "ranging_indication"; 325 private static final String MESSAGE_RANGE_MM = "range_mm"; 326 private static final String MESSAGE_BUNDLE_KEY_NDP_IDS = "ndp_ids"; 327 private static final String MESSAGE_BUNDLE_KEY_NDP_ID = "ndp_id"; 328 private static final String MESSAGE_BUNDLE_KEY_APP_INFO = "app_info"; 329 private static final String MESSAGE_BUNDLE_KEY_ACCEPT_STATE = "accept_state"; 330 private static final String MESSAGE_BUNDLE_KEY_NONCE = "nonce"; 331 private static final String MESSAGE_BUNDLE_KEY_TAG = "tag"; 332 private static final String MESSAGE_BUNDLE_KEY_PAIRING_CONFIG = "pairing_config"; 333 private static final String MESSAGE_BUNDLE_KEY_PAIRING_PASSWORD = "pairing_password"; 334 private static final String MESSAGE_BUNDLE_KEY_PAIRING_ALIAS = "pairing_alias"; 335 private static final String MESSAGE_BUNDLE_KEY_PAIRING_TYPE = "pairing_type"; 336 private static final String MESSAGE_BUNDLE_KEY_PAIRING_AKM = "pairing_akm"; 337 private static final String MESSAGE_BUNDLE_KEY_PAIRING_CIPHER_SUITE = "pairing_cipher_suite"; 338 private static final String MESSAGE_BUNDLE_KEY_PAIRING_PMK = "pairing_pmk"; 339 private static final String MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID = "pairing_request_id"; 340 private static final String MESSAGE_BUNDLE_KEY_PAIRING_ACCEPT = "pairing_accept"; 341 private static final String MESSAGE_BUNDLE_KEY_PAIRING_CACHE = "pairing_cache"; 342 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD = "bootstrapping_method"; 343 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID = 344 "bootstrapping_request_id"; 345 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_ACCEPT = "bootstrapping_accept"; 346 private static final String MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD = "aware_offload"; 347 private static final String MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD = 348 "aware_re_enable_from_offload"; 349 private static final String MESSAGE_BUNDLE_KEY_SUSPENSION_MODE = "suspension_mode"; 350 351 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_RESPONSE_CODE = 352 "bootstrapping_response_state"; 353 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_DELAY = 354 "bootstrapping_come_back_delay"; 355 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE = 356 "bootstrapping_come_back_cookie"; 357 private static final String MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST = 358 "bootstrapping_is_come_back"; 359 private static final String MESSAGE_BUNDLE_KEY_CALLER_TYPE = "caller_type"; 360 private static final String MESSAGE_BUNDLE_KEY_VENDOR_DATA = "vendor_data"; 361 private WifiAwareNativeApi mWifiAwareNativeApi; 362 private WifiAwareNativeManager mWifiAwareNativeManager; 363 364 /* 365 * Asynchronous access with no lock 366 */ 367 private volatile boolean mUsageEnabled = false; 368 369 /* 370 * Synchronous access: state is only accessed through the state machine 371 * handler thread: no need to use a lock. 372 */ 373 private Context mContext; 374 private WifiAwareMetrics mAwareMetrics; 375 private WifiPermissionsUtil mWifiPermissionsUtil; 376 private volatile Capabilities mCapabilities; 377 private volatile Characteristics mCharacteristics = null; 378 private WifiAwareStateMachine mSm; 379 public WifiAwareDataPathStateManager mDataPathMgr; 380 private PowerManager mPowerManager; 381 private InterfaceConflictManager mInterfaceConflictMgr; 382 private WifiManager mWifiManager; 383 private Handler mHandler; 384 private final WifiInjector mWifiInjector; 385 private final PairingConfigManager mPairingConfigManager; 386 private final WifiSettingsConfigStore mSettingsConfigStore; 387 private final WifiGlobals mWifiGlobals; 388 private final FeatureFlags mFeatureFlags; 389 390 private final SparseArray<WifiAwareClientState> mClients = new SparseArray<>(); 391 private ConfigRequest mCurrentAwareConfiguration = null; 392 private boolean mCurrentIdentityNotification = false; 393 private boolean mCurrentRangingEnabled = false; 394 private boolean mInstantCommModeGlobalEnable = false; 395 private int mOverrideInstantMode = INSTANT_MODE_DISABLED; 396 private int mInstantCommModeClientRequest = INSTANT_MODE_DISABLED; 397 private int mClusterIdInt = NAN_PARAM_NOT_SET; // -1 is not set. 398 private static final int AWARE_BAND_2_INSTANT_COMMUNICATION_CHANNEL_FREQ = 2437; // Channel 6 399 private int mAwareBand5InstantCommunicationChannelFreq = 400 NAN_PARAM_NOT_SET; // -1 is not set, 0 is unsupported. 401 private static final int AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_149 = 5745; 402 private static final int AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_44 = 5220; 403 404 private static final byte[] ALL_ZERO_MAC = new byte[] {0, 0, 0, 0, 0, 0}; 405 private byte[] mCurrentDiscoveryInterfaceMac = ALL_ZERO_MAC; 406 private byte[] mClusterId = ALL_ZERO_MAC; 407 private int mClusterEventType = -1; 408 // Flag to help defer the connect request when disable Aware is not finished, to prevent race 409 // condition. 410 private boolean mAwareIsDisabling = false; 411 private final SparseArray<PairingInfo> mPairingRequest = new SparseArray<>(); 412 private final SparseArray<BootStrppingInfo> mBootstrappingRequest = new SparseArray<>(); 413 private WifiAwarePullAtomCallback mWifiAwarePullAtomCallback = null; 414 415 private long mStartTime; 416 417 private static class PairingInfo { 418 public final int mClientId; 419 public final int mSessionId; 420 public final int mPeerId; 421 public final String mAlias; 422 PairingInfo(int clientId, int sessionId, int peerId, String alias)423 PairingInfo(int clientId, int sessionId, int peerId, String alias) { 424 mClientId = clientId; 425 mSessionId = sessionId; 426 mPeerId = peerId; 427 mAlias = alias; 428 } 429 } 430 431 private static class BootStrppingInfo { 432 public final int mClientId; 433 public final int mSessionId; 434 public final int mPeerId; 435 public final int mMethod; 436 public final boolean mIsComeBackFollowUp; 437 BootStrppingInfo(int clientId, int sessionId, int peerId, int method, boolean isComeBackFollowUp)438 BootStrppingInfo(int clientId, int sessionId, int peerId, int method, 439 boolean isComeBackFollowUp) { 440 mClientId = clientId; 441 mSessionId = sessionId; 442 mPeerId = peerId; 443 mMethod = method; 444 mIsComeBackFollowUp = isComeBackFollowUp; 445 } 446 } 447 WifiAwareStateManager(WifiInjector wifiInjector, PairingConfigManager pairingConfigManager)448 public WifiAwareStateManager(WifiInjector wifiInjector, 449 PairingConfigManager pairingConfigManager) { 450 mWifiInjector = wifiInjector; 451 mPairingConfigManager = pairingConfigManager; 452 mWifiGlobals = mWifiInjector.getWifiGlobals(); 453 mFeatureFlags = mWifiInjector.getDeviceConfigFacade().getFeatureFlags(); 454 mSettingsConfigStore = mWifiInjector.getSettingsConfigStore(); 455 onReset(); 456 } 457 458 /** 459 * Enable/Disable verbose logging. 460 */ enableVerboseLogging(boolean verboseEnabled, boolean halVerboseLogging, boolean vDbg)461 public void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseLogging, 462 boolean vDbg) { 463 mVerboseLoggingEnabled = verboseEnabled; 464 mDataPathMgr.enableVerboseLogging(verboseEnabled, vDbg); 465 mVdbg = vDbg; 466 mSm.setLogRecSize(verboseEnabled ? NUM_LOG_RECS_VERBOSE : NUM_LOG_RECS); 467 } 468 469 /** 470 * Inject references to other manager objects. Needed to resolve 471 * circular dependencies and to allow mocking. 472 */ setNative(WifiAwareNativeManager wifiAwareNativeManager, WifiAwareNativeApi wifiAwareNativeApi)473 public void setNative(WifiAwareNativeManager wifiAwareNativeManager, 474 WifiAwareNativeApi wifiAwareNativeApi) { 475 mWifiAwareNativeManager = wifiAwareNativeManager; 476 mWifiAwareNativeApi = wifiAwareNativeApi; 477 } 478 479 /* 480 * parameters settable through shell command 481 */ 482 public static final String PARAM_ON_IDLE_DISABLE_AWARE = "on_idle_disable_aware"; 483 public static final int PARAM_ON_IDLE_DISABLE_AWARE_DEFAULT = 1; // 0 = false, 1 = true 484 485 private final Map<String, Integer> mSettableParameters = new HashMap<>(); 486 487 private final Set<String> mOpportunisticSet = new ArraySet<>(); 488 489 /** 490 * Interpreter of adb shell command 'adb shell wifiaware native_api ...'. 491 * 492 * @return -1 if parameter not recognized or invalid value, 0 otherwise. 493 */ 494 @Override onCommand(BasicShellCommandHandler parentShell)495 public int onCommand(BasicShellCommandHandler parentShell) { 496 final PrintWriter pw_err = parentShell.getErrPrintWriter(); 497 final PrintWriter pw_out = parentShell.getOutPrintWriter(); 498 499 String subCmd = parentShell.getNextArgRequired(); 500 switch (subCmd) { 501 case "set": { 502 String name = parentShell.getNextArgRequired(); 503 if (!mSettableParameters.containsKey(name)) { 504 pw_err.println("Unknown parameter name -- '" + name + "'"); 505 return -1; 506 } 507 508 String valueStr = parentShell.getNextArgRequired(); 509 int value; 510 try { 511 value = Integer.valueOf(valueStr); 512 } catch (NumberFormatException e) { 513 pw_err.println("Can't convert value to integer -- '" + valueStr + "'"); 514 return -1; 515 } 516 mSettableParameters.put(name, value); 517 return 0; 518 } 519 case "get": { 520 String name = parentShell.getNextArgRequired(); 521 if (!mSettableParameters.containsKey(name)) { 522 pw_err.println("Unknown parameter name -- '" + name + "'"); 523 return -1; 524 } 525 526 pw_out.println((int) mSettableParameters.get(name)); 527 return 0; 528 } 529 case "get_capabilities": { 530 if (mCapabilities != null) { 531 try { 532 pw_out.println(mCapabilities.toJSON().toString()); 533 } catch (JSONException e) { 534 Log.e(TAG, "onCommand: get_capabilities e=" + e); 535 } 536 } 537 return 0; 538 } 539 case "get_aware_resources": { 540 if (!SdkLevel.isAtLeastS()) { 541 return -1; 542 } 543 JSONObject j = new JSONObject(); 544 AwareResources resources = getAvailableAwareResources(); 545 if (resources != null) { 546 try { 547 j.put("numOfAvailableNdps", resources.getAvailableDataPathsCount()); 548 j.put("numOfAvailablePublishSessions", 549 resources.getAvailablePublishSessionsCount()); 550 j.put("numOfAvailableSubscribeSessions", 551 resources.getAvailableSubscribeSessionsCount()); 552 } catch (JSONException e) { 553 Log.e(TAG, "onCommand: get_aware_resources e=" + e); 554 } 555 } 556 pw_out.println(j.toString()); 557 return 0; 558 } 559 case "allow_ndp_any": { 560 String flag = parentShell.getNextArgRequired(); 561 if (mDataPathMgr == null) { 562 pw_err.println("Null Aware data-path manager - can't configure"); 563 return -1; 564 } 565 if (TextUtils.equals("true", flag)) { 566 mDataPathMgr.mAllowNdpResponderFromAnyOverride = true; 567 return 0; 568 } else if (TextUtils.equals("false", flag)) { 569 mDataPathMgr.mAllowNdpResponderFromAnyOverride = false; 570 return 0; 571 } else { 572 pw_err.println( 573 "Unknown configuration flag for 'allow_ndp_any' - true|false expected" 574 + " -- '" 575 + flag + "'"); 576 return -1; 577 } 578 } 579 case "get_instant_communication_channel": { 580 String arg = parentShell.getNextArgRequired(); 581 int band; 582 if (TextUtils.equals(arg, "2G")) { 583 band = WifiScanner.WIFI_BAND_24_GHZ; 584 } else if (TextUtils.equals(arg, "5G")) { 585 band = WifiScanner.WIFI_BAND_5_GHZ; 586 } else { 587 pw_err.println("Unknown band -- " + arg); 588 return -1; 589 } 590 List<WifiAvailableChannel> channels = mWifiInjector.getWifiThreadRunner().call( 591 () -> mWifiInjector.getWifiNative().getUsableChannels(band, 592 OP_MODE_WIFI_AWARE, 593 WifiAvailableChannel.FILTER_NAN_INSTANT_MODE), null, 594 TAG + "#get_instant_communication_channel"); 595 StringBuilder out = new StringBuilder(); 596 for (WifiAvailableChannel channel : channels) { 597 out.append(channel.toString()); 598 out.append(", "); 599 } 600 pw_out.println(out.toString()); 601 return 0; 602 } 603 case "set_override_instant_communication_mode": { 604 String arg = parentShell.getNextArgRequired(); 605 if (TextUtils.equals(arg, "2G")) { 606 mOverrideInstantMode = INSTANT_MODE_24GHZ; 607 } else if (TextUtils.equals(arg, "5G")) { 608 mOverrideInstantMode = INSTANT_MODE_5GHZ; 609 } else { 610 pw_err.println("Unknown band -- " + arg); 611 return -1; 612 } 613 return 0; 614 } 615 case "clear_override_instant_communication_mode": { 616 mOverrideInstantMode = INSTANT_MODE_DISABLED; 617 return 0; 618 } 619 case "set_cluster_id": { 620 String arg = parentShell.getNextArgRequired(); 621 int clusterId; 622 try { 623 clusterId = Integer.valueOf(arg); 624 } catch (NumberFormatException e) { 625 pw_err.println("Can't convert value to integer -- '" + arg + "'"); 626 return -1; 627 } 628 629 if (clusterId < ConfigRequest.CLUSTER_ID_MIN 630 || clusterId > ConfigRequest.CLUSTER_ID_MAX) { 631 pw_err.println("cluster ID must be in the range of 0x0000, 0xFFFF. " 632 + "Cluster ID =" + arg); 633 return -1; 634 } 635 636 return setClusterId(clusterId) ? 0 : -1; 637 } 638 default: 639 pw_err.println("Unknown 'wifiaware state_mgr <cmd>'"); 640 } 641 642 return -1; 643 } 644 645 @Override onReset()646 public void onReset() { 647 mSettableParameters.put(PARAM_ON_IDLE_DISABLE_AWARE, PARAM_ON_IDLE_DISABLE_AWARE_DEFAULT); 648 if (mDataPathMgr != null) { 649 mDataPathMgr.mAllowNdpResponderFromAnyOverride = false; 650 } 651 } 652 653 @Override onHelp(String command, BasicShellCommandHandler parentShell)654 public void onHelp(String command, BasicShellCommandHandler parentShell) { 655 final PrintWriter pw = parentShell.getOutPrintWriter(); 656 657 pw.println(" " + command); 658 pw.println(" set <name> <value>: sets named parameter to value. Names: " 659 + mSettableParameters.keySet()); 660 pw.println(" get <name>: gets named parameter value. Names: " 661 + mSettableParameters.keySet()); 662 pw.println(" get_capabilities: prints out the capabilities as a JSON string"); 663 pw.println( 664 " allow_ndp_any true|false: configure whether Responders can be specified to " 665 + "accept requests from ANY requestor (null peer spec)"); 666 pw.println(" get_instant_communication_channel 2G|5G: get instant communication mode " 667 + "channel available for the target band"); 668 pw.println(" set_override_instant_communication_mode 2G|5G: override the instant " 669 + "communication mode to 'enabled' with the specified band"); 670 pw.println(" clear_override_instant_communication_mode: clear the override of the instant " 671 + "communication mode"); 672 pw.println(" set_cluster_id <value>: set the cluster id to request to join a cluster"); 673 } 674 675 /** 676 * Initialize the handler of the state manager with the specified thread 677 * looper. 678 * 679 * @param looper Thread looper on which to run the handler. 680 */ start(Context context, Looper looper, WifiAwareMetrics awareMetrics, WifiPermissionsUtil wifiPermissionsUtil, WifiPermissionsWrapper permissionsWrapper, Clock clock, NetdWrapper netdWrapper, InterfaceConflictManager interfaceConflictMgr)681 public void start(Context context, Looper looper, WifiAwareMetrics awareMetrics, 682 WifiPermissionsUtil wifiPermissionsUtil, WifiPermissionsWrapper permissionsWrapper, 683 Clock clock, NetdWrapper netdWrapper, InterfaceConflictManager interfaceConflictMgr) { 684 Log.i(TAG, "start()"); 685 686 mContext = context; 687 mAwareMetrics = awareMetrics; 688 mWifiPermissionsUtil = wifiPermissionsUtil; 689 mInterfaceConflictMgr = interfaceConflictMgr; 690 mSm = new WifiAwareStateMachine(TAG, looper); 691 mSm.setDbg(mVdbg); 692 mSm.start(); 693 mHandler = new Handler(looper); 694 695 mDataPathMgr = new WifiAwareDataPathStateManager(this, clock); 696 mDataPathMgr.start(mContext, mSm.getHandler().getLooper(), awareMetrics, 697 wifiPermissionsUtil, permissionsWrapper, netdWrapper); 698 699 mPowerManager = mContext.getSystemService(PowerManager.class); 700 mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); 701 } 702 703 /** 704 * Initialize the late-initialization sub-services: depend on other services already existing. 705 */ startLate()706 public void startLate() { 707 delayedInitialization(); 708 IntentFilter intentFilter = new IntentFilter(); 709 intentFilter.addAction(Intent.ACTION_SCREEN_ON); 710 intentFilter.addAction(Intent.ACTION_SCREEN_OFF); 711 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED); 712 mContext.registerReceiver( 713 new BroadcastReceiver() { 714 @Override 715 public void onReceive(Context context, Intent intent) { 716 String action = intent.getAction(); 717 if (mVerboseLoggingEnabled) { 718 Log.v(TAG, "BroadcastReceiver: action=" + action); 719 } 720 if (action.equals(Intent.ACTION_SCREEN_ON) 721 || action.equals(Intent.ACTION_SCREEN_OFF)) { 722 mHandler.post(() -> reconfigure()); 723 } 724 725 if (action.equals(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED)) { 726 mHandler.post(() -> reconfigure()); 727 } 728 } 729 }, 730 intentFilter); 731 732 intentFilter = new IntentFilter(); 733 intentFilter.addAction(LocationManager.MODE_CHANGED_ACTION); 734 mContext.registerReceiverForAllUsers( 735 new BroadcastReceiver() { 736 @Override 737 public void onReceive(Context context, Intent intent) { 738 if (mVerboseLoggingEnabled) { 739 Log.v(TAG, "onReceive: MODE_CHANGED_ACTION: intent=" + intent); 740 } 741 mHandler.post(() -> { 742 if (mWifiPermissionsUtil.isLocationModeEnabled()) { 743 enableUsage(); 744 } else { 745 if (SdkLevel.isAtLeastT()) { 746 handleLocationModeDisabled(); 747 } else { 748 disableUsage(false); 749 } 750 } 751 }); 752 } 753 }, 754 intentFilter, null, null); 755 756 intentFilter = new IntentFilter(); 757 intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 758 mContext.registerReceiver( 759 new BroadcastReceiver() { 760 @Override 761 public void onReceive(Context context, Intent intent) { 762 if (mVerboseLoggingEnabled) { 763 Log.v(TAG, "onReceive: WIFI_STATE_CHANGED_ACTION: intent=" + intent); 764 } 765 boolean isEnabled = 766 intent.getIntExtra( 767 WifiManager.EXTRA_WIFI_STATE, 768 WifiManager.WIFI_STATE_UNKNOWN) 769 == WifiManager.WIFI_STATE_ENABLED; 770 mHandler.post(() -> { 771 if (isEnabled) { 772 enableUsage(); 773 } else { 774 if (!isD2dAllowedWhenStaDisabled()) { 775 disableUsage(false); 776 } 777 } 778 }); 779 } 780 }, 781 intentFilter); 782 mSettingsConfigStore.registerChangeListener(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED, 783 (key, value) -> { 784 // Check setting & wifi enabled status only when feature is supported. 785 if (mWifiGlobals.isD2dSupportedWhenInfraStaDisabled()) { 786 if (mSettingsConfigStore.get(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED)) { 787 enableUsage(); 788 } else if (mWifiManager.getWifiState() 789 != WifiManager.WIFI_STATE_ENABLED) { 790 disableUsage(false); 791 } 792 } 793 }, mHandler); 794 if (isD2dAllowedWhenStaDisabled()) { 795 enableUsage(); 796 } 797 } 798 isD2dAllowedWhenStaDisabled()799 public boolean isD2dAllowedWhenStaDisabled() { 800 return mWifiGlobals.isD2dSupportedWhenInfraStaDisabled() 801 && mSettingsConfigStore.get(D2D_ALLOWED_WHEN_INFRA_STA_DISABLED); 802 } 803 804 private class CountryCodeChangeCallback implements 805 WifiManager.ActiveCountryCodeChangedCallback { 806 807 @Override onActiveCountryCodeChanged(@ndroidx.annotation.NonNull String countryCode)808 public void onActiveCountryCodeChanged(@androidx.annotation.NonNull String countryCode) { 809 mAwareBand5InstantCommunicationChannelFreq = -1; 810 reconfigure(); 811 } 812 813 @Override onCountryCodeInactive()814 public void onCountryCodeInactive() { 815 // Ignore. 816 } 817 } 818 819 /** 820 * Try to get capability if it is null. 821 */ tryToGetAwareCapability()822 public void tryToGetAwareCapability() { 823 if (mCapabilities != null) return; 824 // Internal request for fetching capabilities. 825 getAwareInterface(new WorkSource(Process.WIFI_UID)); 826 queryCapabilities(); 827 releaseAwareInterface(); 828 } 829 830 /** 831 * Get the client state for the specified ID (or null if none exists). 832 */ getClient(int clientId)833 /* package */ WifiAwareClientState getClient(int clientId) { 834 return mClients.get(clientId); 835 } 836 837 /** 838 * Get the capabilities. 839 */ getCapabilities()840 public Capabilities getCapabilities() { 841 return mCapabilities; 842 } 843 844 /** 845 * Get the available aware resources. 846 */ getAvailableAwareResources()847 public AwareResources getAvailableAwareResources() { 848 if (mCapabilities == null) { 849 if (mVerboseLoggingEnabled) { 850 Log.v(TAG, "Aware capability hasn't loaded, resources is unknown."); 851 } 852 return null; 853 } 854 Pair<Integer, Integer> numOfDiscoverySessions = getNumOfDiscoverySessions(); 855 int numOfAvailableNdps = mCapabilities.maxNdpSessions - mDataPathMgr.getNumOfNdps(); 856 int numOfAvailablePublishSessions = 857 mCapabilities.maxPublishes - numOfDiscoverySessions.first; 858 int numOfAvailableSubscribeSessions = 859 mCapabilities.maxSubscribes - numOfDiscoverySessions.second; 860 if (numOfAvailableNdps < 0) { 861 Log.w(TAG, "Available NDPs number is negative, wrong capability?"); 862 } 863 if (numOfAvailablePublishSessions < 0) { 864 Log.w(TAG, "Available publish session number is negative, wrong capability?"); 865 } 866 if (numOfAvailableSubscribeSessions < 0) { 867 Log.w(TAG, "Available subscribe session number is negative, wrong capability?"); 868 } 869 return new AwareResources(numOfAvailableNdps, numOfAvailablePublishSessions, 870 numOfAvailableSubscribeSessions); 871 } 872 getNumOfDiscoverySessions()873 private Pair<Integer, Integer> getNumOfDiscoverySessions() { 874 int numOfPub = 0; 875 int numOfSub = 0; 876 for (int i = 0; i < mClients.size(); i++) { 877 WifiAwareClientState clientState = mClients.valueAt(i); 878 for (int j = 0; j < clientState.getSessions().size(); j++) { 879 WifiAwareDiscoverySessionState session = clientState.getSessions().valueAt(j); 880 if (session.isPublishSession()) { 881 numOfPub++; 882 } else { 883 numOfSub++; 884 } 885 } 886 } 887 return Pair.create(numOfPub, numOfSub); 888 } 889 890 /** 891 * Get the public characteristics derived from the capabilities. Use lazy initialization. 892 */ getCharacteristics()893 public Characteristics getCharacteristics() { 894 if (mCharacteristics == null && mCapabilities != null) { 895 mCharacteristics = mCapabilities.toPublicCharacteristics( 896 mWifiInjector.getDeviceConfigFacade()); 897 } 898 899 return mCharacteristics; 900 } 901 902 /** 903 * Check if there is any active attach session 904 */ isDeviceAttached()905 public boolean isDeviceAttached() { 906 return mClients != null && mClients.size() > 0; 907 } 908 909 /* 910 * Cross-service API: synchronized but independent of state machine 911 */ 912 913 /** 914 * Translate (and return in the callback) the peerId to its MAC address representation. 915 */ requestMacAddresses(int uid, int[] peerIds, IWifiAwareMacAddressProvider callback)916 public void requestMacAddresses(int uid, int[] peerIds, 917 IWifiAwareMacAddressProvider callback) { 918 mSm.getHandler().post(() -> { 919 if (mVdbg) { 920 Log.v(TAG, "requestMacAddresses: uid=" + uid + ", peerIds=" 921 + Arrays.toString(peerIds)); 922 } 923 Map<Integer, MacAddrMapping> peerIdToMacMap = new HashMap<>(); 924 for (int i = 0; i < mClients.size(); ++i) { 925 WifiAwareClientState client = mClients.valueAt(i); 926 if (client.getUid() != uid) { 927 continue; 928 } 929 930 SparseArray<WifiAwareDiscoverySessionState> sessions = client.getSessions(); 931 for (int j = 0; j < sessions.size(); ++j) { 932 WifiAwareDiscoverySessionState session = sessions.valueAt(j); 933 934 for (int peerId : peerIds) { 935 WifiAwareDiscoverySessionState.PeerInfo peerInfo = session.getPeerInfo( 936 peerId); 937 if (peerInfo != null) { 938 MacAddrMapping mapping = new MacAddrMapping(); 939 mapping.peerId = peerId; 940 mapping.macAddress = peerInfo.mMac; 941 peerIdToMacMap.put(peerId, mapping); 942 } 943 } 944 } 945 } 946 947 try { 948 MacAddrMapping[] peerIdToMacList = peerIdToMacMap.values() 949 .toArray(new MacAddrMapping[0]); 950 if (mVerboseLoggingEnabled) { 951 Log.v(TAG, "requestMacAddresses: peerIdToMacList begin"); 952 for (MacAddrMapping mapping : peerIdToMacList) { 953 Log.v(TAG, " " + mapping.peerId + ": " 954 + MacAddress.fromBytes(mapping.macAddress)); 955 } 956 Log.v(TAG, "requestMacAddresses: peerIdToMacList end"); 957 } 958 callback.macAddress(peerIdToMacList); 959 } catch (RemoteException e) { 960 Log.e(TAG, "requestMacAddress (sync): exception on callback -- " + e); 961 } 962 }); 963 } 964 965 /* 966 * COMMANDS 967 */ 968 969 /** 970 * Place a request for delayed start operation on the state machine queue. 971 */ delayedInitialization()972 public void delayedInitialization() { 973 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 974 msg.arg1 = COMMAND_TYPE_DELAYED_INITIALIZATION; 975 mSm.sendMessage(msg); 976 } 977 978 /** 979 * Place a request to get the Wi-Fi Aware interface (before which no HAL command can be 980 * executed). 981 */ getAwareInterface(@onNull WorkSource requestorWs)982 public void getAwareInterface(@NonNull WorkSource requestorWs) { 983 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 984 msg.arg1 = COMMAND_TYPE_GET_AWARE; 985 msg.obj = requestorWs; 986 mSm.sendMessage(msg); 987 } 988 989 /** 990 * Place a request to release the Wi-Fi Aware interface (after which no HAL command can be 991 * executed). 992 */ releaseAwareInterface()993 public void releaseAwareInterface() { 994 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 995 msg.arg1 = COMMAND_TYPE_RELEASE_AWARE; 996 mSm.sendMessage(msg); 997 } 998 999 /** 1000 * Enable instant communication mode if supported. 1001 * @param enabled true for enable, false for disable. 1002 */ enableInstantCommunicationMode(boolean enabled)1003 public void enableInstantCommunicationMode(boolean enabled) { 1004 if (mCapabilities == null) { 1005 if (mVerboseLoggingEnabled) { 1006 Log.v(TAG, "Aware capability is not loaded."); 1007 } 1008 return; 1009 } 1010 1011 if (!mCapabilities.isInstantCommunicationModeSupported) { 1012 if (mVerboseLoggingEnabled) { 1013 Log.v(TAG, "Device does not support instant communication mode."); 1014 } 1015 return; 1016 } 1017 if (mInstantCommModeGlobalEnable == enabled) return; 1018 1019 mInstantCommModeGlobalEnable = enabled; 1020 reconfigure(); 1021 } 1022 1023 /** 1024 * Set cluster ID if supported. 1025 * @param clusterId value ranges from 0x0000 to 0xFFFF. 1026 */ setClusterId(int clusterId)1027 private boolean setClusterId(int clusterId) { 1028 if (mCapabilities == null) { 1029 Log.e(TAG, "Aware capability is not loaded."); 1030 return false; 1031 } 1032 1033 if (!mCapabilities.isSetClusterIdSupported) { 1034 Log.e(TAG, "Device does not support setting cluster ID."); 1035 return false; 1036 } 1037 if (mClusterIdInt == clusterId) return true; 1038 1039 mClusterIdInt = clusterId; 1040 reconfigure(); 1041 return true; 1042 } 1043 1044 /** 1045 * Get if instant communication mode is currently enabled. 1046 * @return true if enabled, false otherwise. 1047 */ isInstantCommModeGlobalEnable()1048 public boolean isInstantCommModeGlobalEnable() { 1049 return mInstantCommModeGlobalEnable; 1050 } 1051 1052 /** 1053 * Get if set channel on data-path request is supported. 1054 * @return true if supported, false otherwise. 1055 */ isSetChannelOnDataPathSupported()1056 public boolean isSetChannelOnDataPathSupported() { 1057 return mContext.getResources() 1058 .getBoolean(R.bool.config_wifiSupportChannelOnDataPath); 1059 } 1060 1061 /** 1062 * Accept using parameter from external to config the Aware, 1063 * @see WifiAwareManager#setAwareParams(AwareParams) 1064 */ setAwareParams(AwareParams parameters)1065 public void setAwareParams(AwareParams parameters) { 1066 mHandler.post(() -> { 1067 mWifiAwareNativeApi.setAwareParams(parameters); 1068 reconfigure(); 1069 }); 1070 } 1071 1072 /** 1073 * @see WifiAwareManager#resetPairedDevices() 1074 */ resetPairedDevices(String callingPackage)1075 public void resetPairedDevices(String callingPackage) { 1076 mHandler.post(() -> mPairingConfigManager.removePackage(callingPackage)); 1077 } 1078 1079 /** 1080 * @see WifiAwareManager#removePairedDevice(String) 1081 */ removePairedDevice(String callingPackage, String alias)1082 public void removePairedDevice(String callingPackage, String alias) { 1083 mHandler.post( 1084 () -> mPairingConfigManager.removePairedDevice(callingPackage, alias)); 1085 } 1086 1087 /** 1088 * @see WifiAwareManager#getPairedDevices(Executor, Consumer) 1089 */ getPairedDevices(String callingPackage, IListListener listener)1090 public void getPairedDevices(String callingPackage, IListListener listener) { 1091 mHandler.post(() -> { 1092 try { 1093 listener.onResult(mPairingConfigManager 1094 .getAllPairedDevices(callingPackage)); 1095 } catch (RemoteException e) { 1096 Log.e(TAG, e.getMessage(), e); 1097 } 1098 } 1099 ); 1100 } 1101 1102 /** 1103 * @see android.net.wifi.aware.WifiAwareSession#setMasterPreference(int) 1104 */ setMasterPreference(int clientId, int masterPreference)1105 public void setMasterPreference(int clientId, int masterPreference) { 1106 mHandler.post(() -> { 1107 WifiAwareClientState state = mClients.get(clientId); 1108 if (state == null) { 1109 Log.e(TAG, "client state is missing"); 1110 return; 1111 } 1112 state.getConfigRequest().mMasterPreference = masterPreference; 1113 reconfigure(); 1114 }); 1115 } 1116 1117 /** 1118 * @see android.net.wifi.aware.WifiAwareSession#getMasterPreference(Executor, Consumer) 1119 */ getMasterPreference(int clientId, IIntegerListener listener)1120 public void getMasterPreference(int clientId, IIntegerListener listener) { 1121 mHandler.post(() -> { 1122 WifiAwareClientState state = mClients.get(clientId); 1123 if (state == null) { 1124 Log.e(TAG, "client state is missing"); 1125 return; 1126 } 1127 try { 1128 listener.onResult(state.getConfigRequest().mMasterPreference); 1129 } catch (RemoteException e) { 1130 Log.e(TAG, e.getMessage(), e); 1131 } 1132 }); 1133 } 1134 1135 /** 1136 * @see WifiAwareManager#setOpportunisticModeEnabled(boolean) 1137 */ setOpportunisticPackage(String ctxPkg, boolean enabled)1138 public void setOpportunisticPackage(String ctxPkg, boolean enabled) { 1139 mHandler.post(() -> { 1140 if (enabled) { 1141 mOpportunisticSet.add(ctxPkg); 1142 } else { 1143 mOpportunisticSet.remove(ctxPkg); 1144 } 1145 if (mClients.size() == 0) { 1146 return; 1147 } 1148 if (!mWifiAwareNativeManager.replaceRequestorWs(createMergedRequestorWs())) { 1149 Log.w(TAG, "Failed to replace requestorWs"); 1150 } 1151 }); 1152 } 1153 1154 /** 1155 * @see WifiAwareManager#isOpportunisticModeEnabled(Executor, Consumer) 1156 */ isOpportunistic(String ctxPkg, IBooleanListener listener)1157 public void isOpportunistic(String ctxPkg, IBooleanListener listener) { 1158 mHandler.post(() -> { 1159 try { 1160 listener.onResult(mOpportunisticSet.contains(ctxPkg)); 1161 } catch (RemoteException e) { 1162 Log.e(TAG, e.getMessage(), e); 1163 } 1164 }); 1165 } 1166 1167 /** 1168 * Place a request for a new client connection on the state machine queue. 1169 */ connect(int clientId, int uid, int pid, String callingPackage, @Nullable String callingFeatureId, IWifiAwareEventCallback callback, ConfigRequest configRequest, boolean notifyOnIdentityChanged, Bundle extra, boolean forAwareOffload)1170 public void connect(int clientId, int uid, int pid, String callingPackage, 1171 @Nullable String callingFeatureId, IWifiAwareEventCallback callback, 1172 ConfigRequest configRequest, boolean notifyOnIdentityChanged, Bundle extra, 1173 boolean forAwareOffload) { 1174 boolean reEnableAware = false; 1175 // If FW could not handle the Aware request priority, disable the Aware first 1176 if (!mContext.getResources() 1177 .getBoolean(R.bool.config_wifiAwareOffloadingFirmwareHandlePriority) 1178 && isAwareOffloading() && !forAwareOffload) { 1179 // Do not release Aware, as new request will get Interface again 1180 deferDisableAware(false); 1181 reEnableAware = true; 1182 } 1183 int callerType; 1184 if (SdkLevel.isAtLeastS()) { 1185 AttributionSource attributionSource = 1186 extra.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE); 1187 callerType = mWifiPermissionsUtil.getWifiCallerType(attributionSource); 1188 } else { 1189 callerType = mWifiPermissionsUtil.getWifiCallerType(uid, callingPackage); 1190 } 1191 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1192 msg.arg1 = COMMAND_TYPE_CONNECT; 1193 msg.arg2 = clientId; 1194 Pair<IWifiAwareEventCallback, Object> callbackAndAttributionSource = new Pair<>( 1195 callback, extra.getParcelable(WifiManager.EXTRA_PARAM_KEY_ATTRIBUTION_SOURCE)); 1196 msg.obj = callbackAndAttributionSource; 1197 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, configRequest); 1198 msg.getData().putInt(MESSAGE_BUNDLE_KEY_UID, uid); 1199 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PID, pid); 1200 msg.getData().putString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE, callingPackage); 1201 msg.getData().putString(MESSAGE_BUNDLE_KEY_CALLING_FEATURE_ID, callingFeatureId); 1202 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE, 1203 notifyOnIdentityChanged); 1204 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD, forAwareOffload); 1205 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD, reEnableAware); 1206 msg.getData().putInt(MESSAGE_BUNDLE_KEY_CALLER_TYPE, callerType); 1207 mSm.sendMessage(msg); 1208 // Clean the client after the connect to avoid Aware disable 1209 if (!forAwareOffload) { 1210 for (int i = 0; i < mClients.size(); i++) { 1211 WifiAwareClientState clientState = mClients.valueAt(i); 1212 if (clientState.isAwareOffload()) { 1213 disconnect(clientState.getClientId()); 1214 } 1215 } 1216 } 1217 } 1218 1219 /** 1220 * Place a request to disconnect (destroy) an existing client on the state 1221 * machine queue. 1222 */ disconnect(int clientId)1223 public void disconnect(int clientId) { 1224 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1225 msg.arg1 = COMMAND_TYPE_DISCONNECT; 1226 msg.arg2 = clientId; 1227 mSm.sendMessage(msg); 1228 } 1229 1230 /** 1231 * Place a request to defer Disable Aware on the state machine queue. 1232 * @param releaseAware 1233 */ deferDisableAware(boolean releaseAware)1234 private void deferDisableAware(boolean releaseAware) { 1235 mAwareIsDisabling = true; 1236 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1237 msg.arg1 = COMMAND_TYPE_DISABLE; 1238 msg.obj = releaseAware; 1239 mSm.sendMessage(msg); 1240 } 1241 1242 /** 1243 * Place a request to reconfigure Aware. No additional input - intended to use current 1244 * power settings when executed. Thus possibly entering or exiting power saving mode if 1245 * needed (or do nothing if Aware is not active). 1246 */ reconfigure()1247 public void reconfigure() { 1248 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1249 msg.arg1 = COMMAND_TYPE_RECONFIGURE; 1250 mSm.sendMessage(msg); 1251 } 1252 1253 /** 1254 * Place a request to stop a discovery session on the state machine queue. 1255 */ terminateSession(int clientId, int sessionId)1256 public void terminateSession(int clientId, int sessionId) { 1257 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1258 msg.arg1 = COMMAND_TYPE_TERMINATE_SESSION; 1259 msg.arg2 = clientId; 1260 msg.obj = sessionId; 1261 mSm.sendMessage(msg); 1262 } 1263 1264 /** 1265 * Place a request to start a new publish discovery session on the state 1266 * machine queue. 1267 */ publish(int clientId, PublishConfig publishConfig, IWifiAwareDiscoverySessionCallback callback)1268 public void publish(int clientId, PublishConfig publishConfig, 1269 IWifiAwareDiscoverySessionCallback callback) { 1270 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1271 msg.arg1 = COMMAND_TYPE_PUBLISH; 1272 msg.arg2 = clientId; 1273 msg.obj = callback; 1274 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, publishConfig); 1275 mSm.sendMessage(msg); 1276 } 1277 1278 /** 1279 * Place a request to modify an existing publish discovery session on the 1280 * state machine queue. 1281 */ updatePublish(int clientId, int sessionId, PublishConfig publishConfig)1282 public void updatePublish(int clientId, int sessionId, PublishConfig publishConfig) { 1283 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1284 msg.arg1 = COMMAND_TYPE_UPDATE_PUBLISH; 1285 msg.arg2 = clientId; 1286 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, publishConfig); 1287 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1288 mSm.sendMessage(msg); 1289 } 1290 1291 /** 1292 * Place a request to start a new subscribe discovery session on the state 1293 * machine queue. 1294 */ subscribe(int clientId, SubscribeConfig subscribeConfig, IWifiAwareDiscoverySessionCallback callback)1295 public void subscribe(int clientId, SubscribeConfig subscribeConfig, 1296 IWifiAwareDiscoverySessionCallback callback) { 1297 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1298 msg.arg1 = COMMAND_TYPE_SUBSCRIBE; 1299 msg.arg2 = clientId; 1300 msg.obj = callback; 1301 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, subscribeConfig); 1302 mSm.sendMessage(msg); 1303 } 1304 1305 /** 1306 * Place a request to modify an existing subscribe discovery session on the 1307 * state machine queue. 1308 */ updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig)1309 public void updateSubscribe(int clientId, int sessionId, SubscribeConfig subscribeConfig) { 1310 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1311 msg.arg1 = COMMAND_TYPE_UPDATE_SUBSCRIBE; 1312 msg.arg2 = clientId; 1313 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_CONFIG, subscribeConfig); 1314 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1315 mSm.sendMessage(msg); 1316 } 1317 1318 /** 1319 * Place a request to send a message on a discovery session on the state 1320 * machine queue. 1321 */ sendMessage(int uid, int clientId, int sessionId, int peerId, byte[] message, int messageId, int retryCount)1322 public void sendMessage(int uid, int clientId, int sessionId, int peerId, byte[] message, 1323 int messageId, int retryCount) { 1324 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1325 msg.arg1 = COMMAND_TYPE_ENQUEUE_SEND_MESSAGE; 1326 msg.arg2 = clientId; 1327 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1328 msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID, peerId); 1329 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message); 1330 msg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID, messageId); 1331 msg.getData().putInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT, retryCount); 1332 msg.getData().putInt(MESSAGE_BUNDLE_KEY_UID, uid); 1333 mSm.sendMessage(msg); 1334 } 1335 1336 /** 1337 * Initiate a NAN pairing setup request 1338 */ initiateNanPairingSetupRequest(int clientId, int sessionId, int peerId, String password, String pairingDeviceAlias, int cipherSuite)1339 public void initiateNanPairingSetupRequest(int clientId, int sessionId, int peerId, 1340 String password, String pairingDeviceAlias, int cipherSuite) { 1341 initiateNanPairingRequest(clientId, sessionId, peerId, password, pairingDeviceAlias, 1342 NAN_PAIRING_REQUEST_TYPE_SETUP, null, 1343 TextUtils.isEmpty(password) ? NAN_PAIRING_AKM_PASN : NAN_PAIRING_AKM_SAE, 1344 cipherSuite); 1345 } 1346 initiateNanPairingVerificationRequest(int clientId, int sessionId, int peerId, String pairingDeviceAlias, byte[] pmk, int akm, int cipherSuite)1347 private void initiateNanPairingVerificationRequest(int clientId, int sessionId, int peerId, 1348 String pairingDeviceAlias, byte[] pmk, int akm, int cipherSuite) { 1349 initiateNanPairingRequest(clientId, sessionId, peerId, null, pairingDeviceAlias, 1350 NAN_PAIRING_REQUEST_TYPE_VERIFICATION, pmk, akm, cipherSuite); 1351 } 1352 initiateNanPairingRequest(int clientId, int sessionId, int peerId, String password, String pairingDeviceAlias, int requestType, byte[] pmk, int akm, int cipherSuite)1353 private void initiateNanPairingRequest(int clientId, int sessionId, int peerId, 1354 String password, String pairingDeviceAlias, int requestType, byte[] pmk, int akm, 1355 int cipherSuite) { 1356 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1357 msg.arg1 = COMMAND_TYPE_INITIATE_PAIRING_REQUEST; 1358 msg.arg2 = clientId; 1359 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1360 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 1361 msg.getData().putString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS, pairingDeviceAlias); 1362 msg.getData().putString(MESSAGE_BUNDLE_KEY_PAIRING_PASSWORD, password); 1363 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE, requestType); 1364 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_AKM, akm); 1365 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_CIPHER_SUITE, cipherSuite); 1366 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PAIRING_PMK, pmk); 1367 mSm.sendMessage(msg); 1368 } 1369 1370 /** 1371 * Response to a NAN pairing setup request 1372 */ responseNanPairingSetupRequest(int clientId, int sessionId, int peerId, int requestId, String password, String pairingDeviceAlias, boolean accept, int cipherSuite)1373 public void responseNanPairingSetupRequest(int clientId, int sessionId, int peerId, 1374 int requestId, String password, String pairingDeviceAlias, boolean accept, 1375 int cipherSuite) { 1376 responseNanPairingRequest(clientId, sessionId, peerId, requestId, password, 1377 pairingDeviceAlias, NAN_PAIRING_REQUEST_TYPE_SETUP, null, 1378 TextUtils.isEmpty(password) ? NAN_PAIRING_AKM_PASN : NAN_PAIRING_AKM_SAE, accept, 1379 cipherSuite); 1380 } 1381 responseNanPairingVerificationRequest(int clientId, int sessionId, int peerId, int requestId, String pairingDeviceAlias, boolean accept, byte[] pmk, int akm, int cipherSuite)1382 private void responseNanPairingVerificationRequest(int clientId, int sessionId, int peerId, 1383 int requestId, String pairingDeviceAlias, boolean accept, byte[] pmk, int akm, 1384 int cipherSuite) { 1385 responseNanPairingRequest(clientId, sessionId, peerId, requestId, null, 1386 pairingDeviceAlias, NAN_PAIRING_REQUEST_TYPE_VERIFICATION, pmk, akm, accept, 1387 cipherSuite); 1388 } 1389 responseNanPairingRequest(int clientId, int sessionId, int peerId, int requestId, String password, String pairingDeviceAlias, int requestType, byte[] pmk, int akm, boolean accept, int cipherSuite)1390 private void responseNanPairingRequest(int clientId, int sessionId, int peerId, int requestId, 1391 String password, String pairingDeviceAlias, int requestType, byte[] pmk, int akm, 1392 boolean accept, int cipherSuite) { 1393 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1394 msg.arg1 = COMMAND_TYPE_RESPONSE_PAIRING_REQUEST; 1395 msg.arg2 = clientId; 1396 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1397 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 1398 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID, requestId); 1399 msg.getData().putString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS, pairingDeviceAlias); 1400 msg.getData().putString(MESSAGE_BUNDLE_KEY_PAIRING_PASSWORD, password); 1401 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE, requestType); 1402 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_AKM, akm); 1403 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_CIPHER_SUITE, cipherSuite); 1404 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_PAIRING_PMK, pmk); 1405 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_PAIRING_ACCEPT, accept); 1406 mSm.sendMessage(msg); 1407 } 1408 1409 /** 1410 * Initiate a bootstrapping request 1411 */ initiateBootStrappingSetupRequest(int clientId, int sessionId, int peerId, int method, long comeBackDelayMills, byte[] cookie)1412 public void initiateBootStrappingSetupRequest(int clientId, int sessionId, int peerId, int 1413 method, long comeBackDelayMills, byte[] cookie) { 1414 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1415 msg.arg1 = COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST; 1416 msg.arg2 = clientId; 1417 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1418 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 1419 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD, method); 1420 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE, cookie); 1421 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST, 1422 comeBackDelayMills > 0); 1423 mSm.sendMessageDelayed(msg, comeBackDelayMills); 1424 } 1425 1426 /** 1427 * Respond to a bootstrapping request 1428 */ respondToBootstrappingRequest(int clientId, int sessionId, int peerId, int bootstrappingId, boolean accept, int method)1429 private void respondToBootstrappingRequest(int clientId, int sessionId, int peerId, 1430 int bootstrappingId, boolean accept, int method) { 1431 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1432 msg.arg1 = COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST; 1433 msg.arg2 = clientId; 1434 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1435 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 1436 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_ACCEPT, accept); 1437 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD, method); 1438 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID, bootstrappingId); 1439 mSm.sendMessage(msg); 1440 } 1441 1442 /** 1443 * Enable usage of Aware. Doesn't actually turn on Aware (form clusters) - that 1444 * only happens when a connection is created. 1445 */ enableUsage()1446 public void enableUsage() { 1447 if (!SdkLevel.isAtLeastT() && !mWifiPermissionsUtil.isLocationModeEnabled()) { 1448 if (mVerboseLoggingEnabled) { 1449 Log.d(TAG, "enableUsage(): while location is disabled - ignoring"); 1450 } 1451 return; 1452 } 1453 if (mWifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED) { 1454 if (!isD2dAllowedWhenStaDisabled()) { 1455 if (mVerboseLoggingEnabled) { 1456 Log.d(TAG, "enableUsage(): while Wi-Fi is disabled" 1457 + " & D2D isn't allowed - ignoring"); 1458 } 1459 return; 1460 } 1461 } 1462 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1463 msg.arg1 = COMMAND_TYPE_ENABLE_USAGE; 1464 mSm.sendMessage(msg); 1465 } 1466 1467 /** 1468 * Disable usage of Aware. Terminates all existing clients with onAwareDown(). 1469 * @param markAsAvailable mark the Aware service as available to all app or not. 1470 */ disableUsage(boolean markAsAvailable)1471 public void disableUsage(boolean markAsAvailable) { 1472 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1473 msg.arg1 = COMMAND_TYPE_DISABLE_USAGE; 1474 msg.arg2 = markAsAvailable ? 1 : 0; 1475 mSm.sendMessage(msg); 1476 } 1477 1478 /** 1479 * Checks whether Aware usage is enabled (not necessarily that Aware is up right 1480 * now) or disabled. 1481 * 1482 * @return A boolean indicating whether Aware usage is enabled (true) or 1483 * disabled (false). 1484 */ isUsageEnabled()1485 public boolean isUsageEnabled() { 1486 return mUsageEnabled; 1487 } 1488 1489 /** 1490 * Get the capabilities of the current Aware firmware. 1491 */ queryCapabilities()1492 public void queryCapabilities() { 1493 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1494 msg.arg1 = COMMAND_TYPE_GET_CAPABILITIES; 1495 mSm.sendMessage(msg); 1496 } 1497 1498 /** 1499 * delete all Aware data path interfaces. 1500 */ deleteAllDataPathInterfaces()1501 public void deleteAllDataPathInterfaces() { 1502 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1503 msg.arg1 = COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES; 1504 mSm.sendMessage(msg); 1505 } 1506 1507 /** 1508 * Create the specified data-path interface. Doesn't actually creates a data-path. 1509 */ createDataPathInterface(String interfaceName)1510 public void createDataPathInterface(String interfaceName) { 1511 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1512 msg.arg1 = COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE; 1513 msg.obj = interfaceName; 1514 mSm.sendMessage(msg); 1515 } 1516 1517 /** 1518 * Deletes the specified data-path interface. 1519 */ deleteDataPathInterface(String interfaceName)1520 public void deleteDataPathInterface(String interfaceName) { 1521 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1522 msg.arg1 = COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE; 1523 msg.obj = interfaceName; 1524 mSm.sendMessage(msg); 1525 } 1526 1527 /** 1528 * Command to initiate a data-path (executed by the initiator). 1529 */ initiateDataPathSetup(WifiAwareNetworkSpecifier networkSpecifier, int peerId, int channelRequestType, int channel, byte[] peer, String interfaceName, boolean isOutOfBand, byte[] appInfo)1530 public void initiateDataPathSetup(WifiAwareNetworkSpecifier networkSpecifier, int peerId, 1531 int channelRequestType, int channel, byte[] peer, String interfaceName, 1532 boolean isOutOfBand, byte[] appInfo) { 1533 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1534 msg.arg1 = COMMAND_TYPE_INITIATE_DATA_PATH_SETUP; 1535 msg.arg2 = networkSpecifier.clientId; 1536 msg.obj = networkSpecifier; 1537 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PEER_ID, peerId); 1538 msg.getData().putInt(MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE, channelRequestType); 1539 msg.getData().putInt(MESSAGE_BUNDLE_KEY_CHANNEL, channel); 1540 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peer); 1541 msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName); 1542 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_OOB, isOutOfBand); 1543 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_APP_INFO, appInfo); 1544 mSm.sendMessage(msg); 1545 } 1546 1547 /** 1548 * Command to respond to the data-path request (executed by the responder). 1549 */ respondToDataPathRequest(boolean accept, int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand, WifiAwareNetworkSpecifier networkSpecifier)1550 public void respondToDataPathRequest(boolean accept, int ndpId, String interfaceName, 1551 byte[] appInfo, boolean isOutOfBand, 1552 WifiAwareNetworkSpecifier networkSpecifier) { 1553 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1554 msg.arg1 = COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST; 1555 if (networkSpecifier != null) { 1556 msg.arg2 = networkSpecifier.clientId; 1557 } 1558 msg.obj = networkSpecifier; 1559 msg.getData().putInt(MESSAGE_BUNDLE_KEY_NDP_ID, ndpId); 1560 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_ACCEPT_STATE, accept); 1561 msg.getData().putString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME, interfaceName); 1562 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_APP_INFO, appInfo); 1563 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_OOB, isOutOfBand); 1564 mSm.sendMessage(msg); 1565 } 1566 1567 /** 1568 * Command to terminate the specified data-path. 1569 */ endDataPath(int ndpId)1570 public void endDataPath(int ndpId) { 1571 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1572 msg.arg1 = COMMAND_TYPE_END_DATA_PATH; 1573 msg.arg2 = ndpId; 1574 mSm.sendMessage(msg); 1575 } 1576 1577 /** 1578 * Command to terminate the specified data-path. 1579 */ endPairing(int pairingId)1580 public void endPairing(int pairingId) { 1581 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1582 msg.arg1 = COMMAND_TYPE_END_PAIRING; 1583 msg.arg2 = pairingId; 1584 mSm.sendMessage(msg); 1585 } 1586 1587 /** 1588 * Suspend the specified Aware session. 1589 */ suspend(int clientId, int sessionId)1590 public void suspend(int clientId, int sessionId) { 1591 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1592 msg.arg1 = COMMAND_TYPE_SUSPEND_SESSION; 1593 msg.arg2 = clientId; 1594 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1595 mSm.sendMessage(msg); 1596 } 1597 1598 /** 1599 * Resume the specified (suspended) Aware session. 1600 */ resume(int clientId, int sessionId)1601 public void resume(int clientId, int sessionId) { 1602 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1603 msg.arg1 = COMMAND_TYPE_RESUME_SESSION; 1604 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1605 msg.arg2 = clientId; 1606 mSm.sendMessage(msg); 1607 } 1608 1609 /** 1610 * Aware follow-on messages (L2 messages) are queued by the firmware for transmission 1611 * on-the-air. The firmware has limited queue depth. The host queues all messages and doles 1612 * them out to the firmware when possible. This command removes the next messages for 1613 * transmission from the host queue and attempts to send it through the firmware. The queues 1614 * are inspected when the command is executed - not when the command is placed on the handler 1615 * (i.e. not evaluated here). 1616 */ transmitNextMessage()1617 private void transmitNextMessage() { 1618 Message msg = mSm.obtainMessage(MESSAGE_TYPE_COMMAND); 1619 msg.arg1 = COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE; 1620 mSm.sendMessage(msg); 1621 } 1622 1623 /* 1624 * RESPONSES 1625 */ 1626 1627 /** 1628 * Place a callback request on the state machine queue: configuration 1629 * request completed (successfully). 1630 */ onConfigSuccessResponse(short transactionId)1631 public void onConfigSuccessResponse(short transactionId) { 1632 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1633 msg.arg1 = RESPONSE_TYPE_ON_CONFIG_SUCCESS; 1634 msg.arg2 = transactionId; 1635 mSm.sendMessage(msg); 1636 } 1637 1638 /** 1639 * Place a callback request on the state machine queue: configuration 1640 * request failed. 1641 */ onConfigFailedResponse(short transactionId, int reason)1642 public void onConfigFailedResponse(short transactionId, int reason) { 1643 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1644 msg.arg1 = RESPONSE_TYPE_ON_CONFIG_FAIL; 1645 msg.arg2 = transactionId; 1646 msg.obj = reason; 1647 mSm.sendMessage(msg); 1648 } 1649 1650 /** 1651 * Place a callback request on the stage machine queue: disable request finished 1652 * (with the provided reason code). 1653 */ onDisableResponse(short transactionId, int reason)1654 public void onDisableResponse(short transactionId, int reason) { 1655 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1656 msg.arg1 = RESPONSE_TYPE_ON_DISABLE; 1657 msg.arg2 = transactionId; 1658 msg.obj = reason; 1659 mSm.sendMessage(msg); 1660 } 1661 1662 /** 1663 * Place a callback request on the state machine queue: session 1664 * configuration (new or update) request succeeded. 1665 */ onSessionConfigSuccessResponse(short transactionId, boolean isPublish, byte pubSubId)1666 public void onSessionConfigSuccessResponse(short transactionId, boolean isPublish, 1667 byte pubSubId) { 1668 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1669 msg.arg1 = RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS; 1670 msg.arg2 = transactionId; 1671 msg.obj = pubSubId; 1672 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish); 1673 mSm.sendMessage(msg); 1674 } 1675 1676 /** 1677 * Place a callback request on the state machine queue: session 1678 * configuration (new or update) request failed. 1679 */ onSessionConfigFailResponse(short transactionId, boolean isPublish, int reason)1680 public void onSessionConfigFailResponse(short transactionId, boolean isPublish, int reason) { 1681 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1682 msg.arg1 = RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL; 1683 msg.arg2 = transactionId; 1684 msg.obj = reason; 1685 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish); 1686 mSm.sendMessage(msg); 1687 } 1688 1689 /** 1690 * Place a callback request on the state machine queue: message has been queued successfully. 1691 */ onMessageSendQueuedSuccessResponse(short transactionId)1692 public void onMessageSendQueuedSuccessResponse(short transactionId) { 1693 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1694 msg.arg1 = RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS; 1695 msg.arg2 = transactionId; 1696 mSm.sendMessage(msg); 1697 } 1698 1699 /** 1700 * Place a callback request on the state machine queue: attempt to queue the message failed. 1701 */ onMessageSendQueuedFailResponse(short transactionId, int reason)1702 public void onMessageSendQueuedFailResponse(short transactionId, int reason) { 1703 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1704 msg.arg1 = RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL; 1705 msg.arg2 = transactionId; 1706 msg.obj = reason; 1707 mSm.sendMessage(msg); 1708 } 1709 1710 /** 1711 * Place a callback request on the state machine queue: update vendor 1712 * capabilities of the Aware stack. 1713 */ onCapabilitiesUpdateResponse(short transactionId, Capabilities capabilities)1714 public void onCapabilitiesUpdateResponse(short transactionId, 1715 Capabilities capabilities) { 1716 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1717 msg.arg1 = RESPONSE_TYPE_ON_CAPABILITIES_UPDATED; 1718 msg.arg2 = transactionId; 1719 msg.obj = capabilities; 1720 mSm.sendMessage(msg); 1721 } 1722 1723 /** 1724 * Place a callback request on the state machine queue: update vendor 1725 * capabilities of the Aware stack. 1726 */ onRangingResults(List<RangingResult> rangingResults, int sessionId)1727 public void onRangingResults(List<RangingResult> rangingResults, int sessionId) { 1728 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 1729 msg.arg1 = NOTIFICATION_TYPE_RANGING_RESULTS; 1730 msg.obj = rangingResults; 1731 msg.getData().putInt(MESSAGE_BUNDLE_KEY_SESSION_ID, sessionId); 1732 mSm.sendMessage(msg); 1733 } 1734 1735 /** 1736 * Places a callback request on the state machine queue: data-path interface creation command 1737 * completed. 1738 */ onCreateDataPathInterfaceResponse(short transactionId, boolean success, int reasonOnFailure)1739 public void onCreateDataPathInterfaceResponse(short transactionId, boolean success, 1740 int reasonOnFailure) { 1741 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1742 msg.arg1 = RESPONSE_TYPE_ON_CREATE_INTERFACE; 1743 msg.arg2 = transactionId; 1744 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success); 1745 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure); 1746 mSm.sendMessage(msg); 1747 } 1748 1749 /** 1750 * Places a callback request on the state machine queue: data-path interface deletion command 1751 * completed. 1752 */ onDeleteDataPathInterfaceResponse(short transactionId, boolean success, int reasonOnFailure)1753 public void onDeleteDataPathInterfaceResponse(short transactionId, boolean success, 1754 int reasonOnFailure) { 1755 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1756 msg.arg1 = RESPONSE_TYPE_ON_DELETE_INTERFACE; 1757 msg.arg2 = transactionId; 1758 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success); 1759 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure); 1760 mSm.sendMessage(msg); 1761 } 1762 1763 /** 1764 * Response from firmware to initiateDataPathSetup(...). Indicates that command has started 1765 * succesfully (not completed!). 1766 */ onInitiateDataPathResponseSuccess(short transactionId, int ndpId)1767 public void onInitiateDataPathResponseSuccess(short transactionId, int ndpId) { 1768 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1769 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS; 1770 msg.arg2 = transactionId; 1771 msg.obj = ndpId; 1772 mSm.sendMessage(msg); 1773 } 1774 1775 /** 1776 * Response from firmware to initiateDataPathSetup(...). 1777 * Indicates that command has failed. 1778 */ onInitiateDataPathResponseFail(short transactionId, int reason)1779 public void onInitiateDataPathResponseFail(short transactionId, int reason) { 1780 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1781 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL; 1782 msg.arg2 = transactionId; 1783 msg.obj = reason; 1784 mSm.sendMessage(msg); 1785 } 1786 1787 /** 1788 * Response from firmware to initiatePairing(...). Indicates that command has started 1789 * successfully (not completed!). 1790 */ onInitiatePairingResponseSuccess(short transactionId, int pairId)1791 public void onInitiatePairingResponseSuccess(short transactionId, int pairId) { 1792 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1793 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS; 1794 msg.arg2 = transactionId; 1795 msg.obj = pairId; 1796 mSm.sendMessage(msg); 1797 } 1798 1799 /** 1800 * Response from firmware to initiatePairing(...). 1801 * Indicates that command has failed. 1802 */ onInitiatePairingResponseFail(short transactionId, int reason)1803 public void onInitiatePairingResponseFail(short transactionId, int reason) { 1804 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1805 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL; 1806 msg.arg2 = transactionId; 1807 msg.obj = reason; 1808 mSm.sendMessage(msg); 1809 } 1810 1811 /** 1812 * Response from firmware to respondToPairingRequest(...). Indicates that command has started 1813 * successfully (not completed!). 1814 */ onRespondToPairingIndicationResponseSuccess(short transactionId)1815 public void onRespondToPairingIndicationResponseSuccess(short transactionId) { 1816 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1817 msg.arg1 = RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS; 1818 msg.arg2 = transactionId; 1819 mSm.sendMessage(msg); 1820 } 1821 1822 /** 1823 * Response from firmware to respondToPairingRequest(...). 1824 * Indicates that command has failed. 1825 */ onRespondToPairingIndicationResponseFail(short transactionId, int reason)1826 public void onRespondToPairingIndicationResponseFail(short transactionId, int reason) { 1827 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1828 msg.arg1 = RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL; 1829 msg.arg2 = transactionId; 1830 msg.obj = reason; 1831 mSm.sendMessage(msg); 1832 } 1833 1834 /** 1835 * Response from firmware to initiateDataPathSetup(...). Indicates that command has started 1836 * successfully (not completed!). 1837 */ onInitiateBootStrappingResponseSuccess(short transactionId, int ndpId)1838 public void onInitiateBootStrappingResponseSuccess(short transactionId, int ndpId) { 1839 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1840 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS; 1841 msg.arg2 = transactionId; 1842 msg.obj = ndpId; 1843 mSm.sendMessage(msg); 1844 } 1845 1846 /** 1847 * Response from firmware to initiateDataPathSetup(...). 1848 * Indicates that command has failed. 1849 */ onInitiateBootStrappingResponseFail(short transactionId, int reason)1850 public void onInitiateBootStrappingResponseFail(short transactionId, int reason) { 1851 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1852 msg.arg1 = RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL; 1853 msg.arg2 = transactionId; 1854 msg.obj = reason; 1855 mSm.sendMessage(msg); 1856 } 1857 1858 /** 1859 * Response from firmware to initiateDataPathSetup(...). Indicates that command has started 1860 * successfully (not completed!). 1861 */ onRespondToBootstrappingIndicationResponseSuccess(short transactionId)1862 public void onRespondToBootstrappingIndicationResponseSuccess(short transactionId) { 1863 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1864 msg.arg1 = RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS; 1865 msg.arg2 = transactionId; 1866 mSm.sendMessage(msg); 1867 } 1868 1869 /** 1870 * Response from firmware to initiateDataPathSetup(...). 1871 * Indicates that command has failed. 1872 */ onRespondToBootstrappingIndicationResponseFail(short transactionId, int reason)1873 public void onRespondToBootstrappingIndicationResponseFail(short transactionId, int reason) { 1874 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1875 msg.arg1 = RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL; 1876 msg.arg2 = transactionId; 1877 msg.obj = reason; 1878 mSm.sendMessage(msg); 1879 } 1880 1881 /** 1882 * Response from firmware to 1883 * {@link #respondToDataPathRequest(boolean, int, String, byte[], boolean, WifiAwareNetworkSpecifier)} 1884 */ onRespondToDataPathSetupRequestResponse(short transactionId, boolean success, int reasonOnFailure)1885 public void onRespondToDataPathSetupRequestResponse(short transactionId, boolean success, 1886 int reasonOnFailure) { 1887 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1888 msg.arg1 = RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST; 1889 msg.arg2 = transactionId; 1890 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success); 1891 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure); 1892 mSm.sendMessage(msg); 1893 } 1894 1895 /** 1896 * Response from firmware to {@link #endDataPath(int)}. 1897 */ onEndDataPathResponse(short transactionId, boolean success, int reasonOnFailure)1898 public void onEndDataPathResponse(short transactionId, boolean success, int reasonOnFailure) { 1899 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1900 msg.arg1 = RESPONSE_TYPE_ON_END_DATA_PATH; 1901 msg.arg2 = transactionId; 1902 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success); 1903 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure); 1904 mSm.sendMessage(msg); 1905 } 1906 1907 /** 1908 * Response from firmware to {@link #endPairing(int)}. 1909 */ onEndPairingResponse(short transactionId, boolean success, int reasonOnFailure)1910 public void onEndPairingResponse(short transactionId, boolean success, int reasonOnFailure) { 1911 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1912 msg.arg1 = RESPONSE_TYPE_ON_END_PAIRING; 1913 msg.arg2 = transactionId; 1914 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, success); 1915 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reasonOnFailure); 1916 mSm.sendMessage(msg); 1917 } 1918 1919 /** 1920 * Response from firmware to {@link #suspend(int, int)}. 1921 */ onSuspendResponse(short transactionId, int status)1922 public void onSuspendResponse(short transactionId, int status) { 1923 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1924 msg.arg1 = RESPONSE_TYPE_ON_SUSPEND; 1925 msg.arg2 = transactionId; 1926 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, status == NanStatusCode.SUCCESS); 1927 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, status); 1928 mSm.sendMessage(msg); 1929 } 1930 1931 /** 1932 * Response from firmware to {@link #resume(int, int)}. 1933 */ onResumeResponse(short transactionId, int status)1934 public void onResumeResponse(short transactionId, int status) { 1935 Message msg = mSm.obtainMessage(MESSAGE_TYPE_RESPONSE); 1936 msg.arg1 = RESPONSE_TYPE_ON_RESUME; 1937 msg.arg2 = transactionId; 1938 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, status == NanStatusCode.SUCCESS); 1939 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, status); 1940 mSm.sendMessage(msg); 1941 } 1942 1943 /* 1944 * NOTIFICATIONS 1945 */ 1946 1947 /** 1948 * Place a callback request on the state machine queue: the discovery 1949 * interface has changed. 1950 */ onInterfaceAddressChangeNotification(byte[] mac)1951 public void onInterfaceAddressChangeNotification(byte[] mac) { 1952 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 1953 msg.arg1 = NOTIFICATION_TYPE_INTERFACE_CHANGE; 1954 msg.obj = mac; 1955 mSm.sendMessage(msg); 1956 } 1957 1958 /** 1959 * Place a callback request on the state machine queue: the cluster 1960 * membership has changed (e.g. due to starting a new cluster or joining 1961 * another cluster). 1962 */ onClusterChangeNotification( @dentityChangedListener.ClusterChangeEvent int clusterEventType, byte[] clusterId)1963 public void onClusterChangeNotification( 1964 @IdentityChangedListener.ClusterChangeEvent int clusterEventType, 1965 byte[] clusterId) { 1966 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 1967 msg.arg1 = NOTIFICATION_TYPE_CLUSTER_CHANGE; 1968 msg.arg2 = clusterEventType; 1969 msg.obj = clusterId; 1970 mSm.sendMessage(msg); 1971 } 1972 1973 /** 1974 * Place a callback request on the state machine queue: a discovery match 1975 * has occurred - e.g. our subscription discovered someone else publishing a 1976 * matching service (to the one we were looking for). 1977 */ onMatchNotification(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm, byte[] scid, int peerCipherSuite, byte[] nonce, byte[] tag, AwarePairingConfig pairingConfig, @Nullable List<OuiKeyedData> vendorData)1978 public void onMatchNotification(int pubSubId, int requestorInstanceId, byte[] peerMac, 1979 byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm, 1980 byte[] scid, int peerCipherSuite, byte[] nonce, byte[] tag, 1981 AwarePairingConfig pairingConfig, @Nullable List<OuiKeyedData> vendorData) { 1982 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 1983 msg.arg1 = NOTIFICATION_TYPE_MATCH; 1984 msg.arg2 = pubSubId; 1985 msg.getData().putInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID, requestorInstanceId); 1986 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac); 1987 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA, serviceSpecificInfo); 1988 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA, matchFilter); 1989 msg.getData().putInt(MESSAGE_RANGING_INDICATION, rangingIndication); 1990 msg.getData().putInt(MESSAGE_RANGE_MM, rangeMm); 1991 msg.getData().putInt(MESSAGE_BUNDLE_KEY_CIPHER_SUITE, peerCipherSuite); 1992 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_SCID, scid); 1993 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_NONCE, nonce); 1994 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_TAG, tag); 1995 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_PAIRING_CONFIG, pairingConfig); 1996 msg.getData().putParcelableArrayList(MESSAGE_BUNDLE_KEY_VENDOR_DATA, 1997 vendorData != null ? new ArrayList<>(vendorData) : new ArrayList<>()); 1998 mSm.sendMessage(msg); 1999 } 2000 2001 /** 2002 * Place a callback request on the state machine queue: a discovered session 2003 * has expired - e.g. some discovered peer is no longer visible. 2004 */ onMatchExpiredNotification(int pubSubId, int requestorInstanceId)2005 public void onMatchExpiredNotification(int pubSubId, int requestorInstanceId) { 2006 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2007 msg.arg1 = NOTIFICATION_TYPE_MATCH_EXPIRED; 2008 msg.arg2 = pubSubId; 2009 msg.getData().putInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID, requestorInstanceId); 2010 mSm.sendMessage(msg); 2011 } 2012 2013 /** 2014 * Place a callback request on the state machine queue: a session (publish 2015 * or subscribe) has terminated (per plan or due to an error). 2016 */ onSessionTerminatedNotification(int pubSubId, int reason, boolean isPublish)2017 public void onSessionTerminatedNotification(int pubSubId, int reason, boolean isPublish) { 2018 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2019 msg.arg1 = NOTIFICATION_TYPE_SESSION_TERMINATED; 2020 msg.arg2 = pubSubId; 2021 msg.obj = reason; 2022 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE, isPublish); 2023 mSm.sendMessage(msg); 2024 } 2025 2026 /** 2027 * Place a callback request on the state machine queue: a message has been 2028 * received as part of a discovery session. 2029 */ onMessageReceivedNotification(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] message)2030 public void onMessageReceivedNotification(int pubSubId, int requestorInstanceId, byte[] peerMac, 2031 byte[] message) { 2032 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2033 msg.arg1 = NOTIFICATION_TYPE_MESSAGE_RECEIVED; 2034 msg.arg2 = pubSubId; 2035 msg.obj = requestorInstanceId; 2036 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac); 2037 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message); 2038 mSm.sendMessage(msg); 2039 } 2040 2041 /** 2042 * Place a callback request on the state machine queue: Aware is going down. 2043 */ onAwareDownNotification(int reason)2044 public void onAwareDownNotification(int reason) { 2045 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2046 msg.arg1 = NOTIFICATION_TYPE_AWARE_DOWN; 2047 msg.arg2 = reason; 2048 mSm.sendMessage(msg); 2049 } 2050 2051 /** 2052 * Notification that a message has been sent successfully (i.e. an ACK has been received). 2053 */ onMessageSendSuccessNotification(short transactionId)2054 public void onMessageSendSuccessNotification(short transactionId) { 2055 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2056 msg.arg1 = NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS; 2057 msg.arg2 = transactionId; 2058 mSm.sendMessage(msg); 2059 } 2060 2061 /** 2062 * Notification that a message transmission has failed due to the indicated reason - e.g. no ACK 2063 * was received. 2064 */ onMessageSendFailNotification(short transactionId, int reason)2065 public void onMessageSendFailNotification(short transactionId, int reason) { 2066 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2067 msg.arg1 = NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL; 2068 msg.arg2 = transactionId; 2069 msg.obj = reason; 2070 mSm.sendMessage(msg); 2071 } 2072 2073 /** 2074 * Place a callback request on the state machine queue: data-path request (from peer) received. 2075 */ onDataPathRequestNotification(int pubSubId, byte[] mac, int ndpId, byte[] message)2076 public void onDataPathRequestNotification(int pubSubId, byte[] mac, int ndpId, byte[] message) { 2077 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2078 msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST; 2079 msg.arg2 = pubSubId; 2080 msg.obj = ndpId; 2081 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac); 2082 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE, message); 2083 mSm.sendMessage(msg); 2084 } 2085 2086 /** 2087 * Place a callback request on the state machine queue: data-path confirmation received - i.e. 2088 * data-path is now up. 2089 */ onDataPathConfirmNotification(int ndpId, byte[] mac, boolean accept, int reason, byte[] message, List<WifiAwareChannelInfo> channelInfo)2090 public void onDataPathConfirmNotification(int ndpId, byte[] mac, boolean accept, int reason, 2091 byte[] message, List<WifiAwareChannelInfo> channelInfo) { 2092 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2093 msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM; 2094 msg.arg2 = ndpId; 2095 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac); 2096 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG, accept); 2097 msg.getData().putInt(MESSAGE_BUNDLE_KEY_STATUS_CODE, reason); 2098 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA, message); 2099 msg.obj = channelInfo; 2100 mSm.sendMessage(msg); 2101 } 2102 2103 /** 2104 * Place a callback request on the state machine queue: the specified data-path has been 2105 * terminated. 2106 */ onDataPathEndNotification(int ndpId)2107 public void onDataPathEndNotification(int ndpId) { 2108 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2109 msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_END; 2110 msg.arg2 = ndpId; 2111 mSm.sendMessage(msg); 2112 } 2113 2114 /** 2115 * Place a callback request on the state machine queue: schedule update for the specified 2116 * data-paths. 2117 */ onDataPathScheduleUpdateNotification(byte[] peerMac, ArrayList<Integer> ndpIds, List<WifiAwareChannelInfo> channelInfo)2118 public void onDataPathScheduleUpdateNotification(byte[] peerMac, ArrayList<Integer> ndpIds, 2119 List<WifiAwareChannelInfo> channelInfo) { 2120 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2121 msg.arg1 = NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE; 2122 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, peerMac); 2123 msg.getData().putIntegerArrayList(MESSAGE_BUNDLE_KEY_NDP_IDS, ndpIds); 2124 msg.obj = channelInfo; 2125 mSm.sendMessage(msg); 2126 } 2127 2128 /** 2129 * Place a callback request on the state machine queue: NAN Pairing request (from peer) 2130 * received. 2131 */ onPairingRequestNotification(int pubSubId, int requestorInstanceId, byte[] mac, int pairingId, int requestType, boolean enableCache, byte[] nonce, byte[] tag)2132 public void onPairingRequestNotification(int pubSubId, int requestorInstanceId, byte[] mac, 2133 int pairingId, int requestType, boolean enableCache, byte[] nonce, byte[] tag) { 2134 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2135 msg.arg1 = NOTIFICATION_TYPE_ON_PAIRING_REQUEST; 2136 msg.arg2 = pubSubId; 2137 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac); 2138 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID, pairingId); 2139 msg.getData().putInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID, requestorInstanceId); 2140 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE, requestType); 2141 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_PAIRING_CACHE, enableCache); 2142 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_NONCE, nonce); 2143 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_TAG, tag); 2144 mSm.sendMessage(msg); 2145 } 2146 2147 /** 2148 * Place a callback request on the state machine queue: NAN Pairing confirm received. 2149 */ onPairingConfirmNotification(int pairingId, boolean accept, int reason, int requestType, boolean enableCache, PairingSecurityAssociationInfo npksa)2150 public void onPairingConfirmNotification(int pairingId, boolean accept, int reason, 2151 int requestType, boolean enableCache, 2152 PairingSecurityAssociationInfo npksa) { 2153 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2154 msg.arg1 = NOTIFICATION_TYPE_ON_PAIRING_CONFIRM; 2155 msg.arg2 = reason; 2156 msg.obj = npksa; 2157 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID, pairingId); 2158 msg.getData().putInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE, requestType); 2159 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_PAIRING_CACHE, enableCache); 2160 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_PAIRING_ACCEPT, accept); 2161 mSm.sendMessage(msg); 2162 } 2163 2164 /** 2165 * Place a callback request on the state machine queue: bootstrapping request (from peer) 2166 * received. 2167 */ onBootstrappingRequestNotification(int pubSubId, int requestorInstanceId, byte[] mac, int bootstrappingInstanceId, int method)2168 public void onBootstrappingRequestNotification(int pubSubId, int requestorInstanceId, 2169 byte[] mac, int bootstrappingInstanceId, int method) { 2170 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2171 msg.arg1 = NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST; 2172 msg.arg2 = pubSubId; 2173 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS, mac); 2174 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID, bootstrappingInstanceId); 2175 msg.getData().putInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID, requestorInstanceId); 2176 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD, method); 2177 mSm.sendMessage(msg); 2178 } 2179 2180 /** 2181 * Place a callback request on the state machine queue: bootstrapping confirm received. 2182 */ onBootstrappingConfirmNotification(int bootstrappingId, int responseCode, int reason, int comebackDelay, byte[] cookie)2183 public void onBootstrappingConfirmNotification(int bootstrappingId, int responseCode, 2184 int reason, int comebackDelay, byte[] cookie) { 2185 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2186 msg.arg1 = NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM; 2187 msg.arg2 = reason; 2188 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID, bootstrappingId); 2189 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_RESPONSE_CODE, responseCode); 2190 msg.getData().putInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_DELAY, comebackDelay); 2191 msg.getData().putByteArray(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE, cookie); 2192 mSm.sendMessage(msg); 2193 } 2194 2195 /** 2196 * Place a callback request on the state machine queue: suspension mode changed. 2197 */ onSuspensionModeChangedNotification(boolean isSuspended)2198 public void onSuspensionModeChangedNotification(boolean isSuspended) { 2199 Message msg = mSm.obtainMessage(MESSAGE_TYPE_NOTIFICATION); 2200 msg.arg1 = NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED; 2201 msg.getData().putBoolean(MESSAGE_BUNDLE_KEY_SUSPENSION_MODE, isSuspended); 2202 mSm.sendMessage(msg); 2203 } 2204 2205 /** 2206 * State machine. 2207 */ 2208 @VisibleForTesting 2209 class WifiAwareStateMachine extends StateMachine { 2210 private static final int TRANSACTION_ID_IGNORE = 0; 2211 2212 private final DefaultState mDefaultState; 2213 private final WaitState mWaitState; 2214 private final WaitForResponseState mWaitForResponseState; 2215 private final WaitingState mWaitingState = new WaitingState(this); 2216 2217 private short mNextTransactionId = 1; 2218 public int mNextSessionId = 1; 2219 2220 private Message mCurrentCommand; 2221 private short mCurrentTransactionId = TRANSACTION_ID_IGNORE; 2222 2223 private static final long AWARE_SEND_MESSAGE_TIMEOUT = 10_000; 2224 private static final int MESSAGE_QUEUE_DEPTH_PER_UID = 50; 2225 private int mSendArrivalSequenceCounter = 0; 2226 private boolean mSendQueueBlocked = false; 2227 private final SparseArray<Message> mHostQueuedSendMessages = new SparseArray<>(); 2228 private final Map<Short, Message> mFwQueuedSendMessages = new LinkedHashMap<>(); 2229 private final WakeupMessage mSendMessageTimeoutMessage = new WakeupMessage(mContext, 2230 getHandler(), HAL_SEND_MESSAGE_TIMEOUT_TAG, MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT); 2231 2232 private static final long AWARE_WAIT_FOR_DP_CONFIRM_TIMEOUT = 20_000; 2233 private static final long AWARE_WAIT_FOR_PAIRING_CONFIRM_TIMEOUT = 20_000; 2234 private final SparseArray<WakeupMessage> 2235 mDataPathConfirmTimeoutMessages = new SparseArray<>(); 2236 private final SparseArray<WakeupMessage> 2237 mPairingConfirmTimeoutMessages = new SparseArray<>(); 2238 private final SparseArray<WakeupMessage> 2239 mBootstrappingConfirmTimeoutMessages = new SparseArray<>(); 2240 WifiAwareStateMachine(String name, Looper looper)2241 WifiAwareStateMachine(String name, Looper looper) { 2242 super(name, looper); 2243 final int threshold = mContext.getResources().getInteger( 2244 R.integer.config_wifiConfigurationWifiRunnerThresholdInMs); 2245 mDefaultState = new DefaultState(threshold); 2246 mWaitState = new WaitState(threshold); 2247 mWaitForResponseState = new WaitForResponseState(threshold); 2248 addState(mDefaultState); 2249 /* --> */ addState(mWaitState, mDefaultState); 2250 /* ----> */ addState(mWaitingState, mWaitState); 2251 /* --> */ addState(mWaitForResponseState, mDefaultState); 2252 2253 setInitialState(mWaitState); 2254 setLogRecSize(NUM_LOG_RECS); 2255 } 2256 2257 @Override getWhatToString(int what)2258 protected String getWhatToString(int what) { 2259 return switch (what) { 2260 case COMMAND_TYPE_CONNECT -> "COMMAND_TYPE_CONNECT"; 2261 case COMMAND_TYPE_DISCONNECT -> "COMMAND_TYPE_DISCONNECT"; 2262 case COMMAND_TYPE_TERMINATE_SESSION -> "COMMAND_TYPE_TERMINATE_SESSION"; 2263 case COMMAND_TYPE_PUBLISH -> "COMMAND_TYPE_PUBLISH"; 2264 case COMMAND_TYPE_UPDATE_PUBLISH -> "COMMAND_TYPE_UPDATE_PUBLISH"; 2265 case COMMAND_TYPE_SUBSCRIBE -> "COMMAND_TYPE_SUBSCRIBE"; 2266 case COMMAND_TYPE_UPDATE_SUBSCRIBE -> "COMMAND_TYPE_UPDATE_SUBSCRIBE"; 2267 case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE -> "COMMAND_TYPE_ENQUEUE_SEND_MESSAGE"; 2268 case COMMAND_TYPE_ENABLE_USAGE -> "COMMAND_TYPE_ENABLE_USAGE"; 2269 case COMMAND_TYPE_DISABLE_USAGE -> "COMMAND_TYPE_DISABLE_USAGE"; 2270 case COMMAND_TYPE_GET_CAPABILITIES -> "COMMAND_TYPE_GET_CAPABILITIES"; 2271 case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES 2272 -> "COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES"; 2273 case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE 2274 -> "COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE"; 2275 case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE 2276 -> "COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE"; 2277 case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP 2278 -> "COMMAND_TYPE_INITIATE_DATA_PATH_SETUP"; 2279 case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST 2280 -> "COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST"; 2281 case COMMAND_TYPE_END_DATA_PATH -> "COMMAND_TYPE_END_DATA_PATH"; 2282 case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE -> "COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE"; 2283 case COMMAND_TYPE_RECONFIGURE -> "COMMAND_TYPE_RECONFIGURE"; 2284 case COMMAND_TYPE_DELAYED_INITIALIZATION -> "COMMAND_TYPE_DELAYED_INITIALIZATION"; 2285 case COMMAND_TYPE_GET_AWARE -> "COMMAND_TYPE_GET_AWARE"; 2286 case COMMAND_TYPE_RELEASE_AWARE -> "COMMAND_TYPE_RELEASE_AWARE"; 2287 case COMMAND_TYPE_DISABLE -> "COMMAND_TYPE_DISABLE"; 2288 case COMMAND_TYPE_INITIATE_PAIRING_REQUEST 2289 -> "COMMAND_TYPE_INITIATE_PAIRING_REQUEST"; 2290 case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST 2291 -> "COMMAND_TYPE_RESPONSE_PAIRING_REQUEST"; 2292 case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST 2293 -> "COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST"; 2294 case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST 2295 -> "COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST"; 2296 case COMMAND_TYPE_SUSPEND_SESSION -> "COMMAND_TYPE_SUSPEND_SESSION"; 2297 case COMMAND_TYPE_RESUME_SESSION -> "COMMAND_TYPE_RESUME_SESSION"; 2298 case COMMAND_TYPE_END_PAIRING -> "COMMAND_TYPE_END_PAIRING"; 2299 2300 case RESPONSE_TYPE_ON_CONFIG_SUCCESS -> "RESPONSE_TYPE_ON_CONFIG_SUCCESS"; 2301 case RESPONSE_TYPE_ON_CONFIG_FAIL -> "RESPONSE_TYPE_ON_CONFIG_FAIL"; 2302 case RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS 2303 -> "RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS"; 2304 case RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL -> "RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL"; 2305 case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS 2306 -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS"; 2307 case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL 2308 -> "RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL"; 2309 case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED 2310 -> "RESPONSE_TYPE_ON_CAPABILITIES_UPDATED"; 2311 case RESPONSE_TYPE_ON_CREATE_INTERFACE -> "RESPONSE_TYPE_ON_CREATE_INTERFACE"; 2312 case RESPONSE_TYPE_ON_DELETE_INTERFACE -> "RESPONSE_TYPE_ON_DELETE_INTERFACE"; 2313 case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS 2314 -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS"; 2315 case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL 2316 -> "RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL"; 2317 case RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST 2318 -> "RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST"; 2319 case RESPONSE_TYPE_ON_END_DATA_PATH -> "RESPONSE_TYPE_ON_END_DATA_PATH"; 2320 case RESPONSE_TYPE_ON_DISABLE -> "RESPONSE_TYPE_ON_DISABLE"; 2321 case RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS 2322 -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS"; 2323 case RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL 2324 -> "RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL"; 2325 case RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS 2326 -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS"; 2327 case RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL 2328 -> "RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL"; 2329 case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS 2330 -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS"; 2331 case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL 2332 -> "RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL"; 2333 case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS 2334 -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS"; 2335 case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL 2336 -> "RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL"; 2337 case RESPONSE_TYPE_ON_SUSPEND -> "RESPONSE_TYPE_ON_SUSPEND"; 2338 case RESPONSE_TYPE_ON_RESUME -> "RESPONSE_TYPE_ON_RESUME"; 2339 case RESPONSE_TYPE_ON_END_PAIRING -> "RESPONSE_TYPE_ON_END_PAIRING"; 2340 2341 case NOTIFICATION_TYPE_INTERFACE_CHANGE -> "NOTIFICATION_TYPE_INTERFACE_CHANGE"; 2342 case NOTIFICATION_TYPE_CLUSTER_CHANGE -> "NOTIFICATION_TYPE_CLUSTER_CHANGE"; 2343 case NOTIFICATION_TYPE_MATCH -> "NOTIFICATION_TYPE_MATCH"; 2344 case NOTIFICATION_TYPE_SESSION_TERMINATED -> "NOTIFICATION_TYPE_SESSION_TERMINATED"; 2345 case NOTIFICATION_TYPE_MESSAGE_RECEIVED -> "NOTIFICATION_TYPE_MESSAGE_RECEIVED"; 2346 case NOTIFICATION_TYPE_AWARE_DOWN -> "NOTIFICATION_TYPE_AWARE_DOWN"; 2347 case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS 2348 -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS"; 2349 case NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL 2350 -> "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL"; 2351 case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST 2352 -> "NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST"; 2353 case NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM 2354 -> "NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM"; 2355 case NOTIFICATION_TYPE_ON_DATA_PATH_END -> "NOTIFICATION_TYPE_ON_DATA_PATH_END"; 2356 case NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE 2357 -> "NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE"; 2358 case NOTIFICATION_TYPE_MATCH_EXPIRED -> "NOTIFICATION_TYPE_MATCH_EXPIRED"; 2359 case NOTIFICATION_TYPE_ON_PAIRING_REQUEST -> "NOTIFICATION_TYPE_ON_PAIRING_REQUEST"; 2360 case NOTIFICATION_TYPE_ON_PAIRING_CONFIRM -> "NOTIFICATION_TYPE_ON_PAIRING_CONFIRM"; 2361 case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST 2362 -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST"; 2363 case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM 2364 -> "NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM"; 2365 case NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED 2366 -> "NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED"; 2367 case RunnerState.STATE_ENTER_CMD -> "Enter"; 2368 case RunnerState.STATE_EXIT_CMD -> "Exit"; 2369 case MESSAGE_TYPE_COMMAND -> "MESSAGE_TYPE_COMMAND"; 2370 case MESSAGE_TYPE_RESPONSE -> "MESSAGE_TYPE_RESPONSE"; 2371 case MESSAGE_TYPE_NOTIFICATION -> "MESSAGE_TYPE_NOTIFICATION"; 2372 case MESSAGE_TYPE_RESPONSE_TIMEOUT -> "MESSAGE_TYPE_RESPONSE_TIMEOUT"; 2373 case MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT -> "MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT"; 2374 case MESSAGE_TYPE_DATA_PATH_TIMEOUT -> "MESSAGE_TYPE_DATA_PATH_TIMEOUT"; 2375 case MESSAGE_TYPE_PAIRING_TIMEOUT -> "MESSAGE_TYPE_PAIRING_TIMEOUT"; 2376 case MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT -> "MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT"; 2377 default -> { 2378 Log.e(TAG, "unknown message what: " + what); 2379 yield "<unknown>"; 2380 } 2381 }; 2382 } 2383 onAwareDownCleanupSendQueueState()2384 public void onAwareDownCleanupSendQueueState() { 2385 mSendQueueBlocked = false; 2386 mHostQueuedSendMessages.clear(); 2387 mFwQueuedSendMessages.clear(); 2388 } 2389 2390 private class DefaultState extends RunnerState { 2391 DefaultState(int threshold)2392 DefaultState(int threshold) { 2393 super(threshold, mWifiInjector.getWifiHandlerLocalLog()); 2394 } 2395 2396 @Override getMessageLogRec(Message message)2397 public String getMessageLogRec(Message message) { 2398 return WifiAwareStateManager.class.getSimpleName() + "." 2399 + DefaultState.class.getSimpleName() + "." + getWhatToString(message.what) 2400 + "#" + getWhatToString(message.arg1); 2401 } 2402 2403 @Override enterImpl()2404 public void enterImpl() { 2405 } 2406 2407 @Override exitImpl()2408 public void exitImpl() { 2409 } 2410 @Override processMessageImpl(Message msg)2411 public boolean processMessageImpl(Message msg) { 2412 if (mVdbg) { 2413 Log.v(TAG, getName() + msg.toString()); 2414 } 2415 2416 switch (msg.what) { 2417 case MESSAGE_TYPE_NOTIFICATION: 2418 processNotification(msg); 2419 return HANDLED; 2420 case MESSAGE_TYPE_SEND_MESSAGE_TIMEOUT: 2421 processSendMessageTimeout(); 2422 return HANDLED; 2423 case MESSAGE_TYPE_DATA_PATH_TIMEOUT: { 2424 int ndpId = msg.arg1; 2425 2426 if (mVerboseLoggingEnabled) { 2427 Log.v(TAG, "MESSAGE_TYPE_DATA_PATH_TIMEOUT: ndpId=" 2428 + ndpId); 2429 } 2430 2431 mDataPathMgr.handleDataPathTimeout(ndpId); 2432 mDataPathConfirmTimeoutMessages.remove(ndpId); 2433 return HANDLED; 2434 } 2435 case MESSAGE_TYPE_PAIRING_TIMEOUT: { 2436 int pairId = msg.arg1; 2437 endPairing(pairId); 2438 onPairingConfirmNotification(pairId, false, 2439 NanStatusCode.INTERNAL_FAILURE, msg.arg2, false, null); 2440 mPairingConfirmTimeoutMessages.remove(pairId); 2441 return HANDLED; 2442 } 2443 case MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT: { 2444 int bootstrappingId = msg.arg1; 2445 onBootstrappingConfirmNotification(bootstrappingId, 2446 NAN_BOOTSTRAPPING_REJECT, NanStatusCode.INTERNAL_FAILURE, 0, null); 2447 mBootstrappingConfirmTimeoutMessages.remove(bootstrappingId); 2448 return HANDLED; 2449 } 2450 default: 2451 /* fall-through */ 2452 } 2453 2454 Log.wtf(TAG, 2455 "DefaultState: should not get non-NOTIFICATION in this state: msg=" + msg); 2456 return NOT_HANDLED; 2457 } 2458 } 2459 2460 private class WaitState extends RunnerState { 2461 WaitState(int threshold)2462 WaitState(int threshold) { 2463 super(threshold, mWifiInjector.getWifiHandlerLocalLog()); 2464 } 2465 2466 @Override getMessageLogRec(Message message)2467 public String getMessageLogRec(Message message) { 2468 return WifiAwareStateManager.class.getSimpleName() + "." 2469 + WaitState.class.getSimpleName() + "." + getWhatToString(message.what) 2470 + "#" + getWhatToString(message.arg1); 2471 } 2472 2473 @Override enterImpl()2474 public void enterImpl() { 2475 mCurrentCommand = null; 2476 mCurrentTransactionId = TRANSACTION_ID_IGNORE; 2477 } 2478 2479 @Override exitImpl()2480 public void exitImpl() { 2481 } 2482 @Override processMessageImpl(Message msg)2483 public boolean processMessageImpl(Message msg) { 2484 if (mVdbg) { 2485 Log.v(TAG, getName() + msg.toString()); 2486 } 2487 2488 switch (msg.what) { 2489 case MESSAGE_TYPE_COMMAND: 2490 if (processCommand(msg)) { 2491 transitionTo(mWaitForResponseState); 2492 } 2493 return HANDLED; 2494 case MESSAGE_TYPE_RESPONSE: 2495 /* fall-through */ 2496 case MESSAGE_TYPE_RESPONSE_TIMEOUT: 2497 /* 2498 * remnants/delayed/out-of-sync messages - but let 2499 * WaitForResponseState deal with them (identified as 2500 * out-of-date by transaction ID). 2501 */ 2502 deferMessage(msg); 2503 return HANDLED; 2504 default: 2505 /* fall-through */ 2506 } 2507 2508 return NOT_HANDLED; 2509 } 2510 } 2511 2512 private class WaitForResponseState extends RunnerState { 2513 private static final long AWARE_COMMAND_TIMEOUT = 5_000; 2514 private WakeupMessage mTimeoutMessage; 2515 WaitForResponseState(int threshold)2516 WaitForResponseState(int threshold) { 2517 super(threshold, mWifiInjector.getWifiHandlerLocalLog()); 2518 } 2519 2520 @Override getMessageLogRec(Message message)2521 public String getMessageLogRec(Message message) { 2522 return WifiAwareStateManager.class.getSimpleName() + "." 2523 + WaitForResponseState.class.getSimpleName() + "." 2524 + getWhatToString(message.what) + "#" + getWhatToString(message.arg1); 2525 } 2526 2527 @Override enterImpl()2528 public void enterImpl() { 2529 mTimeoutMessage = new WakeupMessage(mContext, getHandler(), HAL_COMMAND_TIMEOUT_TAG, 2530 MESSAGE_TYPE_RESPONSE_TIMEOUT, mCurrentCommand.arg1, mCurrentTransactionId); 2531 mTimeoutMessage.schedule(SystemClock.elapsedRealtime() + AWARE_COMMAND_TIMEOUT); 2532 mStartTime = SystemClock.elapsedRealtime(); 2533 } 2534 2535 @Override exitImpl()2536 public void exitImpl() { 2537 mTimeoutMessage.cancel(); 2538 } 2539 2540 @Override processMessageImpl(Message msg)2541 public boolean processMessageImpl(Message msg) { 2542 if (mVdbg) { 2543 Log.v(TAG, getName() + msg.toString()); 2544 } 2545 2546 switch (msg.what) { 2547 case MESSAGE_TYPE_COMMAND: 2548 /* 2549 * don't want COMMANDs in this state - defer until back 2550 * in WaitState 2551 */ 2552 deferMessage(msg); 2553 return HANDLED; 2554 case MESSAGE_TYPE_RESPONSE: 2555 if (msg.arg2 == mCurrentTransactionId) { 2556 processResponse(msg); 2557 transitionTo(mWaitState); 2558 } else { 2559 Log.w(TAG, 2560 "WaitForResponseState: processMessage: non-matching " 2561 + "transaction ID on RESPONSE (a very late " 2562 + "response) -- msg=" + msg); 2563 /* no transition */ 2564 } 2565 return HANDLED; 2566 case MESSAGE_TYPE_RESPONSE_TIMEOUT: 2567 if (msg.arg2 == mCurrentTransactionId) { 2568 processTimeout(msg); 2569 transitionTo(mWaitState); 2570 } else { 2571 Log.w(TAG, "WaitForResponseState: processMessage: non-matching " 2572 + "transaction ID on RESPONSE_TIMEOUT (either a non-cancelled " 2573 + "timeout or a race condition with cancel) -- msg=" + msg); 2574 /* no transition */ 2575 } 2576 return HANDLED; 2577 default: 2578 /* fall-through */ 2579 } 2580 2581 return NOT_HANDLED; 2582 } 2583 } 2584 processNotification(Message msg)2585 private void processNotification(Message msg) { 2586 if (mVdbg) { 2587 Log.v(TAG, "processNotification: msg=" + msg); 2588 } 2589 2590 switch (msg.arg1) { 2591 case NOTIFICATION_TYPE_INTERFACE_CHANGE: { 2592 byte[] mac = (byte[]) msg.obj; 2593 2594 onInterfaceAddressChangeLocal(mac); 2595 break; 2596 } 2597 case NOTIFICATION_TYPE_CLUSTER_CHANGE: { 2598 int clusterEventType = msg.arg2; 2599 byte[] clusterId = (byte[]) msg.obj; 2600 2601 onClusterChangeLocal(clusterEventType, clusterId); 2602 break; 2603 } 2604 case NOTIFICATION_TYPE_MATCH: { 2605 int pubSubId = msg.arg2; 2606 int requesterInstanceId = msg.getData() 2607 .getInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID); 2608 byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 2609 byte[] serviceSpecificInfo = msg.getData() 2610 .getByteArray(MESSAGE_BUNDLE_KEY_SSI_DATA); 2611 byte[] matchFilter = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_FILTER_DATA); 2612 int rangingIndication = msg.getData().getInt(MESSAGE_RANGING_INDICATION); 2613 int rangeMm = msg.getData().getInt(MESSAGE_RANGE_MM); 2614 int cipherSuite = msg.getData().getInt(MESSAGE_BUNDLE_KEY_CIPHER_SUITE); 2615 byte[] scid = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_SCID); 2616 byte[] nonce = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_NONCE); 2617 byte[] tag = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_TAG); 2618 AwarePairingConfig pairingConfig = msg.getData() 2619 .getParcelable(MESSAGE_BUNDLE_KEY_PAIRING_CONFIG); 2620 ArrayList<OuiKeyedData> vendorData = 2621 msg.getData().getParcelableArrayList(MESSAGE_BUNDLE_KEY_VENDOR_DATA); 2622 2623 onMatchLocal(pubSubId, requesterInstanceId, peerMac, serviceSpecificInfo, 2624 matchFilter, rangingIndication, rangeMm, cipherSuite, scid, nonce, tag, 2625 pairingConfig, vendorData); 2626 break; 2627 } 2628 case NOTIFICATION_TYPE_MATCH_EXPIRED: { 2629 int pubSubId = msg.arg2; 2630 int requestorInstanceId = msg.getData() 2631 .getInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID); 2632 onMatchExpiredLocal(pubSubId, requestorInstanceId); 2633 break; 2634 } 2635 case NOTIFICATION_TYPE_SESSION_TERMINATED: { 2636 int pubSubId = msg.arg2; 2637 int reason = (Integer) msg.obj; 2638 boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE); 2639 2640 onSessionTerminatedLocal(pubSubId, isPublish, reason); 2641 break; 2642 } 2643 case NOTIFICATION_TYPE_MESSAGE_RECEIVED: { 2644 int pubSubId = msg.arg2; 2645 int requestorInstanceId = (Integer) msg.obj; 2646 byte[] peerMac = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 2647 byte[] message = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA); 2648 2649 onMessageReceivedLocal(pubSubId, requestorInstanceId, peerMac, message); 2650 break; 2651 } 2652 case NOTIFICATION_TYPE_AWARE_DOWN: { 2653 int reason = msg.arg2; 2654 2655 /* 2656 * TODO: b/28615938. Use reason code to determine whether or not need clean-up 2657 * local state (only needed if AWARE_DOWN is due to internal firmware reason, 2658 * e.g. concurrency, rather than due to a requested shutdown). 2659 */ 2660 2661 onAwareDownLocal(); 2662 if (reason != NanStatusCode.SUCCESS) { 2663 sendAwareStateChangedBroadcast(false); 2664 releaseAwareInterface(); 2665 } 2666 break; 2667 } 2668 case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: { 2669 short transactionId = (short) msg.arg2; 2670 Message queuedSendCommand = mFwQueuedSendMessages.get(transactionId); 2671 if (mVdbg) { 2672 Log.v(TAG, "NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: queuedSendCommand=" 2673 + queuedSendCommand); 2674 } 2675 if (queuedSendCommand == null) { 2676 Log.w(TAG, 2677 "processNotification: NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS:" 2678 + " transactionId=" + transactionId 2679 + " - no such queued send command (timed-out?)"); 2680 } else { 2681 mFwQueuedSendMessages.remove(transactionId); 2682 updateSendMessageTimeout(); 2683 onMessageSendSuccessLocal(queuedSendCommand); 2684 } 2685 mSendQueueBlocked = false; 2686 transmitNextMessage(); 2687 2688 break; 2689 } 2690 case NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: { 2691 short transactionId = (short) msg.arg2; 2692 int reason = (Integer) msg.obj; 2693 Message sentMessage = mFwQueuedSendMessages.get(transactionId); 2694 if (mVdbg) { 2695 Log.v(TAG, "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: sentMessage=" 2696 + sentMessage); 2697 } 2698 if (sentMessage == null) { 2699 Log.w(TAG, 2700 "processNotification: NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL:" 2701 + " transactionId=" + transactionId 2702 + " - no such queued send command (timed-out?)"); 2703 } else { 2704 mFwQueuedSendMessages.remove(transactionId); 2705 updateSendMessageTimeout(); 2706 2707 int retryCount = sentMessage.getData() 2708 .getInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT); 2709 if (retryCount > 0 && reason == NanStatusCode.NO_OTA_ACK) { 2710 if (mVerboseLoggingEnabled) { 2711 Log.v(TAG, 2712 "NOTIFICATION_TYPE_ON_MESSAGE_SEND_FAIL: transactionId=" 2713 + transactionId + ", reason=" + reason 2714 + ": retransmitting - retryCount=" + retryCount); 2715 } 2716 sentMessage.getData().putInt(MESSAGE_BUNDLE_KEY_RETRY_COUNT, 2717 retryCount - 1); 2718 2719 int arrivalSeq = sentMessage.getData().getInt( 2720 MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ); 2721 mHostQueuedSendMessages.put(arrivalSeq, sentMessage); 2722 } else { 2723 onMessageSendFailLocal(sentMessage, reason); 2724 } 2725 mSendQueueBlocked = false; 2726 transmitNextMessage(); 2727 } 2728 break; 2729 } 2730 case NOTIFICATION_TYPE_ON_DATA_PATH_REQUEST: { 2731 int ndpId = (int) msg.obj; 2732 mDataPathMgr.onDataPathRequest( 2733 msg.arg2, msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS), 2734 ndpId, msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE)); 2735 2736 break; 2737 } 2738 case NOTIFICATION_TYPE_ON_DATA_PATH_CONFIRM: { 2739 int ndpId = msg.arg2; 2740 boolean success = mDataPathMgr.onDataPathConfirm( 2741 ndpId, msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS), 2742 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), 2743 msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE), 2744 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE_DATA), 2745 (List<WifiAwareChannelInfo>) msg.obj); 2746 2747 if (success) { 2748 WakeupMessage timeout = mDataPathConfirmTimeoutMessages.get(ndpId); 2749 if (timeout != null) { 2750 mDataPathConfirmTimeoutMessages.remove(ndpId); 2751 timeout.cancel(); 2752 } 2753 } 2754 2755 break; 2756 } 2757 case NOTIFICATION_TYPE_ON_DATA_PATH_END: 2758 mDataPathMgr.onDataPathEnd(msg.arg2); 2759 sendAwareResourcesChangedBroadcast(); 2760 break; 2761 case NOTIFICATION_TYPE_ON_DATA_PATH_SCHED_UPDATE: 2762 mDataPathMgr.onDataPathSchedUpdate( 2763 msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS), 2764 msg.getData().getIntegerArrayList(MESSAGE_BUNDLE_KEY_NDP_IDS), 2765 (List<WifiAwareChannelInfo>) msg.obj); 2766 break; 2767 case NOTIFICATION_TYPE_ON_PAIRING_REQUEST: { 2768 Bundle data = msg.getData(); 2769 int pubSubId = msg.arg2; 2770 int pairId = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID); 2771 int requestorInstanceId = data.getInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID); 2772 byte[] mac = data.getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 2773 int requestType = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE); 2774 byte[] nonce = data.getByteArray(MESSAGE_BUNDLE_KEY_NONCE); 2775 byte[] tag = data.getByteArray(MESSAGE_BUNDLE_KEY_TAG); 2776 onPairingRequestReceivedLocal(pubSubId, requestorInstanceId, mac, pairId, 2777 requestType, nonce, tag); 2778 break; 2779 } 2780 case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_REQUEST: { 2781 Bundle data = msg.getData(); 2782 int pubSubId = msg.arg2; 2783 int bootStrappingId = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID); 2784 int requestorInstanceId = data.getInt(MESSAGE_BUNDLE_KEY_REQ_INSTANCE_ID); 2785 byte[] mac = data.getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 2786 int method = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD); 2787 onBootstrappingRequestReceivedLocal(pubSubId, requestorInstanceId, mac, 2788 bootStrappingId, method); 2789 break; 2790 } 2791 case NOTIFICATION_TYPE_ON_PAIRING_CONFIRM: { 2792 Bundle data = msg.getData(); 2793 int reason = msg.arg2; 2794 PairingSecurityAssociationInfo npksa = (PairingSecurityAssociationInfo) msg.obj; 2795 int pairId = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID); 2796 boolean accept = data.getBoolean(MESSAGE_BUNDLE_KEY_PAIRING_ACCEPT); 2797 boolean enableCache = data.getBoolean(MESSAGE_BUNDLE_KEY_PAIRING_CACHE); 2798 int requestType = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE); 2799 boolean success = onPairingConfirmReceivedLocal(pairId, accept, reason, 2800 requestType, enableCache, npksa); 2801 if (success) { 2802 WakeupMessage timeout = mPairingConfirmTimeoutMessages.get(pairId); 2803 if (timeout != null) { 2804 mPairingConfirmTimeoutMessages.remove(pairId); 2805 timeout.cancel(); 2806 } 2807 } 2808 break; 2809 } 2810 case NOTIFICATION_TYPE_ON_BOOTSTRAPPING_CONFIRM: { 2811 Bundle data = msg.getData(); 2812 int reason = msg.arg2; 2813 int bootstrappingId = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID); 2814 int responseCode = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_RESPONSE_CODE); 2815 int comBackDelay = data.getInt( 2816 MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_DELAY); 2817 byte[] cookie = data.getByteArray( 2818 MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE); 2819 boolean success = onBootStrappingConfirmReceivedLocal(bootstrappingId, 2820 reason, responseCode, comBackDelay, cookie); 2821 if (success) { 2822 WakeupMessage timeout = mBootstrappingConfirmTimeoutMessages 2823 .get(bootstrappingId); 2824 if (timeout != null) { 2825 mBootstrappingConfirmTimeoutMessages.remove(bootstrappingId); 2826 timeout.cancel(); 2827 } 2828 } 2829 break; 2830 } 2831 case NOTIFICATION_TYPE_ON_SUSPENSION_MODE_CHANGED: { 2832 Bundle data = msg.getData(); 2833 boolean isSuspended = data.getBoolean(MESSAGE_BUNDLE_KEY_SUSPENSION_MODE); 2834 onSuspensionModeChangedLocal(isSuspended); 2835 break; 2836 } 2837 case NOTIFICATION_TYPE_RANGING_RESULTS: { 2838 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 2839 onRangingResultsReceivedLocal((List<RangingResult>) msg.obj, sessionId); 2840 break; 2841 } 2842 default: 2843 Log.wtf(TAG, "processNotification: this isn't a NOTIFICATION -- msg=" + msg); 2844 } 2845 } 2846 2847 /** 2848 * Execute the command specified by the input Message. Returns a true if 2849 * need to wait for a RESPONSE, otherwise a false. We may not have to 2850 * wait for a RESPONSE if there was an error in the state (so no command 2851 * is sent to HAL) OR if we choose not to wait for response - e.g. for 2852 * disconnected/terminate commands failure is not possible. 2853 */ processCommand(Message msg)2854 private boolean processCommand(Message msg) { 2855 if (mVdbg) { 2856 Log.v(TAG, "processCommand: msg=" + msg); 2857 } 2858 2859 if (mCurrentCommand != null) { 2860 Log.wtf(TAG, 2861 "processCommand: receiving a command (msg=" + msg 2862 + ") but current (previous) command isn't null (prev_msg=" 2863 + mCurrentCommand + ")"); 2864 mCurrentCommand = null; 2865 } 2866 2867 mCurrentTransactionId = mNextTransactionId++; 2868 2869 boolean waitForResponse = true; 2870 2871 switch (msg.arg1) { 2872 case COMMAND_TYPE_CONNECT: { 2873 if (mAwareIsDisabling) { 2874 deferMessage(msg); 2875 waitForResponse = false; 2876 if (WaitingState.wasMessageInWaitingState(msg)) { 2877 mInterfaceConflictMgr.reset(); 2878 } 2879 break; 2880 } 2881 2882 int clientId = msg.arg2; 2883 Pair<IWifiAwareEventCallback, Object> callbackAndAttributionSource = 2884 (Pair<IWifiAwareEventCallback, Object>) msg.obj; 2885 IWifiAwareEventCallback callback = callbackAndAttributionSource.first; 2886 ConfigRequest configRequest = (ConfigRequest) msg.getData() 2887 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 2888 int uid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_UID); 2889 int pid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_PID); 2890 String callingPackage = msg.getData().getString( 2891 MESSAGE_BUNDLE_KEY_CALLING_PACKAGE); 2892 String callingFeatureId = msg.getData().getString( 2893 MESSAGE_BUNDLE_KEY_CALLING_FEATURE_ID); 2894 boolean notifyIdentityChange = msg.getData().getBoolean( 2895 MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE); 2896 boolean awareOffload = msg.getData().getBoolean( 2897 MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD); 2898 boolean reEnableAware = msg.getData() 2899 .getBoolean(MESSAGE_BUNDLE_KEY_RE_ENABLE_AWARE_FROM_OFFLOAD); 2900 int callerType = msg.getData().getInt(MESSAGE_BUNDLE_KEY_CALLER_TYPE); 2901 int proceedWithOperation = 2902 mInterfaceConflictMgr.manageInterfaceConflictForStateMachine(TAG, 2903 msg, this, mWaitingState, mWaitState, 2904 HalDeviceManager.HDM_CREATE_IFACE_NAN, 2905 new WorkSource(uid, callingPackage), 2906 awareOffload || mOpportunisticSet.contains(callingPackage) 2907 /* bypassDialog */); 2908 2909 if (proceedWithOperation == InterfaceConflictManager.ICM_ABORT_COMMAND) { 2910 // handling user rejection or possible conflict (pending command) 2911 try { 2912 callback.onConnectFail( 2913 NanStatusCode.NO_RESOURCES_AVAILABLE); 2914 mAwareMetrics.recordAttachStatus(NanStatusCode.NO_RESOURCES_AVAILABLE, 2915 callerType, callingFeatureId, uid); 2916 } catch (RemoteException e) { 2917 Log.w(TAG, "displayUserApprovalDialog user refusal: RemoteException " 2918 + "(FYI): " + e); 2919 } 2920 waitForResponse = false; 2921 } else if (proceedWithOperation 2922 == InterfaceConflictManager.ICM_EXECUTE_COMMAND) { 2923 waitForResponse = connectLocal(mCurrentTransactionId, clientId, uid, pid, 2924 callingPackage, callingFeatureId, callback, configRequest, 2925 notifyIdentityChange, 2926 callbackAndAttributionSource.second, 2927 awareOffload, reEnableAware, callerType); 2928 } else { // InterfaceConflictManager.ICM_SKIP_COMMAND_WAIT_FOR_USER 2929 waitForResponse = false; 2930 } 2931 break; 2932 } 2933 case COMMAND_TYPE_DISCONNECT: { 2934 int clientId = msg.arg2; 2935 2936 waitForResponse = disconnectLocal(mCurrentTransactionId, clientId); 2937 break; 2938 } 2939 case COMMAND_TYPE_DISABLE: { 2940 mAwareIsDisabling = false; 2941 // Must trigger a state transition to execute the deferred connect command 2942 if (!mWifiAwareNativeApi.disable(mCurrentTransactionId)) { 2943 onDisableResponse(mCurrentTransactionId, WifiStatusCode.ERROR_UNKNOWN); 2944 } 2945 break; 2946 } 2947 case COMMAND_TYPE_RECONFIGURE: 2948 waitForResponse = reconfigureLocal(mCurrentTransactionId); 2949 break; 2950 case COMMAND_TYPE_TERMINATE_SESSION: { 2951 int clientId = msg.arg2; 2952 int sessionId = (Integer) msg.obj; 2953 2954 terminateSessionLocal(clientId, sessionId); 2955 waitForResponse = false; 2956 break; 2957 } 2958 case COMMAND_TYPE_PUBLISH: { 2959 int clientId = msg.arg2; 2960 IWifiAwareDiscoverySessionCallback callback = 2961 (IWifiAwareDiscoverySessionCallback) msg.obj; 2962 PublishConfig publishConfig = (PublishConfig) msg.getData() 2963 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 2964 2965 waitForResponse = publishLocal(mCurrentTransactionId, clientId, publishConfig, 2966 callback); 2967 break; 2968 } 2969 case COMMAND_TYPE_UPDATE_PUBLISH: { 2970 int clientId = msg.arg2; 2971 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 2972 PublishConfig publishConfig = (PublishConfig) msg.getData() 2973 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 2974 waitForResponse = updatePublishLocal(mCurrentTransactionId, clientId, sessionId, 2975 publishConfig); 2976 break; 2977 } 2978 case COMMAND_TYPE_SUBSCRIBE: { 2979 int clientId = msg.arg2; 2980 IWifiAwareDiscoverySessionCallback callback = 2981 (IWifiAwareDiscoverySessionCallback) msg.obj; 2982 SubscribeConfig subscribeConfig = (SubscribeConfig) msg.getData() 2983 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 2984 2985 waitForResponse = subscribeLocal(mCurrentTransactionId, clientId, 2986 subscribeConfig, callback); 2987 break; 2988 } 2989 case COMMAND_TYPE_UPDATE_SUBSCRIBE: { 2990 int clientId = msg.arg2; 2991 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 2992 SubscribeConfig subscribeConfig = (SubscribeConfig) msg.getData() 2993 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 2994 2995 waitForResponse = updateSubscribeLocal(mCurrentTransactionId, clientId, 2996 sessionId, subscribeConfig); 2997 break; 2998 } 2999 case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: { 3000 if (mVdbg) { 3001 Log.v(TAG, "processCommand: ENQUEUE_SEND_MESSAGE - messageId=" 3002 + msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID) 3003 + ", mSendArrivalSequenceCounter=" + mSendArrivalSequenceCounter); 3004 } 3005 int uid = msg.getData().getInt(MESSAGE_BUNDLE_KEY_UID); 3006 if (isUidExceededMessageQueueDepthLimit(uid)) { 3007 if (mVerboseLoggingEnabled) { 3008 Log.v(TAG, "message queue limit exceeded for uid=" + uid 3009 + " at messageId=" 3010 + msg.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID)); 3011 } 3012 onMessageSendFailLocal(msg, NanStatusCode.INTERNAL_FAILURE); 3013 waitForResponse = false; 3014 break; 3015 } 3016 Message sendMsg = obtainMessage(msg.what); 3017 sendMsg.copyFrom(msg); 3018 sendMsg.getData().putInt(MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ, 3019 mSendArrivalSequenceCounter); 3020 mHostQueuedSendMessages.put(mSendArrivalSequenceCounter, sendMsg); 3021 mSendArrivalSequenceCounter++; 3022 waitForResponse = false; 3023 3024 if (!mSendQueueBlocked) { 3025 transmitNextMessage(); 3026 } 3027 3028 break; 3029 } 3030 case COMMAND_TYPE_INITIATE_PAIRING_REQUEST: { 3031 int clientId = msg.arg2; 3032 Bundle data = msg.getData(); 3033 int sessionId = data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3034 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID); 3035 String password = data.getString(MESSAGE_BUNDLE_KEY_PAIRING_PASSWORD); 3036 int requestType = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE); 3037 int akm = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_AKM); 3038 int cipherSuite = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_CIPHER_SUITE); 3039 byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PAIRING_PMK); 3040 waitForResponse = initiateNanPairingRequestLocal(mCurrentTransactionId, 3041 clientId, sessionId, peerId, password, requestType, akm, pmk, 3042 cipherSuite); 3043 break; 3044 } 3045 case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST: { 3046 int clientId = msg.arg2; 3047 Bundle data = msg.getData(); 3048 int sessionId = data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3049 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID); 3050 int requestId = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID); 3051 String password = data.getString(MESSAGE_BUNDLE_KEY_PAIRING_PASSWORD); 3052 int requestType = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE); 3053 int akm = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_AKM); 3054 int cipherSuite = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_CIPHER_SUITE); 3055 byte[] pmk = data.getByteArray(MESSAGE_BUNDLE_KEY_PAIRING_PMK); 3056 boolean accept = data.getBoolean(MESSAGE_BUNDLE_KEY_PAIRING_ACCEPT); 3057 waitForResponse = respondToPairingRequestLocal(mCurrentTransactionId, clientId, 3058 sessionId, peerId, requestId, accept, requestType, pmk, password, akm, 3059 cipherSuite); 3060 break; 3061 } 3062 case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST: { 3063 int clientId = msg.arg2; 3064 Bundle data = msg.getData(); 3065 int sessionId = data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3066 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID); 3067 int method = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD); 3068 byte[] cookie = data.getByteArray( 3069 MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_COME_BACK_COOKIE); 3070 boolean isComeBack = data 3071 .getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST); 3072 waitForResponse = initiateBootstrappingRequestLocal(mCurrentTransactionId, 3073 clientId, sessionId, peerId, method, cookie, isComeBack); 3074 break; 3075 } 3076 case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST: { 3077 int clientId = msg.arg2; 3078 Bundle data = msg.getData(); 3079 int sessionId = data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3080 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID); 3081 boolean accept = data.getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_ACCEPT); 3082 int bootstrappingId = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_REQUEST_ID); 3083 int method = data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD); 3084 waitForResponse = respondToBootstrappingRequestLocal(mCurrentTransactionId, 3085 clientId, sessionId, peerId, bootstrappingId, accept, method); 3086 break; 3087 } 3088 case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: { 3089 if (mSendQueueBlocked || mHostQueuedSendMessages.size() == 0) { 3090 if (mVdbg) { 3091 Log.v(TAG, "processCommand: SEND_TOP_OF_QUEUE_MESSAGE - blocked or " 3092 + "empty host queue"); 3093 } 3094 waitForResponse = false; 3095 } else { 3096 if (mVdbg) { 3097 Log.v(TAG, "processCommand: SEND_TOP_OF_QUEUE_MESSAGE - " 3098 + "sendArrivalSequenceCounter=" 3099 + mHostQueuedSendMessages.keyAt(0)); 3100 } 3101 Message sendMessage = mHostQueuedSendMessages.valueAt(0); 3102 mHostQueuedSendMessages.removeAt(0); 3103 3104 Bundle data = sendMessage.getData(); 3105 int clientId = sendMessage.arg2; 3106 int sessionId = sendMessage.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3107 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_PEER_ID); 3108 byte[] message = data.getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE); 3109 int messageId = data.getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID); 3110 3111 msg.getData().putParcelable(MESSAGE_BUNDLE_KEY_SENT_MESSAGE, sendMessage); 3112 3113 waitForResponse = sendFollowonMessageLocal(mCurrentTransactionId, clientId, 3114 sessionId, peerId, message, messageId); 3115 } 3116 break; 3117 } 3118 case COMMAND_TYPE_ENABLE_USAGE: 3119 enableUsageLocal(); 3120 waitForResponse = false; 3121 break; 3122 case COMMAND_TYPE_DISABLE_USAGE: 3123 disableUsageLocal(mCurrentTransactionId, msg.arg2 == 1); 3124 waitForResponse = false; 3125 break; 3126 case COMMAND_TYPE_GET_CAPABILITIES: 3127 if (mCapabilities == null) { 3128 waitForResponse = mWifiAwareNativeApi.getCapabilities( 3129 mCurrentTransactionId); 3130 } else { 3131 if (mVdbg) { 3132 Log.v(TAG, "COMMAND_TYPE_GET_CAPABILITIES: already have capabilities - " 3133 + "skipping"); 3134 } 3135 waitForResponse = false; 3136 } 3137 break; 3138 case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES: 3139 mDataPathMgr.deleteAllInterfaces(); 3140 waitForResponse = false; 3141 break; 3142 case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE: 3143 waitForResponse = mWifiAwareNativeApi.createAwareNetworkInterface( 3144 mCurrentTransactionId, (String) msg.obj); 3145 break; 3146 case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE: 3147 waitForResponse = mWifiAwareNativeApi.deleteAwareNetworkInterface( 3148 mCurrentTransactionId, (String) msg.obj); 3149 break; 3150 case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP: { 3151 Bundle data = msg.getData(); 3152 3153 WifiAwareNetworkSpecifier networkSpecifier = 3154 (WifiAwareNetworkSpecifier) msg.obj; 3155 3156 int peerId = data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID); 3157 int channelRequestType = data.getInt(MESSAGE_BUNDLE_KEY_CHANNEL_REQ_TYPE); 3158 int channel = data.getInt(MESSAGE_BUNDLE_KEY_CHANNEL); 3159 byte[] peer = data.getByteArray(MESSAGE_BUNDLE_KEY_MAC_ADDRESS); 3160 String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME); 3161 boolean isOutOfBand = data.getBoolean(MESSAGE_BUNDLE_KEY_OOB); 3162 byte[] appInfo = data.getByteArray(MESSAGE_BUNDLE_KEY_APP_INFO); 3163 3164 waitForResponse = initiateDataPathSetupLocal(mCurrentTransactionId, 3165 networkSpecifier, peerId, channelRequestType, channel, peer, 3166 interfaceName, isOutOfBand, appInfo); 3167 break; 3168 } 3169 case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST: { 3170 Bundle data = msg.getData(); 3171 3172 int ndpId = data.getInt(MESSAGE_BUNDLE_KEY_NDP_ID); 3173 WifiAwareNetworkSpecifier specifier = 3174 (WifiAwareNetworkSpecifier) msg.obj; 3175 boolean accept = data.getBoolean(MESSAGE_BUNDLE_KEY_ACCEPT_STATE); 3176 String interfaceName = data.getString(MESSAGE_BUNDLE_KEY_INTERFACE_NAME); 3177 byte[] appInfo = data.getByteArray(MESSAGE_BUNDLE_KEY_APP_INFO); 3178 boolean isOutOfBand = data.getBoolean(MESSAGE_BUNDLE_KEY_OOB); 3179 3180 waitForResponse = respondToDataPathRequestLocal(mCurrentTransactionId, accept, 3181 ndpId, interfaceName, appInfo, isOutOfBand, specifier); 3182 3183 break; 3184 } 3185 case COMMAND_TYPE_END_DATA_PATH: { 3186 int ndpId = msg.arg2; 3187 WakeupMessage timeout = mDataPathConfirmTimeoutMessages.get(ndpId); 3188 if (timeout != null) { 3189 mDataPathConfirmTimeoutMessages.remove(ndpId); 3190 timeout.cancel(); 3191 } 3192 waitForResponse = endDataPathLocal(mCurrentTransactionId, ndpId); 3193 break; 3194 } 3195 case COMMAND_TYPE_END_PAIRING: { 3196 int pairId = msg.arg2; 3197 WakeupMessage timeout = mPairingConfirmTimeoutMessages.get(pairId); 3198 if (timeout != null) { 3199 mPairingConfirmTimeoutMessages.remove(pairId); 3200 timeout.cancel(); 3201 } 3202 waitForResponse = endPairingLocal(mCurrentTransactionId, pairId); 3203 break; 3204 } 3205 case COMMAND_TYPE_DELAYED_INITIALIZATION: 3206 if (SdkLevel.isAtLeastT()) { 3207 mWifiManager.registerActiveCountryCodeChangedCallback( 3208 new HandlerExecutor(mHandler), new CountryCodeChangeCallback()); 3209 } 3210 mWifiAwareNativeManager.start(getHandler()); 3211 waitForResponse = false; 3212 break; 3213 case COMMAND_TYPE_GET_AWARE: 3214 WorkSource requestorWs = (WorkSource) msg.obj; 3215 mWifiAwareNativeManager.tryToGetAware(requestorWs); 3216 waitForResponse = false; 3217 break; 3218 case COMMAND_TYPE_RELEASE_AWARE: 3219 mWifiAwareNativeManager.releaseAware(); 3220 waitForResponse = false; 3221 break; 3222 case COMMAND_TYPE_SUSPEND_SESSION: { 3223 int clientId = msg.arg2; 3224 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3225 3226 waitForResponse = suspendSessionLocal(mCurrentTransactionId, clientId, 3227 sessionId); 3228 break; 3229 } 3230 case COMMAND_TYPE_RESUME_SESSION: { 3231 int clientId = msg.arg2; 3232 int sessionId = msg.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 3233 3234 waitForResponse = resumeSessionLocal(mCurrentTransactionId, clientId, 3235 sessionId); 3236 break; 3237 } 3238 default: 3239 waitForResponse = false; 3240 Log.wtf(TAG, "processCommand: this isn't a COMMAND -- msg=" + msg); 3241 /* fall-through */ 3242 } 3243 3244 if (!waitForResponse) { 3245 mCurrentTransactionId = TRANSACTION_ID_IGNORE; 3246 } else { 3247 mCurrentCommand = obtainMessage(msg.what); 3248 mCurrentCommand.copyFrom(msg); 3249 } 3250 3251 return waitForResponse; 3252 } 3253 processResponse(Message msg)3254 private void processResponse(Message msg) { 3255 if (mVdbg) { 3256 Log.v(TAG, "processResponse: msg=" + msg); 3257 } 3258 3259 if (mCurrentCommand == null) { 3260 Log.wtf(TAG, "processResponse: no existing command stored!? msg=" + msg); 3261 mCurrentTransactionId = TRANSACTION_ID_IGNORE; 3262 return; 3263 } 3264 int reason = NanStatusCode.SUCCESS; 3265 3266 switch (msg.arg1) { 3267 case RESPONSE_TYPE_ON_CONFIG_SUCCESS: 3268 onConfigCompletedLocal(mCurrentCommand); 3269 break; 3270 case RESPONSE_TYPE_ON_CONFIG_FAIL: { 3271 reason = (Integer) msg.obj; 3272 3273 onConfigFailedLocal(mCurrentCommand, reason); 3274 break; 3275 } 3276 case RESPONSE_TYPE_ON_SESSION_CONFIG_SUCCESS: { 3277 byte pubSubId = (Byte) msg.obj; 3278 boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE); 3279 3280 onSessionConfigSuccessLocal(mCurrentCommand, pubSubId, isPublish); 3281 break; 3282 } 3283 case RESPONSE_TYPE_ON_SESSION_CONFIG_FAIL: { 3284 reason = (int) msg.obj; 3285 boolean isPublish = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SESSION_TYPE); 3286 3287 onSessionConfigFailLocal(mCurrentCommand, isPublish, reason); 3288 break; 3289 } 3290 case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_SUCCESS: { 3291 Message sentMessage = mCurrentCommand.getData().getParcelable( 3292 MESSAGE_BUNDLE_KEY_SENT_MESSAGE); 3293 sentMessage.getData().putLong(MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME, 3294 SystemClock.elapsedRealtime()); 3295 mFwQueuedSendMessages.put(mCurrentTransactionId, sentMessage); 3296 updateSendMessageTimeout(); 3297 if (!mSendQueueBlocked) { 3298 transmitNextMessage(); 3299 } 3300 3301 if (mVdbg) { 3302 Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_SUCCESS - arrivalSeq=" 3303 + sentMessage.getData().getInt( 3304 MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ)); 3305 } 3306 break; 3307 } 3308 case RESPONSE_TYPE_ON_MESSAGE_SEND_QUEUED_FAIL: { 3309 if (mVdbg) { 3310 Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_FAIL - blocking!"); 3311 } 3312 reason = (int) msg.obj; 3313 Message sentMessage = mCurrentCommand.getData().getParcelable( 3314 MESSAGE_BUNDLE_KEY_SENT_MESSAGE); 3315 if (reason == NanStatusCode.FOLLOWUP_TX_QUEUE_FULL) { 3316 int arrivalSeq = sentMessage.getData().getInt( 3317 MESSAGE_BUNDLE_KEY_MESSAGE_ARRIVAL_SEQ); 3318 mHostQueuedSendMessages.put(arrivalSeq, sentMessage); 3319 mSendQueueBlocked = true; 3320 3321 if (mVdbg) { 3322 Log.v(TAG, "processResponse: ON_MESSAGE_SEND_QUEUED_FAIL - arrivalSeq=" 3323 + arrivalSeq + " -- blocking"); 3324 } 3325 } else { 3326 onMessageSendFailLocal(sentMessage, NanStatusCode.INTERNAL_FAILURE); 3327 if (!mSendQueueBlocked) { 3328 transmitNextMessage(); 3329 } 3330 } 3331 break; 3332 } 3333 case RESPONSE_TYPE_ON_CAPABILITIES_UPDATED: { 3334 onCapabilitiesUpdatedResponseLocal((Capabilities) msg.obj); 3335 break; 3336 } 3337 case RESPONSE_TYPE_ON_CREATE_INTERFACE: 3338 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3339 onCreateDataPathInterfaceResponseLocal(mCurrentCommand, 3340 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), 3341 reason); 3342 break; 3343 case RESPONSE_TYPE_ON_DELETE_INTERFACE: 3344 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3345 onDeleteDataPathInterfaceResponseLocal(mCurrentCommand, 3346 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), 3347 reason); 3348 break; 3349 case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_SUCCESS: { 3350 int ndpId = (int) msg.obj; 3351 boolean success = onInitiateDataPathResponseSuccessLocal(mCurrentCommand, 3352 ndpId); 3353 if (success) { 3354 WakeupMessage timeout = new WakeupMessage(mContext, getHandler(), 3355 HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_DATA_PATH_TIMEOUT, 3356 ndpId); 3357 mDataPathConfirmTimeoutMessages.put(ndpId, timeout); 3358 timeout.schedule( 3359 SystemClock.elapsedRealtime() + AWARE_WAIT_FOR_DP_CONFIRM_TIMEOUT); 3360 sendAwareResourcesChangedBroadcast(); 3361 } 3362 break; 3363 } 3364 case RESPONSE_TYPE_ON_INITIATE_DATA_PATH_FAIL: 3365 reason = (int) msg.obj; 3366 onInitiateDataPathResponseFailLocal(mCurrentCommand, reason); 3367 break; 3368 case RESPONSE_TYPE_ON_RESPOND_TO_DATA_PATH_SETUP_REQUEST: { 3369 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3370 boolean success = onRespondToDataPathSetupRequestResponseLocal(mCurrentCommand, 3371 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), 3372 reason); 3373 if (success) { 3374 int ndpId = mCurrentCommand.getData().getInt(MESSAGE_BUNDLE_KEY_NDP_ID); 3375 WakeupMessage timeout = new WakeupMessage(mContext, getHandler(), 3376 HAL_DATA_PATH_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_DATA_PATH_TIMEOUT, 3377 ndpId); 3378 mDataPathConfirmTimeoutMessages.put(ndpId, timeout); 3379 timeout.schedule( 3380 SystemClock.elapsedRealtime() + AWARE_WAIT_FOR_DP_CONFIRM_TIMEOUT); 3381 } 3382 break; 3383 } 3384 case RESPONSE_TYPE_ON_END_DATA_PATH: 3385 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3386 onEndPathEndResponseLocal(mCurrentCommand, 3387 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), 3388 reason); 3389 break; 3390 case RESPONSE_TYPE_ON_END_PAIRING: 3391 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3392 onPairingEndResponseLocal(mCurrentCommand, 3393 msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG), reason); 3394 break; 3395 case RESPONSE_TYPE_ON_DISABLE: 3396 reason = (int) msg.obj; 3397 onDisableResponseLocal(mCurrentCommand, reason); 3398 break; 3399 case RESPONSE_TYPE_ON_INITIATE_PAIRING_SUCCESS: { 3400 int pairingId = (int) msg.obj; 3401 boolean success = onInitiatePairingResponseSuccessLocal(mCurrentCommand, 3402 pairingId); 3403 if (success) { 3404 WakeupMessage timeout = new WakeupMessage(mContext, getHandler(), 3405 HAL_PAIRING_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_PAIRING_TIMEOUT, 3406 pairingId, msg.getData().getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE)); 3407 mPairingConfirmTimeoutMessages.put(pairingId, timeout); 3408 timeout.schedule(SystemClock.elapsedRealtime() 3409 + AWARE_WAIT_FOR_PAIRING_CONFIRM_TIMEOUT); 3410 } 3411 break; 3412 } 3413 case RESPONSE_TYPE_ON_INITIATE_PAIRING_FAIL: { 3414 reason = (int) msg.obj; 3415 onInitiatePairingResponseFailLocal(mCurrentCommand, reason); 3416 break; 3417 } 3418 case RESPONSE_TYPE_ON_RESPONSE_PAIRING_SUCCESS: { 3419 boolean success = onRespondToPairingIndicationResponseSuccessLocal( 3420 mCurrentCommand); 3421 if (success) { 3422 int pairingId = mCurrentCommand.getData() 3423 .getInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID); 3424 WakeupMessage timeout = new WakeupMessage(mContext, getHandler(), 3425 HAL_PAIRING_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_PAIRING_TIMEOUT, 3426 pairingId, msg.getData().getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE)); 3427 mPairingConfirmTimeoutMessages.put(pairingId, timeout); 3428 timeout.schedule(SystemClock.elapsedRealtime() 3429 + AWARE_WAIT_FOR_PAIRING_CONFIRM_TIMEOUT); 3430 } 3431 break; 3432 } 3433 case RESPONSE_TYPE_ON_RESPONSE_PAIRING_FAIL: { 3434 reason = (int) msg.obj; 3435 onRespondToPairingIndicationResponseFail(mCurrentCommand, reason); 3436 break; 3437 } 3438 case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_SUCCESS: { 3439 int bootstrappingId = (int) msg.obj; 3440 boolean success = onInitiateBootstrappingResponseSuccessLocal(mCurrentCommand, 3441 bootstrappingId); 3442 3443 if (success) { 3444 WakeupMessage timeout = new WakeupMessage(mContext, getHandler(), 3445 HAL_PAIRING_CONFIRM_TIMEOUT_TAG, MESSAGE_TYPE_BOOTSTRAPPING_TIMEOUT, 3446 bootstrappingId, 0, mCurrentCommand); 3447 mBootstrappingConfirmTimeoutMessages.put(bootstrappingId, timeout); 3448 timeout.schedule(SystemClock.elapsedRealtime() 3449 + AWARE_WAIT_FOR_PAIRING_CONFIRM_TIMEOUT); 3450 } 3451 break; 3452 } 3453 case RESPONSE_TYPE_ON_INITIATE_BOOTSTRAPPING_FAIL: { 3454 reason = (int) msg.obj; 3455 onInitiateBootStrappingResponseFailLocal(mCurrentCommand, reason); 3456 break; 3457 } 3458 case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_SUCCESS: { 3459 onRespondToBootStrappingRequestSuccessLocal(mCurrentCommand); 3460 break; 3461 } 3462 case RESPONSE_TYPE_ON_RESPONSE_BOOTSTRAPPING_FAIL: { 3463 reason = (int) msg.obj; 3464 Log.e(TAG, "RespondToBootstrappingIndication failed, reason: " + reason); 3465 break; 3466 } 3467 case RESPONSE_TYPE_ON_SUSPEND: { 3468 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3469 boolean success = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG); 3470 onSuspendResponseLocal(mCurrentCommand, success, reason); 3471 break; 3472 } 3473 case RESPONSE_TYPE_ON_RESUME: { 3474 reason = msg.getData().getInt(MESSAGE_BUNDLE_KEY_STATUS_CODE); 3475 boolean success = msg.getData().getBoolean(MESSAGE_BUNDLE_KEY_SUCCESS_FLAG); 3476 onResumeResponseLocal(mCurrentCommand, success, reason); 3477 break; 3478 } 3479 default: 3480 Log.wtf(TAG, "processResponse: this isn't a RESPONSE -- msg=" + msg); 3481 return; 3482 } 3483 if (msg.arg1 != RESPONSE_TYPE_ON_CONFIG_SUCCESS 3484 && msg.arg1 != RESPONSE_TYPE_ON_CONFIG_FAIL) { 3485 // Config response handle separately to identify it's connect or reconfigure 3486 recordHalApiCall(mCurrentCommand.arg1, reason, mStartTime); 3487 } 3488 } 3489 processTimeout(Message msg)3490 private void processTimeout(Message msg) { 3491 if (mVerboseLoggingEnabled) { 3492 Log.v(TAG, "processTimeout: msg=" + msg); 3493 } 3494 3495 if (mCurrentCommand == null) { 3496 Log.wtf(TAG, "processTimeout: no existing command stored!? msg=" + msg); 3497 mCurrentTransactionId = TRANSACTION_ID_IGNORE; 3498 return; 3499 } 3500 3501 /* 3502 * Only have to handle those COMMANDs which wait for a response. 3503 */ 3504 switch (msg.arg1) { 3505 case COMMAND_TYPE_CONNECT: 3506 case COMMAND_TYPE_DISCONNECT: 3507 3508 case COMMAND_TYPE_RECONFIGURE: 3509 /* 3510 * Reconfigure timed-out. There is nothing to do but log the issue - which 3511 * will be done in the callback. 3512 */ 3513 onConfigFailedLocal(mCurrentCommand, NanStatusCode.INTERNAL_FAILURE); 3514 break; 3515 case COMMAND_TYPE_TERMINATE_SESSION: { 3516 Log.wtf(TAG, "processTimeout: TERMINATE_SESSION - shouldn't be waiting!"); 3517 break; 3518 } 3519 case COMMAND_TYPE_PUBLISH: 3520 case COMMAND_TYPE_UPDATE_PUBLISH: { 3521 onSessionConfigFailLocal(mCurrentCommand, true, NanStatusCode.INTERNAL_FAILURE); 3522 break; 3523 } 3524 case COMMAND_TYPE_SUBSCRIBE: 3525 case COMMAND_TYPE_UPDATE_SUBSCRIBE: { 3526 onSessionConfigFailLocal(mCurrentCommand, false, 3527 NanStatusCode.INTERNAL_FAILURE); 3528 break; 3529 } 3530 case COMMAND_TYPE_ENQUEUE_SEND_MESSAGE: { 3531 Log.wtf(TAG, "processTimeout: ENQUEUE_SEND_MESSAGE - shouldn't be waiting!"); 3532 break; 3533 } 3534 case COMMAND_TYPE_INITIATE_PAIRING_REQUEST: { 3535 onInitiatePairingResponseFailLocal(mCurrentCommand, 3536 NanStatusCode.INTERNAL_FAILURE); 3537 break; 3538 } 3539 case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST: { 3540 onRespondToPairingIndicationResponseFail(mCurrentCommand, 3541 NanStatusCode.INTERNAL_FAILURE); 3542 break; 3543 } 3544 case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST: { 3545 onInitiateBootStrappingResponseFailLocal(mCurrentCommand, 3546 NanStatusCode.INTERNAL_FAILURE); 3547 break; 3548 } 3549 case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST: { 3550 break; 3551 } 3552 case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: { 3553 Message sentMessage = mCurrentCommand.getData().getParcelable( 3554 MESSAGE_BUNDLE_KEY_SENT_MESSAGE); 3555 onMessageSendFailLocal(sentMessage, NanStatusCode.INTERNAL_FAILURE); 3556 mSendQueueBlocked = false; 3557 transmitNextMessage(); 3558 break; 3559 } 3560 case COMMAND_TYPE_ENABLE_USAGE: 3561 Log.wtf(TAG, "processTimeout: ENABLE_USAGE - shouldn't be waiting!"); 3562 break; 3563 case COMMAND_TYPE_DISABLE_USAGE: 3564 Log.wtf(TAG, "processTimeout: DISABLE_USAGE - shouldn't be waiting!"); 3565 break; 3566 case COMMAND_TYPE_GET_CAPABILITIES: 3567 Log.e(TAG, 3568 "processTimeout: GET_CAPABILITIES timed-out - strange, will try again" 3569 + " when next enabled!?"); 3570 break; 3571 case COMMAND_TYPE_DELETE_ALL_DATA_PATH_INTERFACES: 3572 Log.wtf(TAG, 3573 "processTimeout: DELETE_ALL_DATA_PATH_INTERFACES - shouldn't be " 3574 + "waiting!"); 3575 break; 3576 case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE: 3577 // TODO: fix status: timeout 3578 onCreateDataPathInterfaceResponseLocal(mCurrentCommand, false, 0); 3579 break; 3580 case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE: 3581 // TODO: fix status: timeout 3582 onDeleteDataPathInterfaceResponseLocal(mCurrentCommand, false, 0); 3583 break; 3584 case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP: 3585 // TODO: fix status: timeout 3586 onInitiateDataPathResponseFailLocal(mCurrentCommand, 0); 3587 break; 3588 case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST: 3589 // TODO: fix status: timeout 3590 onRespondToDataPathSetupRequestResponseLocal(mCurrentCommand, false, 0); 3591 break; 3592 case COMMAND_TYPE_END_DATA_PATH: 3593 // TODO: fix status: timeout 3594 onEndPathEndResponseLocal(mCurrentCommand, false, 0); 3595 break; 3596 case COMMAND_TYPE_END_PAIRING: 3597 // TODO: fix status: timeout 3598 break; 3599 case COMMAND_TYPE_DELAYED_INITIALIZATION: 3600 Log.wtf(TAG, 3601 "processTimeout: COMMAND_TYPE_DELAYED_INITIALIZATION - shouldn't be " 3602 + "waiting!"); 3603 break; 3604 case COMMAND_TYPE_GET_AWARE: 3605 Log.wtf(TAG, 3606 "processTimeout: COMMAND_TYPE_GET_AWARE - shouldn't be waiting!"); 3607 break; 3608 case COMMAND_TYPE_RELEASE_AWARE: 3609 Log.wtf(TAG, 3610 "processTimeout: COMMAND_TYPE_RELEASE_AWARE - shouldn't be waiting!"); 3611 break; 3612 case COMMAND_TYPE_DISABLE: 3613 onDisableResponseLocal(mCurrentCommand, NanStatusCode.INTERNAL_FAILURE); 3614 break; 3615 default: 3616 Log.wtf(TAG, "processTimeout: this isn't a COMMAND -- msg=" + msg); 3617 /* fall-through */ 3618 } 3619 } 3620 updateSendMessageTimeout()3621 private void updateSendMessageTimeout() { 3622 if (mVdbg) { 3623 Log.v(TAG, "updateSendMessageTimeout: mHostQueuedSendMessages.size()=" 3624 + mHostQueuedSendMessages.size() + ", mFwQueuedSendMessages.size()=" 3625 + mFwQueuedSendMessages.size() + ", mSendQueueBlocked=" 3626 + mSendQueueBlocked); 3627 } 3628 Iterator<Message> it = mFwQueuedSendMessages.values().iterator(); 3629 if (it.hasNext()) { 3630 /* 3631 * Schedule timeout based on the first message in the queue (which is the earliest 3632 * submitted message). Timeout = queuing time + timeout constant. 3633 */ 3634 Message msg = it.next(); 3635 mSendMessageTimeoutMessage.schedule( 3636 msg.getData().getLong(MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME) 3637 + AWARE_SEND_MESSAGE_TIMEOUT); 3638 } else { 3639 mSendMessageTimeoutMessage.cancel(); 3640 } 3641 } 3642 processSendMessageTimeout()3643 private void processSendMessageTimeout() { 3644 if (mVdbg) { 3645 Log.v(TAG, "processSendMessageTimeout: mHostQueuedSendMessages.size()=" 3646 + mHostQueuedSendMessages.size() + ", mFwQueuedSendMessages.size()=" 3647 + mFwQueuedSendMessages.size() + ", mSendQueueBlocked=" 3648 + mSendQueueBlocked); 3649 } 3650 3651 /* 3652 * Note: using 'first' to always time-out (remove) at least 1 notification (partially) 3653 * due to test code needs: there's no way to mock elapsedRealtime(). TODO: replace with 3654 * injected getClock() once moved off of mmwd. 3655 */ 3656 boolean first = true; 3657 long currentTime = SystemClock.elapsedRealtime(); 3658 Iterator<Map.Entry<Short, Message>> it = mFwQueuedSendMessages.entrySet().iterator(); 3659 while (it.hasNext()) { 3660 Map.Entry<Short, Message> entry = it.next(); 3661 short transactionId = entry.getKey(); 3662 Message message = entry.getValue(); 3663 long messageEnqueueTime = message.getData().getLong( 3664 MESSAGE_BUNDLE_KEY_SEND_MESSAGE_ENQUEUE_TIME); 3665 if (first || messageEnqueueTime + AWARE_SEND_MESSAGE_TIMEOUT <= currentTime) { 3666 if (mVerboseLoggingEnabled) { 3667 Log.v(TAG, "processSendMessageTimeout: expiring - transactionId=" 3668 + transactionId + ", message=" + message 3669 + ", due to messageEnqueueTime=" + messageEnqueueTime 3670 + ", currentTime=" + currentTime); 3671 } 3672 onMessageSendFailLocal(message, NanStatusCode.INTERNAL_FAILURE); 3673 it.remove(); 3674 first = false; 3675 } else { 3676 break; 3677 } 3678 } 3679 updateSendMessageTimeout(); 3680 mSendQueueBlocked = false; 3681 transmitNextMessage(); 3682 } 3683 isUidExceededMessageQueueDepthLimit(int uid)3684 private boolean isUidExceededMessageQueueDepthLimit(int uid) { 3685 int size = mHostQueuedSendMessages.size(); 3686 int numOfMessages = 0; 3687 if (size < MESSAGE_QUEUE_DEPTH_PER_UID) { 3688 return false; 3689 } 3690 for (int i = 0; i < size; ++i) { 3691 if (mHostQueuedSendMessages.valueAt(i).getData() 3692 .getInt(MESSAGE_BUNDLE_KEY_UID) == uid) { 3693 numOfMessages++; 3694 if (numOfMessages >= MESSAGE_QUEUE_DEPTH_PER_UID) { 3695 return true; 3696 } 3697 } 3698 } 3699 return false; 3700 } 3701 3702 @Override getLogRecString(Message msg)3703 protected String getLogRecString(Message msg) { 3704 StringBuilder sb = new StringBuilder(); 3705 if (msg.what == MESSAGE_TYPE_NOTIFICATION || msg.what == MESSAGE_TYPE_COMMAND 3706 || msg.what == MESSAGE_TYPE_RESPONSE 3707 || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) { 3708 sb.append(getWhatToString(msg.arg1)); 3709 } 3710 3711 Message message = msg; 3712 if ((msg.what == MESSAGE_TYPE_RESPONSE || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) 3713 && mCurrentCommand != null) { 3714 message = mCurrentCommand; 3715 } 3716 if (msg.what == MESSAGE_TYPE_COMMAND 3717 || msg.what == MESSAGE_TYPE_RESPONSE 3718 || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) { 3719 if (message.arg1 == COMMAND_TYPE_CONNECT) { 3720 sb.append(" caller=") 3721 .append(message.getData().getString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE)) 3722 .append("(") 3723 .append(message.getData().getInt(MESSAGE_BUNDLE_KEY_UID)) 3724 .append(")"); 3725 } else { 3726 WifiAwareClientState client = mClients.get(message.arg2); 3727 if (client != null) { 3728 sb.append(" caller=") 3729 .append(client.getCallingPackage()) 3730 .append("(") 3731 .append(client.getUid()) 3732 .append(")"); 3733 } 3734 } 3735 } 3736 if (msg.what == MESSAGE_TYPE_COMMAND 3737 && mCurrentTransactionId != TRANSACTION_ID_IGNORE) { 3738 sb.append(" (Transaction ID=").append(mCurrentTransactionId).append(")"); 3739 } else if (msg.what == MESSAGE_TYPE_RESPONSE 3740 || msg.what == MESSAGE_TYPE_RESPONSE_TIMEOUT) { 3741 sb.append(" (Transaction ID=").append(msg.arg2).append(")"); 3742 } 3743 3744 return sb.toString(); 3745 } 3746 3747 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)3748 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 3749 pw.println("WifiAwareStateMachine:"); 3750 pw.println(" mNextTransactionId: " + mNextTransactionId); 3751 pw.println(" mNextSessionId: " + mNextSessionId); 3752 pw.println(" mCurrentCommand: " + mCurrentCommand); 3753 pw.println(" mCurrentTransaction: " + mCurrentTransactionId); 3754 pw.println(" mSendQueueBlocked: " + mSendQueueBlocked); 3755 pw.println(" mSendArrivalSequenceCounter: " + mSendArrivalSequenceCounter); 3756 pw.println(" mHostQueuedSendMessages: [" + mHostQueuedSendMessages + "]"); 3757 pw.println(" mFwQueuedSendMessages: [" + mFwQueuedSendMessages + "]"); 3758 super.dump(fd, pw, args); 3759 } 3760 } 3761 sendAwareStateChangedBroadcast(boolean enabled)3762 private void sendAwareStateChangedBroadcast(boolean enabled) { 3763 if (mVdbg) { 3764 Log.v(TAG, "sendAwareStateChangedBroadcast: enabled=" + enabled); 3765 } 3766 final Intent intent = new Intent(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED); 3767 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3768 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 3769 } 3770 sendAwareResourcesChangedBroadcast()3771 private void sendAwareResourcesChangedBroadcast() { 3772 if (!SdkLevel.isAtLeastT()) { 3773 return; 3774 } 3775 if (mVdbg) { 3776 Log.v(TAG, "sendAwareResourcesChangedBroadcast"); 3777 } 3778 final Intent intent = new Intent(WifiAwareManager.ACTION_WIFI_AWARE_RESOURCE_CHANGED); 3779 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 3780 intent.putExtra(WifiAwareManager.EXTRA_AWARE_RESOURCES, getAvailableAwareResources()); 3781 mContext.sendBroadcastAsUser(intent, UserHandle.ALL, ACCESS_WIFI_STATE); 3782 } 3783 3784 /* 3785 * COMMANDS 3786 */ 3787 connectLocal(short transactionId, int clientId, int uid, int pid, String callingPackage, @Nullable String callingFeatureId, IWifiAwareEventCallback callback, ConfigRequest configRequest, boolean notifyIdentityChange, Object attributionSource, boolean awareOffload, boolean reEnableAware, int callerType)3788 private boolean connectLocal(short transactionId, int clientId, int uid, int pid, 3789 String callingPackage, @Nullable String callingFeatureId, 3790 IWifiAwareEventCallback callback, ConfigRequest configRequest, 3791 boolean notifyIdentityChange, Object attributionSource, boolean awareOffload, 3792 boolean reEnableAware, int callerType) { 3793 if (mVerboseLoggingEnabled) { 3794 Log.v(TAG, 3795 "connectLocal(): transactionId=" + transactionId + ", clientId=" + clientId 3796 + ", uid=" + uid + ", pid=" + pid + ", callingPackage=" + callingPackage 3797 + ", callback=" + callback + ", configRequest=" + configRequest 3798 + ", notifyIdentityChange=" + notifyIdentityChange 3799 + ", awareOffload" + awareOffload 3800 + ", reEnableAware" + reEnableAware); 3801 } 3802 if (!mUsageEnabled) { 3803 Log.w(TAG, "connect(): called with mUsageEnabled=false"); 3804 try { 3805 callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE); 3806 mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE, callerType, 3807 callingFeatureId, uid); 3808 } catch (RemoteException e) { 3809 Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e); 3810 } 3811 return false; 3812 } 3813 3814 if (mClients.get(clientId) != null) { 3815 Log.e(TAG, "connectLocal: entry already exists for clientId=" + clientId); 3816 } 3817 3818 if (mVdbg) { 3819 Log.v(TAG, "mCurrentAwareConfiguration=" + mCurrentAwareConfiguration 3820 + ", mCurrentIdentityNotification=" + mCurrentIdentityNotification); 3821 } 3822 3823 ConfigRequest merged = mergeConfigRequests(configRequest); 3824 if (merged == null) { 3825 Log.e(TAG, "connectLocal: requested configRequest=" + configRequest 3826 + ", incompatible with current configurations"); 3827 try { 3828 callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE); 3829 mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE, callerType, 3830 callingFeatureId, uid); 3831 } catch (RemoteException e) { 3832 Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e); 3833 } 3834 return false; 3835 } else if (mVdbg) { 3836 Log.v(TAG, "connectLocal: merged=" + merged); 3837 } 3838 3839 if (mCurrentAwareConfiguration != null && mCurrentAwareConfiguration.equals(merged) 3840 && (mCurrentIdentityNotification || !notifyIdentityChange) 3841 && !reEnableAware) { 3842 if (awareOffload && !isAwareOffloading()) { 3843 try { 3844 if (mVdbg) { 3845 Log.v(TAG, "Connect failure for clientId:" + clientId); 3846 } 3847 callback.onConnectFail(clientId); 3848 } catch (RemoteException e) { 3849 Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e); 3850 } 3851 return false; 3852 } 3853 WifiAwareClientState client = new WifiAwareClientState(mContext, clientId, uid, pid, 3854 callingPackage, callingFeatureId, callback, configRequest, notifyIdentityChange, 3855 SystemClock.elapsedRealtime(), mWifiPermissionsUtil, attributionSource, 3856 awareOffload, callerType); 3857 client.enableVerboseLogging(mVerboseLoggingEnabled, mVdbg); 3858 client.onClusterChange(mClusterEventType, mClusterId, mCurrentDiscoveryInterfaceMac); 3859 mClients.append(clientId, client); 3860 mAwareMetrics.recordAttachSession(uid, notifyIdentityChange, mClients, callerType, 3861 callingFeatureId); 3862 try { 3863 if (mVdbg) { 3864 Log.v(TAG, "Connect success for clientId:" + clientId); 3865 } 3866 callback.onConnectSuccess(clientId); 3867 } catch (RemoteException e) { 3868 Log.w(TAG, "connectLocal onConnectSuccess(): RemoteException (FYI): " + e); 3869 } 3870 if (!mWifiAwareNativeManager.replaceRequestorWs(createMergedRequestorWs())) { 3871 Log.w(TAG, "Failed to replace requestorWs"); 3872 } 3873 return false; 3874 } 3875 boolean notificationRequired = 3876 doesAnyClientNeedIdentityChangeNotifications() || notifyIdentityChange; 3877 boolean rangingRequired = doesAnyClientNeedRanging(); 3878 int instantMode = getInstantModeFromAllClients(); 3879 boolean enableInstantMode = false; 3880 int instantModeChannel = 0; 3881 if (instantMode != INSTANT_MODE_DISABLED || mInstantCommModeGlobalEnable) { 3882 enableInstantMode = true; 3883 instantModeChannel = getAwareInstantCommunicationChannel(instantMode); 3884 } 3885 3886 if (mCurrentAwareConfiguration == null) { 3887 WorkSource workSource; 3888 if (awareOffload || mOpportunisticSet.contains(callingPackage)) { 3889 workSource = new WorkSource(Process.WIFI_UID); 3890 } else { 3891 workSource = new WorkSource(uid, callingPackage); 3892 } 3893 mWifiAwareNativeManager.tryToGetAware(workSource); 3894 } 3895 boolean initialConfiguration = mCurrentAwareConfiguration == null 3896 || reEnableAware; 3897 boolean success = mWifiAwareNativeApi.enableAndConfigure(transactionId, merged, 3898 notificationRequired, initialConfiguration, 3899 mPowerManager.isInteractive(), mPowerManager.isDeviceIdleMode(), 3900 rangingRequired, enableInstantMode, instantModeChannel, mClusterIdInt); 3901 if (!success) { 3902 if (mCurrentAwareConfiguration == null) { 3903 mWifiAwareNativeManager.releaseAware(); 3904 } 3905 try { 3906 callback.onConnectFail(NanStatusCode.INTERNAL_FAILURE); 3907 mAwareMetrics.recordAttachStatus(NanStatusCode.INTERNAL_FAILURE, callerType, 3908 callingFeatureId, uid); 3909 } catch (RemoteException e) { 3910 Log.w(TAG, "connectLocal onConnectFail(): RemoteException (FYI): " + e); 3911 } 3912 } 3913 3914 return success; 3915 } 3916 disconnectLocal(short transactionId, int clientId)3917 private boolean disconnectLocal(short transactionId, int clientId) { 3918 if (mVerboseLoggingEnabled) { 3919 Log.v(TAG, "disconnectLocal(): transactionId=" + transactionId 3920 + ", clientId=" + clientId); 3921 } 3922 3923 WifiAwareClientState client = mClients.get(clientId); 3924 if (client == null) { 3925 Log.e(TAG, "disconnectLocal: no entry for clientId=" + clientId); 3926 return false; 3927 } 3928 mClients.delete(clientId); 3929 mAwareMetrics.recordAttachSessionDuration(client.getCreationTime()); 3930 SparseArray<WifiAwareDiscoverySessionState> sessions = client.getSessions(); 3931 for (int i = 0; i < sessions.size(); ++i) { 3932 mAwareMetrics.recordDiscoverySessionDuration(sessions.valueAt(i).getCreationTime(), 3933 sessions.valueAt(i).isPublishSession(), sessions.valueAt(i).getSessionId()); 3934 } 3935 client.destroy(); 3936 3937 if (mClients.size() == 0) { 3938 mCurrentAwareConfiguration = null; 3939 mPairingRequest.clear(); 3940 mDataPathMgr.deleteAllInterfaces(); 3941 mCurrentRangingEnabled = false; 3942 mCurrentIdentityNotification = false; 3943 mInstantCommModeClientRequest = INSTANT_MODE_DISABLED; 3944 mAwareMetrics.reportAwareInstantModeEnabled(false); 3945 mSm.onAwareDownCleanupSendQueueState(); 3946 deferDisableAware(true); 3947 return false; 3948 } 3949 3950 if (!mWifiAwareNativeManager.replaceRequestorWs(createMergedRequestorWs())) { 3951 Log.w(TAG, "Failed to replace requestorWs"); 3952 } 3953 3954 ConfigRequest merged = mergeConfigRequests(null); 3955 if (merged == null) { 3956 Log.wtf(TAG, "disconnectLocal: got an incompatible merge on remaining configs!?"); 3957 return false; 3958 } 3959 boolean notificationReqs = doesAnyClientNeedIdentityChangeNotifications(); 3960 boolean rangingEnabled = doesAnyClientNeedRanging(); 3961 int instantMode = getInstantModeFromAllClients(); 3962 boolean enableInstantMode = false; 3963 int instantModeChannel = 0; 3964 if (instantMode != INSTANT_MODE_DISABLED || mInstantCommModeGlobalEnable) { 3965 enableInstantMode = true; 3966 instantModeChannel = getAwareInstantCommunicationChannel(instantMode); 3967 } 3968 if (merged.equals(mCurrentAwareConfiguration) 3969 && mCurrentIdentityNotification == notificationReqs 3970 && mCurrentRangingEnabled == rangingEnabled 3971 && mInstantCommModeClientRequest == instantMode) { 3972 return false; 3973 } 3974 3975 return mWifiAwareNativeApi.enableAndConfigure(transactionId, merged, notificationReqs, 3976 false, mPowerManager.isInteractive(), mPowerManager.isDeviceIdleMode(), 3977 rangingEnabled, enableInstantMode, instantModeChannel, mClusterIdInt); 3978 } 3979 reconfigureLocal(short transactionId)3980 private boolean reconfigureLocal(short transactionId) { 3981 if (mVdbg) Log.v(TAG, "reconfigureLocal(): transactionId=" + transactionId); 3982 3983 if (mClients.size() == 0) { 3984 // no clients - Aware is not enabled, nothing to reconfigure 3985 return false; 3986 } 3987 3988 boolean notificationReqs = doesAnyClientNeedIdentityChangeNotifications(); 3989 boolean rangingEnabled = doesAnyClientNeedRanging(); 3990 int instantMode = getInstantModeFromAllClients(); 3991 boolean enableInstantMode = false; 3992 int instantModeChannel = 0; 3993 if (instantMode != INSTANT_MODE_DISABLED || mInstantCommModeGlobalEnable) { 3994 enableInstantMode = true; 3995 instantModeChannel = getAwareInstantCommunicationChannel(instantMode); 3996 } 3997 3998 return mWifiAwareNativeApi.enableAndConfigure(transactionId, mergeConfigRequests(null), 3999 notificationReqs, false, mPowerManager.isInteractive(), 4000 mPowerManager.isDeviceIdleMode(), rangingEnabled, 4001 enableInstantMode, instantModeChannel, mClusterIdInt); 4002 } 4003 terminateSessionLocal(int clientId, int sessionId)4004 private void terminateSessionLocal(int clientId, int sessionId) { 4005 if (mVerboseLoggingEnabled) { 4006 Log.v(TAG, "terminateSessionLocal(): clientId=" + clientId 4007 + ", sessionId=" + sessionId); 4008 } 4009 4010 WifiAwareClientState client = mClients.get(clientId); 4011 if (client == null) { 4012 Log.e(TAG, "terminateSession: no client exists for clientId=" + clientId); 4013 return; 4014 } 4015 4016 WifiAwareDiscoverySessionState session = client.terminateSession(sessionId); 4017 // If Ranging enabled or instant mode require changes, reconfigure. 4018 if (mCurrentRangingEnabled != doesAnyClientNeedRanging() 4019 || mInstantCommModeClientRequest != getInstantModeFromAllClients()) { 4020 reconfigure(); 4021 } 4022 if (session != null) { 4023 mAwareMetrics.recordDiscoverySessionDuration(session.getCreationTime(), 4024 session.isPublishSession(), sessionId); 4025 } 4026 sendAwareResourcesChangedBroadcast(); 4027 } 4028 publishLocal(short transactionId, int clientId, PublishConfig publishConfig, IWifiAwareDiscoverySessionCallback callback)4029 private boolean publishLocal(short transactionId, int clientId, PublishConfig publishConfig, 4030 IWifiAwareDiscoverySessionCallback callback) { 4031 if (mVerboseLoggingEnabled) { 4032 Log.v(TAG, "publishLocal(): transactionId=" + transactionId + ", clientId=" + clientId 4033 + ", publishConfig=" + publishConfig + ", callback=" + callback); 4034 } 4035 4036 WifiAwareClientState client = mClients.get(clientId); 4037 if (client == null) { 4038 Log.e(TAG, "publishLocal: no client exists for clientId=" + clientId); 4039 try { 4040 callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE); 4041 } catch (RemoteException e) { 4042 Log.w(TAG, "publishLocal onSessionConfigFail(): RemoteException (FYI): " + e); 4043 } 4044 return false; 4045 } 4046 AwarePairingConfig pairingConfig = publishConfig.getPairingConfig(); 4047 byte[] nik = null; 4048 if (pairingConfig != null && pairingConfig.isPairingVerificationEnabled()) { 4049 nik = mPairingConfigManager 4050 .getNikForCallingPackage(client.getCallingPackage()); 4051 } 4052 boolean success = mWifiAwareNativeApi.publish(transactionId, (byte) 0, publishConfig, nik); 4053 if (!success) { 4054 try { 4055 callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE); 4056 } catch (RemoteException e) { 4057 Log.w(TAG, "publishLocal onSessionConfigFail(): RemoteException (FYI): " + e); 4058 } 4059 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE, 4060 true, client.mCallerType, client.mCallingFeatureId); 4061 } 4062 4063 return success; 4064 } 4065 updatePublishLocal(short transactionId, int clientId, int sessionId, PublishConfig publishConfig)4066 private boolean updatePublishLocal(short transactionId, int clientId, int sessionId, 4067 PublishConfig publishConfig) { 4068 if (mVdbg) { 4069 Log.v(TAG, "updatePublishLocal(): transactionId=" + transactionId + ", clientId=" 4070 + clientId + ", sessionId=" + sessionId + ", publishConfig=" + publishConfig); 4071 } 4072 4073 WifiAwareClientState client = mClients.get(clientId); 4074 if (client == null) { 4075 Log.e(TAG, "updatePublishLocal: no client exists for clientId=" + clientId); 4076 return false; 4077 } 4078 4079 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4080 if (session == null) { 4081 Log.e(TAG, "updatePublishLocal: no session exists for clientId=" + clientId 4082 + ", sessionId=" + sessionId); 4083 return false; 4084 } 4085 4086 AwarePairingConfig pairingConfig = publishConfig.getPairingConfig(); 4087 byte[] nik = null; 4088 if (pairingConfig != null && pairingConfig.isPairingVerificationEnabled()) { 4089 nik = mPairingConfigManager.getNikForCallingPackage( 4090 client.getCallingPackage()); 4091 } 4092 4093 boolean status = session.updatePublish(transactionId, publishConfig, nik); 4094 if (!status) { 4095 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE, 4096 true, client.mCallerType, client.mCallingFeatureId); 4097 } 4098 return status; 4099 } 4100 subscribeLocal(short transactionId, int clientId, SubscribeConfig subscribeConfig, IWifiAwareDiscoverySessionCallback callback)4101 private boolean subscribeLocal(short transactionId, int clientId, 4102 SubscribeConfig subscribeConfig, IWifiAwareDiscoverySessionCallback callback) { 4103 if (mVerboseLoggingEnabled) { 4104 Log.v(TAG, "subscribeLocal(): transactionId=" + transactionId + ", clientId=" + clientId 4105 + ", subscribeConfig=" + subscribeConfig + ", callback=" + callback); 4106 } 4107 4108 WifiAwareClientState client = mClients.get(clientId); 4109 if (client == null) { 4110 try { 4111 callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE); 4112 } catch (RemoteException e) { 4113 Log.w(TAG, "subscribeLocal onSessionConfigFail(): RemoteException (FYI): " + e); 4114 } 4115 Log.e(TAG, "subscribeLocal: no client exists for clientId=" + clientId); 4116 return false; 4117 } 4118 AwarePairingConfig pairingConfig = subscribeConfig.getPairingConfig(); 4119 byte[] nik = null; 4120 if (pairingConfig != null && pairingConfig.isPairingVerificationEnabled()) { 4121 nik = mPairingConfigManager.getNikForCallingPackage( 4122 client.getCallingPackage()); 4123 } 4124 4125 boolean success = mWifiAwareNativeApi.subscribe(transactionId, (byte) 0, subscribeConfig, 4126 nik); 4127 if (!success) { 4128 try { 4129 callback.onSessionConfigFail(NanStatusCode.INTERNAL_FAILURE); 4130 } catch (RemoteException e) { 4131 Log.w(TAG, "subscribeLocal onSessionConfigFail(): RemoteException (FYI): " + e); 4132 } 4133 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE, 4134 false, client.mCallerType, client.mCallingFeatureId); 4135 } 4136 4137 return success; 4138 } 4139 updateSubscribeLocal(short transactionId, int clientId, int sessionId, SubscribeConfig subscribeConfig)4140 private boolean updateSubscribeLocal(short transactionId, int clientId, int sessionId, 4141 SubscribeConfig subscribeConfig) { 4142 if (mVdbg) { 4143 Log.v(TAG, 4144 "updateSubscribeLocal(): transactionId=" + transactionId + ", clientId=" 4145 + clientId + ", sessionId=" + sessionId + ", subscribeConfig=" 4146 + subscribeConfig); 4147 } 4148 4149 WifiAwareClientState client = mClients.get(clientId); 4150 if (client == null) { 4151 Log.e(TAG, "updateSubscribeLocal: no client exists for clientId=" + clientId); 4152 return false; 4153 } 4154 4155 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4156 if (session == null) { 4157 Log.e(TAG, "updateSubscribeLocal: no session exists for clientId=" + clientId 4158 + ", sessionId=" + sessionId); 4159 return false; 4160 } 4161 AwarePairingConfig pairingConfig = subscribeConfig.getPairingConfig(); 4162 byte[] nik = null; 4163 if (pairingConfig != null && pairingConfig.isPairingVerificationEnabled()) { 4164 nik = mPairingConfigManager.getNikForCallingPackage( 4165 client.getCallingPackage()); 4166 } 4167 boolean status = session.updateSubscribe(transactionId, subscribeConfig, nik); 4168 if (!status) { 4169 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.INTERNAL_FAILURE, 4170 false, client.mCallerType, client.mCallingFeatureId); 4171 } 4172 return status; 4173 } 4174 initiateNanPairingRequestLocal(short transactionId, int clientId, int sessionId, int peerId, String password, int requestType, int akm, byte[] pmk, int cipherSuite)4175 private boolean initiateNanPairingRequestLocal(short transactionId, int clientId, int sessionId, 4176 int peerId, String password, int requestType, int akm, 4177 byte[] pmk, int cipherSuite) { 4178 if (mVdbg) { 4179 Log.v(TAG, "initiateNanPairingRequestLocal: transactionId=" + transactionId 4180 + ", clientId=" + clientId + ", sessionId=" + sessionId + ", peerId=" + peerId); 4181 } 4182 WifiAwareClientState client = mClients.get(clientId); 4183 if (client == null) { 4184 Log.e(TAG, "initiateNanPairingRequestLocal: no client exists for clientId=" + clientId); 4185 return false; 4186 } 4187 4188 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4189 if (session == null) { 4190 Log.e(TAG, "initiateNanPairingRequestLocal: no session exists for clientId=" 4191 + clientId + ", sessionId=" + sessionId); 4192 return false; 4193 } 4194 return session.initiatePairing(transactionId, peerId, password, requestType, 4195 mPairingConfigManager.getNikForCallingPackage(client.getCallingPackage()), 4196 pmk, akm, cipherSuite); 4197 } 4198 respondToPairingRequestLocal(short transactionId, int clientId, int sessionId, int peerId, int pairingId, boolean accept, int requestType, byte[] pmk, String password, int akm, int cipherSuite)4199 private boolean respondToPairingRequestLocal(short transactionId, int clientId, int sessionId, 4200 int peerId, int pairingId, boolean accept, int requestType, byte[] pmk, 4201 String password, int akm, int cipherSuite) { 4202 if (mVdbg) { 4203 Log.v(TAG, 4204 "respondToPairingRequestLocal: transactionId=" + transactionId + ", clientId=" 4205 + clientId + ", sessionId=" + sessionId + ", peerId=" 4206 + peerId); 4207 } 4208 WifiAwareClientState client = mClients.get(clientId); 4209 if (client == null) { 4210 Log.e(TAG, "respondToPairingRequestLocal: no client exists for clientId=" + clientId); 4211 return false; 4212 } 4213 4214 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4215 if (session == null) { 4216 Log.e(TAG, "respondToPairingRequestLocal: no session exists for clientId=" + clientId 4217 + ", sessionId=" + sessionId); 4218 return false; 4219 } 4220 return session.respondToPairingRequest(transactionId, peerId, pairingId, 4221 accept, 4222 mPairingConfigManager.getNikForCallingPackage(client.getCallingPackage()), 4223 requestType, pmk, password, akm, cipherSuite); 4224 } 4225 initiateBootstrappingRequestLocal(short transactionId, int clientId, int sessionId, int peerId, int method, byte[] cookie, boolean isComeBack)4226 private boolean initiateBootstrappingRequestLocal(short transactionId, int clientId, 4227 int sessionId, int peerId, int method, byte[] cookie, boolean isComeBack) { 4228 String methodString = "initiateBootstrappingRequestLocal"; 4229 if (mVdbg) { 4230 Log.v(TAG, methodString + ": transactionId=" + transactionId 4231 + ", clientId=" + clientId + ", sessionId=" + sessionId + ", peerId=" + peerId); 4232 } 4233 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 4234 methodString); 4235 if (session == null) { 4236 return false; 4237 } 4238 return session.initiateBootstrapping(transactionId, peerId, method, cookie, isComeBack); 4239 } 4240 respondToBootstrappingRequestLocal(short transactionId, int clientId, int sessionId, int peerId, int bootstrappingId, boolean accept, int method)4241 private boolean respondToBootstrappingRequestLocal(short transactionId, int clientId, 4242 int sessionId, int peerId, int bootstrappingId, boolean accept, int method) { 4243 String methodString = "respondToBootstrappingRequestLocal"; 4244 if (mVdbg) { 4245 Log.v(TAG, methodString + ": transactionId=" + transactionId 4246 + ", clientId=" + clientId + ", sessionId=" + sessionId + ", peerId=" + peerId); 4247 } 4248 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 4249 methodString); 4250 if (session == null) { 4251 return false; 4252 } 4253 return session.respondToBootstrapping(transactionId, peerId, bootstrappingId, accept, 4254 method); 4255 } 4256 sendFollowonMessageLocal(short transactionId, int clientId, int sessionId, int peerId, byte[] message, int messageId)4257 private boolean sendFollowonMessageLocal(short transactionId, int clientId, int sessionId, 4258 int peerId, byte[] message, int messageId) { 4259 String methodString = "sendFollowonMessageLocal"; 4260 if (mVdbg) { 4261 Log.v(TAG, methodString + "(): transactionId=" + transactionId + ", clientId=" 4262 + clientId + ", sessionId=" + sessionId + ", peerId=" + peerId 4263 + ", messageId=" + messageId); 4264 } 4265 4266 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 4267 methodString); 4268 if (session == null) { 4269 return false; 4270 } 4271 4272 return session.sendMessage(transactionId, peerId, message, messageId); 4273 } 4274 enableUsageLocal()4275 private void enableUsageLocal() { 4276 Log.d(TAG, "enableUsageLocal: mUsageEnabled=" + mUsageEnabled); 4277 4278 if (mUsageEnabled) { 4279 return; 4280 } 4281 mUsageEnabled = true; 4282 sendAwareStateChangedBroadcast(true); 4283 4284 mAwareMetrics.recordEnableUsage(); 4285 } 4286 disableUsageLocal(short transactionId, boolean markAsAvailable)4287 private void disableUsageLocal(short transactionId, boolean markAsAvailable) { 4288 Log.d(TAG, "disableUsageLocal: transactionId=" + transactionId + ", mUsageEnabled=" 4289 + mUsageEnabled); 4290 4291 if (!mUsageEnabled) { 4292 return; 4293 } 4294 onAwareDownLocal(); 4295 4296 mUsageEnabled = markAsAvailable; 4297 mCurrentRangingEnabled = false; 4298 mCurrentIdentityNotification = false; 4299 mInstantCommModeClientRequest = INSTANT_MODE_DISABLED; 4300 mAwareMetrics.reportAwareInstantModeEnabled(false); 4301 deferDisableAware(true); 4302 sendAwareStateChangedBroadcast(markAsAvailable); 4303 if (!markAsAvailable) { 4304 mAwareMetrics.recordDisableUsage(); 4305 } 4306 } 4307 initiateDataPathSetupLocal(short transactionId, WifiAwareNetworkSpecifier networkSpecifier, int peerId, int channelRequestType, int channel, byte[] peer, String interfaceName, boolean isOutOfBand, byte[] appInfo)4308 private boolean initiateDataPathSetupLocal(short transactionId, 4309 WifiAwareNetworkSpecifier networkSpecifier, int peerId, int channelRequestType, 4310 int channel, byte[] peer, String interfaceName, 4311 boolean isOutOfBand, byte[] appInfo) { 4312 WifiAwareDataPathSecurityConfig securityConfig = networkSpecifier 4313 .getWifiAwareDataPathSecurityConfig(); 4314 if (mVerboseLoggingEnabled) { 4315 Log.v(TAG, "initiateDataPathSetupLocal(): transactionId=" + transactionId 4316 + ", networkSpecifier=" + networkSpecifier + ", peerId=" + peerId 4317 + ", channelRequestType=" + channelRequestType + ", channel=" + channel 4318 + ", peer=" 4319 + String.valueOf(HexEncoding.encode(peer)) + ", interfaceName=" + interfaceName 4320 + ", securityConfig=" + ((securityConfig == null) ? "" : securityConfig) 4321 + ", isOutOfBand=" 4322 + isOutOfBand + ", appInfo=" + (appInfo == null ? "<null>" : "<non-null>")); 4323 } 4324 byte pubSubId = 0; 4325 if (!isOutOfBand) { 4326 WifiAwareClientState client = mClients.get(networkSpecifier.clientId); 4327 if (client == null) { 4328 Log.e(TAG, "initiateDataPathSetupLocal: no client exists for clientId=" 4329 + networkSpecifier.clientId); 4330 return false; 4331 } 4332 4333 WifiAwareDiscoverySessionState session = client.getSession(networkSpecifier.sessionId); 4334 if (session == null) { 4335 Log.e(TAG, "initiateDataPathSetupLocal: no session exists for clientId=" 4336 + networkSpecifier.clientId + ", sessionId=" + networkSpecifier.sessionId); 4337 return false; 4338 } 4339 pubSubId = (byte) session.getPubSubId(); 4340 } 4341 boolean success = mWifiAwareNativeApi.initiateDataPath(transactionId, peerId, 4342 channelRequestType, channel, peer, interfaceName, isOutOfBand, 4343 appInfo, mCapabilities, networkSpecifier.getWifiAwareDataPathSecurityConfig(), 4344 pubSubId); 4345 if (!success) { 4346 mDataPathMgr.onDataPathInitiateFail(networkSpecifier, NanStatusCode.INTERNAL_FAILURE); 4347 } 4348 4349 return success; 4350 } 4351 respondToDataPathRequestLocal(short transactionId, boolean accept, int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand, WifiAwareNetworkSpecifier networkSpecifier)4352 private boolean respondToDataPathRequestLocal(short transactionId, boolean accept, 4353 int ndpId, String interfaceName, byte[] appInfo, boolean isOutOfBand, 4354 WifiAwareNetworkSpecifier networkSpecifier) { 4355 WifiAwareDataPathSecurityConfig securityConfig = accept ? networkSpecifier 4356 .getWifiAwareDataPathSecurityConfig() : null; 4357 if (mVerboseLoggingEnabled) { 4358 Log.v(TAG, "respondToDataPathRequestLocal(): transactionId=" + transactionId 4359 + ", accept=" + accept + ", ndpId=" + ndpId + ", interfaceName=" + interfaceName 4360 + ", securityConfig=" + securityConfig 4361 + ", isOutOfBand=" + isOutOfBand 4362 + ", appInfo=" + (appInfo == null ? "<null>" : "<non-null>")); 4363 } 4364 byte pubSubId = 0; 4365 if (!isOutOfBand && accept) { 4366 WifiAwareClientState client = mClients.get(networkSpecifier.clientId); 4367 if (client == null) { 4368 Log.e(TAG, "respondToDataPathRequestLocal: no client exists for clientId=" 4369 + networkSpecifier.clientId); 4370 return false; 4371 } 4372 4373 WifiAwareDiscoverySessionState session = client.getSession(networkSpecifier.sessionId); 4374 if (session == null) { 4375 Log.e(TAG, "respondToDataPathRequestLocal: no session exists for clientId=" 4376 + networkSpecifier.clientId + ", sessionId=" + networkSpecifier.sessionId); 4377 return false; 4378 } 4379 pubSubId = (byte) session.getPubSubId(); 4380 } 4381 boolean success = mWifiAwareNativeApi.respondToDataPathRequest(transactionId, accept, ndpId, 4382 interfaceName, appInfo, isOutOfBand, mCapabilities, securityConfig, pubSubId); 4383 if (!success) { 4384 mDataPathMgr.onRespondToDataPathRequest(ndpId, false, NanStatusCode.INTERNAL_FAILURE); 4385 } else { 4386 sendAwareResourcesChangedBroadcast(); 4387 } 4388 return success; 4389 } 4390 endDataPathLocal(short transactionId, int ndpId)4391 private boolean endDataPathLocal(short transactionId, int ndpId) { 4392 if (mVerboseLoggingEnabled) { 4393 Log.v(TAG, "endDataPathLocal: transactionId=" + transactionId + ", ndpId=" + ndpId); 4394 } 4395 sendAwareResourcesChangedBroadcast(); 4396 return mWifiAwareNativeApi.endDataPath(transactionId, ndpId); 4397 } 4398 endPairingLocal(short transactionId, int pairId)4399 private boolean endPairingLocal(short transactionId, int pairId) { 4400 if (mVerboseLoggingEnabled) { 4401 Log.v(TAG, "endPairingLocal: transactionId=" + transactionId + ", pairId=" + pairId); 4402 } 4403 return mWifiAwareNativeApi.endPairing(transactionId, pairId); 4404 } 4405 4406 /* 4407 * RESPONSES 4408 */ 4409 onConfigCompletedLocal(Message completedCommand)4410 private void onConfigCompletedLocal(Message completedCommand) { 4411 Log.d(TAG, "onConfigCompleted: completedCommand=" + completedCommand); 4412 4413 if (completedCommand.arg1 == COMMAND_TYPE_CONNECT) { 4414 if (mCurrentAwareConfiguration == null) { // enabled (as opposed to re-configured) 4415 queryCapabilities(); 4416 mDataPathMgr.createAllInterfaces(); 4417 recordHalApiCall(COMMAND_TYPE_CONNECT, NanStatusCode.SUCCESS, mStartTime); 4418 } else { 4419 recordHalApiCall(COMMAND_TYPE_RECONFIGURE, NanStatusCode.SUCCESS, mStartTime); 4420 } 4421 4422 Bundle data = completedCommand.getData(); 4423 4424 int clientId = completedCommand.arg2; 4425 Pair<IWifiAwareEventCallback, Object> callbackAndAttributionSource = 4426 (Pair<IWifiAwareEventCallback, Object>) completedCommand.obj; 4427 IWifiAwareEventCallback callback = callbackAndAttributionSource.first; 4428 ConfigRequest configRequest = (ConfigRequest) data 4429 .getParcelable(MESSAGE_BUNDLE_KEY_CONFIG); 4430 int uid = data.getInt(MESSAGE_BUNDLE_KEY_UID); 4431 int pid = data.getInt(MESSAGE_BUNDLE_KEY_PID); 4432 boolean notifyIdentityChange = data.getBoolean( 4433 MESSAGE_BUNDLE_KEY_NOTIFY_IDENTITY_CHANGE); 4434 String callingPackage = data.getString(MESSAGE_BUNDLE_KEY_CALLING_PACKAGE); 4435 String callingFeatureId = data.getString(MESSAGE_BUNDLE_KEY_CALLING_FEATURE_ID); 4436 boolean awareOffload = data.getBoolean(MESSAGE_BUNDLE_KEY_AWARE_OFFLOAD); 4437 int callerType = data.getInt(MESSAGE_BUNDLE_KEY_CALLER_TYPE); 4438 4439 WifiAwareClientState client = new WifiAwareClientState(mContext, clientId, uid, pid, 4440 callingPackage, callingFeatureId, callback, configRequest, notifyIdentityChange, 4441 SystemClock.elapsedRealtime(), mWifiPermissionsUtil, 4442 callbackAndAttributionSource.second, awareOffload, callerType); 4443 client.enableVerboseLogging(mVerboseLoggingEnabled, mVdbg); 4444 mClients.put(clientId, client); 4445 mAwareMetrics.recordAttachSession(uid, notifyIdentityChange, mClients, callerType, 4446 callingFeatureId); 4447 try { 4448 if (mVdbg) { 4449 Log.v(TAG, "Connect success for clientId:" + clientId); 4450 } 4451 callback.onConnectSuccess(clientId); 4452 } catch (RemoteException e) { 4453 Log.w(TAG, 4454 "onConfigCompletedLocal onConnectSuccess(): RemoteException (FYI): " + e); 4455 } 4456 client.onClusterChange(mClusterEventType, mClusterId, mCurrentDiscoveryInterfaceMac); 4457 } else if (completedCommand.arg1 == COMMAND_TYPE_DISCONNECT) { 4458 recordHalApiCall(COMMAND_TYPE_RECONFIGURE, NanStatusCode.SUCCESS, mStartTime); 4459 /* 4460 * NOP (i.e. updated configuration after disconnecting a client) 4461 */ 4462 } else if (completedCommand.arg1 == COMMAND_TYPE_RECONFIGURE) { 4463 recordHalApiCall(COMMAND_TYPE_RECONFIGURE, NanStatusCode.SUCCESS, mStartTime); 4464 /* 4465 * NOP (i.e. updated configuration at power saving event) 4466 */ 4467 } else { 4468 Log.wtf(TAG, "onConfigCompletedLocal: unexpected completedCommand=" + completedCommand); 4469 return; 4470 } 4471 4472 mCurrentAwareConfiguration = mergeConfigRequests(null); 4473 if (mCurrentAwareConfiguration == null) { 4474 Log.wtf(TAG, "onConfigCompletedLocal: got a null merged configuration after config!?"); 4475 } 4476 mCurrentIdentityNotification = doesAnyClientNeedIdentityChangeNotifications(); 4477 mCurrentRangingEnabled = doesAnyClientNeedRanging(); 4478 mInstantCommModeClientRequest = getInstantModeFromAllClients(); 4479 if (mInstantCommModeClientRequest == INSTANT_MODE_DISABLED) { 4480 mAwareMetrics.reportAwareInstantModeEnabled(false); 4481 return; 4482 } 4483 mAwareMetrics.reportAwareInstantModeEnabled(true); 4484 if (!mInstantCommModeGlobalEnable) { 4485 // Change the instant communication mode when timeout 4486 mHandler.postDelayed(this::reconfigure, (long) mContext.getResources() 4487 .getInteger(R.integer.config_wifiAwareInstantCommunicationModeDurationMillis)); 4488 } 4489 } 4490 onConfigFailedLocal(Message failedCommand, int reason)4491 private void onConfigFailedLocal(Message failedCommand, int reason) { 4492 if (mVdbg) { 4493 Log.v(TAG, 4494 "onConfigFailedLocal: failedCommand=" + failedCommand + ", reason=" + reason); 4495 } 4496 4497 if (failedCommand.arg1 == COMMAND_TYPE_CONNECT) { 4498 mWifiAwareNativeManager.releaseAware(); 4499 Pair<IWifiAwareEventCallback, Object> callbackAndAttributionSource = 4500 (Pair<IWifiAwareEventCallback, Object>) failedCommand.obj; 4501 IWifiAwareEventCallback callback = callbackAndAttributionSource.first; 4502 try { 4503 callback.onConnectFail(reason); 4504 mAwareMetrics.recordAttachStatus(reason, 0, null, 0); 4505 } catch (RemoteException e) { 4506 Log.w(TAG, "onConfigFailedLocal onConnectFail(): RemoteException (FYI): " + e); 4507 } 4508 recordHalApiCall(COMMAND_TYPE_CONNECT, reason, mStartTime); 4509 } else if (failedCommand.arg1 == COMMAND_TYPE_DISCONNECT) { 4510 recordHalApiCall(COMMAND_TYPE_RECONFIGURE, reason, mStartTime); 4511 /* 4512 * NOP (tried updating configuration after disconnecting a client - 4513 * shouldn't fail but there's nothing to do - the old configuration 4514 * is still up-and-running). 4515 * 4516 * OR: timed-out getting a response to a disable. Either way a NOP. 4517 */ 4518 } else if (failedCommand.arg1 == COMMAND_TYPE_RECONFIGURE) { 4519 recordHalApiCall(COMMAND_TYPE_RECONFIGURE, reason, mStartTime); 4520 /* 4521 * NOP (configuration change as part of possibly power saving event - should not 4522 * fail but there's nothing to do). 4523 */ 4524 } else { 4525 Log.wtf(TAG, "onConfigFailedLocal: unexpected failedCommand=" + failedCommand); 4526 } 4527 } 4528 onDisableResponseLocal(Message command, int reason)4529 private void onDisableResponseLocal(Message command, int reason) { 4530 Log.d(TAG, "onDisableResponseLocal: command=" + command + ", reason=" + reason); 4531 /* 4532 * do nothing: 4533 * - success: was waiting so that don't enable while disabling 4534 * - fail: shouldn't happen (though can if already disabled for instance) 4535 */ 4536 if (reason != NanStatusCode.SUCCESS) { 4537 Log.e(TAG, "onDisableResponseLocal: FAILED!? command=" + command + ", reason=" 4538 + reason); 4539 } 4540 4541 boolean releaseAware = (boolean) command.obj; 4542 if (releaseAware) { 4543 // Need to release Aware 4544 mWifiAwareNativeManager.releaseAware(); 4545 } 4546 mAwareMetrics.recordDisableAware(); 4547 } 4548 onSessionConfigSuccessLocal(Message completedCommand, byte pubSubId, boolean isPublish)4549 private void onSessionConfigSuccessLocal(Message completedCommand, byte pubSubId, 4550 boolean isPublish) { 4551 if (mVdbg) { 4552 Log.v(TAG, "onSessionConfigSuccessLocal: completedCommand=" + completedCommand 4553 + ", pubSubId=" + pubSubId + ", isPublish=" + isPublish); 4554 } 4555 4556 boolean isRangingEnabled; 4557 boolean enableInstantMode; 4558 boolean isSuspendable; 4559 int instantModeBand; 4560 int minRange = -1; 4561 int maxRange = -1; 4562 AwarePairingConfig pairingConfig; 4563 if (isPublish) { 4564 PublishConfig publishConfig = completedCommand.getData().getParcelable( 4565 MESSAGE_BUNDLE_KEY_CONFIG); 4566 isRangingEnabled = publishConfig.mEnableRanging; 4567 enableInstantMode = publishConfig.isInstantCommunicationModeEnabled(); 4568 isSuspendable = SdkLevel.isAtLeastU() && publishConfig.isSuspendable(); 4569 instantModeBand = publishConfig.getInstantCommunicationBand(); 4570 pairingConfig = publishConfig.getPairingConfig(); 4571 } else { 4572 SubscribeConfig subscribeConfig = completedCommand.getData().getParcelable( 4573 MESSAGE_BUNDLE_KEY_CONFIG); 4574 isRangingEnabled = 4575 subscribeConfig.mMinDistanceMmSet || subscribeConfig.mMaxDistanceMmSet; 4576 isSuspendable = SdkLevel.isAtLeastU() && subscribeConfig.isSuspendable(); 4577 if (subscribeConfig.mMinDistanceMmSet) { 4578 minRange = subscribeConfig.mMinDistanceMm; 4579 } 4580 if (subscribeConfig.mMaxDistanceMmSet) { 4581 maxRange = subscribeConfig.mMaxDistanceMm; 4582 } 4583 enableInstantMode = subscribeConfig.isInstantCommunicationModeEnabled(); 4584 instantModeBand = subscribeConfig.getInstantCommunicationBand(); 4585 pairingConfig = subscribeConfig.getPairingConfig(); 4586 } 4587 4588 if (completedCommand.arg1 == COMMAND_TYPE_PUBLISH 4589 || completedCommand.arg1 == COMMAND_TYPE_SUBSCRIBE) { 4590 int clientId = completedCommand.arg2; 4591 IWifiAwareDiscoverySessionCallback callback = 4592 (IWifiAwareDiscoverySessionCallback) completedCommand.obj; 4593 4594 WifiAwareClientState client = mClients.get(clientId); 4595 if (client == null) { 4596 Log.e(TAG, 4597 "onSessionConfigSuccessLocal: no client exists for clientId=" + clientId); 4598 return; 4599 } 4600 4601 int sessionId = mSm.mNextSessionId++; 4602 try { 4603 if (mVdbg) { 4604 Log.v(TAG, 4605 (isPublish ? "publish" : "subscribe") + " session started, sessionId=" 4606 + sessionId); 4607 } 4608 callback.onSessionStarted(sessionId); 4609 } catch (RemoteException e) { 4610 Log.e(TAG, "onSessionConfigSuccessLocal: onSessionStarted() RemoteException=" + e); 4611 return; 4612 } 4613 4614 WifiAwareDiscoverySessionState session = new WifiAwareDiscoverySessionState( 4615 mWifiAwareNativeApi, sessionId, pubSubId, callback, isPublish, isRangingEnabled, 4616 SystemClock.elapsedRealtime(), enableInstantMode, instantModeBand, 4617 isSuspendable, pairingConfig); 4618 session.enableVerboseLogging(mVerboseLoggingEnabled); 4619 client.addSession(session); 4620 4621 if (isRangingEnabled) { 4622 mAwareMetrics.recordDiscoverySessionWithRanging(client.getUid(), 4623 completedCommand.arg1 != COMMAND_TYPE_PUBLISH, minRange, maxRange, 4624 mClients); 4625 } else { 4626 mAwareMetrics.recordDiscoverySession(client.getUid(), mClients); 4627 } 4628 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.SUCCESS, 4629 completedCommand.arg1 == COMMAND_TYPE_PUBLISH, sessionId, 4630 client.mCallerType, client.mCallingFeatureId); 4631 sendAwareResourcesChangedBroadcast(); 4632 } else if (completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH 4633 || completedCommand.arg1 == COMMAND_TYPE_UPDATE_SUBSCRIBE) { 4634 int clientId = completedCommand.arg2; 4635 int sessionId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 4636 4637 WifiAwareClientState client = mClients.get(clientId); 4638 if (client == null) { 4639 Log.e(TAG, 4640 "onSessionConfigSuccessLocal: no client exists for clientId=" + clientId); 4641 return; 4642 } 4643 4644 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4645 if (session == null) { 4646 Log.e(TAG, "onSessionConfigSuccessLocal: no session exists for clientId=" + clientId 4647 + ", sessionId=" + sessionId); 4648 return; 4649 } 4650 4651 try { 4652 session.getCallback().onSessionConfigSuccess(); 4653 } catch (RemoteException e) { 4654 Log.e(TAG, "onSessionConfigSuccessLocal: onSessionConfigSuccess() RemoteException=" 4655 + e); 4656 } 4657 session.setRangingEnabled(isRangingEnabled); 4658 session.setInstantModeEnabled(enableInstantMode); 4659 session.setInstantModeBand(instantModeBand); 4660 mAwareMetrics.recordDiscoveryStatus(client.getUid(), NanStatusCode.SUCCESS, 4661 completedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH, 4662 client.mCallerType, client.mCallingFeatureId); 4663 } else { 4664 Log.wtf(TAG, 4665 "onSessionConfigSuccessLocal: unexpected completedCommand=" + completedCommand); 4666 return; 4667 } 4668 // If Ranging enabled or instant mode require changes, reconfigure. 4669 if (mCurrentRangingEnabled != doesAnyClientNeedRanging() 4670 || mInstantCommModeClientRequest != getInstantModeFromAllClients()) { 4671 reconfigure(); 4672 } 4673 } 4674 onSessionConfigFailLocal(Message failedCommand, boolean isPublish, int reason)4675 private void onSessionConfigFailLocal(Message failedCommand, boolean isPublish, int reason) { 4676 if (mVdbg) { 4677 Log.v(TAG, "onSessionConfigFailLocal: failedCommand=" + failedCommand + ", isPublish=" 4678 + isPublish + ", reason=" + reason); 4679 } 4680 4681 if (failedCommand.arg1 == COMMAND_TYPE_PUBLISH 4682 || failedCommand.arg1 == COMMAND_TYPE_SUBSCRIBE) { 4683 int clientId = failedCommand.arg2; 4684 IWifiAwareDiscoverySessionCallback callback = 4685 (IWifiAwareDiscoverySessionCallback) failedCommand.obj; 4686 4687 WifiAwareClientState client = mClients.get(clientId); 4688 if (client == null) { 4689 Log.e(TAG, "onSessionConfigFailLocal: no client exists for clientId=" + clientId); 4690 return; 4691 } 4692 4693 try { 4694 callback.onSessionConfigFail(reason); 4695 } catch (RemoteException e) { 4696 Log.w(TAG, "onSessionConfigFailLocal onSessionConfigFail(): RemoteException (FYI): " 4697 + e); 4698 } 4699 mAwareMetrics.recordDiscoveryStatus(client.getUid(), reason, 4700 failedCommand.arg1 == COMMAND_TYPE_PUBLISH, client.mCallerType, 4701 client.mCallingFeatureId); 4702 } else if (failedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH 4703 || failedCommand.arg1 == COMMAND_TYPE_UPDATE_SUBSCRIBE) { 4704 int clientId = failedCommand.arg2; 4705 int sessionId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 4706 4707 WifiAwareClientState client = mClients.get(clientId); 4708 if (client == null) { 4709 Log.e(TAG, "onSessionConfigFailLocal: no client exists for clientId=" + clientId); 4710 return; 4711 } 4712 4713 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 4714 if (session == null) { 4715 Log.e(TAG, "onSessionConfigFailLocal: no session exists for clientId=" + clientId 4716 + ", sessionId=" + sessionId); 4717 return; 4718 } 4719 4720 try { 4721 session.getCallback().onSessionConfigFail(reason); 4722 } catch (RemoteException e) { 4723 Log.e(TAG, "onSessionConfigFailLocal: onSessionConfigFail() RemoteException=" + e); 4724 } 4725 mAwareMetrics.recordDiscoveryStatus(client.getUid(), reason, 4726 failedCommand.arg1 == COMMAND_TYPE_UPDATE_PUBLISH, client.mCallerType, 4727 client.mCallingFeatureId); 4728 4729 if (reason == NanStatusCode.INVALID_SESSION_ID) { 4730 client.removeSession(sessionId); 4731 // If Ranging enabled or instant mode require changes, reconfigure. 4732 if (mCurrentRangingEnabled != doesAnyClientNeedRanging() 4733 || mInstantCommModeClientRequest != getInstantModeFromAllClients()) { 4734 reconfigure(); 4735 } 4736 sendAwareResourcesChangedBroadcast(); 4737 } 4738 } else { 4739 Log.wtf(TAG, "onSessionConfigFailLocal: unexpected failedCommand=" + failedCommand); 4740 } 4741 } 4742 onMessageSendSuccessLocal(Message completedCommand)4743 private void onMessageSendSuccessLocal(Message completedCommand) { 4744 String methodString = "onMessageSendSuccessLocal"; 4745 if (mVdbg) { 4746 Log.v(TAG, methodString + ": completedCommand=" + completedCommand); 4747 } 4748 4749 int clientId = completedCommand.arg2; 4750 int sessionId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 4751 int messageId = completedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID); 4752 4753 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 4754 methodString); 4755 if (session == null) { 4756 return; 4757 } 4758 4759 try { 4760 session.getCallback().onMessageSendSuccess(messageId); 4761 } catch (RemoteException e) { 4762 Log.w(TAG, "onMessageSendSuccessLocal: RemoteException (FYI): " + e); 4763 } 4764 } 4765 onMessageSendFailLocal(Message failedCommand, int reason)4766 private void onMessageSendFailLocal(Message failedCommand, int reason) { 4767 String methodString = "onMessageSendFailLocal"; 4768 if (mVdbg) { 4769 Log.v(TAG, methodString + ": failedCommand=" + failedCommand + ", reason=" + reason); 4770 } 4771 4772 int clientId = failedCommand.arg2; 4773 int sessionId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 4774 int messageId = failedCommand.getData().getInt(MESSAGE_BUNDLE_KEY_MESSAGE_ID); 4775 4776 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 4777 methodString); 4778 if (session == null) { 4779 return; 4780 } 4781 4782 try { 4783 session.getCallback().onMessageSendFail(messageId, reason); 4784 } catch (RemoteException e) { 4785 Log.e(TAG, "onMessageSendFailLocal: onMessageSendFail RemoteException=" + e); 4786 } 4787 } 4788 onCapabilitiesUpdatedResponseLocal(Capabilities capabilities)4789 private void onCapabilitiesUpdatedResponseLocal(Capabilities capabilities) { 4790 if (mVdbg) { 4791 Log.v(TAG, "onCapabilitiesUpdatedResponseLocal: capabilites=" + capabilities); 4792 } 4793 4794 mCapabilities = capabilities; 4795 mCharacteristics = null; 4796 if (mWifiAwarePullAtomCallback != null) { 4797 //Should only register this callback once 4798 return; 4799 } 4800 StatsManager statsManager = mContext.getSystemService(StatsManager.class); 4801 if (statsManager != null) { 4802 mWifiAwarePullAtomCallback = new WifiAwarePullAtomCallback(); 4803 statsManager.setPullAtomCallback(WIFI_AWARE_CAPABILITIES, null, 4804 new HandlerExecutor(mHandler), mWifiAwarePullAtomCallback); 4805 } 4806 } 4807 private class WifiAwarePullAtomCallback implements StatsManager.StatsPullAtomCallback { 4808 4809 @Override onPullAtom(int atomTag, @androidx.annotation.NonNull List<StatsEvent> data)4810 public int onPullAtom(int atomTag, @androidx.annotation.NonNull List<StatsEvent> data) { 4811 data.add(WifiStatsLog.buildStatsEvent(atomTag, 4812 mCapabilities.isInstantCommunicationModeSupported, 4813 mCapabilities.isNanPairingSupported, 4814 mCapabilities.isSuspensionSupported, 4815 mCapabilities.supportedDataPathCipherSuites, 4816 mCapabilities.maxNdiInterfaces, 4817 mCapabilities.maxNdpSessions, 4818 mCapabilities.maxPublishes)); 4819 return StatsManager.PULL_SUCCESS; 4820 } 4821 } 4822 onCreateDataPathInterfaceResponseLocal(Message command, boolean success, int reasonOnFailure)4823 private void onCreateDataPathInterfaceResponseLocal(Message command, boolean success, 4824 int reasonOnFailure) { 4825 if (mVdbg) { 4826 Log.v(TAG, "onCreateDataPathInterfaceResponseLocal: command=" + command + ", success=" 4827 + success + ", reasonOnFailure=" + reasonOnFailure); 4828 } 4829 4830 if (success) { 4831 if (mVdbg) { 4832 Log.v(TAG, "onCreateDataPathInterfaceResponseLocal: successfully created interface " 4833 + command.obj); 4834 } 4835 mDataPathMgr.onInterfaceCreated((String) command.obj); 4836 } else { 4837 Log.e(TAG, 4838 "onCreateDataPathInterfaceResponseLocal: failed when trying to create " 4839 + "interface " 4840 + command.obj + ". Reason code=" + reasonOnFailure); 4841 } 4842 } 4843 onDeleteDataPathInterfaceResponseLocal(Message command, boolean success, int reasonOnFailure)4844 private void onDeleteDataPathInterfaceResponseLocal(Message command, boolean success, 4845 int reasonOnFailure) { 4846 if (mVdbg) { 4847 Log.v(TAG, "onDeleteDataPathInterfaceResponseLocal: command=" + command + ", success=" 4848 + success + ", reasonOnFailure=" + reasonOnFailure); 4849 } 4850 4851 if (success) { 4852 if (mVdbg) { 4853 Log.v(TAG, "onDeleteDataPathInterfaceResponseLocal: successfully deleted interface " 4854 + command.obj); 4855 } 4856 mDataPathMgr.onInterfaceDeleted((String) command.obj); 4857 } else { 4858 Log.e(TAG, 4859 "onDeleteDataPathInterfaceResponseLocal: failed when trying to delete " 4860 + "interface " 4861 + command.obj + ". Reason code=" + reasonOnFailure); 4862 } 4863 } 4864 onRespondToPairingIndicationResponseSuccessLocal(Message command)4865 private boolean onRespondToPairingIndicationResponseSuccessLocal(Message command) { 4866 String methodString = "onRespondToPairingIndicationResponseSuccessLocal"; 4867 if (mVdbg) { 4868 Log.v(TAG, methodString + ": command=" + command); 4869 } 4870 Bundle data = command.getData(); 4871 PairingInfo pairingInfo = new PairingInfo(command.arg2, 4872 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4873 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4874 data.getString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS)); 4875 int requestId = data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_REQUEST_ID); 4876 4877 WifiAwareDiscoverySessionState session = getClientSession(pairingInfo.mClientId, 4878 pairingInfo.mSessionId, methodString); 4879 if (session == null) { 4880 return false; 4881 } 4882 mPairingRequest.append(requestId, pairingInfo); 4883 return true; 4884 } 4885 onRespondToPairingIndicationResponseFail(Message command, int reason)4886 private void onRespondToPairingIndicationResponseFail(Message command, int reason) { 4887 String methodString = "onRespondToPairingIndicationResponseFail"; 4888 if (mVdbg) { 4889 Log.v(TAG, methodString + ": command=" + command + " reason=" + reason); 4890 } 4891 4892 Bundle data = command.getData(); 4893 PairingInfo pairingInfo = new PairingInfo(command.arg2, 4894 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4895 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4896 data.getString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS)); 4897 4898 WifiAwareDiscoverySessionState session = getClientSession(pairingInfo.mClientId, 4899 pairingInfo.mSessionId, methodString); 4900 if (session == null) { 4901 return; 4902 } 4903 if (data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE) == NAN_PAIRING_REQUEST_TYPE_SETUP) { 4904 session.onPairingConfirmReceived(pairingInfo.mPeerId, false, pairingInfo.mAlias, 4905 NAN_PAIRING_REQUEST_TYPE_SETUP); 4906 } 4907 } 4908 onInitiateDataPathResponseSuccessLocal(Message command, int ndpId)4909 private boolean onInitiateDataPathResponseSuccessLocal(Message command, int ndpId) { 4910 return mDataPathMgr 4911 .onDataPathInitiateSuccess((WifiAwareNetworkSpecifier) command.obj, ndpId); 4912 } 4913 onInitiatePairingResponseSuccessLocal(Message command, int paireId)4914 private boolean onInitiatePairingResponseSuccessLocal(Message command, int paireId) { 4915 String methodString = "onInitiatePairingResponseSuccessLocal"; 4916 if (mVdbg) { 4917 Log.v(TAG, methodString + ": command=" + command + ", ndpId=" + paireId); 4918 } 4919 4920 Bundle data = command.getData(); 4921 PairingInfo pairingInfo = new PairingInfo(command.arg2, 4922 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4923 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4924 data.getString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS)); 4925 4926 WifiAwareDiscoverySessionState session = getClientSession(pairingInfo.mClientId, 4927 pairingInfo.mSessionId, methodString); 4928 if (session == null) { 4929 return false; 4930 } 4931 4932 mPairingRequest.append(paireId, pairingInfo); 4933 return true; 4934 } 4935 onInitiatePairingResponseFailLocal(Message command, int reason)4936 private void onInitiatePairingResponseFailLocal(Message command, int reason) { 4937 String methodString = "onInitiatePairingResponseFailLocal"; 4938 if (mVdbg) { 4939 Log.v(TAG, methodString + ": command=" + command + ", reason=" + reason); 4940 } 4941 4942 Bundle data = command.getData(); 4943 PairingInfo pairingInfo = new PairingInfo(command.arg2, 4944 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4945 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4946 data.getString(MESSAGE_BUNDLE_KEY_PAIRING_ALIAS)); 4947 4948 WifiAwareDiscoverySessionState session = getClientSession(pairingInfo.mClientId, 4949 pairingInfo.mSessionId, methodString); 4950 if (session == null) { 4951 return; 4952 } 4953 if (data.getInt(MESSAGE_BUNDLE_KEY_PAIRING_TYPE) == NAN_PAIRING_REQUEST_TYPE_SETUP) { 4954 session.onPairingConfirmReceived(pairingInfo.mPeerId, false, pairingInfo.mAlias, 4955 NAN_PAIRING_REQUEST_TYPE_SETUP); 4956 } 4957 } 4958 onInitiateBootstrappingResponseSuccessLocal(Message command, int id)4959 private boolean onInitiateBootstrappingResponseSuccessLocal(Message command, int id) { 4960 String methodString = "onInitiateBootstrappingResponseSuccessLocal"; 4961 if (mVdbg) { 4962 Log.v(TAG, methodString + ": command=" + command + ", ndpId=" + id); 4963 } 4964 4965 Bundle data = command.getData(); 4966 BootStrppingInfo info = new BootStrppingInfo(command.arg2, 4967 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4968 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4969 data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD), 4970 data.getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST)); 4971 WifiAwareDiscoverySessionState session = getClientSession(info.mClientId, info.mSessionId, 4972 methodString); 4973 if (session == null) { 4974 return false; 4975 } 4976 4977 mBootstrappingRequest.append(id, info); 4978 return true; 4979 } 4980 onInitiateBootStrappingResponseFailLocal(Message command, int reason)4981 private void onInitiateBootStrappingResponseFailLocal(Message command, int reason) { 4982 String methodString = "onInitiateBootStrappingResponseFailLocal"; 4983 if (mVdbg) { 4984 Log.v(TAG, methodString + ": command=" + command + ", reason=" + reason); 4985 } 4986 4987 Bundle data = command.getData(); 4988 BootStrppingInfo info = new BootStrppingInfo(command.arg2, 4989 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 4990 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 4991 data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD), 4992 data.getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST)); 4993 4994 WifiAwareDiscoverySessionState session = getClientSession(info.mClientId, info.mSessionId, 4995 methodString); 4996 if (session == null) { 4997 return; 4998 } 4999 session.onBootStrappingConfirmReceived(info.mPeerId, false, info.mMethod); 5000 } 5001 onRespondToBootStrappingRequestSuccessLocal(Message command)5002 private void onRespondToBootStrappingRequestSuccessLocal(Message command) { 5003 String methodString = "onRespondToBootStrappingRequestSuccessLocal"; 5004 if (mVdbg) { 5005 Log.v(TAG, methodString + ": command=" + command); 5006 } 5007 5008 Bundle data = command.getData(); 5009 BootStrppingInfo info = new BootStrppingInfo(command.arg2, 5010 data.getInt(MESSAGE_BUNDLE_KEY_SESSION_ID), 5011 data.getInt(MESSAGE_BUNDLE_KEY_PEER_ID), 5012 data.getInt(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_METHOD), 5013 data.getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_IS_COME_BACK_REQUEST)); 5014 5015 WifiAwareDiscoverySessionState session = getClientSession(info.mClientId, info.mSessionId, 5016 methodString); 5017 if (session == null) { 5018 return; 5019 } 5020 if (data.getBoolean(MESSAGE_BUNDLE_KEY_BOOTSTRAPPING_ACCEPT)) { 5021 session.onBootStrappingConfirmReceived(info.mPeerId, true, info.mMethod); 5022 } 5023 } 5024 onSuspendResponseLocal(Message command, boolean success, int reason)5025 private void onSuspendResponseLocal(Message command, boolean success, int reason) { 5026 String methodString = "onSuspendResponseLocal"; 5027 if (mVdbg) { 5028 Log.v(TAG, methodString + ": command=" + command + ", success=" + success 5029 + ", reason=" + reason); 5030 } 5031 5032 int clientId = command.arg2; 5033 int sessionId = command.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 5034 5035 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 5036 methodString); 5037 if (session == null) { 5038 return; 5039 } 5040 if (success) { 5041 session.onSuspendSuccess(); 5042 } else { 5043 session.onSuspendFail(convertFrameworkStatusToSuspensionFailedReason(reason)); 5044 } 5045 } 5046 5047 @WifiAwareManager.SessionSuspensionFailedReasonCode convertFrameworkStatusToSuspensionFailedReason(int reason)5048 private int convertFrameworkStatusToSuspensionFailedReason(int reason) { 5049 switch (reason) { 5050 case REDUNDANT_REQUEST: 5051 return WIFI_AWARE_SUSPEND_REDUNDANT_REQUEST; 5052 case NOT_SUPPORTED: 5053 return WIFI_AWARE_SUSPEND_INVALID_SESSION; 5054 case NO_CONNECTION: 5055 return WIFI_AWARE_SUSPEND_CANNOT_SUSPEND; 5056 default: 5057 return WIFI_AWARE_SUSPEND_INTERNAL_ERROR; 5058 } 5059 } 5060 onResumeResponseLocal(Message command, boolean success, @WifiAwareManager.SessionResumptionFailedReasonCode int reason)5061 private void onResumeResponseLocal(Message command, boolean success, 5062 @WifiAwareManager.SessionResumptionFailedReasonCode int reason) { 5063 String methodString = "onResumeResponseLocal"; 5064 if (mVdbg) { 5065 Log.v(TAG, methodString + ": command=" 5066 + command + ", success=" + success + ", reason=" + reason); 5067 } 5068 5069 int clientId = command.arg2; 5070 int sessionId = command.getData().getInt(MESSAGE_BUNDLE_KEY_SESSION_ID); 5071 5072 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 5073 methodString); 5074 if (session == null) { 5075 return; 5076 } 5077 if (!success) { 5078 session.onResumeFail(convertFrameworkStatusToResumptionFailedReasonCode(reason)); 5079 } 5080 } 5081 5082 @WifiAwareManager.SessionResumptionFailedReasonCode convertFrameworkStatusToResumptionFailedReasonCode(int reason)5083 private int convertFrameworkStatusToResumptionFailedReasonCode(int reason) { 5084 switch (reason) { 5085 case REDUNDANT_REQUEST: 5086 return WIFI_AWARE_RESUME_REDUNDANT_REQUEST; 5087 case NOT_SUPPORTED: 5088 return WIFI_AWARE_RESUME_INVALID_SESSION; 5089 default: 5090 return WIFI_AWARE_RESUME_INTERNAL_ERROR; 5091 } 5092 } 5093 5094 5095 onInitiateDataPathResponseFailLocal(Message command, int reason)5096 private void onInitiateDataPathResponseFailLocal(Message command, int reason) { 5097 if (mVdbg) { 5098 Log.v(TAG, "onInitiateDataPathResponseFailLocal: command=" + command + ", reason=" 5099 + reason); 5100 } 5101 mDataPathMgr.onDataPathInitiateFail((WifiAwareNetworkSpecifier) command.obj, reason); 5102 } 5103 onRespondToDataPathSetupRequestResponseLocal(Message command, boolean success, int reasonOnFailure)5104 private boolean onRespondToDataPathSetupRequestResponseLocal(Message command, boolean success, 5105 int reasonOnFailure) { 5106 if (mVdbg) { 5107 Log.v(TAG, "onRespondToDataPathSetupRequestResponseLocal: command=" + command 5108 + ", success=" + success + ", reasonOnFailure=" + reasonOnFailure); 5109 } 5110 5111 return mDataPathMgr.onRespondToDataPathRequest( 5112 command.getData().getInt(MESSAGE_BUNDLE_KEY_NDP_ID), success, reasonOnFailure); 5113 } 5114 onEndPathEndResponseLocal(Message command, boolean success, int reasonOnFailure)5115 private void onEndPathEndResponseLocal(Message command, boolean success, int reasonOnFailure) { 5116 if (mVdbg) { 5117 Log.v(TAG, "onEndPathEndResponseLocal: command=" + command 5118 + ", success=" + success + ", reasonOnFailure=" + reasonOnFailure); 5119 } 5120 // TODO: do something with this 5121 } 5122 onPairingEndResponseLocal(Message command, boolean success, int reasonOnFailure)5123 private void onPairingEndResponseLocal(Message command, boolean success, int reasonOnFailure) { 5124 if (mVdbg) { 5125 Log.v(TAG, "onPairingEndResponseLocal: command=" + command 5126 + ", success=" + success + ", reasonOnFailure=" + reasonOnFailure); 5127 } 5128 } 5129 suspendSessionLocal(short transactionId, int clientId, int sessionId)5130 private boolean suspendSessionLocal(short transactionId, int clientId, int sessionId) { 5131 String methodString = "suspendSessionLocal"; 5132 if (mVdbg) { 5133 Log.v(TAG, methodString + "(): transactionId=" + transactionId + ", clientId=" 5134 + clientId + ", sessionId=" + sessionId); 5135 } 5136 5137 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 5138 methodString); 5139 if (session == null) { 5140 return false; 5141 } 5142 if (!session.isSuspendable()) { 5143 session.onSuspendFail(WIFI_AWARE_SUSPEND_INVALID_SESSION); 5144 return false; 5145 } 5146 if (session.isSessionSuspended()) { 5147 session.onSuspendFail(WIFI_AWARE_SUSPEND_REDUNDANT_REQUEST); 5148 return false; 5149 } 5150 5151 return session.suspend(transactionId); 5152 } 5153 resumeSessionLocal(short transactionId, int clientId, int sessionId)5154 private boolean resumeSessionLocal(short transactionId, int clientId, int sessionId) { 5155 if (mVdbg) { 5156 Log.v(TAG, "resumeSessionLocal(): transactionId=" + transactionId + ", clientId=" 5157 + clientId + ", sessionId=" + sessionId); 5158 } 5159 5160 String methodString = "resumeSessionLocal"; 5161 WifiAwareDiscoverySessionState session = getClientSession(clientId, sessionId, 5162 methodString); 5163 if (session == null) { 5164 return false; 5165 } 5166 if (!session.isSuspendable()) { 5167 session.onResumeFail(WIFI_AWARE_RESUME_INVALID_SESSION); 5168 return false; 5169 } 5170 if (!session.isSessionSuspended()) { 5171 session.onResumeFail(WIFI_AWARE_RESUME_REDUNDANT_REQUEST); 5172 return false; 5173 } 5174 5175 return session.resume(transactionId); 5176 } 5177 5178 /* 5179 * NOTIFICATIONS 5180 */ 5181 onInterfaceAddressChangeLocal(byte[] mac)5182 private void onInterfaceAddressChangeLocal(byte[] mac) { 5183 Log.d(TAG, "onInterfaceAddressChange: mac=" + String.valueOf(HexEncoding.encode(mac))); 5184 5185 mCurrentDiscoveryInterfaceMac = mac; 5186 5187 for (int i = 0; i < mClients.size(); ++i) { 5188 WifiAwareClientState client = mClients.valueAt(i); 5189 client.onInterfaceAddressChange(mac); 5190 } 5191 5192 mAwareMetrics.recordEnableAware(); 5193 } 5194 onRangingResultsReceivedLocal(List<RangingResult> rangingResults, int pubSubId)5195 private void onRangingResultsReceivedLocal(List<RangingResult> rangingResults, 5196 int pubSubId) { 5197 if (mVdbg) { 5198 Log.v(TAG, 5199 "onRangingResultsReceivedNotification: pubSubId=" + pubSubId); 5200 } 5201 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5202 getClientSessionForPubSubId(pubSubId); 5203 if (data == null) { 5204 Log.e(TAG, "onRangingResultsReceivedLocal: no session found for pubSubId=" + pubSubId); 5205 return; 5206 } 5207 data.second.onRangingResultsReceived(rangingResults); 5208 } 5209 onClusterChangeLocal(int clusterEventType, byte[] clusterId)5210 private void onClusterChangeLocal(int clusterEventType, byte[] clusterId) { 5211 mClusterId = clusterId; 5212 mClusterEventType = clusterEventType; 5213 5214 if (mVdbg) { 5215 Log.v(TAG, "onClusterChange: clusterEventType=" + clusterEventType + ", clusterId=" 5216 + String.valueOf(HexEncoding.encode(clusterId))); 5217 } 5218 5219 for (int i = 0; i < mClients.size(); ++i) { 5220 WifiAwareClientState client = mClients.valueAt(i); 5221 client.onClusterChange(clusterEventType, clusterId, mCurrentDiscoveryInterfaceMac); 5222 } 5223 5224 mAwareMetrics.recordEnableAware(); 5225 } 5226 onMatchLocal(int pubSubId, int requestorinstanceid, byte[] peerMac, byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm, int cipherSuite, byte[] scid, byte[] nonce, byte[] tag, AwarePairingConfig pairingConfig, @NonNull List<OuiKeyedData> vendorData)5227 private void onMatchLocal(int pubSubId, int requestorinstanceid, byte[] peerMac, 5228 byte[] serviceSpecificInfo, byte[] matchFilter, int rangingIndication, int rangeMm, 5229 int cipherSuite, byte[] scid, byte[] nonce, byte[] tag, 5230 AwarePairingConfig pairingConfig, @NonNull List<OuiKeyedData> vendorData) { 5231 if (mVerboseLoggingEnabled) { 5232 Log.v(TAG, "onMatch: pubSubId=" + pubSubId 5233 + ", requestorInstanceId=" + requestorinstanceid 5234 + ", peerDiscoveryMac=" + String.valueOf(HexEncoding.encode(peerMac)) 5235 + ", serviceSpecificInfo=" + Arrays.toString(serviceSpecificInfo) 5236 + ", matchFilter=" + Arrays.toString(matchFilter) 5237 + ", rangingIndication=" + rangingIndication + ", rangeMm=" + rangeMm); 5238 } 5239 5240 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5241 getClientSessionForPubSubId(pubSubId); 5242 if (data == null) { 5243 Log.e(TAG, "onMatch: no session found for pubSubId=" + pubSubId); 5244 return; 5245 } 5246 5247 if (data.second.isRangingEnabled()) { 5248 mAwareMetrics.recordMatchIndicationForRangeEnabledSubscribe(rangingIndication != 0); 5249 } 5250 String pairingAlias = mPairingConfigManager.getPairedDeviceAlias( 5251 data.first.getCallingPackage(), nonce, tag, peerMac); 5252 int peerId = data.second.onMatch(requestorinstanceid, peerMac, serviceSpecificInfo, 5253 matchFilter, rangingIndication, rangeMm, cipherSuite, scid, pairingAlias, 5254 pairingConfig, vendorData); 5255 if (TextUtils.isEmpty(pairingAlias)) { 5256 return; 5257 } 5258 PairingSecurityAssociationInfo securityInfo = mPairingConfigManager 5259 .getSecurityInfoPairedDevice(pairingAlias); 5260 if (securityInfo == null) { 5261 return; 5262 } 5263 initiateNanPairingVerificationRequest(data.first.getClientId(), data.second.getSessionId(), 5264 peerId, pairingAlias, securityInfo.mNpk, securityInfo.mAkm, 5265 securityInfo.mCipherSuite); 5266 } 5267 onMatchExpiredLocal(int pubSubId, int requestorInstanceId)5268 private void onMatchExpiredLocal(int pubSubId, int requestorInstanceId) { 5269 if (mVdbg) { 5270 Log.v(TAG, 5271 "onMatchExpiredNotification: pubSubId=" + pubSubId 5272 + ", requestorInstanceId=" + requestorInstanceId); 5273 } 5274 5275 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5276 getClientSessionForPubSubId(pubSubId); 5277 if (data == null) { 5278 Log.e(TAG, "onMatch: no session found for pubSubId=" + pubSubId); 5279 return; 5280 } 5281 data.second.onMatchExpired(requestorInstanceId); 5282 } 5283 onSessionTerminatedLocal(int pubSubId, boolean isPublish, int reason)5284 private void onSessionTerminatedLocal(int pubSubId, boolean isPublish, int reason) { 5285 if (mVerboseLoggingEnabled) { 5286 Log.v(TAG, "onSessionTerminatedLocal: pubSubId=" + pubSubId + ", isPublish=" + isPublish 5287 + ", reason=" + reason); 5288 } 5289 5290 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5291 getClientSessionForPubSubId(pubSubId); 5292 if (data == null) { 5293 Log.e(TAG, "onSessionTerminatedLocal: no session found for pubSubId=" + pubSubId); 5294 return; 5295 } 5296 5297 try { 5298 data.second.getCallback().onSessionTerminated(reason); 5299 } catch (RemoteException e) { 5300 Log.w(TAG, 5301 "onSessionTerminatedLocal onSessionTerminated(): RemoteException (FYI): " + e); 5302 } 5303 data.first.removeSession(data.second.getSessionId()); 5304 // If Ranging enabled or instant mode require changes, reconfigure. 5305 if (mCurrentRangingEnabled != doesAnyClientNeedRanging() 5306 || mInstantCommModeClientRequest != getInstantModeFromAllClients()) { 5307 reconfigure(); 5308 } 5309 mAwareMetrics.recordDiscoverySessionDuration(data.second.getCreationTime(), 5310 data.second.isPublishSession(), data.second.getSessionId()); 5311 sendAwareResourcesChangedBroadcast(); 5312 } 5313 onMessageReceivedLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, byte[] message)5314 private void onMessageReceivedLocal(int pubSubId, int requestorInstanceId, byte[] peerMac, 5315 byte[] message) { 5316 if (mVerboseLoggingEnabled) { 5317 Log.v(TAG, "onMessageReceivedLocal: pubSubId=" + pubSubId + ", requestorInstanceId=" 5318 + requestorInstanceId + ", peerDiscoveryMac=" 5319 + String.valueOf(HexEncoding.encode(peerMac))); 5320 } 5321 5322 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5323 getClientSessionForPubSubId(pubSubId); 5324 if (data == null) { 5325 Log.e(TAG, "onMessageReceivedLocal: no session found for pubSubId=" + pubSubId); 5326 return; 5327 } 5328 5329 data.second.onMessageReceived(requestorInstanceId, peerMac, message); 5330 } 5331 onAwareDownLocal()5332 private void onAwareDownLocal() { 5333 Log.d(TAG, "onAwareDown: mCurrentAwareConfiguration=" + mCurrentAwareConfiguration); 5334 5335 if (mCurrentAwareConfiguration == null) { 5336 return; 5337 } 5338 5339 for (int i = 0; i < mClients.size(); ++i) { 5340 WifiAwareClientState client = mClients.valueAt(i); 5341 mAwareMetrics.recordAttachSessionDuration(client.getCreationTime()); 5342 SparseArray<WifiAwareDiscoverySessionState> sessions = client.getSessions(); 5343 for (int j = 0; j < sessions.size(); ++j) { 5344 mAwareMetrics.recordDiscoverySessionDuration(sessions.valueAt(j).getCreationTime(), 5345 sessions.valueAt(j).isPublishSession(), sessions.valueAt(j).getSessionId()); 5346 } 5347 client.destroy(); 5348 } 5349 mAwareMetrics.recordDisableAware(); 5350 5351 mClients.clear(); 5352 mPairingRequest.clear(); 5353 mCurrentAwareConfiguration = null; 5354 mSm.onAwareDownCleanupSendQueueState(); 5355 mDataPathMgr.onAwareDownCleanupDataPaths(); 5356 mCurrentDiscoveryInterfaceMac = ALL_ZERO_MAC; 5357 mDataPathMgr.deleteAllInterfaces(); 5358 sendAwareResourcesChangedBroadcast(); 5359 } 5360 onPairingRequestReceivedLocal(int discoverySessionId, int peerId, byte[] peerDiscMacAddr, int pairingId, int requestType, byte[] nonce, byte[] tag)5361 private void onPairingRequestReceivedLocal(int discoverySessionId, int peerId, 5362 byte[] peerDiscMacAddr, int pairingId, int requestType, byte[] nonce, byte[] tag) { 5363 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5364 getClientSessionForPubSubId(discoverySessionId); 5365 if (data == null) { 5366 Log.e(TAG, "onPairingRequestReceivedLocal: no session found for pubSubId=" 5367 + discoverySessionId); 5368 return; 5369 } 5370 if (requestType == NAN_PAIRING_REQUEST_TYPE_SETUP) { 5371 data.second.onPairingRequestReceived(peerId, peerDiscMacAddr, pairingId); 5372 return; 5373 } 5374 // Response with the cache NPKSA 5375 String alias = mPairingConfigManager.getPairedDeviceAlias( 5376 data.first.getCallingPackage(), nonce, tag, peerDiscMacAddr); 5377 PairingSecurityAssociationInfo securityInfo = null; 5378 if (alias != null) { 5379 securityInfo = mPairingConfigManager.getSecurityInfoPairedDevice(alias); 5380 } 5381 if (securityInfo != null) { 5382 responseNanPairingVerificationRequest(data.first.getClientId(), 5383 data.second.getSessionId(), 5384 data.second.getPeerIdOrAddIfNew(peerId, peerDiscMacAddr), pairingId, alias, 5385 true, securityInfo.mNpk, securityInfo.mAkm, securityInfo.mCipherSuite); 5386 } else { 5387 // If local cache is not found, reject the verification request. 5388 responseNanPairingVerificationRequest(data.first.getClientId(), discoverySessionId, 5389 data.second.getPeerIdOrAddIfNew(peerId, peerDiscMacAddr), pairingId, alias, 5390 false, null, 0, WIFI_AWARE_CIPHER_SUITE_NCS_PK_PASN_128); 5391 } 5392 } 5393 onPairingConfirmReceivedLocal(int pairingId, boolean accept, int reason, int requestType, boolean enableCache, PairingSecurityAssociationInfo npksa)5394 private boolean onPairingConfirmReceivedLocal(int pairingId, boolean accept, int reason, 5395 int requestType, boolean enableCache, PairingSecurityAssociationInfo npksa) { 5396 PairingInfo info = mPairingRequest.get(pairingId); 5397 mPairingRequest.remove(pairingId); 5398 if (info == null) { 5399 return false; 5400 } 5401 WifiAwareClientState client = mClients.get(info.mClientId); 5402 if (client == null) { 5403 Log.e(TAG, 5404 "onPairingConfirmReceivedLocal: no client exists for clientId=" 5405 + info.mClientId); 5406 return false; 5407 } 5408 5409 WifiAwareDiscoverySessionState session = client.getSession(info.mSessionId); 5410 if (session == null) { 5411 Log.e(TAG, "onPairingConfirmReceivedLocal: no session exists for clientId=" 5412 + info.mClientId 5413 + ", sessionId=" + info.mSessionId); 5414 return false; 5415 } 5416 session.onPairingConfirmReceived(info.mPeerId, accept, info.mAlias, requestType); 5417 if (accept) { 5418 if (enableCache && requestType == NAN_PAIRING_REQUEST_TYPE_SETUP) { 5419 mPairingConfigManager.addPairedDeviceSecurityAssociation( 5420 client.getCallingPackage(), info.mAlias, npksa); 5421 } 5422 return true; 5423 } 5424 if (mVerboseLoggingEnabled) { 5425 Log.v(TAG, "Pairing request reject, reason=" + reason); 5426 } 5427 return true; 5428 } 5429 onBootstrappingRequestReceivedLocal(int discoverySessionId, int peerId, byte[] peerDiscMacAddr, int bootstrappingId, int method)5430 private void onBootstrappingRequestReceivedLocal(int discoverySessionId, int peerId, 5431 byte[] peerDiscMacAddr, int bootstrappingId, int method) { 5432 Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> data = 5433 getClientSessionForPubSubId(discoverySessionId); 5434 if (data == null) { 5435 Log.e(TAG, "onBootstrappingRequestReceivedLocal: no session found for pubSubId=" 5436 + discoverySessionId); 5437 return; 5438 } 5439 if (data.second.acceptsBootstrappingMethod(method)) { 5440 respondToBootstrappingRequest(data.first.getClientId(), data.second.getSessionId(), 5441 data.second.getPeerIdOrAddIfNew(peerId, peerDiscMacAddr), bootstrappingId, 5442 true, method); 5443 } else { 5444 respondToBootstrappingRequest(data.first.getClientId(), data.second.getSessionId(), 5445 data.second.getPeerIdOrAddIfNew(peerId, peerDiscMacAddr), bootstrappingId, 5446 false, method); 5447 } 5448 } 5449 onBootStrappingConfirmReceivedLocal(int id, int reason, int responseCode, int comeBackDelay, byte[] cookie)5450 private boolean onBootStrappingConfirmReceivedLocal(int id, int reason, int responseCode, 5451 int comeBackDelay, byte[] cookie) { 5452 BootStrppingInfo info = mBootstrappingRequest.get(id); 5453 mBootstrappingRequest.remove(id); 5454 if (info == null) { 5455 return false; 5456 } 5457 if (responseCode == NAN_BOOTSTRAPPING_COMEBACK && comeBackDelay > 0) { 5458 if (!info.mIsComeBackFollowUp) { 5459 initiateBootStrappingSetupRequest(info.mClientId, info.mSessionId, info.mPeerId, 5460 info.mMethod, comeBackDelay * 1000L, cookie); 5461 return true; 5462 } 5463 Log.e(TAG, "onBootStrappingConfirmReceivedLocal come back event on a" 5464 + "comback followup request, handle it as reject!"); 5465 } 5466 String methodString = "onBootStrappingConfirmReceivedLocal"; 5467 WifiAwareDiscoverySessionState session = getClientSession(info.mClientId, info.mSessionId, 5468 methodString); 5469 if (session == null) { 5470 return false; 5471 } 5472 boolean accept = responseCode == NAN_BOOTSTRAPPING_ACCEPT; 5473 session.onBootStrappingConfirmReceived(info.mPeerId, accept, info.mMethod); 5474 5475 if (!accept && mVerboseLoggingEnabled) { 5476 Log.v(TAG, "bootstrapping request reject, reason=" + reason); 5477 } 5478 return true; 5479 } 5480 onSuspensionModeChangedLocal(boolean isSuspended)5481 private void onSuspensionModeChangedLocal(boolean isSuspended) { 5482 if (isSuspended) return; 5483 5484 // Trigger resume success callback for all suspended sessions when device exits 5485 // suspended mode. 5486 for (int i = 0; i < mClients.size(); i++) { 5487 WifiAwareClientState clientState = mClients.valueAt(i); 5488 SparseArray<WifiAwareDiscoverySessionState> sessions = clientState.getSessions(); 5489 for (int j = 0; j < sessions.size(); j++) { 5490 WifiAwareDiscoverySessionState session = sessions.valueAt(j); 5491 if (session != null && session.isSessionSuspended()) { 5492 session.onResumeSuccess(); 5493 } 5494 } 5495 } 5496 } 5497 5498 /* 5499 * Utilities 5500 */ 5501 getClientSessionForPubSubId( int pubSubId)5502 private Pair<WifiAwareClientState, WifiAwareDiscoverySessionState> getClientSessionForPubSubId( 5503 int pubSubId) { 5504 for (int i = 0; i < mClients.size(); ++i) { 5505 WifiAwareClientState client = mClients.valueAt(i); 5506 WifiAwareDiscoverySessionState session = client.getAwareSessionStateForPubSubId( 5507 pubSubId); 5508 if (session != null) { 5509 return new Pair<>(client, session); 5510 } 5511 } 5512 5513 return null; 5514 } 5515 5516 @Nullable getClientSession(int clientId, int sessionId, String methodString)5517 private WifiAwareDiscoverySessionState getClientSession(int clientId, int sessionId, 5518 String methodString) { 5519 WifiAwareClientState client = mClients.get(clientId); 5520 if (client == null) { 5521 Log.e( 5522 TAG, 5523 methodString + ": no client exists for " + "clientId=" + clientId); 5524 return null; 5525 } 5526 5527 WifiAwareDiscoverySessionState session = client.getSession(sessionId); 5528 if (session == null) { 5529 Log.e(TAG, 5530 methodString + ": no session exists for " 5531 + "clientId=" + clientId + ", sessionId=" + sessionId); 5532 return null; 5533 } 5534 5535 return session; 5536 } 5537 5538 /** 5539 * Merge all the existing client configurations with the (optional) input configuration request. 5540 * If the configurations are "incompatible" (rules in comment below) return a null. 5541 */ mergeConfigRequests(ConfigRequest configRequest)5542 private ConfigRequest mergeConfigRequests(ConfigRequest configRequest) { 5543 if (mVerboseLoggingEnabled) { 5544 Log.v(TAG, "mergeConfigRequests(): mClients=[" + mClients + "], configRequest=" 5545 + configRequest); 5546 } 5547 5548 if (mClients.size() == 0 && configRequest == null) { 5549 Log.e(TAG, "mergeConfigRequests: invalid state - called with 0 clients registered!"); 5550 return null; 5551 } 5552 5553 // TODO: continue working on merge algorithm: 5554 // - if any request 5g: enable 5555 // - maximal master preference 5556 // - cluster range: must be identical 5557 // - if any request identity change: enable 5558 // - discovery window: minimum value if specified, 0 (disable) is considered an infinity 5559 boolean support5gBand = false; 5560 boolean support6gBand = false; 5561 int masterPreference = 0; 5562 boolean clusterIdValid = false; 5563 int clusterLow = 0; 5564 int clusterHigh = ConfigRequest.CLUSTER_ID_MAX; 5565 int[] discoveryWindowInterval = 5566 {ConfigRequest.DW_INTERVAL_NOT_INIT, ConfigRequest.DW_INTERVAL_NOT_INIT}; 5567 List<OuiKeyedData> vendorData = null; 5568 if (configRequest != null) { 5569 support5gBand = configRequest.mSupport5gBand; 5570 support6gBand = configRequest.mSupport6gBand; 5571 masterPreference = configRequest.mMasterPreference; 5572 clusterIdValid = true; 5573 clusterLow = configRequest.mClusterLow; 5574 clusterHigh = configRequest.mClusterHigh; 5575 discoveryWindowInterval = configRequest.mDiscoveryWindowInterval; 5576 } 5577 for (int i = 0; i < mClients.size(); ++i) { 5578 ConfigRequest cr = mClients.valueAt(i).getConfigRequest(); 5579 5580 // any request turns on 5G 5581 if (cr.mSupport5gBand) { 5582 support5gBand = true; 5583 } 5584 5585 // any request turns on 5G 5586 if (cr.mSupport6gBand) { 5587 support6gBand = true; 5588 } 5589 5590 // maximal master preference 5591 masterPreference = Math.max(masterPreference, cr.mMasterPreference); 5592 5593 // cluster range must be the same across all config requests 5594 if (!clusterIdValid) { 5595 clusterIdValid = true; 5596 clusterLow = cr.mClusterLow; 5597 clusterHigh = cr.mClusterHigh; 5598 } else { 5599 if (clusterLow != cr.mClusterLow) return null; 5600 if (clusterHigh != cr.mClusterHigh) return null; 5601 } 5602 5603 for (int band = ConfigRequest.NAN_BAND_24GHZ; band <= ConfigRequest.NAN_BAND_5GHZ; 5604 ++band) { 5605 if (discoveryWindowInterval[band] == ConfigRequest.DW_INTERVAL_NOT_INIT) { 5606 discoveryWindowInterval[band] = cr.mDiscoveryWindowInterval[band]; 5607 } else if (cr.mDiscoveryWindowInterval[band] 5608 == ConfigRequest.DW_INTERVAL_NOT_INIT) { 5609 // do nothing: keep my values 5610 } else if (discoveryWindowInterval[band] == ConfigRequest.DW_DISABLE) { 5611 discoveryWindowInterval[band] = cr.mDiscoveryWindowInterval[band]; 5612 } else if (cr.mDiscoveryWindowInterval[band] == ConfigRequest.DW_DISABLE) { 5613 // do nothing: keep my values 5614 } else { 5615 discoveryWindowInterval[band] = Math.min(discoveryWindowInterval[band], 5616 cr.mDiscoveryWindowInterval[band]); 5617 } 5618 } 5619 5620 if (SdkLevel.isAtLeastV() && !cr.getVendorData().isEmpty()) { 5621 vendorData = cr.getVendorData(); 5622 } 5623 } 5624 ConfigRequest.Builder builder = new ConfigRequest.Builder().setSupport5gBand(support5gBand) 5625 .setMasterPreference(masterPreference).setClusterLow(clusterLow) 5626 .setClusterHigh(clusterHigh); 5627 for (int band = ConfigRequest.NAN_BAND_24GHZ; band <= ConfigRequest.NAN_BAND_5GHZ; ++band) { 5628 if (discoveryWindowInterval[band] != ConfigRequest.DW_INTERVAL_NOT_INIT) { 5629 builder.setDiscoveryWindowInterval(band, discoveryWindowInterval[band]); 5630 } 5631 } 5632 if (SdkLevel.isAtLeastV()) { 5633 // Always use the vendor data from the incoming ConfigRequest if provided. 5634 // Otherwise, use the most recent vendor data in the mClients list. 5635 if (configRequest != null && !configRequest.getVendorData().isEmpty()) { 5636 vendorData = configRequest.getVendorData(); 5637 } 5638 if (vendorData != null) { 5639 builder.setVendorData(vendorData); 5640 } 5641 } 5642 return builder.build(); 5643 } 5644 createMergedRequestorWs()5645 private WorkSource createMergedRequestorWs() { 5646 if (mVerboseLoggingEnabled) { 5647 Log.v(TAG, "createMergedRequestorWs(): mClients=[" + mClients + "]"); 5648 } 5649 WorkSource requestorWs = new WorkSource(); 5650 boolean isOpportunistic = false; 5651 for (int i = 0; i < mClients.size(); ++i) { 5652 WifiAwareClientState clientState = mClients.valueAt(i); 5653 if (clientState.isAwareOffload() 5654 || mOpportunisticSet.contains(clientState.getCallingPackage())) { 5655 isOpportunistic = true; 5656 } else { 5657 requestorWs.add( 5658 new WorkSource(clientState.getUid(), clientState.getCallingPackage())); 5659 } 5660 } 5661 if (requestorWs.size() == 0 && isOpportunistic) { 5662 // All clients are opportunistic, use Wifi UID 5663 return new WorkSource(Process.WIFI_UID); 5664 } 5665 return requestorWs; 5666 } 5667 doesAnyClientNeedIdentityChangeNotifications()5668 private boolean doesAnyClientNeedIdentityChangeNotifications() { 5669 for (int i = 0; i < mClients.size(); ++i) { 5670 if (mClients.valueAt(i).getNotifyIdentityChange()) { 5671 return true; 5672 } 5673 } 5674 return false; 5675 } 5676 doesAnyClientNeedRanging()5677 private boolean doesAnyClientNeedRanging() { 5678 for (int i = 0; i < mClients.size(); ++i) { 5679 if (mClients.valueAt(i).isRangingEnabled()) { 5680 return true; 5681 } 5682 } 5683 return false; 5684 } 5685 getInstantModeFromAllClients()5686 private int getInstantModeFromAllClients() { 5687 if (mOverrideInstantMode != INSTANT_MODE_DISABLED) { 5688 return mOverrideInstantMode; 5689 } 5690 int instantMode = INSTANT_MODE_DISABLED; 5691 for (int i = 0; i < mClients.size(); ++i) { 5692 int currentClient = mClients.valueAt(i).getInstantMode((long) mContext.getResources() 5693 .getInteger(R.integer.config_wifiAwareInstantCommunicationModeDurationMillis)); 5694 if (currentClient == INSTANT_MODE_5GHZ) { 5695 return currentClient; 5696 } 5697 if (currentClient == INSTANT_MODE_24GHZ) { 5698 instantMode = currentClient; 5699 } 5700 } 5701 return instantMode; 5702 } 5703 5704 /** 5705 * Just a proxy to call {@link WifiAwareDataPathStateManager#createAllInterfaces()} for test. 5706 */ 5707 @VisibleForTesting createAllDataPathInterfaces()5708 public void createAllDataPathInterfaces() { 5709 mDataPathMgr.createAllInterfaces(); 5710 } 5711 5712 /** 5713 * Dump the internal state of the class. 5714 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)5715 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 5716 pw.println("AwareStateManager:"); 5717 pw.println(" mClients: [" + mClients + "]"); 5718 pw.println(" mUsageEnabled: " + mUsageEnabled); 5719 pw.println(" mCapabilities: [" + mCapabilities + "]"); 5720 pw.println(" mCurrentAwareConfiguration: " + mCurrentAwareConfiguration); 5721 pw.println(" mCurrentIdentityNotification: " + mCurrentIdentityNotification); 5722 pw.println(" mOpportunisticSet: " + mOpportunisticSet); 5723 for (int i = 0; i < mClients.size(); ++i) { 5724 mClients.valueAt(i).dump(fd, pw, args); 5725 } 5726 pw.println(" mSettableParameters: " + mSettableParameters); 5727 mSm.dump(fd, pw, args); 5728 mDataPathMgr.dump(fd, pw, args); 5729 mWifiAwareNativeApi.dump(fd, pw, args); 5730 pw.println("mAwareMetrics:"); 5731 mAwareMetrics.dump(fd, pw, args); 5732 } 5733 handleLocationModeDisabled()5734 private void handleLocationModeDisabled() { 5735 for (int i = 0; i < mClients.size(); i++) { 5736 WifiAwareClientState clientState = mClients.valueAt(i); 5737 if (SdkLevel.isAtLeastT()) { 5738 try { 5739 // As location mode is disabled, only app disavowal the location can pass the 5740 // check. 5741 mWifiPermissionsUtil.enforceNearbyDevicesPermission( 5742 (AttributionSource) clientState.getAttributionSource(), true, 5743 "Wifi Aware location mode change."); 5744 } catch (SecurityException e) { 5745 disconnect(clientState.getClientId()); 5746 } 5747 } else { 5748 disconnect(clientState.getClientId()); 5749 } 5750 } 5751 } 5752 getAwareInstantCommunicationChannel(int instantMode)5753 private int getAwareInstantCommunicationChannel(int instantMode) { 5754 if (instantMode != INSTANT_MODE_5GHZ) { 5755 return AWARE_BAND_2_INSTANT_COMMUNICATION_CHANNEL_FREQ; 5756 } 5757 if (mAwareBand5InstantCommunicationChannelFreq == 0) { 5758 // If 5G instant communication doesn't have a valid channel, fallback to 2G. 5759 return AWARE_BAND_2_INSTANT_COMMUNICATION_CHANNEL_FREQ; 5760 } 5761 if (mAwareBand5InstantCommunicationChannelFreq > 0) { 5762 return mAwareBand5InstantCommunicationChannelFreq; 5763 } 5764 List<WifiAvailableChannel> channels = mWifiInjector.getWifiThreadRunner().call( 5765 () -> mWifiInjector.getWifiNative().getUsableChannels(WifiScanner.WIFI_BAND_5_GHZ, 5766 OP_MODE_WIFI_AWARE, WifiAvailableChannel.FILTER_NAN_INSTANT_MODE), null, 5767 TAG + "#getAwareInstantCommunicationChannel"); 5768 if (channels == null || channels.isEmpty()) { 5769 if (mVerboseLoggingEnabled) { 5770 Log.v(TAG, "No available instant communication mode channel"); 5771 } 5772 mAwareBand5InstantCommunicationChannelFreq = 0; 5773 } else { 5774 if (channels.size() > 1) { 5775 if (mVerboseLoggingEnabled) { 5776 Log.v(TAG, "should have only one 5G instant communication channel," 5777 + "but size=" + channels.size()); 5778 } 5779 } 5780 // TODO(b/232138258): When the filter issue fixed, just check if only return channel is 5781 // correct 5782 for (WifiAvailableChannel channel : channels) { 5783 int freq = channel.getFrequencyMhz(); 5784 if (freq == AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_149) { 5785 mAwareBand5InstantCommunicationChannelFreq = 5786 AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_149; 5787 break; 5788 } else if (freq == AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_44) { 5789 mAwareBand5InstantCommunicationChannelFreq = 5790 AWARE_BAND_5_INSTANT_COMMUNICATION_CHANNEL_FREQ_CHANNEL_44; 5791 } 5792 } 5793 if (mAwareBand5InstantCommunicationChannelFreq == -1) { 5794 Log.e(TAG, "Both channel 149 and 44 are not available when the 5G WI-FI is " 5795 + "supported"); 5796 mAwareBand5InstantCommunicationChannelFreq = 0; 5797 } 5798 } 5799 return mAwareBand5InstantCommunicationChannelFreq == 0 5800 ? AWARE_BAND_2_INSTANT_COMMUNICATION_CHANNEL_FREQ 5801 : mAwareBand5InstantCommunicationChannelFreq; 5802 } 5803 isAwareOffloading()5804 private boolean isAwareOffloading() { 5805 for (int i = 0; i < mClients.size(); ++i) { 5806 WifiAwareClientState clientState = mClients.valueAt(i); 5807 if (clientState.isAwareOffload()) { 5808 return true; 5809 } 5810 } 5811 return false; 5812 } 5813 isAnyCallerIgnoringBatteryOptimizations()5814 private boolean isAnyCallerIgnoringBatteryOptimizations() { 5815 for (int i = 0; i < mClients.size(); ++i) { 5816 WifiAwareClientState clientState = mClients.valueAt(i); 5817 if (mPowerManager.isIgnoringBatteryOptimizations(clientState.getCallingPackage())) { 5818 return true; 5819 } 5820 } 5821 return false; 5822 } 5823 convertFrameworkHalCommandToEnum(int cmd)5824 private int convertFrameworkHalCommandToEnum(int cmd) { 5825 switch (cmd) { 5826 case COMMAND_TYPE_CONNECT: 5827 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_ENABLE_REQUEST; 5828 case COMMAND_TYPE_RECONFIGURE: 5829 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_CONFIG_REQUEST; 5830 case COMMAND_TYPE_DISABLE: 5831 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_DISABLE_REQUEST; 5832 case COMMAND_TYPE_PUBLISH: 5833 case COMMAND_TYPE_UPDATE_PUBLISH: 5834 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_START_PUBLISH_REQUEST; 5835 case COMMAND_TYPE_SUBSCRIBE: 5836 case COMMAND_TYPE_UPDATE_SUBSCRIBE: 5837 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_START_SUBSCRIBE_REQUEST; 5838 case COMMAND_TYPE_TRANSMIT_NEXT_MESSAGE: 5839 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TRANSMIT_FOLLOW_UP_REQUEST; 5840 case COMMAND_TYPE_INITIATE_PAIRING_REQUEST: 5841 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_PAIRING_REQUEST; 5842 case COMMAND_TYPE_RESPONSE_PAIRING_REQUEST: 5843 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_PAIRING_INDICATION_REQUEST; 5844 case COMMAND_TYPE_INITIATE_BOOTSTRAPPING_REQUEST: 5845 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_BOOTSTRAPPING_REQUEST; 5846 case COMMAND_TYPE_RESPONSE_BOOTSTRAPPING_REQUEST: 5847 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_BOOTSTRAPPING_INDICATION_REQUEST; 5848 case COMMAND_TYPE_GET_CAPABILITIES: 5849 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_GET_CAPABILITIES_REQUEST; 5850 case COMMAND_TYPE_CREATE_DATA_PATH_INTERFACE: 5851 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_CREATE_DATA_INTERFACE_REQUEST; 5852 case COMMAND_TYPE_DELETE_DATA_PATH_INTERFACE: 5853 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_DELETE_DATA_INTERFACE_REQUEST; 5854 case COMMAND_TYPE_INITIATE_DATA_PATH_SETUP: 5855 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_INITIATE_DATA_PATH_REQUEST; 5856 case COMMAND_TYPE_RESPOND_TO_DATA_PATH_SETUP_REQUEST: 5857 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESPOND_TO_DATA_PATH_INDICATION_REQUEST; 5858 case COMMAND_TYPE_END_DATA_PATH: 5859 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TERMINATE_DATA_PATH_REQUEST; 5860 case COMMAND_TYPE_END_PAIRING: 5861 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_TERMINATE_PAIRING_REQUEST; 5862 case COMMAND_TYPE_SUSPEND_SESSION: 5863 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_SUSPEND_REQUEST; 5864 case COMMAND_TYPE_RESUME_SESSION: 5865 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_RESUME_REQUEST; 5866 default: 5867 return WIFI_AWARE_HAL_API_CALLED__COMMAND__AWARE_API_UNKNOWN; 5868 } 5869 } 5870 recordHalApiCall(int command, int state, long starTime)5871 private void recordHalApiCall(int command, int state, long starTime) { 5872 WifiStatsLog.write( 5873 WIFI_AWARE_HAL_API_CALLED, 5874 convertFrameworkHalCommandToEnum(command), 5875 convertNanStatusCodeToWifiStatsLogEnum(state), 5876 (int) (SystemClock.elapsedRealtime() - starTime)); 5877 } 5878 } 5879