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