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