1 /* 2 * Copyright (C) 2021 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 package com.android.server.wifi; 17 18 import static android.net.wifi.WifiManager.WIFI_FEATURE_DECORATED_IDENTITY; 19 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP; 20 import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP_ENROLLEE_RESPONDER; 21 import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA256; 22 import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA384; 23 import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO; 24 import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE; 25 import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; 26 import static android.net.wifi.WifiManager.WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS; 27 import static android.net.wifi.WifiManager.WIFI_FEATURE_SAE_PK; 28 import static android.net.wifi.WifiManager.WIFI_FEATURE_WAPI; 29 import static android.net.wifi.WifiManager.WIFI_FEATURE_WFD_R2; 30 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE; 31 import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B; 32 33 import android.annotation.NonNull; 34 import android.content.Context; 35 import android.hardware.wifi.V1_0.WifiChannelWidthInMhz; 36 import android.hardware.wifi.supplicant.V1_0.ISupplicant; 37 import android.hardware.wifi.supplicant.V1_0.ISupplicantIface; 38 import android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork; 39 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface; 40 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback; 41 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; 42 import android.hardware.wifi.supplicant.V1_0.IfaceType; 43 import android.hardware.wifi.supplicant.V1_0.SupplicantStatus; 44 import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; 45 import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods; 46 import android.hardware.wifi.supplicant.V1_2.DppAkm; 47 import android.hardware.wifi.supplicant.V1_2.DppNetRole; 48 import android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities; 49 import android.hardware.wifi.supplicant.V1_3.WifiTechnology; 50 import android.hardware.wifi.supplicant.V1_3.WpaDriverCapabilitiesMask; 51 import android.hardware.wifi.supplicant.V1_4.DppCurve; 52 import android.hardware.wifi.supplicant.V1_4.LegacyMode; 53 import android.hidl.manager.V1_0.IServiceManager; 54 import android.hidl.manager.V1_0.IServiceNotification; 55 import android.net.MacAddress; 56 import android.net.wifi.ScanResult; 57 import android.net.wifi.SecurityParams; 58 import android.net.wifi.WifiAnnotations.WifiStandard; 59 import android.net.wifi.WifiConfiguration; 60 import android.os.Handler; 61 import android.os.IHwBinder.DeathRecipient; 62 import android.os.RemoteException; 63 import android.text.TextUtils; 64 import android.util.Log; 65 import android.util.Pair; 66 67 import com.android.internal.annotations.VisibleForTesting; 68 import com.android.server.wifi.WifiNative.DppEventCallback; 69 import com.android.server.wifi.WifiNative.SupplicantDeathEventHandler; 70 import com.android.server.wifi.util.GeneralUtil.Mutable; 71 import com.android.server.wifi.util.NativeUtil; 72 73 import java.nio.ByteBuffer; 74 import java.nio.ByteOrder; 75 import java.util.ArrayList; 76 import java.util.HashMap; 77 import java.util.List; 78 import java.util.Map; 79 import java.util.NoSuchElementException; 80 import java.util.Objects; 81 import java.util.Random; 82 import java.util.concurrent.CountDownLatch; 83 import java.util.concurrent.TimeUnit; 84 import java.util.regex.Matcher; 85 import java.util.regex.Pattern; 86 87 import javax.annotation.concurrent.ThreadSafe; 88 89 /** 90 * Hal calls for bring up/shut down of the supplicant daemon and for 91 * sending requests to the supplicant daemon 92 * To maintain thread-safety, the locking protocol is that every non-static method (regardless of 93 * access level) acquires mLock. 94 */ 95 @ThreadSafe 96 public class SupplicantStaIfaceHalHidlImpl implements ISupplicantStaIfaceHal { 97 private static final String TAG = "SupplicantStaIfaceHalHidlImp"; 98 @VisibleForTesting 99 public static final String HAL_INSTANCE_NAME = "default"; 100 @VisibleForTesting 101 public static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L; 102 /** 103 * Regex pattern for extracting the wps device type bytes. 104 * Matches a strings like the following: "<categ>-<OUI>-<subcateg>"; 105 */ 106 private static final Pattern WPS_DEVICE_TYPE_PATTERN = 107 Pattern.compile("^(\\d{1,2})-([0-9a-fA-F]{8})-(\\d{1,2})$"); 108 109 private final Object mLock = new Object(); 110 private boolean mVerboseLoggingEnabled = false; 111 private boolean mVerboseHalLoggingEnabled = false; 112 113 // Supplicant HAL interface objects 114 private IServiceManager mIServiceManager = null; 115 private ISupplicant mISupplicant; 116 private Map<String, ISupplicantStaIface> mISupplicantStaIfaces = new HashMap<>(); 117 private Map<String, ISupplicantStaIfaceCallback> mISupplicantStaIfaceCallbacks = 118 new HashMap<>(); 119 private Map<String, SupplicantStaNetworkHalHidlImpl> mCurrentNetworkRemoteHandles = 120 new HashMap<>(); 121 private Map<String, WifiConfiguration> mCurrentNetworkLocalConfigs = new HashMap<>(); 122 private Map<String, List<Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration>>> 123 mLinkedNetworkLocalAndRemoteConfigs = new HashMap<>(); 124 @VisibleForTesting 125 PmkCacheManager mPmkCacheManager; 126 private SupplicantDeathEventHandler mDeathEventHandler; 127 private ServiceManagerDeathRecipient mServiceManagerDeathRecipient; 128 private SupplicantDeathRecipient mSupplicantDeathRecipient; 129 // Death recipient cookie registered for current supplicant instance. 130 private long mDeathRecipientCookie = 0; 131 private final Context mContext; 132 private final WifiMonitor mWifiMonitor; 133 private final FrameworkFacade mFrameworkFacade; 134 private final Handler mEventHandler; 135 private DppEventCallback mDppCallback = null; 136 private final Clock mClock; 137 private final WifiMetrics mWifiMetrics; 138 private final WifiGlobals mWifiGlobals; 139 140 private final IServiceNotification mServiceNotificationCallback = 141 new IServiceNotification.Stub() { 142 public void onRegistration(String fqName, String name, boolean preexisting) { 143 synchronized (mLock) { 144 if (mVerboseLoggingEnabled) { 145 Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName 146 + ", " + name + " preexisting=" + preexisting); 147 } 148 if (!initSupplicantService()) { 149 Log.e(TAG, "Initializing ISupplicant failed."); 150 supplicantServiceDiedHandler(mDeathRecipientCookie); 151 } else { 152 Log.i(TAG, "Completed initialization of ISupplicant."); 153 } 154 } 155 } 156 }; 157 private class ServiceManagerDeathRecipient implements DeathRecipient { 158 @Override serviceDied(long cookie)159 public void serviceDied(long cookie) { 160 mEventHandler.post(() -> { 161 synchronized (mLock) { 162 Log.w(TAG, "IServiceManager died: cookie=" + cookie); 163 supplicantServiceDiedHandler(mDeathRecipientCookie); 164 mIServiceManager = null; // Will need to register a new ServiceNotification 165 } 166 }); 167 } 168 } 169 private class SupplicantDeathRecipient implements DeathRecipient { 170 @Override serviceDied(long cookie)171 public void serviceDied(long cookie) { 172 mEventHandler.post(() -> { 173 synchronized (mLock) { 174 Log.w(TAG, "ISupplicant died: cookie=" + cookie); 175 supplicantServiceDiedHandler(cookie); 176 } 177 }); 178 } 179 } 180 SupplicantStaIfaceHalHidlImpl(Context context, WifiMonitor monitor, FrameworkFacade frameworkFacade, Handler handler, Clock clock, WifiMetrics wifiMetrics, WifiGlobals wifiGlobals)181 public SupplicantStaIfaceHalHidlImpl(Context context, WifiMonitor monitor, 182 FrameworkFacade frameworkFacade, Handler handler, 183 Clock clock, WifiMetrics wifiMetrics, 184 WifiGlobals wifiGlobals) { 185 mContext = context; 186 mWifiMonitor = monitor; 187 mFrameworkFacade = frameworkFacade; 188 mEventHandler = handler; 189 mClock = clock; 190 mWifiMetrics = wifiMetrics; 191 mWifiGlobals = wifiGlobals; 192 193 mServiceManagerDeathRecipient = new ServiceManagerDeathRecipient(); 194 mSupplicantDeathRecipient = new SupplicantDeathRecipient(); 195 mPmkCacheManager = new PmkCacheManager(mClock, mEventHandler); 196 } 197 198 /** 199 * Enable/Disable verbose logging. 200 * @param verboseEnabled Verbose flag set in overlay XML. 201 * @param halVerboseEnabled Verbose flag set by the user. 202 */ enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)203 public void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) { 204 synchronized (mLock) { 205 mVerboseLoggingEnabled = verboseEnabled; 206 mVerboseHalLoggingEnabled = halVerboseEnabled; 207 setLogLevel(mVerboseHalLoggingEnabled); 208 } 209 } 210 isVerboseLoggingEnabled()211 protected boolean isVerboseLoggingEnabled() { 212 return mVerboseLoggingEnabled; 213 } 214 linkToServiceManagerDeath()215 private boolean linkToServiceManagerDeath() { 216 synchronized (mLock) { 217 if (mIServiceManager == null) return false; 218 try { 219 if (!mIServiceManager.linkToDeath(mServiceManagerDeathRecipient, 0)) { 220 Log.wtf(TAG, "Error on linkToDeath on IServiceManager"); 221 supplicantServiceDiedHandler(mDeathRecipientCookie); 222 mIServiceManager = null; // Will need to register a new ServiceNotification 223 return false; 224 } 225 } catch (RemoteException e) { 226 Log.e(TAG, "IServiceManager.linkToDeath exception", e); 227 return false; 228 } 229 return true; 230 } 231 } 232 233 /** 234 * Registers a service notification for the ISupplicant service, which triggers initialization 235 * of the ISupplicantStaIface 236 * @return true if the service notification was successfully registered 237 */ initialize()238 public boolean initialize() { 239 synchronized (mLock) { 240 if (mVerboseLoggingEnabled) { 241 Log.i(TAG, "Registering ISupplicant service ready callback."); 242 } 243 mISupplicant = null; 244 mISupplicantStaIfaces.clear(); 245 if (mIServiceManager != null) { 246 // Already have an IServiceManager and serviceNotification registered, don't 247 // don't register another. 248 return true; 249 } 250 try { 251 mIServiceManager = getServiceManagerMockable(); 252 if (mIServiceManager == null) { 253 Log.e(TAG, "Failed to get HIDL Service Manager"); 254 return false; 255 } 256 if (!linkToServiceManagerDeath()) { 257 return false; 258 } 259 /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it 260 exists */ 261 if (!mIServiceManager.registerForNotifications( 262 ISupplicant.kInterfaceName, "", mServiceNotificationCallback)) { 263 Log.e(TAG, "Failed to register for notifications to " 264 + ISupplicant.kInterfaceName); 265 mIServiceManager = null; // Will need to register a new ServiceNotification 266 return false; 267 } 268 } catch (RemoteException e) { 269 Log.e(TAG, "Exception while trying to register a listener for " 270 + "ISupplicant service: " + e); 271 supplicantServiceDiedHandler(mDeathRecipientCookie); 272 } 273 return true; 274 } 275 } 276 linkToSupplicantDeath( DeathRecipient deathRecipient, long cookie)277 private boolean linkToSupplicantDeath( 278 DeathRecipient deathRecipient, long cookie) { 279 synchronized (mLock) { 280 if (mISupplicant == null) return false; 281 try { 282 if (!mISupplicant.linkToDeath(deathRecipient, cookie)) { 283 Log.wtf(TAG, "Error on linkToDeath on ISupplicant"); 284 supplicantServiceDiedHandler(mDeathRecipientCookie); 285 return false; 286 } 287 } catch (RemoteException e) { 288 Log.e(TAG, "ISupplicant.linkToDeath exception", e); 289 return false; 290 } 291 return true; 292 } 293 } 294 initSupplicantService()295 private boolean initSupplicantService() { 296 synchronized (mLock) { 297 try { 298 mISupplicant = getSupplicantMockable(); 299 } catch (RemoteException e) { 300 Log.e(TAG, "ISupplicant.getService exception: " + e); 301 return false; 302 } catch (NoSuchElementException e) { 303 Log.e(TAG, "ISupplicant.getService exception: " + e); 304 return false; 305 } 306 if (mISupplicant == null) { 307 Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup"); 308 return false; 309 } 310 if (!linkToSupplicantDeath(mSupplicantDeathRecipient, ++mDeathRecipientCookie)) { 311 return false; 312 } 313 } 314 return true; 315 } 316 getCurrentNetworkId(@onNull String ifaceName)317 protected int getCurrentNetworkId(@NonNull String ifaceName) { 318 synchronized (mLock) { 319 WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName); 320 if (currentConfig == null) { 321 return WifiConfiguration.INVALID_NETWORK_ID; 322 } 323 return currentConfig.networkId; 324 } 325 } 326 trySetupStaIfaceV1_4(@onNull String ifaceName, @NonNull ISupplicantStaIface iface)327 private boolean trySetupStaIfaceV1_4(@NonNull String ifaceName, 328 @NonNull ISupplicantStaIface iface) throws RemoteException { 329 if (!isV1_4()) return false; 330 331 SupplicantStaIfaceHalCallbackV1_4 callbackV14 = 332 new SupplicantStaIfaceHalCallbackV1_4(ifaceName); 333 if (!registerCallbackV1_4(getStaIfaceMockableV1_4(iface), callbackV14)) { 334 throw new RemoteException("Init StaIface V1_4 failed."); 335 } 336 /* keep this in a store to avoid recycling by garbage collector. */ 337 mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV14); 338 return true; 339 } 340 trySetupStaIfaceV1_3(@onNull String ifaceName, @NonNull ISupplicantStaIface iface)341 private boolean trySetupStaIfaceV1_3(@NonNull String ifaceName, 342 @NonNull ISupplicantStaIface iface) throws RemoteException { 343 if (!isV1_3()) return false; 344 345 /* try newer version first. */ 346 if (trySetupStaIfaceV1_4(ifaceName, iface)) { 347 logd("Newer HAL is found, skip V1_3 remaining init flow."); 348 return true; 349 } 350 SupplicantStaIfaceHalCallbackV1_3 callbackV13 = 351 new SupplicantStaIfaceHalCallbackV1_3(ifaceName); 352 if (!registerCallbackV1_3(getStaIfaceMockableV1_3(iface), callbackV13)) { 353 throw new RemoteException("Init StaIface V1_3 failed."); 354 } 355 /* keep this in a store to avoid recycling by garbage collector. */ 356 mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV13); 357 return true; 358 } 359 trySetupStaIfaceV1_2(@onNull String ifaceName, @NonNull ISupplicantStaIface iface)360 private boolean trySetupStaIfaceV1_2(@NonNull String ifaceName, 361 @NonNull ISupplicantStaIface iface) throws RemoteException { 362 if (!isV1_2()) return false; 363 364 /* try newer version first. */ 365 if (trySetupStaIfaceV1_3(ifaceName, iface)) { 366 logd("Newer HAL is found, skip V1_2 remaining init flow."); 367 return true; 368 } 369 370 SupplicantStaIfaceHalCallbackV1_2 callbackV12 = 371 new SupplicantStaIfaceHalCallbackV1_2(ifaceName); 372 if (!registerCallbackV1_2(getStaIfaceMockableV1_2(iface), callbackV12)) { 373 throw new RemoteException("Init StaIface V1_2 failed."); 374 } 375 /* keep this in a store to avoid recycling by garbage collector. */ 376 mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV12); 377 return true; 378 } 379 trySetupStaIfaceV1_1(@onNull String ifaceName, @NonNull ISupplicantStaIface iface)380 private boolean trySetupStaIfaceV1_1(@NonNull String ifaceName, 381 @NonNull ISupplicantStaIface iface) throws RemoteException { 382 if (!isV1_1()) return false; 383 384 /* try newer version first. */ 385 if (trySetupStaIfaceV1_2(ifaceName, iface)) { 386 logd("Newer HAL is found, skip V1_1 remaining init flow."); 387 return true; 388 } 389 390 SupplicantStaIfaceHalCallbackV1_1 callbackV11 = 391 new SupplicantStaIfaceHalCallbackV1_1(ifaceName); 392 if (!registerCallbackV1_1(getStaIfaceMockableV1_1(iface), callbackV11)) { 393 throw new RemoteException("Init StaIface V1_1 failed."); 394 } 395 /* keep this in a store to avoid recycling by garbage collector. */ 396 mISupplicantStaIfaceCallbacks.put(ifaceName, callbackV11); 397 return true; 398 } 399 400 /** 401 * Helper function to set up StaIface with different HAL version. 402 * 403 * This helper function would try newer version recursively. 404 * Once the latest version is found, it would register the callback 405 * of the latest version and skip unnecessary older HAL init flow. 406 * 407 * New version callback will be extended from the older one, as a result, 408 * older callback is always created regardless of the latest version. 409 * 410 * Uprev steps: 411 * 1. add new helper function trySetupStaIfaceV1_Y. 412 * 2. call newly added function in trySetupStaIfaceV1_X (X should be Y-1). 413 */ setupStaIface(@onNull String ifaceName, @NonNull ISupplicantIface ifaceHwBinder)414 private ISupplicantStaIface setupStaIface(@NonNull String ifaceName, 415 @NonNull ISupplicantIface ifaceHwBinder) throws RemoteException { 416 /* Prepare base type for later cast. */ 417 ISupplicantStaIface iface = getStaIfaceMockable(ifaceHwBinder); 418 419 /* try newer version first. */ 420 if (trySetupStaIfaceV1_1(ifaceName, iface)) { 421 logd("Newer HAL is found, skip V1_0 remaining init flow."); 422 return iface; 423 } 424 425 SupplicantStaIfaceHalCallback callback = new SupplicantStaIfaceHalCallback(ifaceName); 426 if (!registerCallback(iface, callback)) { 427 throw new RemoteException("Init StaIface V1_0 failed."); 428 } 429 /* keep this in a store to avoid recycling by garbage collector. */ 430 mISupplicantStaIfaceCallbacks.put(ifaceName, callback); 431 return iface; 432 } 433 434 /** 435 * Setup a STA interface for the specified iface name. 436 * 437 * @param ifaceName Name of the interface. 438 * @return true on success, false otherwise. 439 */ setupIface(@onNull String ifaceName)440 public boolean setupIface(@NonNull String ifaceName) { 441 final String methodStr = "setupIface"; 442 if (checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr) != null) return false; 443 ISupplicantIface ifaceHwBinder; 444 445 if (isV1_1()) { 446 ifaceHwBinder = addIfaceV1_1(ifaceName); 447 } else { 448 ifaceHwBinder = getIfaceV1_0(ifaceName); 449 } 450 if (ifaceHwBinder == null) { 451 Log.e(TAG, "setupIface got null iface"); 452 return false; 453 } 454 455 try { 456 ISupplicantStaIface iface = setupStaIface(ifaceName, ifaceHwBinder); 457 mISupplicantStaIfaces.put(ifaceName, iface); 458 } catch (RemoteException e) { 459 loge("setup StaIface failed: " + e.toString()); 460 return false; 461 } 462 463 return true; 464 } 465 466 /** 467 * Get a STA interface for the specified iface name. 468 * 469 * @param ifaceName Name of the interface. 470 * @return true on success, false otherwise. 471 */ getIfaceV1_0(@onNull String ifaceName)472 private ISupplicantIface getIfaceV1_0(@NonNull String ifaceName) { 473 synchronized (mLock) { 474 if (mISupplicant == null) { 475 return null; 476 } 477 478 /** List all supplicant Ifaces */ 479 final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>(); 480 try { 481 mISupplicant.listInterfaces((SupplicantStatus status, 482 ArrayList<ISupplicant.IfaceInfo> ifaces) -> { 483 if (status.code != SupplicantStatusCode.SUCCESS) { 484 Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code); 485 return; 486 } 487 supplicantIfaces.addAll(ifaces); 488 }); 489 } catch (RemoteException e) { 490 Log.e(TAG, "ISupplicant.listInterfaces exception: " + e); 491 handleRemoteException(e, "listInterfaces"); 492 return null; 493 } 494 if (supplicantIfaces.size() == 0) { 495 Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup."); 496 return null; 497 } 498 Mutable<ISupplicantIface> supplicantIface = new Mutable<>(); 499 for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) { 500 if (ifaceInfo.type == IfaceType.STA 501 && TextUtils.equals(ifaceName, ifaceInfo.name)) { 502 try { 503 mISupplicant.getInterface(ifaceInfo, 504 (SupplicantStatus status, ISupplicantIface iface) -> { 505 if (status.code != SupplicantStatusCode.SUCCESS) { 506 Log.e(TAG, "Fail to get ISupplicantIface " + status.code); 507 return; 508 } 509 supplicantIface.value = iface; 510 }); 511 } catch (RemoteException e) { 512 Log.e(TAG, "ISupplicant.getInterface exception: " + e); 513 handleRemoteException(e, "getInterface"); 514 return null; 515 } 516 break; 517 } 518 } 519 return supplicantIface.value; 520 } 521 } 522 523 /** 524 * Create a STA interface for the specified iface name. 525 * 526 * @param ifaceName Name of the interface. 527 * @return true on success, false otherwise. 528 */ addIfaceV1_1(@onNull String ifaceName)529 private ISupplicantIface addIfaceV1_1(@NonNull String ifaceName) { 530 synchronized (mLock) { 531 ISupplicant.IfaceInfo ifaceInfo = new ISupplicant.IfaceInfo(); 532 ifaceInfo.name = ifaceName; 533 ifaceInfo.type = IfaceType.STA; 534 Mutable<ISupplicantIface> supplicantIface = new Mutable<>(); 535 try { 536 getSupplicantMockableV1_1().addInterface(ifaceInfo, 537 (SupplicantStatus status, ISupplicantIface iface) -> { 538 if (status.code != SupplicantStatusCode.SUCCESS 539 && status.code != SupplicantStatusCode.FAILURE_IFACE_EXISTS) { 540 Log.e(TAG, "Failed to create ISupplicantIface " + status.code); 541 return; 542 } 543 supplicantIface.value = iface; 544 }); 545 } catch (RemoteException e) { 546 Log.e(TAG, "ISupplicant.addInterface exception: " + e); 547 handleRemoteException(e, "addInterface"); 548 return null; 549 } catch (NoSuchElementException e) { 550 Log.e(TAG, "ISupplicant.addInterface exception: " + e); 551 handleNoSuchElementException(e, "addInterface"); 552 return null; 553 } catch (IllegalArgumentException e) { 554 handleIllegalArgumentException(e, "addInterface"); 555 Log.e(TAG, "ISupplicant.addInterface exception: " + e); 556 return null; 557 } 558 return supplicantIface.value; 559 } 560 } 561 562 /** 563 * Teardown a STA interface for the specified iface name. 564 * 565 * @param ifaceName Name of the interface. 566 * @return true on success, false otherwise. 567 */ teardownIface(@onNull String ifaceName)568 public boolean teardownIface(@NonNull String ifaceName) { 569 synchronized (mLock) { 570 final String methodStr = "teardownIface"; 571 if (checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr) == null) return false; 572 if (isV1_1()) { 573 if (!removeIfaceV1_1(ifaceName)) { 574 Log.e(TAG, "Failed to remove iface = " + ifaceName); 575 return false; 576 } 577 } 578 if (mISupplicantStaIfaces.remove(ifaceName) == null) { 579 Log.e(TAG, "Trying to teardown unknown interface"); 580 return false; 581 } 582 mISupplicantStaIfaceCallbacks.remove(ifaceName); 583 return true; 584 } 585 } 586 587 /** 588 * Remove a STA interface for the specified iface name. 589 * 590 * @param ifaceName Name of the interface. 591 * @return true on success, false otherwise. 592 */ removeIfaceV1_1(@onNull String ifaceName)593 private boolean removeIfaceV1_1(@NonNull String ifaceName) { 594 synchronized (mLock) { 595 try { 596 ISupplicant.IfaceInfo ifaceInfo = new ISupplicant.IfaceInfo(); 597 ifaceInfo.name = ifaceName; 598 ifaceInfo.type = IfaceType.STA; 599 SupplicantStatus status = getSupplicantMockableV1_1().removeInterface(ifaceInfo); 600 if (status.code != SupplicantStatusCode.SUCCESS) { 601 Log.e(TAG, "Failed to remove iface " + status.code); 602 return false; 603 } 604 } catch (RemoteException e) { 605 Log.e(TAG, "ISupplicant.removeInterface exception: " + e); 606 handleRemoteException(e, "removeInterface"); 607 return false; 608 } catch (NoSuchElementException e) { 609 Log.e(TAG, "ISupplicant.removeInterface exception: " + e); 610 handleNoSuchElementException(e, "removeInterface"); 611 return false; 612 } 613 return true; 614 } 615 } 616 617 /** 618 * Registers a death notification for supplicant. 619 * @return Returns true on success. 620 */ registerDeathHandler(@onNull SupplicantDeathEventHandler handler)621 public boolean registerDeathHandler(@NonNull SupplicantDeathEventHandler handler) { 622 if (mDeathEventHandler != null) { 623 Log.e(TAG, "Death handler already present"); 624 } 625 mDeathEventHandler = handler; 626 return true; 627 } 628 629 /** 630 * Deregisters a death notification for supplicant. 631 * @return Returns true on success. 632 */ deregisterDeathHandler()633 public boolean deregisterDeathHandler() { 634 if (mDeathEventHandler == null) { 635 Log.e(TAG, "No Death handler present"); 636 } 637 mDeathEventHandler = null; 638 return true; 639 } 640 641 clearState()642 private void clearState() { 643 synchronized (mLock) { 644 mISupplicant = null; 645 mISupplicantStaIfaces.clear(); 646 mCurrentNetworkLocalConfigs.clear(); 647 mCurrentNetworkRemoteHandles.clear(); 648 mLinkedNetworkLocalAndRemoteConfigs.clear(); 649 } 650 } 651 supplicantServiceDiedHandler(long cookie)652 private void supplicantServiceDiedHandler(long cookie) { 653 synchronized (mLock) { 654 if (mDeathRecipientCookie != cookie) { 655 Log.i(TAG, "Ignoring stale death recipient notification"); 656 return; 657 } 658 clearState(); 659 if (mDeathEventHandler != null) { 660 mDeathEventHandler.onDeath(); 661 } 662 } 663 } 664 665 /** 666 * Signals whether Initialization completed successfully. 667 */ isInitializationStarted()668 public boolean isInitializationStarted() { 669 synchronized (mLock) { 670 return mIServiceManager != null; 671 } 672 } 673 674 /** 675 * Signals whether Initialization completed successfully. 676 */ isInitializationComplete()677 public boolean isInitializationComplete() { 678 synchronized (mLock) { 679 return mISupplicant != null; 680 } 681 } 682 683 684 /** 685 * Start the supplicant daemon for V1_1 service. 686 * 687 * @return true on success, false otherwise. 688 */ startDaemon_V1_1()689 private boolean startDaemon_V1_1() { 690 synchronized (mLock) { 691 try { 692 // This should startup supplicant daemon using the lazy start HAL mechanism. 693 getSupplicantMockableV1_1(); 694 } catch (RemoteException e) { 695 Log.e(TAG, "Exception while trying to start supplicant: " 696 + e); 697 supplicantServiceDiedHandler(mDeathRecipientCookie); 698 return false; 699 } catch (NoSuchElementException e) { 700 // We're starting the daemon, so expect |NoSuchElementException|. 701 Log.d(TAG, "Successfully triggered start of supplicant using HIDL"); 702 } 703 return true; 704 } 705 } 706 707 /** 708 * Start the supplicant daemon. 709 * 710 * @return true on success, false otherwise. 711 */ startDaemon()712 public boolean startDaemon() { 713 synchronized (mLock) { 714 if (isV1_1()) { 715 Log.i(TAG, "Starting supplicant using HIDL"); 716 return startDaemon_V1_1(); 717 } else { 718 Log.i(TAG, "Starting supplicant using init"); 719 return mFrameworkFacade.startSupplicant(); 720 } 721 } 722 } 723 724 /** 725 * Terminate the supplicant daemon for V1_1 service. 726 */ terminate_V1_1()727 private void terminate_V1_1() { 728 synchronized (mLock) { 729 final String methodStr = "terminate"; 730 if (!checkSupplicantAndLogFailure(methodStr)) return; 731 try { 732 getSupplicantMockableV1_1().terminate(); 733 } catch (RemoteException e) { 734 handleRemoteException(e, methodStr); 735 } catch (NoSuchElementException e) { 736 handleNoSuchElementException(e, methodStr); 737 } 738 } 739 } 740 741 /** 742 * Terminate the supplicant daemon & wait for it's death. 743 */ terminate()744 public void terminate() { 745 synchronized (mLock) { 746 // Register for a new death listener to block until supplicant is dead. 747 final long waitForDeathCookie = new Random().nextLong(); 748 final CountDownLatch waitForDeathLatch = new CountDownLatch(1); 749 linkToSupplicantDeath((cookie) -> { 750 mEventHandler.post(() -> { 751 Log.d(TAG, "ISupplicant died: cookie=" + cookie); 752 if (cookie != waitForDeathCookie) return; 753 supplicantServiceDiedHandler(mDeathRecipientCookie); 754 waitForDeathLatch.countDown(); 755 }); 756 }, waitForDeathCookie); 757 758 if (isV1_1()) { 759 Log.i(TAG, "Terminating supplicant using HIDL"); 760 terminate_V1_1(); 761 } else { 762 Log.i(TAG, "Terminating supplicant using init"); 763 mFrameworkFacade.stopSupplicant(); 764 } 765 766 // Now wait for death listener callback to confirm that it's dead. 767 try { 768 if (!waitForDeathLatch.await(WAIT_FOR_DEATH_TIMEOUT_MS, TimeUnit.MILLISECONDS)) { 769 Log.w(TAG, "Timed out waiting for confirmation of supplicant death"); 770 } 771 } catch (InterruptedException e) { 772 Log.w(TAG, "Failed to wait for supplicant death"); 773 } 774 } 775 } 776 777 /** 778 * Indicates whether the HIDL service is declared. Uses the IServiceManager to check 779 * if the device is running a version >= V1_0 of the HAL from the VINTF for the device. 780 */ serviceDeclared()781 public static boolean serviceDeclared() { 782 try { 783 IServiceManager serviceManager = IServiceManager.getService(); 784 String interfaceName = android.hardware.wifi.supplicant.V1_0.ISupplicant.kInterfaceName; 785 if (serviceManager.getTransport(interfaceName, HAL_INSTANCE_NAME) 786 != IServiceManager.Transport.EMPTY) { 787 return true; 788 } 789 return false; 790 } catch (RemoteException e) { 791 Log.e(TAG, "Unable to check for existence of HIDL service."); 792 return false; 793 } 794 } 795 796 /** 797 * Wrapper functions to access static HAL methods, created to be mockable in unit tests 798 */ getServiceManagerMockable()799 protected IServiceManager getServiceManagerMockable() throws RemoteException { 800 synchronized (mLock) { 801 return IServiceManager.getService(); 802 } 803 } 804 getSupplicantMockable()805 protected ISupplicant getSupplicantMockable() throws RemoteException, NoSuchElementException { 806 synchronized (mLock) { 807 ISupplicant iSupplicant = ISupplicant.getService(); 808 if (iSupplicant == null) { 809 throw new NoSuchElementException("Cannot get root service."); 810 } 811 return iSupplicant; 812 } 813 } 814 getSupplicantMockableV1_1()815 protected android.hardware.wifi.supplicant.V1_1.ISupplicant getSupplicantMockableV1_1() 816 throws RemoteException, NoSuchElementException { 817 synchronized (mLock) { 818 android.hardware.wifi.supplicant.V1_1.ISupplicant iSupplicantDerived = 819 android.hardware.wifi.supplicant.V1_1.ISupplicant.castFrom( 820 getSupplicantMockable()); 821 if (iSupplicantDerived == null) { 822 throw new NoSuchElementException("Cannot cast to V1.1 service."); 823 } 824 return iSupplicantDerived; 825 } 826 } 827 getSupplicantMockableV1_2()828 protected android.hardware.wifi.supplicant.V1_2.ISupplicant getSupplicantMockableV1_2() 829 throws RemoteException, NoSuchElementException { 830 synchronized (mLock) { 831 android.hardware.wifi.supplicant.V1_2.ISupplicant iSupplicantDerived = 832 android.hardware.wifi.supplicant.V1_2.ISupplicant.castFrom( 833 getSupplicantMockable()); 834 if (iSupplicantDerived == null) { 835 throw new NoSuchElementException("Cannot cast to V1.1 service."); 836 } 837 return iSupplicantDerived; 838 } 839 } 840 getStaIfaceMockable(ISupplicantIface iface)841 protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) { 842 synchronized (mLock) { 843 return ISupplicantStaIface.asInterface(iface.asBinder()); 844 } 845 } 846 847 protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface getStaIfaceMockableV1_1(ISupplicantIface iface)848 getStaIfaceMockableV1_1(ISupplicantIface iface) { 849 synchronized (mLock) { 850 return android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface 851 .asInterface(iface.asBinder()); 852 } 853 } 854 855 protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface getStaIfaceMockableV1_2(ISupplicantIface iface)856 getStaIfaceMockableV1_2(ISupplicantIface iface) { 857 synchronized (mLock) { 858 return android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface 859 .asInterface(iface.asBinder()); 860 } 861 } 862 863 protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface getStaIfaceMockableV1_3(ISupplicantIface iface)864 getStaIfaceMockableV1_3(ISupplicantIface iface) { 865 synchronized (mLock) { 866 return android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface 867 .asInterface(iface.asBinder()); 868 } 869 } 870 871 protected android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface getStaIfaceMockableV1_4(ISupplicantIface iface)872 getStaIfaceMockableV1_4(ISupplicantIface iface) { 873 synchronized (mLock) { 874 return android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface 875 .asInterface(iface.asBinder()); 876 } 877 } 878 879 /** 880 * Uses the IServiceManager to check if the device is running V1_1 of the HAL from the VINTF for 881 * the device. 882 * @return true if supported, false otherwise. 883 */ isV1_1()884 private boolean isV1_1() { 885 return checkHalVersionByInterfaceName( 886 android.hardware.wifi.supplicant.V1_1.ISupplicant.kInterfaceName); 887 } 888 889 /** 890 * Uses the IServiceManager to check if the device is running V1_2 of the HAL from the VINTF for 891 * the device. 892 * @return true if supported, false otherwise. 893 */ isV1_2()894 private boolean isV1_2() { 895 return checkHalVersionByInterfaceName( 896 android.hardware.wifi.supplicant.V1_2.ISupplicant.kInterfaceName); 897 } 898 899 /** 900 * Uses the IServiceManager to check if the device is running V1_3 of the HAL from the VINTF for 901 * the device. 902 * @return true if supported, false otherwise. 903 */ isV1_3()904 private boolean isV1_3() { 905 return checkHalVersionByInterfaceName( 906 android.hardware.wifi.supplicant.V1_3.ISupplicant.kInterfaceName); 907 } 908 909 /** 910 * Uses the IServiceManager to check if the device is running V1_4 of the HAL from the VINTF for 911 * the device. 912 * @return true if supported, false otherwise. 913 */ isV1_4()914 private boolean isV1_4() { 915 return checkHalVersionByInterfaceName( 916 android.hardware.wifi.supplicant.V1_4.ISupplicant.kInterfaceName); 917 } 918 checkHalVersionByInterfaceName(String interfaceName)919 private boolean checkHalVersionByInterfaceName(String interfaceName) { 920 if (interfaceName == null) { 921 return false; 922 } 923 synchronized (mLock) { 924 if (mIServiceManager == null) { 925 Log.e(TAG, "checkHalVersionByInterfaceName: called but " 926 + "mServiceManager is null"); 927 return false; 928 } 929 try { 930 return (mIServiceManager.getTransport( 931 interfaceName, 932 HAL_INSTANCE_NAME) 933 != IServiceManager.Transport.EMPTY); 934 } catch (RemoteException e) { 935 Log.e(TAG, "Exception while operating on IServiceManager: " + e); 936 handleRemoteException(e, "getTransport"); 937 return false; 938 } 939 } 940 } 941 942 /** 943 * Helper method to look up the network object for the specified iface. 944 */ getStaIface(@onNull String ifaceName)945 private ISupplicantStaIface getStaIface(@NonNull String ifaceName) { 946 return mISupplicantStaIfaces.get(ifaceName); 947 } 948 949 /** 950 * Helper method to look up the network object for the specified iface. 951 */ getCurrentNetworkRemoteHandle( @onNull String ifaceName)952 private SupplicantStaNetworkHalHidlImpl getCurrentNetworkRemoteHandle( 953 @NonNull String ifaceName) { 954 return mCurrentNetworkRemoteHandles.get(ifaceName); 955 } 956 957 /** 958 * Helper method to look up the network config for the specified iface. 959 */ getCurrentNetworkLocalConfig(@onNull String ifaceName)960 protected WifiConfiguration getCurrentNetworkLocalConfig(@NonNull String ifaceName) { 961 return mCurrentNetworkLocalConfigs.get(ifaceName); 962 } 963 964 /** 965 * Add a network configuration to wpa_supplicant. 966 * 967 * @param config Config corresponding to the network. 968 * @return a Pair object including SupplicantStaNetworkHal and WifiConfiguration objects 969 * for the current network. 970 */ 971 private Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration> addNetworkAndSaveConfig(@onNull String ifaceName, WifiConfiguration config)972 addNetworkAndSaveConfig(@NonNull String ifaceName, WifiConfiguration config) { 973 synchronized (mLock) { 974 logi("addSupplicantStaNetwork via HIDL"); 975 if (config == null) { 976 loge("Cannot add NULL network!"); 977 return null; 978 } 979 SupplicantStaNetworkHalHidlImpl network = addNetwork(ifaceName); 980 if (network == null) { 981 loge("Failed to add a network!"); 982 return null; 983 } 984 boolean saveSuccess = false; 985 try { 986 saveSuccess = network.saveWifiConfiguration(config); 987 } catch (IllegalArgumentException e) { 988 Log.e(TAG, "Exception while saving config params: " + config, e); 989 } 990 if (!saveSuccess) { 991 loge("Failed to save variables for: " + config.getProfileKey()); 992 if (!removeAllNetworks(ifaceName)) { 993 loge("Failed to remove all networks on failure."); 994 } 995 return null; 996 } 997 return new Pair(network, new WifiConfiguration(config)); 998 } 999 } 1000 1001 /** 1002 * Add the provided network configuration to wpa_supplicant and initiate connection to it. 1003 * This method does the following: 1004 * 1. If |config| is different to the current supplicant network, removes all supplicant 1005 * networks and saves |config|. 1006 * 2. Select the new network in wpa_supplicant. 1007 * 1008 * @param ifaceName Name of the interface. 1009 * @param config WifiConfiguration parameters for the provided network. 1010 * @return {@code true} if it succeeds, {@code false} otherwise 1011 */ connectToNetwork(@onNull String ifaceName, @NonNull WifiConfiguration config)1012 public boolean connectToNetwork(@NonNull String ifaceName, @NonNull WifiConfiguration config) { 1013 synchronized (mLock) { 1014 logd("connectToNetwork " + config.getProfileKey()); 1015 WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName); 1016 if (WifiConfigurationUtil.isSameNetwork(config, currentConfig)) { 1017 String networkSelectionBSSID = config.getNetworkSelectionStatus() 1018 .getNetworkSelectionBSSID(); 1019 String networkSelectionBSSIDCurrent = 1020 currentConfig.getNetworkSelectionStatus().getNetworkSelectionBSSID(); 1021 if (Objects.equals(networkSelectionBSSID, networkSelectionBSSIDCurrent)) { 1022 logd("Network is already saved, will not trigger remove and add operation."); 1023 } else { 1024 logd("Network is already saved, but need to update BSSID."); 1025 if (!setCurrentNetworkBssid( 1026 ifaceName, 1027 config.getNetworkSelectionStatus().getNetworkSelectionBSSID())) { 1028 loge("Failed to set current network BSSID."); 1029 return false; 1030 } 1031 mCurrentNetworkLocalConfigs.put(ifaceName, new WifiConfiguration(config)); 1032 } 1033 } else { 1034 mCurrentNetworkRemoteHandles.remove(ifaceName); 1035 mCurrentNetworkLocalConfigs.remove(ifaceName); 1036 mLinkedNetworkLocalAndRemoteConfigs.remove(ifaceName); 1037 if (!removeAllNetworks(ifaceName)) { 1038 loge("Failed to remove existing networks"); 1039 return false; 1040 } 1041 Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration> pair = 1042 addNetworkAndSaveConfig(ifaceName, config); 1043 if (pair == null) { 1044 loge("Failed to add/save network configuration: " + config 1045 .getProfileKey()); 1046 return false; 1047 } 1048 mCurrentNetworkRemoteHandles.put(ifaceName, pair.first); 1049 mCurrentNetworkLocalConfigs.put(ifaceName, pair.second); 1050 } 1051 SupplicantStaNetworkHalHidlImpl networkHandle = 1052 checkSupplicantStaNetworkAndLogFailure(ifaceName, "connectToNetwork"); 1053 if (networkHandle == null) { 1054 loge("No valid remote network handle for network configuration: " 1055 + config.getProfileKey()); 1056 return false; 1057 } 1058 1059 SecurityParams params = config.getNetworkSelectionStatus() 1060 .getCandidateSecurityParams(); 1061 if (params != null && !params.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)) { 1062 List<ArrayList<Byte>> pmkDataList = mPmkCacheManager.get(config.networkId); 1063 if (pmkDataList != null) { 1064 logi("Set PMK cache for config id " + config.networkId); 1065 pmkDataList.forEach(pmkData -> { 1066 if (networkHandle.setPmkCache(pmkData)) { 1067 mWifiMetrics.setConnectionPmkCache(ifaceName, true); 1068 } 1069 }); 1070 } 1071 } 1072 1073 if (!networkHandle.select()) { 1074 loge("Failed to select network configuration: " + config.getProfileKey()); 1075 return false; 1076 } 1077 return true; 1078 } 1079 } 1080 1081 /** 1082 * Initiates roaming to the already configured network in wpa_supplicant. If the network 1083 * configuration provided does not match the already configured network, then this triggers 1084 * a new connection attempt (instead of roam). 1085 * 1. First check if we're attempting to connect to a linked network, and select the existing 1086 * supplicant network if there is one. 1087 * 2. Set the new bssid for the network in wpa_supplicant. 1088 * 3. Trigger reassociate command to wpa_supplicant. 1089 * 1090 * @param ifaceName Name of the interface. 1091 * @param config WifiConfiguration parameters for the provided network. 1092 * @return {@code true} if it succeeds, {@code false} otherwise 1093 */ roamToNetwork(@onNull String ifaceName, WifiConfiguration config)1094 public boolean roamToNetwork(@NonNull String ifaceName, WifiConfiguration config) { 1095 synchronized (mLock) { 1096 if (updateOnLinkedNetworkRoaming(ifaceName, config.networkId, true)) { 1097 SupplicantStaNetworkHalHidlImpl networkHandle = 1098 getCurrentNetworkRemoteHandle(ifaceName); 1099 if (networkHandle == null) { 1100 loge("Roaming config matches a linked config, but a linked network handle was" 1101 + " not found."); 1102 return false; 1103 } 1104 return networkHandle.select(); 1105 } 1106 if (getCurrentNetworkId(ifaceName) != config.networkId) { 1107 Log.w(TAG, "Cannot roam to a different network, initiate new connection. " 1108 + "Current network ID: " + getCurrentNetworkId(ifaceName)); 1109 return connectToNetwork(ifaceName, config); 1110 } 1111 String bssid = config.getNetworkSelectionStatus().getNetworkSelectionBSSID(); 1112 logd("roamToNetwork" + config.getProfileKey() + " (bssid " + bssid + ")"); 1113 1114 SupplicantStaNetworkHalHidlImpl networkHandle = 1115 checkSupplicantStaNetworkAndLogFailure(ifaceName, "roamToNetwork"); 1116 if (networkHandle == null || !networkHandle.setBssid(bssid)) { 1117 loge("Failed to set new bssid on network: " + config.getProfileKey()); 1118 return false; 1119 } 1120 if (!reassociate(ifaceName)) { 1121 loge("Failed to trigger reassociate"); 1122 return false; 1123 } 1124 return true; 1125 } 1126 } 1127 1128 /** 1129 * Clean HAL cached data for |networkId| in the framework. 1130 * 1131 * @param networkId network id of the network to be removed from supplicant. 1132 */ removeNetworkCachedData(int networkId)1133 public void removeNetworkCachedData(int networkId) { 1134 synchronized (mLock) { 1135 logd("Remove cached HAL data for config id " + networkId); 1136 removePmkCacheEntry(networkId); 1137 } 1138 } 1139 1140 /** 1141 * Clear HAL cached data if MAC address is changed. 1142 * 1143 * @param networkId network id of the network to be checked. 1144 * @param curMacAddress current MAC address 1145 */ removeNetworkCachedDataIfNeeded(int networkId, MacAddress curMacAddress)1146 public void removeNetworkCachedDataIfNeeded(int networkId, MacAddress curMacAddress) { 1147 synchronized (mLock) { 1148 mPmkCacheManager.remove(networkId, curMacAddress); 1149 } 1150 } 1151 1152 /** 1153 * Remove all networks from supplicant 1154 * 1155 * @param ifaceName Name of the interface. 1156 */ removeAllNetworks(@onNull String ifaceName)1157 public boolean removeAllNetworks(@NonNull String ifaceName) { 1158 synchronized (mLock) { 1159 ArrayList<Integer> networks = listNetworks(ifaceName); 1160 if (networks == null) { 1161 Log.e(TAG, "removeAllNetworks failed, got null networks"); 1162 return false; 1163 } 1164 for (int id : networks) { 1165 if (!removeNetwork(ifaceName, id)) { 1166 Log.e(TAG, "removeAllNetworks failed to remove network: " + id); 1167 return false; 1168 } 1169 } 1170 // Reset current network info. 1171 mCurrentNetworkRemoteHandles.remove(ifaceName); 1172 mCurrentNetworkLocalConfigs.remove(ifaceName); 1173 mLinkedNetworkLocalAndRemoteConfigs.remove(ifaceName); 1174 return true; 1175 } 1176 } 1177 1178 /** 1179 * Disable the current network in supplicant 1180 * 1181 * @param ifaceName Name of the interface. 1182 */ disableCurrentNetwork(@onNull String ifaceName)1183 public boolean disableCurrentNetwork(@NonNull String ifaceName) { 1184 synchronized (mLock) { 1185 SupplicantStaNetworkHalHidlImpl networkHandle = 1186 checkSupplicantStaNetworkAndLogFailure(ifaceName, "disableCurrentNetwork"); 1187 if (networkHandle == null) return false; 1188 return networkHandle.disable(); 1189 } 1190 } 1191 1192 /** 1193 * Set the currently configured network's bssid. 1194 * 1195 * @param ifaceName Name of the interface. 1196 * @param bssidStr Bssid to set in the form of "XX:XX:XX:XX:XX:XX" 1197 * @return true if succeeds, false otherwise. 1198 */ setCurrentNetworkBssid(@onNull String ifaceName, String bssidStr)1199 public boolean setCurrentNetworkBssid(@NonNull String ifaceName, String bssidStr) { 1200 synchronized (mLock) { 1201 SupplicantStaNetworkHalHidlImpl networkHandle = 1202 checkSupplicantStaNetworkAndLogFailure(ifaceName, "setCurrentNetworkBssid"); 1203 if (networkHandle == null) return false; 1204 return networkHandle.setBssid(bssidStr); 1205 } 1206 } 1207 1208 /** 1209 * Get the currently configured network's WPS NFC token. 1210 * 1211 * @param ifaceName Name of the interface. 1212 * @return Hex string corresponding to the WPS NFC token. 1213 */ getCurrentNetworkWpsNfcConfigurationToken(@onNull String ifaceName)1214 public String getCurrentNetworkWpsNfcConfigurationToken(@NonNull String ifaceName) { 1215 synchronized (mLock) { 1216 SupplicantStaNetworkHalHidlImpl networkHandle = 1217 checkSupplicantStaNetworkAndLogFailure( 1218 ifaceName, "getCurrentNetworkWpsNfcConfigurationToken"); 1219 if (networkHandle == null) return null; 1220 return networkHandle.getWpsNfcConfigurationToken(); 1221 } 1222 } 1223 1224 /** 1225 * Get the eap anonymous identity for the currently configured network. 1226 * 1227 * @param ifaceName Name of the interface. 1228 * @return anonymous identity string if succeeds, null otherwise. 1229 */ getCurrentNetworkEapAnonymousIdentity(@onNull String ifaceName)1230 public String getCurrentNetworkEapAnonymousIdentity(@NonNull String ifaceName) { 1231 synchronized (mLock) { 1232 SupplicantStaNetworkHalHidlImpl networkHandle = 1233 checkSupplicantStaNetworkAndLogFailure( 1234 ifaceName, "getCurrentNetworkEapAnonymousIdentity"); 1235 if (networkHandle == null) return null; 1236 return networkHandle.fetchEapAnonymousIdentity(); 1237 } 1238 } 1239 1240 /** 1241 * Send the eap identity response for the currently configured network. 1242 * 1243 * @param ifaceName Name of the interface. 1244 * @param identity identity used for EAP-Identity 1245 * @param encryptedIdentity encrypted identity used for EAP-AKA/EAP-SIM 1246 * @return true if succeeds, false otherwise. 1247 */ sendCurrentNetworkEapIdentityResponse( @onNull String ifaceName, @NonNull String identity, String encryptedIdentity)1248 public boolean sendCurrentNetworkEapIdentityResponse( 1249 @NonNull String ifaceName, @NonNull String identity, String encryptedIdentity) { 1250 synchronized (mLock) { 1251 SupplicantStaNetworkHalHidlImpl networkHandle = 1252 checkSupplicantStaNetworkAndLogFailure( 1253 ifaceName, "sendCurrentNetworkEapIdentityResponse"); 1254 if (networkHandle == null) return false; 1255 return networkHandle.sendNetworkEapIdentityResponse(identity, encryptedIdentity); 1256 } 1257 } 1258 1259 /** 1260 * Send the eap sim gsm auth response for the currently configured network. 1261 * 1262 * @param ifaceName Name of the interface. 1263 * @param paramsStr String to send. 1264 * @return true if succeeds, false otherwise. 1265 */ sendCurrentNetworkEapSimGsmAuthResponse( @onNull String ifaceName, String paramsStr)1266 public boolean sendCurrentNetworkEapSimGsmAuthResponse( 1267 @NonNull String ifaceName, String paramsStr) { 1268 synchronized (mLock) { 1269 SupplicantStaNetworkHalHidlImpl networkHandle = 1270 checkSupplicantStaNetworkAndLogFailure( 1271 ifaceName, "sendCurrentNetworkEapSimGsmAuthResponse"); 1272 if (networkHandle == null) return false; 1273 return networkHandle.sendNetworkEapSimGsmAuthResponse(paramsStr); 1274 } 1275 } 1276 1277 /** 1278 * Send the eap sim gsm auth failure for the currently configured network. 1279 * 1280 * @param ifaceName Name of the interface. 1281 * @return true if succeeds, false otherwise. 1282 */ sendCurrentNetworkEapSimGsmAuthFailure(@onNull String ifaceName)1283 public boolean sendCurrentNetworkEapSimGsmAuthFailure(@NonNull String ifaceName) { 1284 synchronized (mLock) { 1285 SupplicantStaNetworkHalHidlImpl networkHandle = 1286 checkSupplicantStaNetworkAndLogFailure( 1287 ifaceName, "sendCurrentNetworkEapSimGsmAuthFailure"); 1288 if (networkHandle == null) return false; 1289 return networkHandle.sendNetworkEapSimGsmAuthFailure(); 1290 } 1291 } 1292 1293 /** 1294 * Send the eap sim umts auth response for the currently configured network. 1295 * 1296 * @param ifaceName Name of the interface. 1297 * @param paramsStr String to send. 1298 * @return true if succeeds, false otherwise. 1299 */ sendCurrentNetworkEapSimUmtsAuthResponse( @onNull String ifaceName, String paramsStr)1300 public boolean sendCurrentNetworkEapSimUmtsAuthResponse( 1301 @NonNull String ifaceName, String paramsStr) { 1302 synchronized (mLock) { 1303 SupplicantStaNetworkHalHidlImpl networkHandle = 1304 checkSupplicantStaNetworkAndLogFailure( 1305 ifaceName, "sendCurrentNetworkEapSimUmtsAuthResponse"); 1306 if (networkHandle == null) return false; 1307 return networkHandle.sendNetworkEapSimUmtsAuthResponse(paramsStr); 1308 } 1309 } 1310 1311 /** 1312 * Send the eap sim umts auts response for the currently configured network. 1313 * 1314 * @param ifaceName Name of the interface. 1315 * @param paramsStr String to send. 1316 * @return true if succeeds, false otherwise. 1317 */ sendCurrentNetworkEapSimUmtsAutsResponse( @onNull String ifaceName, String paramsStr)1318 public boolean sendCurrentNetworkEapSimUmtsAutsResponse( 1319 @NonNull String ifaceName, String paramsStr) { 1320 synchronized (mLock) { 1321 SupplicantStaNetworkHalHidlImpl networkHandle = 1322 checkSupplicantStaNetworkAndLogFailure( 1323 ifaceName, "sendCurrentNetworkEapSimUmtsAutsResponse"); 1324 if (networkHandle == null) return false; 1325 return networkHandle.sendNetworkEapSimUmtsAutsResponse(paramsStr); 1326 } 1327 } 1328 1329 /** 1330 * Send the eap sim umts auth failure for the currently configured network. 1331 * 1332 * @param ifaceName Name of the interface. 1333 * @return true if succeeds, false otherwise. 1334 */ sendCurrentNetworkEapSimUmtsAuthFailure(@onNull String ifaceName)1335 public boolean sendCurrentNetworkEapSimUmtsAuthFailure(@NonNull String ifaceName) { 1336 synchronized (mLock) { 1337 SupplicantStaNetworkHalHidlImpl networkHandle = 1338 checkSupplicantStaNetworkAndLogFailure( 1339 ifaceName, "sendCurrentNetworkEapSimUmtsAuthFailure"); 1340 if (networkHandle == null) return false; 1341 return networkHandle.sendNetworkEapSimUmtsAuthFailure(); 1342 } 1343 } 1344 1345 /** 1346 * Adds a new network. 1347 * 1348 * @return The ISupplicantNetwork object for the new network, or null if the call fails 1349 */ addNetwork(@onNull String ifaceName)1350 private SupplicantStaNetworkHalHidlImpl addNetwork(@NonNull String ifaceName) { 1351 synchronized (mLock) { 1352 final String methodStr = "addNetwork"; 1353 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1354 if (iface == null) return null; 1355 Mutable<ISupplicantNetwork> newNetwork = new Mutable<>(); 1356 try { 1357 iface.addNetwork((SupplicantStatus status, 1358 ISupplicantNetwork network) -> { 1359 if (checkStatusAndLogFailure(status, methodStr)) { 1360 newNetwork.value = network; 1361 } 1362 }); 1363 } catch (RemoteException e) { 1364 handleRemoteException(e, methodStr); 1365 } 1366 if (newNetwork.value != null) { 1367 return getStaNetworkMockable( 1368 ifaceName, 1369 ISupplicantStaNetwork.asInterface(newNetwork.value.asBinder())); 1370 } else { 1371 return null; 1372 } 1373 } 1374 } 1375 1376 /** 1377 * Remove network from supplicant with network Id 1378 * 1379 * @return true if request is sent successfully, false otherwise. 1380 */ removeNetwork(@onNull String ifaceName, int id)1381 private boolean removeNetwork(@NonNull String ifaceName, int id) { 1382 synchronized (mLock) { 1383 final String methodStr = "removeNetwork"; 1384 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1385 if (iface == null) return false; 1386 try { 1387 SupplicantStatus status = iface.removeNetwork(id); 1388 return checkStatusAndLogFailure(status, methodStr); 1389 } catch (RemoteException e) { 1390 handleRemoteException(e, methodStr); 1391 return false; 1392 } 1393 } 1394 } 1395 1396 /** 1397 * Use this to mock the creation of SupplicantStaNetworkHal instance. 1398 * 1399 * @param ifaceName Name of the interface. 1400 * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL. 1401 * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if 1402 * the call fails 1403 */ getStaNetworkMockable( @onNull String ifaceName, ISupplicantStaNetwork iSupplicantStaNetwork)1404 protected SupplicantStaNetworkHalHidlImpl getStaNetworkMockable( 1405 @NonNull String ifaceName, ISupplicantStaNetwork iSupplicantStaNetwork) { 1406 synchronized (mLock) { 1407 SupplicantStaNetworkHalHidlImpl network = 1408 new SupplicantStaNetworkHalHidlImpl(iSupplicantStaNetwork, ifaceName, mContext, 1409 mWifiMonitor, mWifiGlobals, getAdvancedCapabilities(ifaceName)); 1410 if (network != null) { 1411 network.enableVerboseLogging(mVerboseLoggingEnabled, mVerboseHalLoggingEnabled); 1412 } 1413 return network; 1414 } 1415 } 1416 1417 /** 1418 * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if 1419 * the call fails 1420 */ getNetwork(@onNull String ifaceName, int id)1421 private SupplicantStaNetworkHalHidlImpl getNetwork(@NonNull String ifaceName, int id) { 1422 synchronized (mLock) { 1423 final String methodStr = "getNetwork"; 1424 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1425 if (iface == null) return null; 1426 Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>(); 1427 try { 1428 iface.getNetwork(id, (SupplicantStatus status, ISupplicantNetwork network) -> { 1429 if (checkStatusAndLogFailure(status, methodStr)) { 1430 gotNetwork.value = network; 1431 } 1432 }); 1433 } catch (RemoteException e) { 1434 handleRemoteException(e, methodStr); 1435 } 1436 if (gotNetwork.value != null) { 1437 return getStaNetworkMockable( 1438 ifaceName, 1439 ISupplicantStaNetwork.asInterface(gotNetwork.value.asBinder())); 1440 } else { 1441 return null; 1442 } 1443 } 1444 } 1445 1446 /** See ISupplicantStaNetwork.hal for documentation */ registerCallback( ISupplicantStaIface iface, ISupplicantStaIfaceCallback callback)1447 private boolean registerCallback( 1448 ISupplicantStaIface iface, ISupplicantStaIfaceCallback callback) { 1449 synchronized (mLock) { 1450 final String methodStr = "registerCallback"; 1451 if (iface == null) return false; 1452 try { 1453 SupplicantStatus status = iface.registerCallback(callback); 1454 return checkStatusAndLogFailure(status, methodStr); 1455 } catch (RemoteException e) { 1456 handleRemoteException(e, methodStr); 1457 return false; 1458 } 1459 } 1460 } 1461 registerCallbackV1_1( android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface iface, android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback callback)1462 private boolean registerCallbackV1_1( 1463 android.hardware.wifi.supplicant.V1_1.ISupplicantStaIface iface, 1464 android.hardware.wifi.supplicant.V1_1.ISupplicantStaIfaceCallback callback) { 1465 synchronized (mLock) { 1466 String methodStr = "registerCallback_1_1"; 1467 1468 if (iface == null) return false; 1469 try { 1470 SupplicantStatus status = iface.registerCallback_1_1(callback); 1471 return checkStatusAndLogFailure(status, methodStr); 1472 } catch (RemoteException e) { 1473 handleRemoteException(e, methodStr); 1474 return false; 1475 } 1476 } 1477 } 1478 registerCallbackV1_2( android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface iface, android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback callback)1479 private boolean registerCallbackV1_2( 1480 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface iface, 1481 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback callback) { 1482 synchronized (mLock) { 1483 String methodStr = "registerCallback_1_2"; 1484 1485 if (iface == null) return false; 1486 try { 1487 SupplicantStatus status = iface.registerCallback_1_2(callback); 1488 return checkStatusAndLogFailure(status, methodStr); 1489 } catch (RemoteException e) { 1490 handleRemoteException(e, methodStr); 1491 return false; 1492 } 1493 } 1494 } 1495 registerCallbackV1_3( android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface iface, android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback callback)1496 private boolean registerCallbackV1_3( 1497 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface iface, 1498 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback callback) { 1499 synchronized (mLock) { 1500 String methodStr = "registerCallback_1_3"; 1501 1502 if (iface == null) return false; 1503 try { 1504 SupplicantStatus status = iface.registerCallback_1_3(callback); 1505 return checkStatusAndLogFailure(status, methodStr); 1506 } catch (RemoteException e) { 1507 handleRemoteException(e, methodStr); 1508 return false; 1509 } 1510 } 1511 } 1512 registerCallbackV1_4( android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface iface, android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback callback)1513 private boolean registerCallbackV1_4( 1514 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface iface, 1515 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIfaceCallback callback) { 1516 synchronized (mLock) { 1517 String methodStr = "registerCallback_1_4"; 1518 1519 if (iface == null) return false; 1520 try { 1521 android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = 1522 iface.registerCallback_1_4(callback); 1523 return checkStatusAndLogFailure(status, methodStr); 1524 } catch (RemoteException e) { 1525 handleRemoteException(e, methodStr); 1526 return false; 1527 } 1528 } 1529 } 1530 1531 /** 1532 * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns 1533 * null if the call fails 1534 */ listNetworks(@onNull String ifaceName)1535 private java.util.ArrayList<Integer> listNetworks(@NonNull String ifaceName) { 1536 synchronized (mLock) { 1537 final String methodStr = "listNetworks"; 1538 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1539 if (iface == null) return null; 1540 Mutable<ArrayList<Integer>> networkIdList = new Mutable<>(); 1541 try { 1542 iface.listNetworks((SupplicantStatus status, ArrayList<Integer> networkIds) -> { 1543 if (checkStatusAndLogFailure(status, methodStr)) { 1544 networkIdList.value = networkIds; 1545 } 1546 }); 1547 } catch (RemoteException e) { 1548 handleRemoteException(e, methodStr); 1549 } 1550 return networkIdList.value; 1551 } 1552 } 1553 1554 /** 1555 * Set WPS device name. 1556 * 1557 * @param ifaceName Name of the interface. 1558 * @param name String to be set. 1559 * @return true if request is sent successfully, false otherwise. 1560 */ setWpsDeviceName(@onNull String ifaceName, String name)1561 public boolean setWpsDeviceName(@NonNull String ifaceName, String name) { 1562 synchronized (mLock) { 1563 final String methodStr = "setWpsDeviceName"; 1564 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1565 if (iface == null) return false; 1566 try { 1567 SupplicantStatus status = iface.setWpsDeviceName(name); 1568 return checkStatusAndLogFailure(status, methodStr); 1569 } catch (RemoteException e) { 1570 handleRemoteException(e, methodStr); 1571 return false; 1572 } 1573 } 1574 } 1575 1576 /** 1577 * Set WPS device type. 1578 * 1579 * @param ifaceName Name of the interface. 1580 * @param typeStr Type specified as a string. Used format: <categ>-<OUI>-<subcateg> 1581 * @return true if request is sent successfully, false otherwise. 1582 */ setWpsDeviceType(@onNull String ifaceName, String typeStr)1583 public boolean setWpsDeviceType(@NonNull String ifaceName, String typeStr) { 1584 synchronized (mLock) { 1585 try { 1586 Matcher match = WPS_DEVICE_TYPE_PATTERN.matcher(typeStr); 1587 if (!match.find() || match.groupCount() != 3) { 1588 Log.e(TAG, "Malformed WPS device type " + typeStr); 1589 return false; 1590 } 1591 short categ = Short.parseShort(match.group(1)); 1592 byte[] oui = NativeUtil.hexStringToByteArray(match.group(2)); 1593 short subCateg = Short.parseShort(match.group(3)); 1594 1595 byte[] bytes = new byte[8]; 1596 ByteBuffer byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.BIG_ENDIAN); 1597 byteBuffer.putShort(categ); 1598 byteBuffer.put(oui); 1599 byteBuffer.putShort(subCateg); 1600 return setWpsDeviceType(ifaceName, bytes); 1601 } catch (IllegalArgumentException e) { 1602 Log.e(TAG, "Illegal argument " + typeStr, e); 1603 return false; 1604 } 1605 } 1606 } 1607 setWpsDeviceType(@onNull String ifaceName, byte[ ] type)1608 private boolean setWpsDeviceType(@NonNull String ifaceName, byte[/* 8 */] type) { 1609 synchronized (mLock) { 1610 final String methodStr = "setWpsDeviceType"; 1611 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1612 if (iface == null) return false; 1613 try { 1614 SupplicantStatus status = iface.setWpsDeviceType(type); 1615 return checkStatusAndLogFailure(status, methodStr); 1616 } catch (RemoteException e) { 1617 handleRemoteException(e, methodStr); 1618 return false; 1619 } 1620 } 1621 } 1622 1623 /** 1624 * Set WPS manufacturer. 1625 * 1626 * @param ifaceName Name of the interface. 1627 * @param manufacturer String to be set. 1628 * @return true if request is sent successfully, false otherwise. 1629 */ setWpsManufacturer(@onNull String ifaceName, String manufacturer)1630 public boolean setWpsManufacturer(@NonNull String ifaceName, String manufacturer) { 1631 synchronized (mLock) { 1632 final String methodStr = "setWpsManufacturer"; 1633 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1634 if (iface == null) return false; 1635 try { 1636 SupplicantStatus status = iface.setWpsManufacturer(manufacturer); 1637 return checkStatusAndLogFailure(status, methodStr); 1638 } catch (RemoteException e) { 1639 handleRemoteException(e, methodStr); 1640 return false; 1641 } 1642 } 1643 } 1644 1645 /** 1646 * Set WPS model name. 1647 * 1648 * @param ifaceName Name of the interface. 1649 * @param modelName String to be set. 1650 * @return true if request is sent successfully, false otherwise. 1651 */ setWpsModelName(@onNull String ifaceName, String modelName)1652 public boolean setWpsModelName(@NonNull String ifaceName, String modelName) { 1653 synchronized (mLock) { 1654 final String methodStr = "setWpsModelName"; 1655 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1656 if (iface == null) return false; 1657 try { 1658 SupplicantStatus status = iface.setWpsModelName(modelName); 1659 return checkStatusAndLogFailure(status, methodStr); 1660 } catch (RemoteException e) { 1661 handleRemoteException(e, methodStr); 1662 return false; 1663 } 1664 } 1665 } 1666 1667 /** 1668 * Set WPS model number. 1669 * 1670 * @param ifaceName Name of the interface. 1671 * @param modelNumber String to be set. 1672 * @return true if request is sent successfully, false otherwise. 1673 */ setWpsModelNumber(@onNull String ifaceName, String modelNumber)1674 public boolean setWpsModelNumber(@NonNull String ifaceName, String modelNumber) { 1675 synchronized (mLock) { 1676 final String methodStr = "setWpsModelNumber"; 1677 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1678 if (iface == null) return false; 1679 try { 1680 SupplicantStatus status = iface.setWpsModelNumber(modelNumber); 1681 return checkStatusAndLogFailure(status, methodStr); 1682 } catch (RemoteException e) { 1683 handleRemoteException(e, methodStr); 1684 return false; 1685 } 1686 } 1687 } 1688 1689 /** 1690 * Set WPS serial number. 1691 * 1692 * @param ifaceName Name of the interface. 1693 * @param serialNumber String to be set. 1694 * @return true if request is sent successfully, false otherwise. 1695 */ setWpsSerialNumber(@onNull String ifaceName, String serialNumber)1696 public boolean setWpsSerialNumber(@NonNull String ifaceName, String serialNumber) { 1697 synchronized (mLock) { 1698 final String methodStr = "setWpsSerialNumber"; 1699 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1700 if (iface == null) return false; 1701 try { 1702 SupplicantStatus status = iface.setWpsSerialNumber(serialNumber); 1703 return checkStatusAndLogFailure(status, methodStr); 1704 } catch (RemoteException e) { 1705 handleRemoteException(e, methodStr); 1706 return false; 1707 } 1708 } 1709 } 1710 1711 /** 1712 * Set WPS config methods 1713 * 1714 * @param ifaceName Name of the interface. 1715 * @param configMethodsStr List of config methods. 1716 * @return true if request is sent successfully, false otherwise. 1717 */ setWpsConfigMethods(@onNull String ifaceName, String configMethodsStr)1718 public boolean setWpsConfigMethods(@NonNull String ifaceName, String configMethodsStr) { 1719 synchronized (mLock) { 1720 short configMethodsMask = 0; 1721 String[] configMethodsStrArr = configMethodsStr.split("\\s+"); 1722 for (int i = 0; i < configMethodsStrArr.length; i++) { 1723 configMethodsMask |= stringToWpsConfigMethod(configMethodsStrArr[i]); 1724 } 1725 return setWpsConfigMethods(ifaceName, configMethodsMask); 1726 } 1727 } 1728 setWpsConfigMethods(@onNull String ifaceName, short configMethods)1729 private boolean setWpsConfigMethods(@NonNull String ifaceName, short configMethods) { 1730 synchronized (mLock) { 1731 final String methodStr = "setWpsConfigMethods"; 1732 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1733 if (iface == null) return false; 1734 try { 1735 SupplicantStatus status = iface.setWpsConfigMethods(configMethods); 1736 return checkStatusAndLogFailure(status, methodStr); 1737 } catch (RemoteException e) { 1738 handleRemoteException(e, methodStr); 1739 return false; 1740 } 1741 } 1742 } 1743 1744 /** 1745 * Trigger a reassociation even if the iface is currently connected. 1746 * 1747 * @param ifaceName Name of the interface. 1748 * @return true if request is sent successfully, false otherwise. 1749 */ reassociate(@onNull String ifaceName)1750 public boolean reassociate(@NonNull String ifaceName) { 1751 synchronized (mLock) { 1752 final String methodStr = "reassociate"; 1753 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1754 if (iface == null) return false; 1755 try { 1756 SupplicantStatus status = iface.reassociate(); 1757 return checkStatusAndLogFailure(status, methodStr); 1758 } catch (RemoteException e) { 1759 handleRemoteException(e, methodStr); 1760 return false; 1761 } 1762 } 1763 } 1764 1765 /** 1766 * Trigger a reconnection if the iface is disconnected. 1767 * 1768 * @param ifaceName Name of the interface. 1769 * @return true if request is sent successfully, false otherwise. 1770 */ reconnect(@onNull String ifaceName)1771 public boolean reconnect(@NonNull String ifaceName) { 1772 synchronized (mLock) { 1773 final String methodStr = "reconnect"; 1774 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1775 if (iface == null) return false; 1776 try { 1777 SupplicantStatus status = iface.reconnect(); 1778 return checkStatusAndLogFailure(status, methodStr); 1779 } catch (RemoteException e) { 1780 handleRemoteException(e, methodStr); 1781 return false; 1782 } 1783 } 1784 } 1785 1786 /** 1787 * Trigger a disconnection from the currently connected network. 1788 * 1789 * @param ifaceName Name of the interface. 1790 * @return true if request is sent successfully, false otherwise. 1791 */ disconnect(@onNull String ifaceName)1792 public boolean disconnect(@NonNull String ifaceName) { 1793 synchronized (mLock) { 1794 final String methodStr = "disconnect"; 1795 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1796 if (iface == null) return false; 1797 try { 1798 SupplicantStatus status = iface.disconnect(); 1799 return checkStatusAndLogFailure(status, methodStr); 1800 } catch (RemoteException e) { 1801 handleRemoteException(e, methodStr); 1802 return false; 1803 } 1804 } 1805 } 1806 1807 /** 1808 * Enable or disable power save mode. 1809 * 1810 * @param ifaceName Name of the interface. 1811 * @param enable true to enable, false to disable. 1812 * @return true if request is sent successfully, false otherwise. 1813 */ setPowerSave(@onNull String ifaceName, boolean enable)1814 public boolean setPowerSave(@NonNull String ifaceName, boolean enable) { 1815 synchronized (mLock) { 1816 final String methodStr = "setPowerSave"; 1817 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1818 if (iface == null) return false; 1819 try { 1820 SupplicantStatus status = iface.setPowerSave(enable); 1821 return checkStatusAndLogFailure(status, methodStr); 1822 } catch (RemoteException e) { 1823 handleRemoteException(e, methodStr); 1824 return false; 1825 } 1826 } 1827 } 1828 1829 /** 1830 * Initiate TDLS discover with the specified AP. 1831 * 1832 * @param ifaceName Name of the interface. 1833 * @param macAddress MAC Address of the AP. 1834 * @return true if request is sent successfully, false otherwise. 1835 */ initiateTdlsDiscover(@onNull String ifaceName, String macAddress)1836 public boolean initiateTdlsDiscover(@NonNull String ifaceName, String macAddress) { 1837 synchronized (mLock) { 1838 try { 1839 return initiateTdlsDiscover( 1840 ifaceName, NativeUtil.macAddressToByteArray(macAddress)); 1841 } catch (IllegalArgumentException e) { 1842 Log.e(TAG, "Illegal argument " + macAddress, e); 1843 return false; 1844 } 1845 } 1846 } 1847 /** See ISupplicantStaIface.hal for documentation */ initiateTdlsDiscover(@onNull String ifaceName, byte[ ] macAddress)1848 private boolean initiateTdlsDiscover(@NonNull String ifaceName, byte[/* 6 */] macAddress) { 1849 synchronized (mLock) { 1850 final String methodStr = "initiateTdlsDiscover"; 1851 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1852 if (iface == null) return false; 1853 try { 1854 SupplicantStatus status = iface.initiateTdlsDiscover(macAddress); 1855 return checkStatusAndLogFailure(status, methodStr); 1856 } catch (RemoteException e) { 1857 handleRemoteException(e, methodStr); 1858 return false; 1859 } 1860 } 1861 } 1862 1863 /** 1864 * Initiate TDLS setup with the specified AP. 1865 * 1866 * @param ifaceName Name of the interface. 1867 * @param macAddress MAC Address of the AP. 1868 * @return true if request is sent successfully, false otherwise. 1869 */ initiateTdlsSetup(@onNull String ifaceName, String macAddress)1870 public boolean initiateTdlsSetup(@NonNull String ifaceName, String macAddress) { 1871 synchronized (mLock) { 1872 try { 1873 return initiateTdlsSetup(ifaceName, NativeUtil.macAddressToByteArray(macAddress)); 1874 } catch (IllegalArgumentException e) { 1875 Log.e(TAG, "Illegal argument " + macAddress, e); 1876 return false; 1877 } 1878 } 1879 } 1880 /** See ISupplicantStaIface.hal for documentation */ initiateTdlsSetup(@onNull String ifaceName, byte[ ] macAddress)1881 private boolean initiateTdlsSetup(@NonNull String ifaceName, byte[/* 6 */] macAddress) { 1882 synchronized (mLock) { 1883 final String methodStr = "initiateTdlsSetup"; 1884 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1885 if (iface == null) return false; 1886 try { 1887 SupplicantStatus status = iface.initiateTdlsSetup(macAddress); 1888 return checkStatusAndLogFailure(status, methodStr); 1889 } catch (RemoteException e) { 1890 handleRemoteException(e, methodStr); 1891 return false; 1892 } 1893 } 1894 } 1895 1896 /** 1897 * Initiate TDLS teardown with the specified AP. 1898 * @param ifaceName Name of the interface. 1899 * @param macAddress MAC Address of the AP. 1900 * @return true if request is sent successfully, false otherwise. 1901 */ initiateTdlsTeardown(@onNull String ifaceName, String macAddress)1902 public boolean initiateTdlsTeardown(@NonNull String ifaceName, String macAddress) { 1903 synchronized (mLock) { 1904 try { 1905 return initiateTdlsTeardown( 1906 ifaceName, NativeUtil.macAddressToByteArray(macAddress)); 1907 } catch (IllegalArgumentException e) { 1908 Log.e(TAG, "Illegal argument " + macAddress, e); 1909 return false; 1910 } 1911 } 1912 } 1913 1914 /** See ISupplicantStaIface.hal for documentation */ initiateTdlsTeardown(@onNull String ifaceName, byte[ ] macAddress)1915 private boolean initiateTdlsTeardown(@NonNull String ifaceName, byte[/* 6 */] macAddress) { 1916 synchronized (mLock) { 1917 final String methodStr = "initiateTdlsTeardown"; 1918 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1919 if (iface == null) return false; 1920 try { 1921 SupplicantStatus status = iface.initiateTdlsTeardown(macAddress); 1922 return checkStatusAndLogFailure(status, methodStr); 1923 } catch (RemoteException e) { 1924 handleRemoteException(e, methodStr); 1925 return false; 1926 } 1927 } 1928 } 1929 1930 /** 1931 * Request the specified ANQP elements |elements| from the specified AP |bssid|. 1932 * 1933 * @param ifaceName Name of the interface. 1934 * @param bssid BSSID of the AP 1935 * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId. 1936 * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes. 1937 * @return true if request is sent successfully, false otherwise. 1938 */ initiateAnqpQuery(@onNull String ifaceName, String bssid, ArrayList<Short> infoElements, ArrayList<Integer> hs20SubTypes)1939 public boolean initiateAnqpQuery(@NonNull String ifaceName, String bssid, 1940 ArrayList<Short> infoElements, 1941 ArrayList<Integer> hs20SubTypes) { 1942 synchronized (mLock) { 1943 try { 1944 return initiateAnqpQuery( 1945 ifaceName, 1946 NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes); 1947 } catch (IllegalArgumentException e) { 1948 Log.e(TAG, "Illegal argument " + bssid, e); 1949 return false; 1950 } 1951 } 1952 } 1953 1954 /** See ISupplicantStaIface.hal for documentation */ initiateAnqpQuery(@onNull String ifaceName, byte[ ] macAddress, java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes)1955 private boolean initiateAnqpQuery(@NonNull String ifaceName, byte[/* 6 */] macAddress, 1956 java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) { 1957 synchronized (mLock) { 1958 final String methodStr = "initiateAnqpQuery"; 1959 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 1960 if (iface == null) return false; 1961 try { 1962 SupplicantStatus status = iface.initiateAnqpQuery( 1963 macAddress, infoElements, subTypes); 1964 return checkStatusAndLogFailure(status, methodStr); 1965 } catch (RemoteException e) { 1966 handleRemoteException(e, methodStr); 1967 return false; 1968 } 1969 } 1970 } 1971 1972 /** 1973 * Request Venue URL ANQP element from the specified AP |bssid|. 1974 * 1975 * @param ifaceName Name of the interface. 1976 * @param bssid BSSID of the AP 1977 * @return true if request is sent successfully, false otherwise. 1978 */ initiateVenueUrlAnqpQuery(@onNull String ifaceName, String bssid)1979 public boolean initiateVenueUrlAnqpQuery(@NonNull String ifaceName, String bssid) { 1980 synchronized (mLock) { 1981 try { 1982 return initiateVenueUrlAnqpQuery( 1983 ifaceName, NativeUtil.macAddressToByteArray(bssid)); 1984 } catch (IllegalArgumentException e) { 1985 Log.e(TAG, "Illegal argument " + bssid, e); 1986 return false; 1987 } 1988 } 1989 } 1990 1991 /** See ISupplicantStaIface.hal for documentation */ initiateVenueUrlAnqpQuery(@onNull String ifaceName, byte[ ] macAddress)1992 private boolean initiateVenueUrlAnqpQuery(@NonNull String ifaceName, byte[/* 6 */] macAddress) { 1993 synchronized (mLock) { 1994 final String methodStr = "initiateVenueUrlAnqpQuery"; 1995 if (!isV1_4()) { 1996 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 1997 return false; 1998 } 1999 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2000 // Get a v1.4 supplicant STA Interface 2001 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 2002 getStaIfaceMockableV1_4(iface); 2003 2004 if (staIfaceV14 == null) { 2005 Log.e(TAG, methodStr 2006 + ": SupplicantStaIface is null, cannot initiate Venue URL ANQP request"); 2007 return false; 2008 } 2009 try { 2010 android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = 2011 staIfaceV14.initiateVenueUrlAnqpQuery(macAddress); 2012 return checkStatusAndLogFailure(status, methodStr); 2013 } catch (RemoteException e) { 2014 handleRemoteException(e, methodStr); 2015 return false; 2016 } 2017 } 2018 } 2019 2020 /** 2021 * Request the specified ANQP ICON from the specified AP |bssid|. 2022 * 2023 * @param ifaceName Name of the interface. 2024 * @param bssid BSSID of the AP 2025 * @param fileName Name of the file to request. 2026 * @return true if request is sent successfully, false otherwise. 2027 */ initiateHs20IconQuery(@onNull String ifaceName, String bssid, String fileName)2028 public boolean initiateHs20IconQuery(@NonNull String ifaceName, String bssid, String fileName) { 2029 synchronized (mLock) { 2030 try { 2031 return initiateHs20IconQuery( 2032 ifaceName, NativeUtil.macAddressToByteArray(bssid), fileName); 2033 } catch (IllegalArgumentException e) { 2034 Log.e(TAG, "Illegal argument " + bssid, e); 2035 return false; 2036 } 2037 } 2038 } 2039 2040 /** See ISupplicantStaIface.hal for documentation */ initiateHs20IconQuery(@onNull String ifaceName, byte[ ] macAddress, String fileName)2041 private boolean initiateHs20IconQuery(@NonNull String ifaceName, 2042 byte[/* 6 */] macAddress, String fileName) { 2043 synchronized (mLock) { 2044 final String methodStr = "initiateHs20IconQuery"; 2045 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2046 if (iface == null) return false; 2047 try { 2048 SupplicantStatus status = iface.initiateHs20IconQuery(macAddress, fileName); 2049 return checkStatusAndLogFailure(status, methodStr); 2050 } catch (RemoteException e) { 2051 handleRemoteException(e, methodStr); 2052 return false; 2053 } 2054 } 2055 } 2056 2057 /** 2058 * Makes a callback to HIDL to getMacAddress from supplicant 2059 * 2060 * @param ifaceName Name of the interface. 2061 * @return string containing the MAC address, or null on a failed call 2062 */ getMacAddress(@onNull String ifaceName)2063 public String getMacAddress(@NonNull String ifaceName) { 2064 synchronized (mLock) { 2065 final String methodStr = "getMacAddress"; 2066 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2067 if (iface == null) return null; 2068 Mutable<String> gotMac = new Mutable<>(); 2069 try { 2070 iface.getMacAddress((SupplicantStatus status, 2071 byte[/* 6 */] macAddr) -> { 2072 if (checkStatusAndLogFailure(status, methodStr)) { 2073 gotMac.value = NativeUtil.macAddressFromByteArray(macAddr); 2074 } 2075 }); 2076 } catch (RemoteException e) { 2077 handleRemoteException(e, methodStr); 2078 } 2079 return gotMac.value; 2080 } 2081 } 2082 2083 /** 2084 * Start using the added RX filters. 2085 * 2086 * @param ifaceName Name of the interface. 2087 * @return true if request is sent successfully, false otherwise. 2088 */ startRxFilter(@onNull String ifaceName)2089 public boolean startRxFilter(@NonNull String ifaceName) { 2090 synchronized (mLock) { 2091 final String methodStr = "startRxFilter"; 2092 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2093 if (iface == null) return false; 2094 try { 2095 SupplicantStatus status = iface.startRxFilter(); 2096 return checkStatusAndLogFailure(status, methodStr); 2097 } catch (RemoteException e) { 2098 handleRemoteException(e, methodStr); 2099 return false; 2100 } 2101 } 2102 } 2103 2104 /** 2105 * Stop using the added RX filters. 2106 * 2107 * @param ifaceName Name of the interface. 2108 * @return true if request is sent successfully, false otherwise. 2109 */ stopRxFilter(@onNull String ifaceName)2110 public boolean stopRxFilter(@NonNull String ifaceName) { 2111 synchronized (mLock) { 2112 final String methodStr = "stopRxFilter"; 2113 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2114 if (iface == null) return false; 2115 try { 2116 SupplicantStatus status = iface.stopRxFilter(); 2117 return checkStatusAndLogFailure(status, methodStr); 2118 } catch (RemoteException e) { 2119 handleRemoteException(e, methodStr); 2120 return false; 2121 } 2122 } 2123 } 2124 2125 /** 2126 * Add an RX filter. 2127 * 2128 * @param ifaceName Name of the interface. 2129 * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST} 2130 * {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values. 2131 * @return true if request is sent successfully, false otherwise. 2132 */ addRxFilter(@onNull String ifaceName, int type)2133 public boolean addRxFilter(@NonNull String ifaceName, int type) { 2134 synchronized (mLock) { 2135 byte halType; 2136 switch (type) { 2137 case WifiNative.RX_FILTER_TYPE_V4_MULTICAST: 2138 halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST; 2139 break; 2140 case WifiNative.RX_FILTER_TYPE_V6_MULTICAST: 2141 halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST; 2142 break; 2143 default: 2144 Log.e(TAG, "Invalid Rx Filter type: " + type); 2145 return false; 2146 } 2147 return addRxFilter(ifaceName, halType); 2148 } 2149 } 2150 addRxFilter(@onNull String ifaceName, byte type)2151 private boolean addRxFilter(@NonNull String ifaceName, byte type) { 2152 synchronized (mLock) { 2153 final String methodStr = "addRxFilter"; 2154 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2155 if (iface == null) return false; 2156 try { 2157 SupplicantStatus status = iface.addRxFilter(type); 2158 return checkStatusAndLogFailure(status, methodStr); 2159 } catch (RemoteException e) { 2160 handleRemoteException(e, methodStr); 2161 return false; 2162 } 2163 } 2164 } 2165 2166 /** 2167 * Remove an RX filter. 2168 * 2169 * @param ifaceName Name of the interface. 2170 * @param type one of {@link WifiNative#RX_FILTER_TYPE_V4_MULTICAST} 2171 * {@link WifiNative#RX_FILTER_TYPE_V6_MULTICAST} values. 2172 * @return true if request is sent successfully, false otherwise. 2173 */ removeRxFilter(@onNull String ifaceName, int type)2174 public boolean removeRxFilter(@NonNull String ifaceName, int type) { 2175 synchronized (mLock) { 2176 byte halType; 2177 switch (type) { 2178 case WifiNative.RX_FILTER_TYPE_V4_MULTICAST: 2179 halType = ISupplicantStaIface.RxFilterType.V4_MULTICAST; 2180 break; 2181 case WifiNative.RX_FILTER_TYPE_V6_MULTICAST: 2182 halType = ISupplicantStaIface.RxFilterType.V6_MULTICAST; 2183 break; 2184 default: 2185 Log.e(TAG, "Invalid Rx Filter type: " + type); 2186 return false; 2187 } 2188 return removeRxFilter(ifaceName, halType); 2189 } 2190 } 2191 removeRxFilter(@onNull String ifaceName, byte type)2192 private boolean removeRxFilter(@NonNull String ifaceName, byte type) { 2193 synchronized (mLock) { 2194 final String methodStr = "removeRxFilter"; 2195 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2196 if (iface == null) return false; 2197 try { 2198 SupplicantStatus status = iface.removeRxFilter(type); 2199 return checkStatusAndLogFailure(status, methodStr); 2200 } catch (RemoteException e) { 2201 handleRemoteException(e, methodStr); 2202 return false; 2203 } 2204 } 2205 } 2206 2207 /** 2208 * Set Bt co existense mode. 2209 * 2210 * @param ifaceName Name of the interface. 2211 * @param mode one of the above {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_DISABLED}, 2212 * {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_ENABLED} or 2213 * {@link WifiNative#BLUETOOTH_COEXISTENCE_MODE_SENSE}. 2214 * @return true if request is sent successfully, false otherwise. 2215 */ setBtCoexistenceMode(@onNull String ifaceName, int mode)2216 public boolean setBtCoexistenceMode(@NonNull String ifaceName, int mode) { 2217 synchronized (mLock) { 2218 byte halMode; 2219 switch (mode) { 2220 case WifiNative.BLUETOOTH_COEXISTENCE_MODE_ENABLED: 2221 halMode = ISupplicantStaIface.BtCoexistenceMode.ENABLED; 2222 break; 2223 case WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED: 2224 halMode = ISupplicantStaIface.BtCoexistenceMode.DISABLED; 2225 break; 2226 case WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE: 2227 halMode = ISupplicantStaIface.BtCoexistenceMode.SENSE; 2228 break; 2229 default: 2230 Log.e(TAG, "Invalid Bt Coex mode: " + mode); 2231 return false; 2232 } 2233 return setBtCoexistenceMode(ifaceName, halMode); 2234 } 2235 } 2236 setBtCoexistenceMode(@onNull String ifaceName, byte mode)2237 private boolean setBtCoexistenceMode(@NonNull String ifaceName, byte mode) { 2238 synchronized (mLock) { 2239 final String methodStr = "setBtCoexistenceMode"; 2240 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2241 if (iface == null) return false; 2242 try { 2243 SupplicantStatus status = iface.setBtCoexistenceMode(mode); 2244 return checkStatusAndLogFailure(status, methodStr); 2245 } catch (RemoteException e) { 2246 handleRemoteException(e, methodStr); 2247 return false; 2248 } 2249 } 2250 } 2251 2252 /** Enable or disable BT coexistence mode. 2253 * 2254 * @param ifaceName Name of the interface. 2255 * @param enable true to enable, false to disable. 2256 * @return true if request is sent successfully, false otherwise. 2257 */ setBtCoexistenceScanModeEnabled(@onNull String ifaceName, boolean enable)2258 public boolean setBtCoexistenceScanModeEnabled(@NonNull String ifaceName, boolean enable) { 2259 synchronized (mLock) { 2260 final String methodStr = "setBtCoexistenceScanModeEnabled"; 2261 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2262 if (iface == null) return false; 2263 try { 2264 SupplicantStatus status = 2265 iface.setBtCoexistenceScanModeEnabled(enable); 2266 return checkStatusAndLogFailure(status, methodStr); 2267 } catch (RemoteException e) { 2268 handleRemoteException(e, methodStr); 2269 return false; 2270 } 2271 } 2272 } 2273 2274 /** 2275 * Enable or disable suspend mode optimizations. 2276 * 2277 * @param ifaceName Name of the interface. 2278 * @param enable true to enable, false otherwise. 2279 * @return true if request is sent successfully, false otherwise. 2280 */ setSuspendModeEnabled(@onNull String ifaceName, boolean enable)2281 public boolean setSuspendModeEnabled(@NonNull String ifaceName, boolean enable) { 2282 synchronized (mLock) { 2283 final String methodStr = "setSuspendModeEnabled"; 2284 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2285 if (iface == null) return false; 2286 try { 2287 SupplicantStatus status = iface.setSuspendModeEnabled(enable); 2288 return checkStatusAndLogFailure(status, methodStr); 2289 } catch (RemoteException e) { 2290 handleRemoteException(e, methodStr); 2291 return false; 2292 } 2293 } 2294 } 2295 2296 /** 2297 * Set country code. 2298 * 2299 * @param ifaceName Name of the interface. 2300 * @param codeStr 2 byte ASCII string. For ex: US, CA. 2301 * @return true if request is sent successfully, false otherwise. 2302 */ setCountryCode(@onNull String ifaceName, String codeStr)2303 public boolean setCountryCode(@NonNull String ifaceName, String codeStr) { 2304 synchronized (mLock) { 2305 if (TextUtils.isEmpty(codeStr)) return false; 2306 byte[] countryCodeBytes = NativeUtil.stringToByteArray(codeStr); 2307 if (countryCodeBytes.length != 2) return false; 2308 return setCountryCode(ifaceName, countryCodeBytes); 2309 } 2310 } 2311 2312 /** See ISupplicantStaIface.hal for documentation */ setCountryCode(@onNull String ifaceName, byte[ ] code)2313 private boolean setCountryCode(@NonNull String ifaceName, byte[/* 2 */] code) { 2314 synchronized (mLock) { 2315 final String methodStr = "setCountryCode"; 2316 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2317 if (iface == null) return false; 2318 try { 2319 SupplicantStatus status = iface.setCountryCode(code); 2320 return checkStatusAndLogFailure(status, methodStr); 2321 } catch (RemoteException e) { 2322 handleRemoteException(e, methodStr); 2323 return false; 2324 } 2325 } 2326 } 2327 2328 /** 2329 * Flush all previously configured HLPs. 2330 * 2331 * @param ifaceName Name of the interface. 2332 * @return true if request is sent successfully, false otherwise. 2333 */ flushAllHlp(@onNull String ifaceName)2334 public boolean flushAllHlp(@NonNull String ifaceName) { 2335 synchronized (mLock) { 2336 final String methodStr = "filsHlpFlushRequest"; 2337 if (isV1_3()) { 2338 ISupplicantStaIface iface = 2339 checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2340 if (iface == null) { 2341 return false; 2342 } 2343 2344 // Get a v1.3 supplicant STA Interface 2345 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 2346 getStaIfaceMockableV1_3(iface); 2347 2348 if (staIfaceV13 == null) { 2349 Log.e(TAG, methodStr 2350 + ": ISupplicantStaIface is null, cannot flushAllHlp"); 2351 return false; 2352 } 2353 try { 2354 SupplicantStatus status = staIfaceV13.filsHlpFlushRequest(); 2355 return checkStatusAndLogFailure(status, methodStr); 2356 } catch (RemoteException e) { 2357 handleRemoteException(e, methodStr); 2358 return false; 2359 } 2360 } else { 2361 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 2362 return false; 2363 } 2364 } 2365 } 2366 2367 /** 2368 * Set FILS HLP packet. 2369 * 2370 * @param ifaceName Name of the interface. 2371 * @param dst Destination MAC address. 2372 * @param hlpPacket Hlp Packet data in hex. 2373 * @return true if request is sent successfully, false otherwise. 2374 */ addHlpReq(@onNull String ifaceName, byte [] dst, byte [] hlpPacket)2375 public boolean addHlpReq(@NonNull String ifaceName, byte [] dst, byte [] hlpPacket) { 2376 synchronized (mLock) { 2377 final String methodStr = "filsHlpAddRequest"; 2378 if (isV1_3()) { 2379 ISupplicantStaIface iface = 2380 checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2381 if (iface == null) { 2382 return false; 2383 } 2384 2385 // Get a v1.3 supplicant STA Interface 2386 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 2387 getStaIfaceMockableV1_3(iface); 2388 2389 if (staIfaceV13 == null) { 2390 Log.e(TAG, methodStr 2391 + ": ISupplicantStaIface is null, cannot addHlpReq"); 2392 return false; 2393 } 2394 try { 2395 ArrayList<Byte> payload = NativeUtil.byteArrayToArrayList(hlpPacket); 2396 SupplicantStatus status = staIfaceV13.filsHlpAddRequest(dst, payload); 2397 return checkStatusAndLogFailure(status, methodStr); 2398 } catch (RemoteException e) { 2399 handleRemoteException(e, methodStr); 2400 return false; 2401 } 2402 } else { 2403 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 2404 return false; 2405 } 2406 } 2407 } 2408 2409 2410 /** 2411 * Start WPS pin registrar operation with the specified peer and pin. 2412 * 2413 * @param ifaceName Name of the interface. 2414 * @param bssidStr BSSID of the peer. 2415 * @param pin Pin to be used. 2416 * @return true if request is sent successfully, false otherwise. 2417 */ startWpsRegistrar(@onNull String ifaceName, String bssidStr, String pin)2418 public boolean startWpsRegistrar(@NonNull String ifaceName, String bssidStr, String pin) { 2419 synchronized (mLock) { 2420 if (TextUtils.isEmpty(bssidStr) || TextUtils.isEmpty(pin)) return false; 2421 try { 2422 return startWpsRegistrar( 2423 ifaceName, NativeUtil.macAddressToByteArray(bssidStr), pin); 2424 } catch (IllegalArgumentException e) { 2425 Log.e(TAG, "Illegal argument " + bssidStr, e); 2426 return false; 2427 } 2428 } 2429 } 2430 2431 /** See ISupplicantStaIface.hal for documentation */ startWpsRegistrar(@onNull String ifaceName, byte[ ] bssid, String pin)2432 private boolean startWpsRegistrar(@NonNull String ifaceName, byte[/* 6 */] bssid, String pin) { 2433 synchronized (mLock) { 2434 final String methodStr = "startWpsRegistrar"; 2435 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2436 if (iface == null) return false; 2437 try { 2438 SupplicantStatus status = iface.startWpsRegistrar(bssid, pin); 2439 return checkStatusAndLogFailure(status, methodStr); 2440 } catch (RemoteException e) { 2441 handleRemoteException(e, methodStr); 2442 return false; 2443 } 2444 } 2445 } 2446 2447 /** 2448 * Start WPS pin display operation with the specified peer. 2449 * 2450 * @param ifaceName Name of the interface. 2451 * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard. 2452 * @return true if request is sent successfully, false otherwise. 2453 */ startWpsPbc(@onNull String ifaceName, String bssidStr)2454 public boolean startWpsPbc(@NonNull String ifaceName, String bssidStr) { 2455 synchronized (mLock) { 2456 try { 2457 return startWpsPbc(ifaceName, NativeUtil.macAddressToByteArray(bssidStr)); 2458 } catch (IllegalArgumentException e) { 2459 Log.e(TAG, "Illegal argument " + bssidStr, e); 2460 return false; 2461 } 2462 } 2463 } 2464 2465 /** See ISupplicantStaIface.hal for documentation */ startWpsPbc(@onNull String ifaceName, byte[ ] bssid)2466 private boolean startWpsPbc(@NonNull String ifaceName, byte[/* 6 */] bssid) { 2467 synchronized (mLock) { 2468 final String methodStr = "startWpsPbc"; 2469 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2470 if (iface == null) return false; 2471 try { 2472 SupplicantStatus status = iface.startWpsPbc(bssid); 2473 return checkStatusAndLogFailure(status, methodStr); 2474 } catch (RemoteException e) { 2475 handleRemoteException(e, methodStr); 2476 return false; 2477 } 2478 } 2479 } 2480 2481 /** 2482 * Start WPS pin keypad operation with the specified pin. 2483 * 2484 * @param ifaceName Name of the interface. 2485 * @param pin Pin to be used. 2486 * @return true if request is sent successfully, false otherwise. 2487 */ startWpsPinKeypad(@onNull String ifaceName, String pin)2488 public boolean startWpsPinKeypad(@NonNull String ifaceName, String pin) { 2489 if (TextUtils.isEmpty(pin)) return false; 2490 synchronized (mLock) { 2491 final String methodStr = "startWpsPinKeypad"; 2492 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2493 if (iface == null) return false; 2494 try { 2495 SupplicantStatus status = iface.startWpsPinKeypad(pin); 2496 return checkStatusAndLogFailure(status, methodStr); 2497 } catch (RemoteException e) { 2498 handleRemoteException(e, methodStr); 2499 return false; 2500 } 2501 } 2502 } 2503 2504 /** 2505 * Start WPS pin display operation with the specified peer. 2506 * 2507 * @param ifaceName Name of the interface. 2508 * @param bssidStr BSSID of the peer. Use empty bssid to indicate wildcard. 2509 * @return new pin generated on success, null otherwise. 2510 */ startWpsPinDisplay(@onNull String ifaceName, String bssidStr)2511 public String startWpsPinDisplay(@NonNull String ifaceName, String bssidStr) { 2512 synchronized (mLock) { 2513 try { 2514 return startWpsPinDisplay(ifaceName, NativeUtil.macAddressToByteArray(bssidStr)); 2515 } catch (IllegalArgumentException e) { 2516 Log.e(TAG, "Illegal argument " + bssidStr, e); 2517 return null; 2518 } 2519 } 2520 } 2521 2522 /** See ISupplicantStaIface.hal for documentation */ startWpsPinDisplay(@onNull String ifaceName, byte[ ] bssid)2523 private String startWpsPinDisplay(@NonNull String ifaceName, byte[/* 6 */] bssid) { 2524 synchronized (mLock) { 2525 final String methodStr = "startWpsPinDisplay"; 2526 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2527 if (iface == null) return null; 2528 final Mutable<String> gotPin = new Mutable<>(); 2529 try { 2530 iface.startWpsPinDisplay(bssid, 2531 (SupplicantStatus status, String pin) -> { 2532 if (checkStatusAndLogFailure(status, methodStr)) { 2533 gotPin.value = pin; 2534 } 2535 }); 2536 } catch (RemoteException e) { 2537 handleRemoteException(e, methodStr); 2538 } 2539 return gotPin.value; 2540 } 2541 } 2542 2543 /** 2544 * Cancels any ongoing WPS requests. 2545 * 2546 * @param ifaceName Name of the interface. 2547 * @return true if request is sent successfully, false otherwise. 2548 */ cancelWps(@onNull String ifaceName)2549 public boolean cancelWps(@NonNull String ifaceName) { 2550 synchronized (mLock) { 2551 final String methodStr = "cancelWps"; 2552 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2553 if (iface == null) return false; 2554 try { 2555 SupplicantStatus status = iface.cancelWps(); 2556 return checkStatusAndLogFailure(status, methodStr); 2557 } catch (RemoteException e) { 2558 handleRemoteException(e, methodStr); 2559 return false; 2560 } 2561 } 2562 } 2563 2564 /** 2565 * Sets whether to use external sim for SIM/USIM processing. 2566 * 2567 * @param ifaceName Name of the interface. 2568 * @param useExternalSim true to enable, false otherwise. 2569 * @return true if request is sent successfully, false otherwise. 2570 */ setExternalSim(@onNull String ifaceName, boolean useExternalSim)2571 public boolean setExternalSim(@NonNull String ifaceName, boolean useExternalSim) { 2572 synchronized (mLock) { 2573 final String methodStr = "setExternalSim"; 2574 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2575 if (iface == null) return false; 2576 try { 2577 SupplicantStatus status = iface.setExternalSim(useExternalSim); 2578 return checkStatusAndLogFailure(status, methodStr); 2579 } catch (RemoteException e) { 2580 handleRemoteException(e, methodStr); 2581 return false; 2582 } 2583 } 2584 } 2585 2586 /** See ISupplicant.hal for documentation */ enableAutoReconnect(@onNull String ifaceName, boolean enable)2587 public boolean enableAutoReconnect(@NonNull String ifaceName, boolean enable) { 2588 synchronized (mLock) { 2589 final String methodStr = "enableAutoReconnect"; 2590 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2591 if (iface == null) return false; 2592 try { 2593 SupplicantStatus status = iface.enableAutoReconnect(enable); 2594 return checkStatusAndLogFailure(status, methodStr); 2595 } catch (RemoteException e) { 2596 handleRemoteException(e, methodStr); 2597 return false; 2598 } 2599 } 2600 } 2601 2602 /** 2603 * Set the debug log level for wpa_supplicant 2604 * 2605 * @param turnOnVerbose Whether to turn on verbose logging or not. 2606 * @return true if request is sent successfully, false otherwise. 2607 */ setLogLevel(boolean turnOnVerbose)2608 public boolean setLogLevel(boolean turnOnVerbose) { 2609 synchronized (mLock) { 2610 int logLevel = turnOnVerbose 2611 ? ISupplicant.DebugLevel.DEBUG 2612 : ISupplicant.DebugLevel.INFO; 2613 return setDebugParams(logLevel, false, 2614 turnOnVerbose && mWifiGlobals.getShowKeyVerboseLoggingModeEnabled()); 2615 } 2616 } 2617 2618 /** See ISupplicant.hal for documentation */ setDebugParams(int level, boolean showTimestamp, boolean showKeys)2619 private boolean setDebugParams(int level, boolean showTimestamp, boolean showKeys) { 2620 synchronized (mLock) { 2621 final String methodStr = "setDebugParams"; 2622 if (!checkSupplicantAndLogFailure(methodStr)) return false; 2623 try { 2624 SupplicantStatus status = 2625 mISupplicant.setDebugParams(level, showTimestamp, showKeys); 2626 return checkStatusAndLogFailure(status, methodStr); 2627 } catch (RemoteException e) { 2628 handleRemoteException(e, methodStr); 2629 return false; 2630 } 2631 } 2632 } 2633 2634 /** 2635 * Set concurrency priority between P2P & STA operations. 2636 * 2637 * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations, 2638 * false otherwise. 2639 * @return true if request is sent successfully, false otherwise. 2640 */ setConcurrencyPriority(boolean isStaHigherPriority)2641 public boolean setConcurrencyPriority(boolean isStaHigherPriority) { 2642 synchronized (mLock) { 2643 if (isStaHigherPriority) { 2644 return setConcurrencyPriority(IfaceType.STA); 2645 } else { 2646 return setConcurrencyPriority(IfaceType.P2P); 2647 } 2648 } 2649 } 2650 2651 /** See ISupplicant.hal for documentation */ setConcurrencyPriority(int type)2652 private boolean setConcurrencyPriority(int type) { 2653 synchronized (mLock) { 2654 final String methodStr = "setConcurrencyPriority"; 2655 if (!checkSupplicantAndLogFailure(methodStr)) return false; 2656 try { 2657 SupplicantStatus status = mISupplicant.setConcurrencyPriority(type); 2658 return checkStatusAndLogFailure(status, methodStr); 2659 } catch (RemoteException e) { 2660 handleRemoteException(e, methodStr); 2661 return false; 2662 } 2663 } 2664 } 2665 2666 /** 2667 * Returns false if Supplicant is null, and logs failure to call methodStr 2668 */ checkSupplicantAndLogFailure(final String methodStr)2669 private boolean checkSupplicantAndLogFailure(final String methodStr) { 2670 synchronized (mLock) { 2671 if (mISupplicant == null) { 2672 Log.e(TAG, "Can't call " + methodStr + ", ISupplicant is null"); 2673 return false; 2674 } 2675 return true; 2676 } 2677 } 2678 2679 /** 2680 * Returns false if SupplicantStaIface is null, and logs failure to call methodStr 2681 */ checkSupplicantStaIfaceAndLogFailure( @onNull String ifaceName, final String methodStr)2682 private ISupplicantStaIface checkSupplicantStaIfaceAndLogFailure( 2683 @NonNull String ifaceName, final String methodStr) { 2684 synchronized (mLock) { 2685 ISupplicantStaIface iface = getStaIface(ifaceName); 2686 if (iface == null) { 2687 Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null for iface=" 2688 + ifaceName); 2689 return null; 2690 } 2691 return iface; 2692 } 2693 } 2694 2695 /** 2696 * Returns false if SupplicantStaNetwork is null, and logs failure to call methodStr 2697 */ checkSupplicantStaNetworkAndLogFailure( @onNull String ifaceName, final String methodStr)2698 private SupplicantStaNetworkHalHidlImpl checkSupplicantStaNetworkAndLogFailure( 2699 @NonNull String ifaceName, final String methodStr) { 2700 synchronized (mLock) { 2701 SupplicantStaNetworkHalHidlImpl networkHal = getCurrentNetworkRemoteHandle(ifaceName); 2702 if (networkHal == null) { 2703 Log.e(TAG, "Can't call " + methodStr + ", SupplicantStaNetwork is null"); 2704 return null; 2705 } 2706 return networkHal; 2707 } 2708 } 2709 2710 /** 2711 * Returns true if provided status code is SUCCESS, logs debug message and returns false 2712 * otherwise 2713 */ checkStatusAndLogFailure(SupplicantStatus status, final String methodStr)2714 private boolean checkStatusAndLogFailure(SupplicantStatus status, 2715 final String methodStr) { 2716 synchronized (mLock) { 2717 if (status == null || status.code != SupplicantStatusCode.SUCCESS) { 2718 Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: " + status); 2719 return false; 2720 } else { 2721 if (mVerboseLoggingEnabled) { 2722 Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded"); 2723 } 2724 return true; 2725 } 2726 } 2727 } 2728 2729 /** 2730 * Returns true if provided status code is SUCCESS, logs debug message and returns false 2731 * otherwise 2732 */ checkStatusAndLogFailure( android.hardware.wifi.supplicant.V1_4.SupplicantStatus status, final String methodStr)2733 private boolean checkStatusAndLogFailure( 2734 android.hardware.wifi.supplicant.V1_4.SupplicantStatus status, 2735 final String methodStr) { 2736 synchronized (mLock) { 2737 if (status == null 2738 || status.code 2739 != android.hardware.wifi.supplicant.V1_4.SupplicantStatusCode.SUCCESS) { 2740 Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed: " + status); 2741 return false; 2742 } else { 2743 if (mVerboseLoggingEnabled) { 2744 Log.d(TAG, "ISupplicantStaIface." + methodStr + " succeeded"); 2745 } 2746 return true; 2747 } 2748 } 2749 } 2750 2751 /** 2752 * Helper function to log callbacks. 2753 */ logCallback(final String methodStr)2754 protected void logCallback(final String methodStr) { 2755 synchronized (mLock) { 2756 if (mVerboseLoggingEnabled) { 2757 Log.d(TAG, "ISupplicantStaIfaceCallback." + methodStr + " received"); 2758 } 2759 } 2760 } 2761 handleNoSuchElementException(NoSuchElementException e, String methodStr)2762 private void handleNoSuchElementException(NoSuchElementException e, String methodStr) { 2763 synchronized (mLock) { 2764 clearState(); 2765 Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e); 2766 } 2767 } 2768 handleRemoteException(RemoteException e, String methodStr)2769 private void handleRemoteException(RemoteException e, String methodStr) { 2770 synchronized (mLock) { 2771 clearState(); 2772 Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e); 2773 } 2774 } 2775 handleIllegalArgumentException(IllegalArgumentException e, String methodStr)2776 private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) { 2777 synchronized (mLock) { 2778 clearState(); 2779 Log.e(TAG, "ISupplicantStaIface." + methodStr + " failed with exception", e); 2780 } 2781 } 2782 2783 /** 2784 * Converts the Wps config method string to the equivalent enum value. 2785 */ stringToWpsConfigMethod(String configMethod)2786 private static short stringToWpsConfigMethod(String configMethod) { 2787 switch (configMethod) { 2788 case "usba": 2789 return WpsConfigMethods.USBA; 2790 case "ethernet": 2791 return WpsConfigMethods.ETHERNET; 2792 case "label": 2793 return WpsConfigMethods.LABEL; 2794 case "display": 2795 return WpsConfigMethods.DISPLAY; 2796 case "int_nfc_token": 2797 return WpsConfigMethods.INT_NFC_TOKEN; 2798 case "ext_nfc_token": 2799 return WpsConfigMethods.EXT_NFC_TOKEN; 2800 case "nfc_interface": 2801 return WpsConfigMethods.NFC_INTERFACE; 2802 case "push_button": 2803 return WpsConfigMethods.PUSHBUTTON; 2804 case "keypad": 2805 return WpsConfigMethods.KEYPAD; 2806 case "virtual_push_button": 2807 return WpsConfigMethods.VIRT_PUSHBUTTON; 2808 case "physical_push_button": 2809 return WpsConfigMethods.PHY_PUSHBUTTON; 2810 case "p2ps": 2811 return WpsConfigMethods.P2PS; 2812 case "virtual_display": 2813 return WpsConfigMethods.VIRT_DISPLAY; 2814 case "physical_display": 2815 return WpsConfigMethods.PHY_DISPLAY; 2816 default: 2817 throw new IllegalArgumentException( 2818 "Invalid WPS config method: " + configMethod); 2819 } 2820 } 2821 2822 protected class SupplicantStaIfaceHalCallback extends SupplicantStaIfaceCallbackHidlImpl { SupplicantStaIfaceHalCallback(@onNull String ifaceName)2823 SupplicantStaIfaceHalCallback(@NonNull String ifaceName) { 2824 super(SupplicantStaIfaceHalHidlImpl.this, ifaceName, new Object(), mWifiMonitor); 2825 } 2826 } 2827 2828 protected class SupplicantStaIfaceHalCallbackV1_1 extends 2829 SupplicantStaIfaceCallbackHidlV1_1Impl { SupplicantStaIfaceHalCallbackV1_1(@onNull String ifaceName)2830 SupplicantStaIfaceHalCallbackV1_1(@NonNull String ifaceName) { 2831 super(SupplicantStaIfaceHalHidlImpl.this, ifaceName, new Object(), mWifiMonitor); 2832 } 2833 } 2834 2835 protected class SupplicantStaIfaceHalCallbackV1_2 extends 2836 SupplicantStaIfaceCallbackHidlV1_2Impl { SupplicantStaIfaceHalCallbackV1_2(@onNull String ifaceName)2837 SupplicantStaIfaceHalCallbackV1_2(@NonNull String ifaceName) { 2838 super(SupplicantStaIfaceHalHidlImpl.this, ifaceName, mContext); 2839 } 2840 } 2841 2842 protected class SupplicantStaIfaceHalCallbackV1_3 extends 2843 SupplicantStaIfaceCallbackHidlV1_3Impl { SupplicantStaIfaceHalCallbackV1_3(@onNull String ifaceName)2844 SupplicantStaIfaceHalCallbackV1_3(@NonNull String ifaceName) { 2845 super(SupplicantStaIfaceHalHidlImpl.this, ifaceName, mWifiMonitor); 2846 } 2847 } 2848 2849 protected class SupplicantStaIfaceHalCallbackV1_4 extends 2850 SupplicantStaIfaceCallbackHidlV1_4Impl { SupplicantStaIfaceHalCallbackV1_4(@onNull String ifaceName)2851 SupplicantStaIfaceHalCallbackV1_4(@NonNull String ifaceName) { 2852 super(SupplicantStaIfaceHalHidlImpl.this, ifaceName, new Object(), mWifiMonitor); 2853 } 2854 } 2855 addPmkCacheEntry( String ifaceName, int networkId, long expirationTimeInSec, ArrayList<Byte> serializedEntry)2856 protected void addPmkCacheEntry( 2857 String ifaceName, 2858 int networkId, long expirationTimeInSec, ArrayList<Byte> serializedEntry) { 2859 String macAddressStr = getMacAddress(ifaceName); 2860 try { 2861 if (!mPmkCacheManager.add(MacAddress.fromString(macAddressStr), 2862 networkId, expirationTimeInSec, serializedEntry)) { 2863 Log.w(TAG, "Cannot add PMK cache for " + ifaceName); 2864 } 2865 } catch (IllegalArgumentException ex) { 2866 Log.w(TAG, "Cannot add PMK cache: " + ex); 2867 } 2868 } 2869 removePmkCacheEntry(int networkId)2870 protected void removePmkCacheEntry(int networkId) { 2871 mPmkCacheManager.remove(networkId); 2872 } 2873 logd(String s)2874 private static void logd(String s) { 2875 Log.d(TAG, s); 2876 } 2877 logi(String s)2878 private static void logi(String s) { 2879 Log.i(TAG, s); 2880 } 2881 loge(String s)2882 private static void loge(String s) { 2883 Log.e(TAG, s); 2884 } 2885 2886 /** 2887 * Returns a bitmask of advanced capabilities: WPA3 SAE/SUITE B and OWE 2888 * Bitmask used is: 2889 * - WIFI_FEATURE_WPA3_SAE 2890 * - WIFI_FEATURE_WPA3_SUITE_B 2891 * - WIFI_FEATURE_OWE 2892 * 2893 * This is a v1.2+ HAL feature. 2894 * On error, or if these features are not supported, 0 is returned. 2895 */ getAdvancedCapabilities(@onNull String ifaceName)2896 public long getAdvancedCapabilities(@NonNull String ifaceName) { 2897 final String methodStr = "getAdvancedCapabilities"; 2898 2899 long advancedCapabilities = 0; 2900 int keyMgmtCapabilities = getKeyMgmtCapabilities(ifaceName); 2901 2902 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork 2903 .KeyMgmtMask.SAE) != 0) { 2904 advancedCapabilities |= WIFI_FEATURE_WPA3_SAE; 2905 2906 if (mVerboseLoggingEnabled) { 2907 Log.v(TAG, methodStr + ": SAE supported"); 2908 } 2909 } 2910 2911 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork 2912 .KeyMgmtMask.SUITE_B_192) != 0) { 2913 advancedCapabilities |= WIFI_FEATURE_WPA3_SUITE_B; 2914 2915 if (mVerboseLoggingEnabled) { 2916 Log.v(TAG, methodStr + ": SUITE_B supported"); 2917 } 2918 } 2919 2920 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork 2921 .KeyMgmtMask.OWE) != 0) { 2922 advancedCapabilities |= WIFI_FEATURE_OWE; 2923 2924 if (mVerboseLoggingEnabled) { 2925 Log.v(TAG, methodStr + ": OWE supported"); 2926 } 2927 } 2928 2929 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork 2930 .KeyMgmtMask.DPP) != 0) { 2931 advancedCapabilities |= WIFI_FEATURE_DPP; 2932 2933 if (mVerboseLoggingEnabled) { 2934 Log.v(TAG, methodStr + ": DPP supported"); 2935 } 2936 if (isV1_4()) { 2937 advancedCapabilities |= WIFI_FEATURE_DPP_ENROLLEE_RESPONDER; 2938 if (mVerboseLoggingEnabled) { 2939 Log.v(TAG, methodStr + ": DPP ENROLLEE RESPONDER supported"); 2940 } 2941 } 2942 } 2943 2944 if (isV1_4()) { 2945 advancedCapabilities |= WIFI_FEATURE_PASSPOINT_TERMS_AND_CONDITIONS 2946 | WIFI_FEATURE_DECORATED_IDENTITY; 2947 if (mVerboseLoggingEnabled) { 2948 Log.v(TAG, methodStr + ": Passpoint T&C supported"); 2949 Log.v(TAG, methodStr + ": RFC 7542 decorated identity supported"); 2950 } 2951 } 2952 2953 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork 2954 .KeyMgmtMask.WAPI_PSK) != 0) { 2955 advancedCapabilities |= WIFI_FEATURE_WAPI; 2956 2957 if (mVerboseLoggingEnabled) { 2958 Log.v(TAG, methodStr + ": WAPI supported"); 2959 } 2960 } 2961 2962 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork 2963 .KeyMgmtMask.FILS_SHA256) != 0) { 2964 advancedCapabilities |= WIFI_FEATURE_FILS_SHA256; 2965 2966 if (mVerboseLoggingEnabled) { 2967 Log.v(TAG, methodStr + ": FILS_SHA256 supported"); 2968 } 2969 } 2970 if ((keyMgmtCapabilities & android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork 2971 .KeyMgmtMask.FILS_SHA384) != 0) { 2972 advancedCapabilities |= WIFI_FEATURE_FILS_SHA384; 2973 2974 if (mVerboseLoggingEnabled) { 2975 Log.v(TAG, methodStr + ": FILS_SHA384 supported"); 2976 } 2977 } 2978 2979 if (mVerboseLoggingEnabled) { 2980 Log.v(TAG, methodStr + ": Capability flags = " + keyMgmtCapabilities); 2981 } 2982 2983 return advancedCapabilities; 2984 } 2985 getKeyMgmtCapabilities_1_3(@onNull String ifaceName)2986 private int getKeyMgmtCapabilities_1_3(@NonNull String ifaceName) { 2987 final String methodStr = "getKeyMgmtCapabilities_1_3"; 2988 Mutable<Integer> keyMgmtMask = new Mutable<>(0); 2989 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 2990 if (iface == null) { 2991 return 0; 2992 } 2993 2994 // Get a v1.3 supplicant STA Interface 2995 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 2996 getStaIfaceMockableV1_3(iface); 2997 if (staIfaceV13 == null) { 2998 Log.e(TAG, methodStr 2999 + ": ISupplicantStaIface V1.3 is null, cannot get advanced capabilities"); 3000 return 0; 3001 } 3002 3003 try { 3004 // Support for new key management types; WAPI_PSK, WAPI_CERT 3005 // Requires HAL v1.3 or higher 3006 staIfaceV13.getKeyMgmtCapabilities_1_3( 3007 (SupplicantStatus statusInternal, int keyMgmtMaskInternal) -> { 3008 if (statusInternal.code == SupplicantStatusCode.SUCCESS) { 3009 keyMgmtMask.value = keyMgmtMaskInternal; 3010 } 3011 checkStatusAndLogFailure(statusInternal, methodStr); 3012 }); 3013 } catch (RemoteException e) { 3014 handleRemoteException(e, methodStr); 3015 } 3016 return keyMgmtMask.value; 3017 } 3018 getKeyMgmtCapabilities(@onNull String ifaceName)3019 private int getKeyMgmtCapabilities(@NonNull String ifaceName) { 3020 final String methodStr = "getKeyMgmtCapabilities"; 3021 Mutable<Boolean> status = new Mutable<>(false); 3022 Mutable<Integer> keyMgmtMask = new Mutable<>(0); 3023 3024 if (isV1_3()) { 3025 keyMgmtMask.value = getKeyMgmtCapabilities_1_3(ifaceName); 3026 } else if (isV1_2()) { 3027 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3028 if (iface == null) { 3029 return 0; 3030 } 3031 3032 // Get a v1.2 supplicant STA Interface 3033 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3034 getStaIfaceMockableV1_2(iface); 3035 3036 if (staIfaceV12 == null) { 3037 Log.e(TAG, methodStr 3038 + ": ISupplicantStaIface is null, cannot get advanced capabilities"); 3039 return 0; 3040 } 3041 3042 try { 3043 // Support for new key management types; SAE, SUITE_B, OWE 3044 // Requires HAL v1.2 or higher 3045 staIfaceV12.getKeyMgmtCapabilities( 3046 (SupplicantStatus statusInternal, int keyMgmtMaskInternal) -> { 3047 status.value = statusInternal.code == SupplicantStatusCode.SUCCESS; 3048 if (status.value) { 3049 keyMgmtMask.value = keyMgmtMaskInternal; 3050 } 3051 checkStatusAndLogFailure(statusInternal, methodStr); 3052 }); 3053 } catch (RemoteException e) { 3054 handleRemoteException(e, methodStr); 3055 } 3056 } else { 3057 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3058 } 3059 3060 // 0 is returned in case of an error 3061 return keyMgmtMask.value; 3062 } 3063 getWpaDriverCapabilities_1_4(@onNull String ifaceName)3064 private Mutable<Integer> getWpaDriverCapabilities_1_4(@NonNull String ifaceName) { 3065 final String methodStr = "getWpaDriverCapabilities_1_4"; 3066 Mutable<Integer> drvCapabilitiesMask = new Mutable<>(0); 3067 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3068 3069 if (null == iface) return drvCapabilitiesMask; 3070 3071 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 3072 getStaIfaceMockableV1_4(iface); 3073 if (null == staIfaceV14) { 3074 Log.e(TAG, methodStr 3075 + ": SupplicantStaIface is null, cannot get wpa driver features"); 3076 return drvCapabilitiesMask; 3077 } 3078 3079 try { 3080 staIfaceV14.getWpaDriverCapabilities_1_4( 3081 (android.hardware.wifi.supplicant.V1_4.SupplicantStatus statusInternal, 3082 int drvCapabilities) -> { 3083 if (statusInternal.code 3084 == android.hardware.wifi.supplicant.V1_4 3085 .SupplicantStatusCode.SUCCESS) { 3086 drvCapabilitiesMask.value = drvCapabilities; 3087 } 3088 checkStatusAndLogFailure(statusInternal, methodStr); 3089 }); 3090 } catch (RemoteException e) { 3091 handleRemoteException(e, methodStr); 3092 } 3093 return drvCapabilitiesMask; 3094 } 3095 getWpaDriverCapabilities_1_3(@onNull String ifaceName)3096 private Mutable<Integer> getWpaDriverCapabilities_1_3(@NonNull String ifaceName) { 3097 final String methodStr = "getWpaDriverCapabilities_1_3"; 3098 Mutable<Integer> drvCapabilitiesMask = new Mutable<>(0); 3099 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3100 3101 if (null == iface) return drvCapabilitiesMask; 3102 3103 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 3104 getStaIfaceMockableV1_3(iface); 3105 if (null == staIfaceV13) { 3106 Log.e(TAG, methodStr 3107 + ": SupplicantStaIface is null, cannot get wpa driver features"); 3108 return drvCapabilitiesMask; 3109 } 3110 3111 try { 3112 staIfaceV13.getWpaDriverCapabilities( 3113 (SupplicantStatus statusInternal, int drvCapabilities) -> { 3114 if (statusInternal.code == SupplicantStatusCode.SUCCESS) { 3115 drvCapabilitiesMask.value = drvCapabilities; 3116 } 3117 checkStatusAndLogFailure(statusInternal, methodStr); 3118 }); 3119 } catch (RemoteException e) { 3120 handleRemoteException(e, methodStr); 3121 } 3122 return drvCapabilitiesMask; 3123 } 3124 3125 /** 3126 * Get the driver supported features through supplicant. 3127 * 3128 * @param ifaceName Name of the interface. 3129 * @return bitmask defined by WifiManager.WIFI_FEATURE_*. 3130 */ getWpaDriverFeatureSet(@onNull String ifaceName)3131 public long getWpaDriverFeatureSet(@NonNull String ifaceName) { 3132 final String methodStr = "getWpaDriverFeatureSet"; 3133 Mutable<Integer> drvCapabilitiesMask = new Mutable<>(0); 3134 long featureSet = 0; 3135 3136 if (isV1_4()) { 3137 drvCapabilitiesMask = getWpaDriverCapabilities_1_4(ifaceName); 3138 } else if (isV1_3()) { 3139 drvCapabilitiesMask = getWpaDriverCapabilities_1_3(ifaceName); 3140 } else { 3141 Log.i(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3142 return 0; 3143 } 3144 3145 if ((drvCapabilitiesMask.value & WpaDriverCapabilitiesMask.MBO) != 0) { 3146 featureSet |= WIFI_FEATURE_MBO; 3147 if (mVerboseLoggingEnabled) { 3148 Log.v(TAG, methodStr + ": MBO supported"); 3149 } 3150 if ((drvCapabilitiesMask.value 3151 & WpaDriverCapabilitiesMask.OCE) != 0) { 3152 featureSet |= WIFI_FEATURE_OCE; 3153 if (mVerboseLoggingEnabled) { 3154 Log.v(TAG, methodStr + ": OCE supported"); 3155 } 3156 } 3157 } 3158 3159 if ((drvCapabilitiesMask.value 3160 & android.hardware.wifi.supplicant.V1_4.WpaDriverCapabilitiesMask.SAE_PK) != 0) { 3161 featureSet |= WIFI_FEATURE_SAE_PK; 3162 if (mVerboseLoggingEnabled) { 3163 Log.v(TAG, methodStr + ": SAE-PK supported"); 3164 } 3165 } 3166 3167 if ((drvCapabilitiesMask.value 3168 & android.hardware.wifi.supplicant.V1_4.WpaDriverCapabilitiesMask.WFD_R2) != 0) { 3169 featureSet |= WIFI_FEATURE_WFD_R2; 3170 if (mVerboseLoggingEnabled) { 3171 Log.v(TAG, methodStr + ": WFD-R2 supported"); 3172 } 3173 } 3174 3175 return featureSet; 3176 } 3177 getWifiStandard(int technology)3178 private @WifiStandard int getWifiStandard(int technology) { 3179 switch(technology) { 3180 case WifiTechnology.HE: 3181 return ScanResult.WIFI_STANDARD_11AX; 3182 case WifiTechnology.VHT: 3183 return ScanResult.WIFI_STANDARD_11AC; 3184 case WifiTechnology.HT: 3185 return ScanResult.WIFI_STANDARD_11N; 3186 case WifiTechnology.LEGACY: 3187 return ScanResult.WIFI_STANDARD_LEGACY; 3188 default: 3189 return ScanResult.WIFI_STANDARD_UNKNOWN; 3190 } 3191 } 3192 getChannelBandwidth(int channelBandwidth)3193 private int getChannelBandwidth(int channelBandwidth) { 3194 switch(channelBandwidth) { 3195 case WifiChannelWidthInMhz.WIDTH_20: 3196 return ScanResult.CHANNEL_WIDTH_20MHZ; 3197 case WifiChannelWidthInMhz.WIDTH_40: 3198 return ScanResult.CHANNEL_WIDTH_40MHZ; 3199 case WifiChannelWidthInMhz.WIDTH_80: 3200 return ScanResult.CHANNEL_WIDTH_80MHZ; 3201 case WifiChannelWidthInMhz.WIDTH_160: 3202 return ScanResult.CHANNEL_WIDTH_160MHZ; 3203 case WifiChannelWidthInMhz.WIDTH_80P80: 3204 return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; 3205 default: 3206 return ScanResult.CHANNEL_WIDTH_20MHZ; 3207 } 3208 } 3209 frameworkToHidlDppAkm(int dppAkm)3210 private int frameworkToHidlDppAkm(int dppAkm) { 3211 switch(dppAkm) { 3212 case SupplicantStaIfaceHal.DppAkm.PSK: 3213 return DppAkm.PSK; 3214 case SupplicantStaIfaceHal.DppAkm.PSK_SAE: 3215 return DppAkm.PSK_SAE; 3216 case SupplicantStaIfaceHal.DppAkm.SAE: 3217 return DppAkm.SAE; 3218 case SupplicantStaIfaceHal.DppAkm.DPP: 3219 return DppAkm.DPP; 3220 default: 3221 Log.e(TAG, "Invalid DppAkm received"); 3222 return -1; 3223 } 3224 } 3225 frameworkToHidlDppCurve(int dppCurve)3226 private int frameworkToHidlDppCurve(int dppCurve) { 3227 switch(dppCurve) { 3228 case SupplicantStaIfaceHal.DppCurve.PRIME256V1: 3229 return DppCurve.PRIME256V1; 3230 case SupplicantStaIfaceHal.DppCurve.SECP384R1: 3231 return DppCurve.SECP384R1; 3232 case SupplicantStaIfaceHal.DppCurve.SECP521R1: 3233 return DppCurve.SECP521R1; 3234 case SupplicantStaIfaceHal.DppCurve.BRAINPOOLP256R1: 3235 return DppCurve.BRAINPOOLP256R1; 3236 case SupplicantStaIfaceHal.DppCurve.BRAINPOOLP384R1: 3237 return DppCurve.BRAINPOOLP384R1; 3238 case SupplicantStaIfaceHal.DppCurve.BRAINPOOLP512R1: 3239 return DppCurve.BRAINPOOLP512R1; 3240 default: 3241 Log.e(TAG, "Invalid DppAkm received"); 3242 return -1; 3243 } 3244 } 3245 frameworkToHidlDppNetRole(int dppNetRole)3246 private int frameworkToHidlDppNetRole(int dppNetRole) { 3247 switch(dppNetRole) { 3248 case SupplicantStaIfaceHal.DppNetRole.STA: 3249 return DppNetRole.STA; 3250 case SupplicantStaIfaceHal.DppNetRole.AP: 3251 return DppNetRole.AP; 3252 default: 3253 Log.e(TAG, "Invalid DppNetRole received"); 3254 return -1; 3255 } 3256 } 3257 3258 /** 3259 * Returns connection capabilities of the current network 3260 * 3261 * This is a v1.3+ HAL feature. 3262 * @param ifaceName Name of the interface. 3263 * @return connection capabilities of the current network 3264 */ getConnectionCapabilities(@onNull String ifaceName)3265 public WifiNative.ConnectionCapabilities getConnectionCapabilities(@NonNull String ifaceName) { 3266 final String methodStr = "getConnectionCapabilities"; 3267 WifiNative.ConnectionCapabilities capOut = new WifiNative.ConnectionCapabilities(); 3268 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3269 if (iface == null) { 3270 return capOut; 3271 } 3272 if (isV1_4()) { 3273 return getConnectionCapabilities_1_4(iface); 3274 } else if (isV1_3()) { 3275 return getConnectionCapabilities_1_3(iface); 3276 } else { 3277 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3278 } 3279 return capOut; 3280 } 3281 3282 /** 3283 * Returns connection MLO links info 3284 * 3285 * @param ifaceName Name of the interface. 3286 * @return null since this method is not supported on Hidl 3287 */ getConnectionMloLinksInfo(@onNull String ifaceName)3288 public WifiNative.ConnectionMloLinksInfo getConnectionMloLinksInfo(@NonNull String ifaceName) { 3289 return null; 3290 } 3291 getConnectionCapabilities_1_3( @onNull ISupplicantStaIface iface)3292 private WifiNative.ConnectionCapabilities getConnectionCapabilities_1_3( 3293 @NonNull ISupplicantStaIface iface) { 3294 final String methodStr = "getConnectionCapabilities_1_3"; 3295 WifiNative.ConnectionCapabilities capOut = new WifiNative.ConnectionCapabilities(); 3296 3297 // Get a v1.3 supplicant STA Interface 3298 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 3299 getStaIfaceMockableV1_3(iface); 3300 3301 if (staIfaceV13 == null) { 3302 Log.e(TAG, methodStr 3303 + ": SupplicantStaIface is null, cannot get Connection Capabilities"); 3304 return capOut; 3305 } 3306 3307 try { 3308 staIfaceV13.getConnectionCapabilities( 3309 (SupplicantStatus statusInternal, ConnectionCapabilities cap) -> { 3310 if (statusInternal.code == SupplicantStatusCode.SUCCESS) { 3311 capOut.wifiStandard = getWifiStandard(cap.technology); 3312 capOut.channelBandwidth = getChannelBandwidth( 3313 cap.channelBandwidth); 3314 capOut.maxNumberTxSpatialStreams = cap.maxNumberTxSpatialStreams; 3315 capOut.maxNumberRxSpatialStreams = cap.maxNumberRxSpatialStreams; 3316 } 3317 checkStatusAndLogFailure(statusInternal, methodStr); 3318 }); 3319 } catch (RemoteException e) { 3320 handleRemoteException(e, methodStr); 3321 } 3322 return capOut; 3323 } 3324 getConnectionCapabilities_1_4( @onNull ISupplicantStaIface iface)3325 private WifiNative.ConnectionCapabilities getConnectionCapabilities_1_4( 3326 @NonNull ISupplicantStaIface iface) { 3327 final String methodStr = "getConnectionCapabilities_1_4"; 3328 WifiNative.ConnectionCapabilities capOut = new WifiNative.ConnectionCapabilities(); 3329 // Get a v1.4 supplicant STA Interface 3330 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 3331 getStaIfaceMockableV1_4(iface); 3332 3333 if (staIfaceV14 == null) { 3334 Log.e(TAG, methodStr 3335 + ": SupplicantStaIface is null, cannot get Connection Capabilities"); 3336 return capOut; 3337 } 3338 3339 try { 3340 staIfaceV14.getConnectionCapabilities_1_4( 3341 (android.hardware.wifi.supplicant.V1_4.SupplicantStatus statusInternal, 3342 android.hardware.wifi.supplicant.V1_4.ConnectionCapabilities cap) 3343 -> { 3344 if (statusInternal.code == SupplicantStatusCode.SUCCESS) { 3345 capOut.wifiStandard = getWifiStandard(cap.V1_3.technology); 3346 capOut.channelBandwidth = getChannelBandwidth( 3347 cap.V1_3.channelBandwidth); 3348 capOut.is11bMode = (cap.legacyMode == LegacyMode.B_MODE); 3349 capOut.maxNumberTxSpatialStreams = cap.V1_3.maxNumberTxSpatialStreams; 3350 capOut.maxNumberRxSpatialStreams = cap.V1_3.maxNumberRxSpatialStreams; 3351 } 3352 checkStatusAndLogFailure(statusInternal, methodStr); 3353 }); 3354 } catch (RemoteException e) { 3355 handleRemoteException(e, methodStr); 3356 } 3357 return capOut; 3358 } 3359 /** 3360 * Adds a DPP peer URI to the URI list. 3361 * 3362 * This is a v1.2+ HAL feature. 3363 * Returns an ID to be used later to refer to this URI (>0). 3364 * On error, or if these features are not supported, -1 is returned. 3365 */ addDppPeerUri(@onNull String ifaceName, @NonNull String uri)3366 public int addDppPeerUri(@NonNull String ifaceName, @NonNull String uri) { 3367 final String methodStr = "addDppPeerUri"; 3368 Mutable<Boolean> status = new Mutable<>(false); 3369 Mutable<Integer> bootstrapId = new Mutable<>(-1); 3370 3371 if (!isV1_2()) { 3372 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3373 return -1; 3374 } 3375 3376 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3377 if (iface == null) { 3378 return -1; 3379 } 3380 3381 // Get a v1.2 supplicant STA Interface 3382 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3383 getStaIfaceMockableV1_2(iface); 3384 3385 if (staIfaceV12 == null) { 3386 Log.e(TAG, methodStr + ": ISupplicantStaIface is null"); 3387 return -1; 3388 } 3389 3390 try { 3391 // Support for DPP (Easy connect) 3392 // Requires HAL v1.2 or higher 3393 staIfaceV12.addDppPeerUri(uri, 3394 (SupplicantStatus statusInternal, int bootstrapIdInternal) -> { 3395 status.value = statusInternal.code == SupplicantStatusCode.SUCCESS; 3396 if (status.value) { 3397 bootstrapId.value = bootstrapIdInternal; 3398 } 3399 checkStatusAndLogFailure(statusInternal, methodStr); 3400 }); 3401 } catch (RemoteException e) { 3402 handleRemoteException(e, methodStr); 3403 return -1; 3404 } 3405 3406 return bootstrapId.value; 3407 } 3408 3409 /** 3410 * Removes a DPP URI to the URI list given an ID. 3411 * 3412 * This is a v1.2+ HAL feature. 3413 * Returns true when operation is successful 3414 * On error, or if these features are not supported, false is returned. 3415 */ removeDppUri(@onNull String ifaceName, int bootstrapId)3416 public boolean removeDppUri(@NonNull String ifaceName, int bootstrapId) { 3417 final String methodStr = "removeDppUri"; 3418 3419 if (!isV1_2()) { 3420 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3421 return false; 3422 } 3423 3424 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3425 if (iface == null) { 3426 return false; 3427 } 3428 3429 // Get a v1.2 supplicant STA Interface 3430 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3431 getStaIfaceMockableV1_2(iface); 3432 3433 if (staIfaceV12 == null) { 3434 Log.e(TAG, methodStr + ": ISupplicantStaIface is null"); 3435 return false; 3436 } 3437 3438 try { 3439 // Support for DPP (Easy connect) 3440 // Requires HAL v1.2 or higher 3441 SupplicantStatus status = staIfaceV12.removeDppUri(bootstrapId); 3442 return checkStatusAndLogFailure(status, methodStr); 3443 } catch (RemoteException e) { 3444 handleRemoteException(e, methodStr); 3445 } 3446 3447 return false; 3448 } 3449 3450 /** 3451 * Stops/aborts DPP Initiator request 3452 * 3453 * This is a v1.2+ HAL feature. 3454 * Returns true when operation is successful 3455 * On error, or if these features are not supported, false is returned. 3456 */ stopDppInitiator(@onNull String ifaceName)3457 public boolean stopDppInitiator(@NonNull String ifaceName) { 3458 final String methodStr = "stopDppInitiator"; 3459 3460 if (!isV1_2()) { 3461 return false; 3462 } 3463 3464 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3465 if (iface == null) { 3466 return false; 3467 } 3468 3469 // Get a v1.2 supplicant STA Interface 3470 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3471 getStaIfaceMockableV1_2(iface); 3472 3473 if (staIfaceV12 == null) { 3474 Log.e(TAG, methodStr + ": ISupplicantStaIface is null"); 3475 return false; 3476 } 3477 3478 try { 3479 // Support for DPP (Easy connect) 3480 // Requires HAL v1.2 or higher 3481 SupplicantStatus status = staIfaceV12.stopDppInitiator(); 3482 return checkStatusAndLogFailure(status, methodStr); 3483 } catch (RemoteException e) { 3484 handleRemoteException(e, methodStr); 3485 } 3486 3487 return false; 3488 } 3489 3490 /** 3491 * Starts DPP Configurator-Initiator request 3492 * 3493 * This is a v1.2+ HAL feature. 3494 * Returns true when operation is successful 3495 * On error, or if these features are not supported, false is returned. 3496 */ startDppConfiguratorInitiator(@onNull String ifaceName, int peerBootstrapId, int ownBootstrapId, @NonNull String ssid, String password, String psk, int netRole, int securityAkm, byte[] privEckey)3497 public boolean startDppConfiguratorInitiator(@NonNull String ifaceName, int peerBootstrapId, 3498 int ownBootstrapId, @NonNull String ssid, String password, String psk, 3499 int netRole, int securityAkm, byte[] privEckey) { 3500 final String methodStr = "startDppConfiguratorInitiator"; 3501 3502 if (!isV1_2()) { 3503 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3504 return false; 3505 } 3506 3507 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3508 if (iface == null) { 3509 return false; 3510 } 3511 3512 // Get a v1.2 supplicant STA Interface 3513 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3514 getStaIfaceMockableV1_2(iface); 3515 3516 if (staIfaceV12 == null) { 3517 Log.e(TAG, methodStr + ": ISupplicantStaIface is null"); 3518 return false; 3519 } 3520 3521 try { 3522 // Support for DPP (Easy connect) 3523 // Requires HAL v1.2 or higher 3524 SupplicantStatus status = staIfaceV12.startDppConfiguratorInitiator(peerBootstrapId, 3525 ownBootstrapId, ssid, password != null ? password : "", psk != null ? psk : "", 3526 frameworkToHidlDppNetRole(netRole), frameworkToHidlDppAkm(securityAkm)); 3527 return checkStatusAndLogFailure(status, methodStr); 3528 } catch (RemoteException e) { 3529 handleRemoteException(e, methodStr); 3530 } 3531 3532 return false; 3533 } 3534 3535 /** 3536 * Starts DPP Enrollee-Initiator request 3537 * 3538 * This is a v1.2+ HAL feature. 3539 * Returns true when operation is successful 3540 * On error, or if these features are not supported, false is returned. 3541 */ startDppEnrolleeInitiator(@onNull String ifaceName, int peerBootstrapId, int ownBootstrapId)3542 public boolean startDppEnrolleeInitiator(@NonNull String ifaceName, int peerBootstrapId, 3543 int ownBootstrapId) { 3544 final String methodStr = "startDppEnrolleeInitiator"; 3545 3546 if (!isV1_2()) { 3547 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3548 return false; 3549 } 3550 3551 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3552 if (iface == null) { 3553 return false; 3554 } 3555 3556 // Get a v1.2 supplicant STA Interface 3557 android.hardware.wifi.supplicant.V1_2.ISupplicantStaIface staIfaceV12 = 3558 getStaIfaceMockableV1_2(iface); 3559 3560 if (staIfaceV12 == null) { 3561 Log.e(TAG, methodStr + ": ISupplicantStaIface is null"); 3562 return false; 3563 } 3564 3565 try { 3566 // Support for DPP (Easy connect) 3567 // Requires HAL v1.2 or higher 3568 SupplicantStatus status = staIfaceV12.startDppEnrolleeInitiator(peerBootstrapId, 3569 ownBootstrapId); 3570 return checkStatusAndLogFailure(status, methodStr); 3571 } catch (RemoteException e) { 3572 handleRemoteException(e, methodStr); 3573 } 3574 3575 return false; 3576 } 3577 3578 /** 3579 * Generate a DPP QR code based boot strap info 3580 * 3581 * This is a v1.4+ HAL feature. 3582 * Returns DppResponderBootstrapInfo; 3583 */ generateDppBootstrapInfoForResponder( @onNull String ifaceName, String macAddress, @NonNull String deviceInfo, int dppCurve)3584 public WifiNative.DppBootstrapQrCodeInfo generateDppBootstrapInfoForResponder( 3585 @NonNull String ifaceName, String macAddress, @NonNull String deviceInfo, 3586 int dppCurve) { 3587 final String methodStr = "generateDppBootstrapInfoForResponder"; 3588 Mutable<Boolean> status = new Mutable<>(false); 3589 WifiNative.DppBootstrapQrCodeInfo bootstrapInfoOut = 3590 new WifiNative.DppBootstrapQrCodeInfo(); 3591 3592 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3593 if (iface == null) { 3594 return bootstrapInfoOut; 3595 } 3596 3597 // Get a v1.4 supplicant STA Interface 3598 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 3599 getStaIfaceMockableV1_4(iface); 3600 3601 if (staIfaceV14 == null) { 3602 Log.e(TAG, methodStr + ": SupplicantStaIface V1.4 is null"); 3603 return bootstrapInfoOut; 3604 } 3605 3606 try { 3607 // Support for DPP Responder 3608 // Requires HAL v1.4 or higher 3609 staIfaceV14.generateDppBootstrapInfoForResponder( 3610 NativeUtil.macAddressToByteArray(macAddress), deviceInfo, 3611 frameworkToHidlDppCurve(dppCurve), 3612 (android.hardware.wifi.supplicant.V1_4.SupplicantStatus statusInternal, 3613 android.hardware.wifi.supplicant.V1_4 3614 .DppResponderBootstrapInfo info) -> { 3615 if (statusInternal.code == SupplicantStatusCode.SUCCESS) { 3616 bootstrapInfoOut.bootstrapId = info.bootstrapId; 3617 bootstrapInfoOut.listenChannel = info.listenChannel; 3618 bootstrapInfoOut.uri = info.uri; 3619 } 3620 checkStatusAndLogFailure(statusInternal, methodStr); 3621 }); 3622 } catch (RemoteException e) { 3623 handleRemoteException(e, methodStr); 3624 return bootstrapInfoOut; 3625 } 3626 3627 return bootstrapInfoOut; 3628 } 3629 3630 /** 3631 * Starts DPP Enrollee-Responder request 3632 * 3633 * This is a v1.4+ HAL feature. 3634 * Returns true when operation is successful 3635 * On error, or if these features are not supported, false is returned. 3636 */ startDppEnrolleeResponder(@onNull String ifaceName, int listenChannel)3637 public boolean startDppEnrolleeResponder(@NonNull String ifaceName, int listenChannel) { 3638 final String methodStr = "startDppEnrolleeResponder"; 3639 3640 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3641 if (iface == null) { 3642 return false; 3643 } 3644 3645 // Get a v1.4 supplicant STA Interface 3646 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 3647 getStaIfaceMockableV1_4(iface); 3648 3649 if (staIfaceV14 == null) { 3650 Log.e(TAG, methodStr + ": ISupplicantStaIface V1.4 is null"); 3651 return false; 3652 } 3653 3654 try { 3655 // Support for DPP Responder 3656 // Requires HAL v1.4 or higher 3657 android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = 3658 staIfaceV14.startDppEnrolleeResponder(listenChannel); 3659 return checkStatusAndLogFailure(status, methodStr); 3660 } catch (RemoteException e) { 3661 handleRemoteException(e, methodStr); 3662 } 3663 3664 return false; 3665 } 3666 3667 /** 3668 * Stops/aborts DPP Responder request. 3669 * 3670 * This is a v1.4+ HAL feature. 3671 * Returns true when operation is successful 3672 * On error, or if these features are not supported, false is returned. 3673 */ stopDppResponder(@onNull String ifaceName, int ownBootstrapId)3674 public boolean stopDppResponder(@NonNull String ifaceName, int ownBootstrapId) { 3675 final String methodStr = "stopDppResponder"; 3676 3677 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3678 if (iface == null) { 3679 return false; 3680 } 3681 3682 // Get a v1.4 supplicant STA Interface 3683 android.hardware.wifi.supplicant.V1_4.ISupplicantStaIface staIfaceV14 = 3684 getStaIfaceMockableV1_4(iface); 3685 3686 if (staIfaceV14 == null) { 3687 Log.e(TAG, methodStr + ": ISupplicantStaIface V1.4 is null"); 3688 return false; 3689 } 3690 3691 try { 3692 // Support for DPP Responder 3693 // Requires HAL v1.4 or higher 3694 android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = 3695 staIfaceV14.stopDppResponder(ownBootstrapId); 3696 return checkStatusAndLogFailure(status, methodStr); 3697 } catch (RemoteException e) { 3698 handleRemoteException(e, methodStr); 3699 } 3700 3701 return false; 3702 } 3703 3704 3705 /** 3706 * Register callbacks for DPP events. 3707 * 3708 * @param dppCallback DPP callback object. 3709 */ registerDppCallback(DppEventCallback dppCallback)3710 public void registerDppCallback(DppEventCallback dppCallback) { 3711 mDppCallback = dppCallback; 3712 } 3713 getDppCallback()3714 protected DppEventCallback getDppCallback() { 3715 return mDppCallback; 3716 } 3717 3718 /** 3719 * Set MBO cellular data availability. 3720 * 3721 * @param ifaceName Name of the interface. 3722 * @param available true means cellular data available, false otherwise. 3723 * @return None. 3724 */ setMboCellularDataStatus(@onNull String ifaceName, boolean available)3725 public boolean setMboCellularDataStatus(@NonNull String ifaceName, boolean available) { 3726 final String methodStr = "setMboCellularDataStatus"; 3727 3728 if (isV1_3()) { 3729 ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); 3730 if (iface == null) { 3731 return false; 3732 } 3733 3734 // Get a v1.3 supplicant STA Interface 3735 android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 = 3736 getStaIfaceMockableV1_3(iface); 3737 if (staIfaceV13 == null) { 3738 Log.e(TAG, methodStr 3739 + ": SupplicantStaIface is null, cannot update cell status"); 3740 return false; 3741 } 3742 3743 try { 3744 SupplicantStatus status = staIfaceV13.setMboCellularDataStatus(available); 3745 return checkStatusAndLogFailure(status, methodStr); 3746 } catch (RemoteException e) { 3747 handleRemoteException(e, methodStr); 3748 } 3749 } else { 3750 Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL"); 3751 return false; 3752 } 3753 3754 return false; 3755 } 3756 3757 /** 3758 * Check if we've roamed to a linked network and make the linked network the current network 3759 * if we have. 3760 * 3761 * @param ifaceName Name of the interface. 3762 * @param newNetworkId Network id of the new network we've roamed to. If fromFramework is 3763 * {@code true}, this will be a framework network id. Otherwise, this will 3764 * be a remote network id. 3765 * @param fromFramework {@code true} if the network id is a framework network id, {@code false} 3766 if the network id is a remote network id. 3767 * @return true if we've roamed to a linked network, false if not. 3768 */ updateOnLinkedNetworkRoaming( @onNull String ifaceName, int newNetworkId, boolean fromFramework)3769 public boolean updateOnLinkedNetworkRoaming( 3770 @NonNull String ifaceName, int newNetworkId, boolean fromFramework) { 3771 synchronized (mLock) { 3772 List<Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration>> linkedNetworkHandles = 3773 mLinkedNetworkLocalAndRemoteConfigs.get(ifaceName); 3774 SupplicantStaNetworkHalHidlImpl currentHandle = 3775 getCurrentNetworkRemoteHandle(ifaceName); 3776 WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName); 3777 if (linkedNetworkHandles == null || currentHandle == null || currentConfig == null) { 3778 return false; 3779 } 3780 if (fromFramework ? currentConfig.networkId == newNetworkId 3781 : currentHandle.getNetworkId() == newNetworkId) { 3782 return false; 3783 } 3784 for (Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration> pair 3785 : linkedNetworkHandles) { 3786 if (fromFramework ? pair.second.networkId == newNetworkId 3787 : pair.first.getNetworkId() == newNetworkId) { 3788 Log.i(TAG, "Roamed to linked network, " 3789 + "make linked network as current network"); 3790 mCurrentNetworkRemoteHandles.put(ifaceName, pair.first); 3791 mCurrentNetworkLocalConfigs.put(ifaceName, pair.second); 3792 return true; 3793 } 3794 } 3795 return false; 3796 } 3797 } 3798 3799 /** 3800 * Updates the linked networks for the current network and sends them to the supplicant. 3801 * 3802 * @param ifaceName Name of the interface. 3803 * @param networkId network id of the network to link the configurations to. 3804 * @param linkedConfigurations Map of config profile key to config for linking. 3805 * @return true if networks were successfully linked, false otherwise. 3806 */ updateLinkedNetworks(@onNull String ifaceName, int networkId, Map<String, WifiConfiguration> linkedConfigurations)3807 public boolean updateLinkedNetworks(@NonNull String ifaceName, int networkId, 3808 Map<String, WifiConfiguration> linkedConfigurations) { 3809 synchronized (mLock) { 3810 WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName); 3811 SupplicantStaNetworkHalHidlImpl currentHandle = 3812 getCurrentNetworkRemoteHandle(ifaceName); 3813 3814 if (currentConfig == null || currentHandle == null) { 3815 Log.e(TAG, "current network not configured yet."); 3816 return false; 3817 } 3818 3819 if (networkId != currentConfig.networkId) { 3820 Log.e(TAG, "current config network id is not matching"); 3821 return false; 3822 } 3823 3824 final int remoteNetworkId = currentHandle.getNetworkId(); 3825 if (remoteNetworkId == -1) { 3826 Log.e(TAG, "current handle getNetworkId failed"); 3827 return false; 3828 } 3829 3830 if (!removeAllNetworksExcept(ifaceName, remoteNetworkId)) { 3831 Log.e(TAG, "couldn't remove non-current supplicant networks"); 3832 return false; 3833 } 3834 3835 mLinkedNetworkLocalAndRemoteConfigs.remove(ifaceName); 3836 3837 if (linkedConfigurations == null || linkedConfigurations.size() == 0) { 3838 Log.i(TAG, "cleared linked networks"); 3839 return true; 3840 } 3841 3842 List<Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration>> linkedNetworkHandles = 3843 new ArrayList<>(); 3844 linkedNetworkHandles.add(new Pair(currentHandle, currentConfig)); 3845 for (String linkedNetwork : linkedConfigurations.keySet()) { 3846 Log.i(TAG, "add linked network: " + linkedNetwork); 3847 Pair<SupplicantStaNetworkHalHidlImpl, WifiConfiguration> pair = 3848 addNetworkAndSaveConfig(ifaceName, linkedConfigurations.get(linkedNetwork)); 3849 if (pair == null) { 3850 Log.e(TAG, "failed to add/save linked network: " + linkedNetwork); 3851 return false; 3852 } 3853 pair.first.enable(true); 3854 linkedNetworkHandles.add(pair); 3855 } 3856 3857 mLinkedNetworkLocalAndRemoteConfigs.put(ifaceName, linkedNetworkHandles); 3858 3859 return true; 3860 } 3861 } 3862 3863 /** 3864 * Remove all networks except the supplied network ID from supplicant 3865 * 3866 * @param ifaceName Name of the interface 3867 * @param networkId network id to keep 3868 */ removeAllNetworksExcept(@onNull String ifaceName, int networkId)3869 private boolean removeAllNetworksExcept(@NonNull String ifaceName, int networkId) { 3870 synchronized (mLock) { 3871 List<Integer> networks = listNetworks(ifaceName); 3872 if (networks == null) { 3873 Log.e(TAG, "removeAllNetworksExcept failed, got null networks"); 3874 return false; 3875 } 3876 for (int id : networks) { 3877 if (networkId == id) { 3878 continue; 3879 } 3880 if (!removeNetwork(ifaceName, id)) { 3881 Log.e(TAG, "removeAllNetworksExcept failed to remove network: " + id); 3882 return false; 3883 } 3884 } 3885 return true; 3886 } 3887 } 3888 3889 /** 3890 * Gets the security params of the current network associated with this interface 3891 * 3892 * @param ifaceName Name of the interface 3893 * @return Security params of the current network associated with the interface 3894 */ getCurrentNetworkSecurityParams(@onNull String ifaceName)3895 public SecurityParams getCurrentNetworkSecurityParams(@NonNull String ifaceName) { 3896 WifiConfiguration currentConfig = getCurrentNetworkLocalConfig(ifaceName); 3897 3898 if (currentConfig == null) { 3899 return null; 3900 } 3901 3902 return currentConfig.getNetworkSelectionStatus().getCandidateSecurityParams(); 3903 } 3904 3905 /** 3906 * Set whether the network-centric QoS policy feature is enabled or not for this interface. 3907 * 3908 * @param ifaceName name of the interface. 3909 * @param isEnabled true if feature is enabled, false otherwise. 3910 * @return true without action since this is not a supported feature. 3911 */ setNetworkCentricQosPolicyFeatureEnabled(@onNull String ifaceName, boolean isEnabled)3912 public boolean setNetworkCentricQosPolicyFeatureEnabled(@NonNull String ifaceName, 3913 boolean isEnabled) { 3914 return false; 3915 } 3916 3917 /** 3918 * Sends a QoS policy response. 3919 * 3920 * @param ifaceName Name of the interface. 3921 * @param qosPolicyRequestId Dialog token to identify the request. 3922 * @param morePolicies Flag to indicate more QoS policies can be accommodated. 3923 * @param qosPolicyStatusList List of framework QosPolicyStatus objects. 3924 * @return true if response is sent successfully, false otherwise. 3925 */ sendQosPolicyResponse(String ifaceName, int qosPolicyRequestId, boolean morePolicies, @NonNull List<SupplicantStaIfaceHal.QosPolicyStatus> qosPolicyStatusList)3926 public boolean sendQosPolicyResponse(String ifaceName, int qosPolicyRequestId, 3927 boolean morePolicies, 3928 @NonNull List<SupplicantStaIfaceHal.QosPolicyStatus> qosPolicyStatusList) { 3929 Log.e(TAG, "sendQosPolicyResponse is not supported by the HIDL HAL"); 3930 return false; 3931 } 3932 3933 /** 3934 * Indicates the removal of all active QoS policies configured by the AP. 3935 * 3936 * @param ifaceName Name of the interface. 3937 */ removeAllQosPolicies(String ifaceName)3938 public boolean removeAllQosPolicies(String ifaceName) { 3939 Log.e(TAG, "removeAllQosPolicies is not supported by the HIDL HAL"); 3940 return false; 3941 } 3942 3943 /** 3944 * Generate DPP credential for network access 3945 * 3946 * @param ifaceName Name of the interface. 3947 * @param ssid ssid of the network 3948 * @param privEcKey Private EC Key for DPP Configurator 3949 * Returns false. Not Supported throuh HIDL 3950 */ generateSelfDppConfiguration(@onNull String ifaceName, @NonNull String ssid, byte[] privEcKey)3951 public boolean generateSelfDppConfiguration(@NonNull String ifaceName, @NonNull String ssid, 3952 byte[] privEcKey) { 3953 Log.d(TAG, "generateSelfDppConfiguration is not supported"); 3954 return false; 3955 } 3956 3957 /** 3958 * Set the currently configured network's anonymous identity. 3959 * 3960 * @param ifaceName Name of the interface. 3961 * @param anonymousIdentity the anonymouns identity. 3962 * @return true if succeeds, false otherwise. 3963 */ setEapAnonymousIdentity(@onNull String ifaceName, String anonymousIdentity)3964 public boolean setEapAnonymousIdentity(@NonNull String ifaceName, String anonymousIdentity) { 3965 synchronized (mLock) { 3966 SupplicantStaNetworkHalHidlImpl networkHandle = 3967 checkSupplicantStaNetworkAndLogFailure(ifaceName, "setEapAnonymousIdentity"); 3968 if (networkHandle == null) return false; 3969 try { 3970 return networkHandle.setEapAnonymousIdentity( 3971 NativeUtil.stringToByteArrayList(anonymousIdentity)); 3972 } catch (IllegalArgumentException ex) { 3973 return false; 3974 } 3975 } 3976 } 3977 } 3978