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.os.ConditionVariable; 25 26 import java.io.FileDescriptor; 27 import java.io.PrintWriter; 28 import java.util.List; 29 30 31 /** 32 * Utilities and wrappers to simplify communication with IpClient, which lives in the NetworkStack 33 * process. 34 * 35 * @hide 36 */ 37 public class IpClientUtil { 38 // TODO: remove with its callers 39 public static final String DUMP_ARG = "ipclient"; 40 41 /** 42 * Subclass of {@link IpClientCallbacks} allowing clients to block until provisioning is 43 * complete with {@link WaitForProvisioningCallbacks#waitForProvisioning()}. 44 */ 45 public static class WaitForProvisioningCallbacks extends IpClientCallbacks { 46 private final ConditionVariable mCV = new ConditionVariable(); 47 private LinkProperties mCallbackLinkProperties; 48 49 /** 50 * Block until either {@link #onProvisioningSuccess(LinkProperties)} or 51 * {@link #onProvisioningFailure(LinkProperties)} is called. 52 */ waitForProvisioning()53 public LinkProperties waitForProvisioning() { 54 mCV.block(); 55 return mCallbackLinkProperties; 56 } 57 58 @Override onProvisioningSuccess(LinkProperties newLp)59 public void onProvisioningSuccess(LinkProperties newLp) { 60 mCallbackLinkProperties = newLp; 61 mCV.open(); 62 } 63 64 @Override onProvisioningFailure(LinkProperties newLp)65 public void onProvisioningFailure(LinkProperties newLp) { 66 mCallbackLinkProperties = null; 67 mCV.open(); 68 } 69 } 70 71 /** 72 * Create a new IpClient. 73 * 74 * <p>This is a convenience method to allow clients to use {@link IpClientCallbacks} instead of 75 * {@link IIpClientCallbacks}. 76 * @see {@link ModuleNetworkStackClient#makeIpClient(String, IIpClientCallbacks)} 77 */ makeIpClient(Context context, String ifName, IpClientCallbacks callback)78 public static void makeIpClient(Context context, String ifName, IpClientCallbacks callback) { 79 ModuleNetworkStackClient.getInstance(context) 80 .makeIpClient(ifName, new IpClientCallbacksProxy(callback)); 81 } 82 83 /** 84 * Wrapper to relay calls from {@link IIpClientCallbacks} to {@link IpClientCallbacks}. 85 */ 86 private static class IpClientCallbacksProxy extends IIpClientCallbacks.Stub { 87 protected final IpClientCallbacks mCb; 88 89 /** 90 * Create a new IpClientCallbacksProxy. 91 */ IpClientCallbacksProxy(IpClientCallbacks cb)92 public IpClientCallbacksProxy(IpClientCallbacks cb) { 93 mCb = cb; 94 } 95 96 @Override onIpClientCreated(IIpClient ipClient)97 public void onIpClientCreated(IIpClient ipClient) { 98 mCb.onIpClientCreated(ipClient); 99 } 100 101 @Override onPreDhcpAction()102 public void onPreDhcpAction() { 103 mCb.onPreDhcpAction(); 104 } 105 106 @Override onPostDhcpAction()107 public void onPostDhcpAction() { 108 mCb.onPostDhcpAction(); 109 } 110 111 // This is purely advisory and not an indication of provisioning 112 // success or failure. This is only here for callers that want to 113 // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress). 114 // DHCPv4 or static IPv4 configuration failure or success can be 115 // determined by whether or not the passed-in DhcpResults object is 116 // null or not. 117 @Override onNewDhcpResults(DhcpResultsParcelable dhcpResults)118 public void onNewDhcpResults(DhcpResultsParcelable dhcpResults) { 119 mCb.onNewDhcpResults(dhcpResults); 120 } 121 122 @Override onProvisioningSuccess(LinkProperties newLp)123 public void onProvisioningSuccess(LinkProperties newLp) { 124 mCb.onProvisioningSuccess(newLp); 125 } 126 @Override onProvisioningFailure(LinkProperties newLp)127 public void onProvisioningFailure(LinkProperties newLp) { 128 mCb.onProvisioningFailure(newLp); 129 } 130 131 // Invoked on LinkProperties changes. 132 @Override onLinkPropertiesChange(LinkProperties newLp)133 public void onLinkPropertiesChange(LinkProperties newLp) { 134 mCb.onLinkPropertiesChange(newLp); 135 } 136 137 // Called when the internal IpReachabilityMonitor (if enabled) has 138 // detected the loss of a critical number of required neighbors. 139 @Override onReachabilityLost(String logMsg)140 public void onReachabilityLost(String logMsg) { 141 mCb.onReachabilityLost(logMsg); 142 } 143 144 // Called when the IpClient state machine terminates. 145 @Override onQuit()146 public void onQuit() { 147 mCb.onQuit(); 148 } 149 150 // Install an APF program to filter incoming packets. 151 @Override installPacketFilter(byte[] filter)152 public void installPacketFilter(byte[] filter) { 153 mCb.installPacketFilter(filter); 154 } 155 156 // Asynchronously read back the APF program & data buffer from the wifi driver. 157 // Due to Wifi HAL limitations, the current implementation only supports dumping the entire 158 // buffer. In response to this request, the driver returns the data buffer asynchronously 159 // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message. 160 @Override startReadPacketFilter()161 public void startReadPacketFilter() { 162 mCb.startReadPacketFilter(); 163 } 164 165 // If multicast filtering cannot be accomplished with APF, this function will be called to 166 // actuate multicast filtering using another means. 167 @Override setFallbackMulticastFilter(boolean enabled)168 public void setFallbackMulticastFilter(boolean enabled) { 169 mCb.setFallbackMulticastFilter(enabled); 170 } 171 172 // Enabled/disable Neighbor Discover offload functionality. This is 173 // called, for example, whenever 464xlat is being started or stopped. 174 @Override setNeighborDiscoveryOffload(boolean enable)175 public void setNeighborDiscoveryOffload(boolean enable) { 176 mCb.setNeighborDiscoveryOffload(enable); 177 } 178 179 // Invoked on starting preconnection process. 180 @Override onPreconnectionStart(List<Layer2PacketParcelable> packets)181 public void onPreconnectionStart(List<Layer2PacketParcelable> packets) { 182 mCb.onPreconnectionStart(packets); 183 } 184 185 @Override getInterfaceVersion()186 public int getInterfaceVersion() { 187 return this.VERSION; 188 } 189 190 @Override getInterfaceHash()191 public String getInterfaceHash() { 192 return this.HASH; 193 } 194 } 195 196 /** 197 * Dump logs for the specified IpClient. 198 * TODO: remove callers and delete 199 */ dumpIpClient( IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args)200 public static void dumpIpClient( 201 IIpClient connector, FileDescriptor fd, PrintWriter pw, String[] args) { 202 pw.println("IpClient logs have moved to dumpsys network_stack"); 203 } 204 } 205