SupplicantStaIfaceHal.java revision f180b0109b3fce79609b03ae2f7fbeff02d96b80
1240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/* 298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Copyright (C) 2017 The Android Open Source Project 3240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * 4240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Licensed under the Apache License, Version 2.0 (the "License"); 5240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * you may not use this file except in compliance with the License. 6240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * You may obtain a copy of the License at 7240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * 8240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * http://www.apache.org/licenses/LICENSE-2.0 9240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * 10240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Unless required by applicable law or agreed to in writing, software 11240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * distributed under the License is distributed on an "AS IS" BASIS, 12240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * See the License for the specific language governing permissions and 14240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * limitations under the License. 15240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */ 16240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhnepackage com.android.server.wifi; 17240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 18240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicant; 19240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantIface; 2096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantNetwork; 21240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaIface; 2296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; 23240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.IfaceType; 24240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatus; 25240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; 26240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceManager; 27240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.hidl.manager.V1_0.IServiceNotification; 28f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.net.IpConfiguration; 2966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhneimport android.net.wifi.WifiConfiguration; 308c6d09c03532b3936fab2fed6f8b84c895333565Roshan Piusimport android.os.HandlerThread; 31240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.os.RemoteException; 32240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport android.util.Log; 3396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhneimport android.util.MutableBoolean; 34f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport android.util.SparseArray; 3596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 36d95fa596d07855b70ff18a50a48e773155a919f5Roshan Piusimport com.android.server.wifi.util.NativeUtil; 37240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 38240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhneimport java.util.ArrayList; 39f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.HashMap; 40f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.List; 41f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Piusimport java.util.Map; 42d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 43240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne/** 44240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * Hal calls for bring up/shut down of the supplicant daemon and for 45240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * sending requests to the supplicant daemon 46240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */ 47b4419d876beda78c29836726e43d80203b4a656cRoshan Piuspublic class SupplicantStaIfaceHal { 4896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** Invalid Supplicant Iface type */ 4996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne public static final int INVALID_IFACE_TYPE = -1; 50240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne private static final boolean DBG = false; 51b4419d876beda78c29836726e43d80203b4a656cRoshan Pius private static final String TAG = "SupplicantStaIfaceHal"; 5298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private static final String SERVICE_MANAGER_NAME = "manager"; 5398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private IServiceManager mIServiceManager = null; 5498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne // Supplicant HAL interface objects 5598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private ISupplicant mISupplicant; 5698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private ISupplicantStaIface mISupplicantStaIface; 57240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne private final Object mLock = new Object(); 5898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private final HandlerThread mHandlerThread; 59b4419d876beda78c29836726e43d80203b4a656cRoshan Pius public SupplicantStaIfaceHal(HandlerThread handlerThread) { 6098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mHandlerThread = handlerThread; 618c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius } 62240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 63240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne /** 6498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Registers a service notification for the ISupplicant service, which triggers intialization of 6598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * the ISupplicantStaIface 66240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne * @return true if the service notification was successfully registered 67240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne */ 68240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne public boolean initialize() { 6998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (DBG) Log.i(TAG, "Registering ISupplicant service ready callback."); 70240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne synchronized (mLock) { 7198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicant = null; 7298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicantStaIface = null; 7398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (mIServiceManager != null) { 7498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne // Already have an IServiceManager and serviceNotification registered, don't 7598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne // don't register another. 7698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return true; 7798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } 78240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne try { 7998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mIServiceManager = getServiceManagerMockable(); 8098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (mIServiceManager == null) { 81240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Failed to get HIDL Service Manager"); 82240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 83240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 8498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (!mIServiceManager.linkToDeath(cookie -> { 85240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.wtf(TAG, "IServiceManager died: cookie=" + cookie); 86240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne synchronized (mLock) { 87240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne supplicantServiceDiedHandler(); 8898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mIServiceManager = null; // Will need to register a new ServiceNotification 89240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 90240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne }, 0)) { 91240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.wtf(TAG, "Error on linkToDeath on IServiceManager"); 92240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne supplicantServiceDiedHandler(); 9398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mIServiceManager = null; // Will need to register a new ServiceNotification 94240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 95240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 96240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne IServiceNotification serviceNotificationCb = new IServiceNotification.Stub() { 97240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne public void onRegistration(String fqName, String name, boolean preexisting) { 9898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne synchronized (mLock) { 9998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (DBG) { 10098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne Log.i(TAG, "IServiceNotification.onRegistration for: " + fqName 10198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne + ", " + name + " preexisting=" + preexisting); 10298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } 10398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (!initSupplicantService() || !initSupplicantStaIface()) { 10498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne Log.e(TAG, "initalizing ISupplicantIfaces failed."); 10598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne supplicantServiceDiedHandler(); 10698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } else { 10798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne Log.i(TAG, "Completed initialization of ISupplicant interfaces."); 10898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } 109240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 110240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 111240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne }; 112240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne /* TODO(b/33639391) : Use the new ISupplicant.registerForNotifications() once it 113240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne exists */ 11498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (!mIServiceManager.registerForNotifications(ISupplicant.kInterfaceName, 115240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne "", serviceNotificationCb)) { 116240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Failed to register for notifications to " 117240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne + ISupplicant.kInterfaceName); 11898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mIServiceManager = null; // Will need to register a new ServiceNotification 119240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 120240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 121240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } catch (RemoteException e) { 122240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Exception while trying to register a listener for ISupplicant service: " 123240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne + e); 12498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne supplicantServiceDiedHandler(); 125240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 126240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return true; 127240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 128240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 129240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 13098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private boolean initSupplicantService() { 131240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne synchronized (mLock) { 132240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne try { 13398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicant = getSupplicantMockable(); 134240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } catch (RemoteException e) { 135240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "ISupplicant.getService exception: " + e); 136240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 137240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 13898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (mISupplicant == null) { 139240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Got null ISupplicant service. Stopping supplicant HIDL startup"); 140240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 141240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 142240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 143240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return true; 144240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 145240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 14698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private boolean initSupplicantStaIface() { 147240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne synchronized (mLock) { 148240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne /** List all supplicant Ifaces */ 149240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne final ArrayList<ISupplicant.IfaceInfo> supplicantIfaces = new ArrayList<>(); 150240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne try { 15198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicant.listInterfaces((SupplicantStatus status, 152240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne ArrayList<ISupplicant.IfaceInfo> ifaces) -> { 153240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne if (status.code != SupplicantStatusCode.SUCCESS) { 154240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Getting Supplicant Interfaces failed: " + status.code); 155240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return; 156240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 157240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne supplicantIfaces.addAll(ifaces); 158240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne }); 159240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } catch (RemoteException e) { 160240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "ISupplicant.listInterfaces exception: " + e); 16198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return false; 162240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 163240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne if (supplicantIfaces.size() == 0) { 164240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Got zero HIDL supplicant ifaces. Stopping supplicant HIDL startup."); 16598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return false; 166240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 167240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Mutable<ISupplicantIface> supplicantIface = new Mutable<>(); 168240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne for (ISupplicant.IfaceInfo ifaceInfo : supplicantIfaces) { 16998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (ifaceInfo.type == IfaceType.STA) { 170240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne try { 17198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicant.getInterface(ifaceInfo, 172240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne (SupplicantStatus status, ISupplicantIface iface) -> { 173240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne if (status.code != SupplicantStatusCode.SUCCESS) { 174240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "Failed to get ISupplicantIface " + status.code); 175240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return; 176240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 177240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne supplicantIface.value = iface; 178240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne }); 179240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } catch (RemoteException e) { 180240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Log.e(TAG, "ISupplicant.getInterface exception: " + e); 18198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return false; 182240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 183240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne break; 184240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 185240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 18698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne if (supplicantIface.value == null) { 18798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne Log.e(TAG, "initSupplicantStaIface got null iface"); 188240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return false; 189240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 19098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicantStaIface = getStaIfaceMockable(supplicantIface.value); 191240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne return true; 192240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 193240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 194240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 19598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne private void supplicantServiceDiedHandler() { 196240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne synchronized (mLock) { 19798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicant = null; 19898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne mISupplicantStaIface = null; 199240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 200240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 201240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 20298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne /** 20398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Signals whether Initialization completed successfully. Only necessary for testing, is not 20498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * needed to guard calls etc. 20598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne */ 20698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne public boolean isInitializationComplete() { 20798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return mISupplicantStaIface != null; 2088c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius } 2098c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius 2108c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius /** 21198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne * Wrapper functions to access static HAL methods, created to be mockable in unit tests 2128c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius */ 21398152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne protected IServiceManager getServiceManagerMockable() throws RemoteException { 21498152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return IServiceManager.getService(SERVICE_MANAGER_NAME); 21598152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } 21698152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne 21798152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne protected ISupplicant getSupplicantMockable() throws RemoteException { 21898152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return ISupplicant.getService(); 21998152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne } 22098152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne 22198152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne protected ISupplicantStaIface getStaIfaceMockable(ISupplicantIface iface) { 22298152bd4a4e36ea2097abd474248a4c7884f55b5Glen Kuhne return ISupplicantStaIface.asInterface(iface.asBinder()); 2238c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius } 2248c6d09c03532b3936fab2fed6f8b84c895333565Roshan Pius 22596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 22666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne * Add a network configuration to wpa_supplicant, via HAL 227d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 22866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne * @param config Config corresponding to the network. 22966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne * @return SupplicantStaNetwork of the added network in wpa_supplicant. 23066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne */ 231d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius private SupplicantStaNetworkHal addNetwork(WifiConfiguration config) { 23266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne logi("addSupplicantStaNetwork via HIDL"); 23366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (config == null) { 23466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne loge("Cannot add NULL network!"); 23566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return null; 23666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 23766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne SupplicantStaNetworkHal network = addNetwork(); 23866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (network == null) { 23966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne loge("Failed to add a network!"); 24066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return null; 24166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 24266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (network.saveWifiConfiguration(config)) { 24366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return network; 24466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } else { 24566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne loge("Failed to save variables for: " + config.configKey()); 24666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return null; 24766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 24866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 24966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 25066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne /** 251d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Initiate connection to the provided network. 252d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 253d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param config Config corresponding to the network. 254d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param shouldDisconnect Whether to trigger a disconnect first. 255d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 25666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne */ 257d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean connectToNetwork(WifiConfiguration config, boolean shouldDisconnect) { 258d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius logd("connectToNetwork " + config.configKey() 25966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne + " (shouldDisconnect " + shouldDisconnect + ")"); 26066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (shouldDisconnect && !disconnect()) { 26166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne loge("Failed to trigger disconnect"); 26266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 26366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 26466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (!removeAllNetworks()) { 26566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne loge("Failed to remove existing networks"); 26666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 26766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 268d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius SupplicantStaNetworkHal network = addNetwork(config); 26966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (network == null) { 270d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius loge("Failed to add/save network configuration: " + config.configKey()); 27166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 27266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 27366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (!network.select()) { 274d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius loge("Failed to select network configuration: " + config.configKey()); 27566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 27666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 27766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return true; 27866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 27966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 28066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne /** 281f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * Load all the configured networks from wpa_supplicant. 282f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * 283f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @param configs Map of configuration key to configuration objects corresponding to all 284f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * the networks. 285f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf 286f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @return true if succeeds, false otherwise. 287f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius */ 288f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius public boolean loadNetworks(Map<String, WifiConfiguration> configs, 289f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius SparseArray<Map<String, String>> networkExtras) { 290f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius List<Integer> networkIds = listNetworks(); 291f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius if (networkIds == null) { 292f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius Log.e(TAG, "Failed to list networks"); 293f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return false; 294f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 295f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius for (Integer networkId : networkIds) { 296f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius SupplicantStaNetworkHal network = getNetwork(networkId); 297f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius if (network == null) { 298f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius Log.e(TAG, "Failed to get network with ID: " + networkId); 299f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return false; 300f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 301f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius WifiConfiguration config = new WifiConfiguration(); 302f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius Map<String, String> networkExtra = new HashMap<>(); 303f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius if (!network.loadWifiConfiguration(config, networkExtra)) { 304f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius Log.e(TAG, "Failed to load wifi configuration for network with ID: " + networkId); 305f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return false; 306f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 307f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius // Set the default IP assignments. 308f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius config.setIpAssignment(IpConfiguration.IpAssignment.DHCP); 309f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius config.setProxySettings(IpConfiguration.ProxySettings.NONE); 310f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius 311f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius networkExtras.put(networkId, networkExtra); 312f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius String configKey = networkExtra.get(SupplicantStaNetworkHal.ID_STRING_KEY_CONFIG_KEY); 313f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius final WifiConfiguration duplicateConfig = configs.put(configKey, config); 314f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius if (duplicateConfig != null) { 315f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius // The network is already known. Overwrite the duplicate entry. 316f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius Log.i(TAG, "Replacing duplicate network: " + duplicateConfig.networkId); 317f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius removeNetwork(duplicateConfig.networkId); 318f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius networkExtras.remove(duplicateConfig.networkId); 319f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 320f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 321f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return true; 322f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 323f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius 324f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius /** 32566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne * Remove all networks from supplicant 32666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne */ 32766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne public boolean removeAllNetworks() { 32866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne synchronized (mLock) { 32966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne ArrayList<Integer> networks = listNetworks(); 33066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (networks == null) { 33166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne Log.e(TAG, "removeAllNetworks failed, got null networks"); 33266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 33366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 33466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne for (int id : networks) { 33566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne if (!removeNetwork(id)) { 33666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne Log.e(TAG, "removeAllNetworks failed to remove network: " + id); 33766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return false; 33866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 33966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 34066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 34166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne return true; 34266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 34366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 34466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne /** 345d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Gets the interface name. 346d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 34796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * @return returns the name of Iface or null if the call fails 34896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 34996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private String getName() { 35096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 35196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne MutableBoolean statusSuccess = new MutableBoolean(false); 35296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "getName"; 35396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 35496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null; 35596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final StringBuilder builder = new StringBuilder(); 35696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 35796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.getName((SupplicantStatus status, String name) -> { 35896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS; 35996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!statusSuccess.value) { 36096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + status.debugMessage); 36196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 36296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne builder.append(name); 36396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 36496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne }); 36596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 36696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e); 36796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 36896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 36996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (statusSuccess.value) { 37096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return builder.toString(); 37196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 37296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return null; 37396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 37496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 37596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 376d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 37796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 378d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Adds a new network. 379d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 38096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * @return The ISupplicantNetwork object for the new network, or null if the call fails 38196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 38296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private SupplicantStaNetworkHal addNetwork() { 38396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 38496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne MutableBoolean statusSuccess = new MutableBoolean(false); 38596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Mutable<ISupplicantNetwork> newNetwork = new Mutable<>(); 38696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "addNetwork"; 38796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 38896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null; 38996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 39096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.addNetwork((SupplicantStatus status, 39196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne ISupplicantNetwork network) -> { 39296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS; 39396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!statusSuccess.value) { 39496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + status.debugMessage); 39596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 39696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne newNetwork.value = network; 39796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 39896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne }); 39996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 40096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e); 40196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 40296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 40396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (statusSuccess.value) { 404f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return getStaNetworkMockable(ISupplicantStaNetwork.asInterface( 40566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne newNetwork.value.asBinder()), mHandlerThread); 40696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 40796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return null; 40896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 40996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 41096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 411d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 41296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 41396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * Remove network from supplicant with network Id 414d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 415d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 41696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 41796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean removeNetwork(int id) { 41896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 41996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "removeNetwork"; 42096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 42196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 42296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 42396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.removeNetwork(id); 42496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 42596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 42696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 42796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 42896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 42996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 43096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 43196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 432d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 43396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 434f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * Use this to mock the creation of SupplicantStaNetworkHal instance. 435f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * 436f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @param iSupplicantStaNetwork ISupplicantStaNetwork instance retrieved from HIDL. 437f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @param handlerThread Handler thread to send notifications to. 438f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if 439f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius * the call fails 440f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius */ 441f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius protected SupplicantStaNetworkHal getStaNetworkMockable( 442f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius ISupplicantStaNetwork iSupplicantStaNetwork, HandlerThread handlerThread) { 443f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return new SupplicantStaNetworkHal(iSupplicantStaNetwork, handlerThread); 444f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius } 445f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius 446f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius /** 44796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * @return The ISupplicantNetwork object for the given SupplicantNetworkId int, returns null if 44896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * the call fails 44996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 45096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private SupplicantStaNetworkHal getNetwork(int id) { 45196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 45296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne MutableBoolean statusSuccess = new MutableBoolean(false); 45396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Mutable<ISupplicantNetwork> gotNetwork = new Mutable<>(); 45496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "getNetwork"; 45596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 45696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null; 45796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 45896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.getNetwork(id, (SupplicantStatus status, 45996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne ISupplicantNetwork network) -> { 46096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS; 46196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!statusSuccess.value) { 46296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + status.debugMessage); 46396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 46496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne gotNetwork.value = network; 46596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 46696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne }); 46796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 46896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e); 46996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 47096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 47196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (statusSuccess.value) { 472f180b0109b3fce79609b03ae2f7fbeff02d96b80Roshan Pius return getStaNetworkMockable(ISupplicantStaNetwork.asInterface( 47366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne gotNetwork.value.asBinder()), mHandlerThread); 47496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 47596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return null; 47696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 47796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 47896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 47996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 48096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 48196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * @return a list of SupplicantNetworkID ints for all networks controlled by supplicant, returns 48296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * null if the call fails 48396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 48496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private java.util.ArrayList<Integer> listNetworks() { 48596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 48696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne MutableBoolean statusSuccess = new MutableBoolean(false); 48796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Mutable<ArrayList<Integer>> networkIdList = new Mutable<>(); 48896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "listNetworks"; 48996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 49096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null; 49196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 49296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.listNetworks((SupplicantStatus status, 49396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne java.util.ArrayList<Integer> networkIds) -> { 49496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS; 49596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!statusSuccess.value) { 49696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + status.debugMessage); 49796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 49896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne networkIdList.value = networkIds; 49996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 50096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne }); 50196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 50296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e); 50396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 50496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 50596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (statusSuccess.value) { 50696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return networkIdList.value; 50796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 50896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return null; 50996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 51096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 51196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 512d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 513d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 514d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Trigger a reassociation even if the iface is currently connected. 515d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 516d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 517d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 518d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean reassociate() { 51996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 52096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "reassociate"; 52196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 52296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 52396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 52496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.reassociate(); 52596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 52696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 52796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 52896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 52996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 53096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 53196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 53296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 533d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 534d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 535d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Trigger a reconnection if the iface is disconnected. 536d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 537d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 538d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 539d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean reconnect() { 54096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 54196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "reconnect"; 54296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 54396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 54496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 54596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.reconnect(); 54696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 54796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 54896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 54996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 55096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 55196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 55296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 55396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 554d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 555d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 556d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Trigger a disconnection from the currently connected network. 557d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 558d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 559d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 560d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean disconnect() { 56196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 56296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "disconnect"; 56396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 56496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 56596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 56696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.disconnect(); 56796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 56896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 56996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 57096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 57196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 57296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 57396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 57496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 575d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 576d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 577d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Enable or disable power save mode. 578d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 579d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param enable true to enable, false to disable. 580d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 581d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 582d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean setPowerSave(boolean enable) { 58396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 58496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "setPowerSave"; 58596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 58696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 58796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 58896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.setPowerSave(enable); 58996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 59096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 59196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 59296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 59396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 59496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 59596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 59696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 597d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 598d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 599d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Initiate TDLS discover with the specified AP. 600d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 601d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param macAddress MAC Address of the AP. 602d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 603d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 604d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean initiateTdlsDiscover(String macAddress) { 605d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return initiateTdlsDiscover(NativeUtil.macAddressToByteArray(macAddress)); 606d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 607b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 60896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean initiateTdlsDiscover(byte[/* 6 */] macAddress) { 60996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 61096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "initiateTdlsDiscover"; 61196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 61296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 61396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 61496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.initiateTdlsDiscover(macAddress); 61596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 61696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 61796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 61896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 61996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 62096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 62196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 62296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 623d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 624d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 625d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Initiate TDLS setup with the specified AP. 626d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 627d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param macAddress MAC Address of the AP. 628d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 629d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 630d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean initiateTdlsSetup(String macAddress) { 631d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return initiateTdlsSetup(NativeUtil.macAddressToByteArray(macAddress)); 632d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 633b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 63496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean initiateTdlsSetup(byte[/* 6 */] macAddress) { 63596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 63696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "initiateTdlsSetup"; 63796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 63896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 63996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 64096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.initiateTdlsSetup(macAddress); 64196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 64296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 64396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 64496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 64596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 64696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 64796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 64896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 649d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 650d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 651d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Initiate TDLS teardown with the specified AP. 652d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param macAddress MAC Address of the AP. 653d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 654d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 655d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean initiateTdlsTeardown(String macAddress) { 656d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return initiateTdlsTeardown(NativeUtil.macAddressToByteArray(macAddress)); 657d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 658d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 659b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 66096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean initiateTdlsTeardown(byte[/* 6 */] macAddress) { 66196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 66296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "initiateTdlsTeardown"; 66396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 66496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 66596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 66696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.initiateTdlsTeardown(macAddress); 66796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 66896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 66996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 67096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 67196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 67296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 67396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 67496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 675d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 676d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 677d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Request the specified ANQP elements |elements| from the specified AP |bssid|. 678d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 679d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param bssid BSSID of the AP 680d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param infoElements ANQP elements to be queried. Refer to ISupplicantStaIface.AnqpInfoId. 681d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param hs20SubTypes HS subtypes to be queried. Refer to ISupplicantStaIface.Hs20AnqpSubTypes. 682d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 683d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 684d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean initiateAnqpQuery(String bssid, ArrayList<Short> infoElements, 685d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius ArrayList<Integer> hs20SubTypes) { 686d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return initiateAnqpQuery( 687d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius NativeUtil.macAddressToByteArray(bssid), infoElements, hs20SubTypes); 688d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 689d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 690b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 69196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean initiateAnqpQuery(byte[/* 6 */] macAddress, 69296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne java.util.ArrayList<Short> infoElements, java.util.ArrayList<Integer> subTypes) { 69396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 69496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "initiateAnqpQuery"; 69596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 69696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 69796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 69896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.initiateAnqpQuery(macAddress, 69996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne infoElements, subTypes); 70096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 70196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 70296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 70396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 70496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 70596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 70696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 70796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 708d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 709d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 710d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Request the specified ANQP ICON from the specified AP |bssid|. 711d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 712d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param bssid BSSID of the AP 713d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param fileName Name of the file to request. 714d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 715d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 716d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean initiateHs20IconQuery(String bssid, String fileName) { 717d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return initiateHs20IconQuery(NativeUtil.macAddressToByteArray(bssid), fileName); 718d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 719d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 720b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 72196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean initiateHs20IconQuery(byte[/* 6 */] macAddress, String fileName) { 72296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 72396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "initiateHs20IconQuery"; 72496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 72596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 72696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 72796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.initiateHs20IconQuery(macAddress, 72896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne fileName); 72996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 73096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 73196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 73296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 73396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 73496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 73596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 73696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 737d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 73896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 73996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * Makes a callback to HIDL to getMacAddress from supplicant 740d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 74196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * @return string containing the MAC address, or null on a failed call 74296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 743d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public String getMacAddress() { 74496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 74596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne MutableBoolean statusSuccess = new MutableBoolean(false); 74696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "getMacAddress"; 74796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 74896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return null; 74996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Mutable<String> gotMac = new Mutable<>(); 75096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 75196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.getMacAddress((SupplicantStatus status, 75296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne byte[/* 6 */] macAddr) -> { 75396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne statusSuccess.value = status.code == SupplicantStatusCode.SUCCESS; 75496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!statusSuccess.value) { 75596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + status.debugMessage); 75696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 757d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius gotMac.value = NativeUtil.macAddressFromByteArray(macAddr); 75896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 75996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne }); 76096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 76196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception: " + e); 76296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 76396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 76496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (statusSuccess.value) { 76596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return gotMac.value; 76696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } else { 76796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return null; 76896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 76996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 77096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 771d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 772d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 773d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Start using the added RX filters. 774d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 775d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 776d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 777d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean startRxFilter() { 77896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 77996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "startRxFilter"; 78096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 78196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 78296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 78396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.startRxFilter(); 78496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 78596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 78696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 78796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 78896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 78996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 79096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 79196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 792d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 793d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 794d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Stop using the added RX filters. 795d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 796d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 797d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 798d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean stopRxFilter() { 79996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 80096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "stopRxFilter"; 80196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 80296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 80396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 80496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.stopRxFilter(); 80596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 80696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 80796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 80896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 80996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 81096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 81196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 81296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 813d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 814d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public static final byte RX_FILTER_TYPE_V4_MULTICAST = 815d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius ISupplicantStaIface.RxFilterType.V6_MULTICAST; 816d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public static final byte RX_FILTER_TYPE_V6_MULTICAST = 817d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius ISupplicantStaIface.RxFilterType.V6_MULTICAST; 818d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 819d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Add an RX filter. 820d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 821d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or 822d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * {@link #RX_FILTER_TYPE_V6_MULTICAST} values. 823d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 824d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 82596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean addRxFilter(byte type) { 82696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 82796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "addRxFilter"; 82896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 82996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 83096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 83196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.addRxFilter(type); 83296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 83396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 83496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 83596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 83696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 83796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 83896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 83996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 840d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 841d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 842d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Remove an RX filter. 843d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 844d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param type one of {@link #RX_FILTER_TYPE_V4_MULTICAST} or 845d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * {@link #RX_FILTER_TYPE_V6_MULTICAST} values. 846d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 847d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 84896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean removeRxFilter(byte type) { 84996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 85096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "removeRxFilter"; 85196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 85296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 85396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 85496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.removeRxFilter(type); 85596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 85696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 85796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 85896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 85996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 86096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 86196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 86296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 863d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 864d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public static final byte BT_COEX_MODE_ENABLED = ISupplicantStaIface.BtCoexistenceMode.ENABLED; 865d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public static final byte BT_COEX_MODE_DISABLED = ISupplicantStaIface.BtCoexistenceMode.DISABLED; 866d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public static final byte BT_COEX_MODE_SENSE = ISupplicantStaIface.BtCoexistenceMode.SENSE; 867d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 868d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Set Bt co existense mode. 869d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 870d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param mode one of the above {@link #BT_COEX_MODE_ENABLED}, {@link #BT_COEX_MODE_DISABLED} 871d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * or {@link #BT_COEX_MODE_SENSE} values. 872d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 873d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 874d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean setBtCoexistenceMode(byte mode) { 87596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 87696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "setBtCoexistenceMode"; 87796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 87896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 87996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 88096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.setBtCoexistenceMode(mode); 88196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 88296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 88396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 88496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 88596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 88696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 88796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 88896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 889d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 890d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** Enable or disable BT coexistence mode. 891d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 892d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param enable true to enable, false to disable. 893d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 894d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 895d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean setBtCoexistenceScanModeEnabled(boolean enable) { 89696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 89796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "setBtCoexistenceScanModeEnabled"; 89896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 89996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 90096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 90196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = 90296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne mISupplicantStaIface.setBtCoexistenceScanModeEnabled(enable); 90396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 90496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 90596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 90696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 90796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 90896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 90996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 91096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 911d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 912d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 913d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Enable or disable suspend mode optimizations. 914d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 915d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param enable true to enable, false otherwise. 916d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 917d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean setSuspendModeEnabled(boolean enable) { 91896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 91996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "setSuspendModeEnabled"; 92096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 92196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 92296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 92396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.setSuspendModeEnabled(enable); 92496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 92596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 92696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 92796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 92896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 92996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 93096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 93196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 932d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 933d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius /** 934d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * Set country code. 935d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * 936d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @param codeStr 2 byte ASCII string. For ex: US, CA. 937d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius * @return true if request is sent successfully, false otherwise. 938d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius */ 939d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius public boolean setCountryCode(String codeStr) { 940d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius return setCountryCode(NativeUtil.stringToByteArray(codeStr)); 941d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius } 942d95fa596d07855b70ff18a50a48e773155a919f5Roshan Pius 943b4419d876beda78c29836726e43d80203b4a656cRoshan Pius /** See ISupplicantStaIface.hal for documentation */ 94496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean setCountryCode(byte[/* 2 */] code) { 94596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne synchronized (mLock) { 94696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr = "setCountryCode"; 94796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 94896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (!checkSupplicantStaIfaceAndLogFailure(methodStr)) return false; 94996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne try { 95096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne SupplicantStatus status = mISupplicantStaIface.setCountryCode(code); 95196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return checkStatusAndLogFailure(status, methodStr); 95296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } catch (RemoteException e) { 95396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "ISupplicantStaIface." + methodStr + ": exception:" + e); 95496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne supplicantServiceDiedHandler(); 95596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 95696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 95796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 95896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 95996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 96096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 96196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * Returns false if SupplicantStaIface is null, and logs failure to call methodStr 96296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 96396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private boolean checkSupplicantStaIfaceAndLogFailure(final String methodStr) { 96496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 96596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (mISupplicantStaIface == null) { 96696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaIface is null"); 96796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 96896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 96996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return true; 97096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 97196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 97296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 97396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * Returns true if provided status code is SUCCESS, logs debug message and returns false 97496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * otherwise 97596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 97696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne private static boolean checkStatusAndLogFailure(SupplicantStatus status, 97796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne final String methodStr) { 97896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (DBG) Log.i(TAG, methodStr); 97996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne if (status.code != SupplicantStatusCode.SUCCESS) { 98096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne Log.e(TAG, methodStr + " failed: " + supplicantStatusCodeToString(status.code) + ", " 98196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne + status.debugMessage); 98296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return false; 98396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 98496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return true; 98596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 98696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 98796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne /** 98896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * Converts SupplicantStatus code values to strings for debug logging 98996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne * TODO(b/34811152) Remove this, or make it more break resistance 99096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne */ 99196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne public static String supplicantStatusCodeToString(int code) { 99296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne switch (code) { 99396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 0: 99496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "SUCCESS"; 99596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 1: 99696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_UNKNOWN"; 99796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 2: 99896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_ARGS_INVALID"; 99996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 3: 100096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_IFACE_INVALID"; 100196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 4: 100296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_IFACE_UNKNOWN"; 100396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 5: 100496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_IFACE_EXISTS"; 100596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 6: 100696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_IFACE_DISABLED"; 100796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 7: 100896013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_IFACE_NOT_DISCONNECTED"; 100996013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 8: 101096013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_NETWORK_INVALID"; 101196013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne case 9: 101296013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "FAILURE_NETWORK_UNKNOWN"; 101396013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne default: 101496013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne return "??? UNKNOWN_CODE"; 101596013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 101696013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne } 101796013ebe01c095e2bac5ff7a490a2f9b69876e3cGlen Kuhne 1018240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne private static class Mutable<E> { 1019240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne public E value; 1020240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 1021240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Mutable() { 1022240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne value = null; 1023240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 1024240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne 1025240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne Mutable(E value) { 1026240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne this.value = value; 1027240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 1028240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne } 102966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 103066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne private void logd(String s) { 103166e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne Log.d(TAG, s); 103266e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 103366e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 103466e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne private void logi(String s) { 103566e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne Log.i(TAG, s); 103666e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 103766e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne 103866e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne private void loge(String s) { 103966e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne Log.e(TAG, s); 104066e9f4ab597136cbf4accadb8e009fc68ff071a7Glen Kuhne } 1041240671db659a4f7ca7e217d41c7aee9d85e22c33Glen Kuhne} 1042