1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.ip; 18 19 import android.content.Context; 20 import android.net.DhcpResultsParcelable; 21 import android.net.Layer2PacketParcelable; 22 import android.net.LinkProperties; 23 import android.net.networkstack.ModuleNetworkStackClient; 24 import android.net.networkstack.aidl.ip.ReachabilityLossInfoParcelable; 25 import android.os.ConditionVariable; 26 27 import java.io.FileDescriptor; 28 import java.io.PrintWriter; 29 import java.util.List; 30 31 32 /** 33 * Utilities and wrappers to simplify communication with IpClient, which lives in the NetworkStack 34 * process. 35 * 36 * @hide 37 */ 38 public class IpClientUtil { 39 // TODO: remove with its callers 40 public static final String DUMP_ARG = "ipclient"; 41 42 /** 43 * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is 44 * complete with {@link WaitForProvisioningCallbacks#waitForProvisioning()}. 45 */ 46 public static class WaitForProvisioningCallbacks extends IpClientCallbacks { 47 private final ConditionVariable mCV = new ConditionVariable(); 48 private LinkProperties mCallbackLinkProperties; 49 50 /** 51 * Block until either {@link #onProvisioningSuccess(LinkProperties)} or 52 * {@link #onProvisioningFailure(LinkProperties)} is called. 53 */ waitForProvisioning()54 public LinkProperties waitForProvisioning() { 55 mCV.block(); 56 return mCallbackLinkProperties; 57 } 58 59 @Override onProvisioningSuccess(LinkProperties newLp)60 public void onProvisioningSuccess(LinkProperties newLp) { 61 mCallbackLinkProperties = newLp; 62 mCV.open(); 63 } 64 65 @Override onProvisioningFailure(LinkProperties newLp)66 public void onProvisioningFailure(LinkProperties newLp) { 67 mCallbackLinkProperties = null; 68 mCV.open(); 69 } 70 } 71 72 /** 73 * Create a new IpClient. 74 * 75 * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of 76 * {@link IIpClientCallbacks}. 77 * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)} 78 */ makeIpClient(Context context, String ifName, IpClientCallbacks callback)79 public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { 80 ModuleNetworkStackClient.getInstance(context) 81 .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); 82 } 83 84 /** 85 * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}. 86 */ 87 private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { 88 protected final IpClientCallbacks mCb; 89 90 /** 91 * Create a new IpClientCallbacksProxy. 92 */ IpClientCallbacksProxy(IpClientCallbacks cb)93 IpClientCallbacksProxy(IpClientCallbacks cb) { 94 mCb = cb; 95 } 96 97 @Override onIpClientCreated(IIpClient ipClient)98 public void onIpClientCreated(IIpClient ipClient) { 99 mCb.onIpClientCreated(ipClient); 100 } 101 102 @Override onPreDhcpAction()103 public void onPreDhcpAction() { 104 mCb.onPreDhcpAction(); 105 } 106 107 @Override onPostDhcpAction()108 public void onPostDhcpAction() { 109 mCb.onPostDhcpAction(); 110 } 111 112 // This is purely advisory and not an indication of provisioning 113 // success or failure. This is only here for callers that want to 114 // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress). 115 // DHCPv4 or static IPv4 configuration failure or success can be 116 // determined by whether or not the passed-in DhcpResults object is 117 // null or not. 118 @Override onNewDhcpResults(DhcpResultsParcelable dhcpResults)119 public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) { 120 mCb.onNewDhcpResults(dhcpResults); 121 } 122 123 // LinkProperties always have parcelSensitiveFields=false after parceling 124 // and unparceling, so the IIpClientCallback caller's side will always receive 125 // LinkProperties that do not have the flag set, except on Go devices where 126 // IpClient is running in the system_server, it's possible that no parceling 127 // happens and the object is sent as true, which results in wifi throws the 128 // UnsupportedOperationException when calling LinkProperties.clear() and then 129 // reboot. To keep the consistent behavior, deliver LinkProperties with 130 // mParcelSensitiveFields=false to wifi upon callback is triggered. 131 @Override onProvisioningSuccess(LinkProperties newLp)132 public void onProvisioningSuccess(LinkProperties newLp) { 133 mCb.onProvisioningSuccess(new LinkProperties(newLp)); 134 } 135 @Override onProvisioningFailure(LinkProperties newLp)136 public void onProvisioningFailure(LinkProperties newLp) { 137 mCb.onProvisioningFailure(new LinkProperties(newLp)); 138 } 139 140 // Invoked on LinkProperties changes. 141 @Override onLinkPropertiesChange(LinkProperties newLp)142 public void onLinkPropertiesChange(LinkProperties newLp) { 143 mCb.onLinkPropertiesChange(new LinkProperties(newLp)); 144 } 145 146 // Called when the internal IpReachabilityMonitor (if enabled) has 147 // detected the loss of a critical number of required neighbors. 148 @Override onReachabilityLost(String logMsg)149 public void onReachabilityLost(String logMsg) { 150 mCb.onReachabilityLost(logMsg); 151 } 152 153 // Called when the IpClient state machine terminates. 154 @Override onQuit()155 public void onQuit() { 156 mCb.onQuit(); 157 } 158 159 // Install an APF program to filter incoming packets. 160 @Override installPacketFilter(byte[] filter)161 public void installPacketFilter(byte[] filter) { 162 mCb.installPacketFilter(filter); 163 } 164 165 // Asynchronously read back the APF program & data buffer from the wifi driver. 166 // Due to Wifi HAL limitations, the current implementation only supports dumping the entire 167 // buffer. In response to this request, the driver returns the data buffer asynchronously 168 // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message. 169 @Override startReadPacketFilter()170 public void startReadPacketFilter() { 171 mCb.startReadPacketFilter(); 172 } 173 174 // If multicast filtering cannot be accomplished with APF, this function will be called to 175 // actuate multicast filtering using another means. 176 @Override setFallbackMulticastFilter(boolean enabled)177 public void setFallbackMulticastFilter(boolean enabled) { 178 mCb.setFallbackMulticastFilter(enabled); 179 } 180 181 // Enabled/disable Neighbor Discover offload functionality. This is 182 // called, for example, whenever 464xlat is being started or stopped. 183 @Override setNeighborDiscoveryOffload(boolean enable)184 public void setNeighborDiscoveryOffload(boolean enable) { 185 mCb.setNeighborDiscoveryOffload(enable); 186 } 187 188 // Invoked on starting preconnection process. 189 @Override onPreconnectionStart(List<Layer2PacketParcelable> packets)190 public void onPreconnectionStart(List<Layer2PacketParcelable> packets) { 191 mCb.onPreconnectionStart(packets); 192 } 193 194 // Called when the internal IpReachabilityMonitor (if enabled) has detected the loss of a 195 // critical number of required neighbors or DHCP roaming fails. 196 @Override onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo)197 public void onReachabilityFailure(ReachabilityLossInfoParcelable lossInfo) { 198 mCb.onReachabilityFailure(lossInfo); 199 } 200 201 // Set maximum acceptable DTIM multiplier to hardware driver. 202 @Override setMaxDtimMultiplier(int multiplier)203 public void setMaxDtimMultiplier(int multiplier) { 204 mCb.setMaxDtimMultiplier(multiplier); 205 } 206 207 @Override getInterfaceVersion()208 public int getInterfaceVersion() { 209 return this.VERSION; 210 } 211 212 @Override getInterfaceHash()213 public String getInterfaceHash() { 214 return this.HASH; 215 } 216 } 217 218 /** 219 * Dump logs for the specified IpClient. 220 * TODO: remove callers and delete 221 */ dumpIpClient( IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args)222 public static void dumpIpClient( 223 IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) { 224 pw.println("IpClient logs have moved to dumpsys network_stack"); 225 } 226 } 227