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.annotation.Hide; 20 import android.annotation.NonNull; 21 import android.net.NattKeepalivePacketData; 22 import android.net.ProxyInfo; 23 import android.net.TcpKeepalivePacketData; 24 import android.net.shared.Layer2Information; 25 import android.net.shared.ProvisioningConfiguration; 26 import android.net.util.KeepalivePacketDataUtil; 27 import android.os.Binder; 28 import android.os.RemoteException; 29 import android.util.Log; 30 31 /** 32 * A convenience wrapper for IpClient. 33 * 34 * Wraps IIpClient calls, making them a bit more friendly to use. Currently handles: 35 * - Clearing calling identity 36 * - Ignoring RemoteExceptions 37 * - Converting to stable parcelables 38 * 39 * By design, all methods on IIpClient are asynchronous oneway IPCs and are thus void. All the 40 * wrapper methods in this class return a boolean that callers can use to determine whether 41 * RemoteException was thrown. 42 */ 43 @Hide 44 public class IpClientManager { 45 @NonNull private final IIpClient mIpClient; 46 @NonNull private final String mTag; 47 IpClientManager(@onNull IIpClient ipClient, @NonNull String tag)48 public IpClientManager(@NonNull IIpClient ipClient, @NonNull String tag) { 49 mIpClient = ipClient; 50 mTag = tag; 51 } 52 IpClientManager(@onNull IIpClient ipClient)53 public IpClientManager(@NonNull IIpClient ipClient) { 54 this(ipClient, IpClientManager.class.getSimpleName()); 55 } 56 log(String s, Throwable e)57 private void log(String s, Throwable e) { 58 Log.e(mTag, s, e); 59 } 60 61 /** 62 * For clients using {@link ProvisioningConfiguration.Builder#withPreDhcpAction()}, must be 63 * called after {@link IIpClientCallbacks#onPreDhcpAction} to indicate that DHCP is clear to 64 * proceed. 65 */ completedPreDhcpAction()66 public boolean completedPreDhcpAction() { 67 final long token = Binder.clearCallingIdentity(); 68 try { 69 mIpClient.completedPreDhcpAction(); 70 return true; 71 } catch (RemoteException e) { 72 log("Error completing PreDhcpAction", e); 73 return false; 74 } finally { 75 Binder.restoreCallingIdentity(token); 76 } 77 } 78 79 /** 80 * Confirm the provisioning configuration. 81 */ confirmConfiguration()82 public boolean confirmConfiguration() { 83 final long token = Binder.clearCallingIdentity(); 84 try { 85 mIpClient.confirmConfiguration(); 86 return true; 87 } catch (RemoteException e) { 88 log("Error confirming IpClient configuration", e); 89 return false; 90 } 91 } 92 93 /** 94 * Indicate that packet filter read is complete. 95 */ readPacketFilterComplete(byte[] data)96 public boolean readPacketFilterComplete(byte[] data) { 97 final long token = Binder.clearCallingIdentity(); 98 try { 99 mIpClient.readPacketFilterComplete(data); 100 return true; 101 } catch (RemoteException e) { 102 log("Error notifying IpClient of packet filter read", e); 103 return false; 104 } finally { 105 Binder.restoreCallingIdentity(token); 106 } 107 } 108 109 /** 110 * Shut down this IpClient instance altogether. 111 */ shutdown()112 public boolean shutdown() { 113 final long token = Binder.clearCallingIdentity(); 114 try { 115 mIpClient.shutdown(); 116 return true; 117 } catch (RemoteException e) { 118 log("Error shutting down IpClient", e); 119 return false; 120 } finally { 121 Binder.restoreCallingIdentity(token); 122 } 123 } 124 125 /** 126 * Start provisioning with the provided parameters. 127 */ startProvisioning(ProvisioningConfiguration prov)128 public boolean startProvisioning(ProvisioningConfiguration prov) { 129 final long token = Binder.clearCallingIdentity(); 130 try { 131 mIpClient.startProvisioning(prov.toStableParcelable()); 132 return true; 133 } catch (RemoteException e) { 134 log("Error starting IpClient provisioning", e); 135 return false; 136 } finally { 137 Binder.restoreCallingIdentity(token); 138 } 139 } 140 141 /** 142 * Stop this IpClient. 143 * 144 * <p>This does not shut down the StateMachine itself, which is handled by {@link #shutdown()}. 145 */ stop()146 public boolean stop() { 147 final long token = Binder.clearCallingIdentity(); 148 try { 149 mIpClient.stop(); 150 return true; 151 } catch (RemoteException e) { 152 log("Error stopping IpClient", e); 153 return false; 154 } finally { 155 Binder.restoreCallingIdentity(token); 156 } 157 } 158 159 /** 160 * Set the TCP buffer sizes to use. 161 * 162 * This may be called, repeatedly, at any time before or after a call to 163 * #startProvisioning(). The setting is cleared upon calling #stop(). 164 */ setTcpBufferSizes(String tcpBufferSizes)165 public boolean setTcpBufferSizes(String tcpBufferSizes) { 166 final long token = Binder.clearCallingIdentity(); 167 try { 168 mIpClient.setTcpBufferSizes(tcpBufferSizes); 169 return true; 170 } catch (RemoteException e) { 171 log("Error setting IpClient TCP buffer sizes", e); 172 return false; 173 } finally { 174 Binder.restoreCallingIdentity(token); 175 } 176 } 177 178 /** 179 * Set the HTTP Proxy configuration to use. 180 * 181 * This may be called, repeatedly, at any time before or after a call to 182 * #startProvisioning(). The setting is cleared upon calling #stop(). 183 */ setHttpProxy(ProxyInfo proxyInfo)184 public boolean setHttpProxy(ProxyInfo proxyInfo) { 185 final long token = Binder.clearCallingIdentity(); 186 try { 187 mIpClient.setHttpProxy(proxyInfo); 188 return true; 189 } catch (RemoteException e) { 190 log("Error setting IpClient proxy", e); 191 return false; 192 } finally { 193 Binder.restoreCallingIdentity(token); 194 } 195 } 196 197 /** 198 * Enable or disable the multicast filter. Attempts to use APF to accomplish the filtering, 199 * if not, Callback.setFallbackMulticastFilter() is called. 200 */ setMulticastFilter(boolean enabled)201 public boolean setMulticastFilter(boolean enabled) { 202 final long token = Binder.clearCallingIdentity(); 203 try { 204 mIpClient.setMulticastFilter(enabled); 205 return true; 206 } catch (RemoteException e) { 207 log("Error setting multicast filter", e); 208 return false; 209 } finally { 210 Binder.restoreCallingIdentity(token); 211 } 212 } 213 214 /** 215 * Add a TCP keepalive packet filter before setting up keepalive offload. 216 */ addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt)217 public boolean addKeepalivePacketFilter(int slot, TcpKeepalivePacketData pkt) { 218 final long token = Binder.clearCallingIdentity(); 219 try { 220 mIpClient.addKeepalivePacketFilter(slot, pkt.toStableParcelable()); 221 return true; 222 } catch (RemoteException e) { 223 log("Error adding Keepalive Packet Filter ", e); 224 return false; 225 } finally { 226 Binder.restoreCallingIdentity(token); 227 } 228 } 229 230 /** 231 * Add a NAT-T keepalive packet filter before setting up keepalive offload. 232 */ addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt)233 public boolean addKeepalivePacketFilter(int slot, NattKeepalivePacketData pkt) { 234 final long token = Binder.clearCallingIdentity(); 235 try { 236 mIpClient.addNattKeepalivePacketFilter( 237 slot, KeepalivePacketDataUtil.toStableParcelable(pkt)); 238 return true; 239 } catch (RemoteException e) { 240 log("Error adding NAT-T Keepalive Packet Filter ", e); 241 return false; 242 } finally { 243 Binder.restoreCallingIdentity(token); 244 } 245 } 246 247 /** 248 * Remove a keepalive packet filter after stopping keepalive offload. 249 */ removeKeepalivePacketFilter(int slot)250 public boolean removeKeepalivePacketFilter(int slot) { 251 final long token = Binder.clearCallingIdentity(); 252 try { 253 mIpClient.removeKeepalivePacketFilter(slot); 254 return true; 255 } catch (RemoteException e) { 256 log("Error removing Keepalive Packet Filter ", e); 257 return false; 258 } finally { 259 Binder.restoreCallingIdentity(token); 260 } 261 } 262 263 /** 264 * Set the L2 key and group hint for storing info into the memory store. 265 */ setL2KeyAndGroupHint(String l2Key, String groupHint)266 public boolean setL2KeyAndGroupHint(String l2Key, String groupHint) { 267 final long token = Binder.clearCallingIdentity(); 268 try { 269 mIpClient.setL2KeyAndGroupHint(l2Key, groupHint); 270 return true; 271 } catch (RemoteException e) { 272 log("Failed setL2KeyAndGroupHint", e); 273 return false; 274 } finally { 275 Binder.restoreCallingIdentity(token); 276 } 277 } 278 279 /** 280 * Notify IpClient that preconnection is complete and that the link is ready for use. 281 * The success parameter indicates whether the packets passed in by 'onPreconnectionStart' 282 * were successfully sent to the network or not. 283 */ notifyPreconnectionComplete(boolean success)284 public boolean notifyPreconnectionComplete(boolean success) { 285 final long token = Binder.clearCallingIdentity(); 286 try { 287 mIpClient.notifyPreconnectionComplete(success); 288 return true; 289 } catch (RemoteException e) { 290 log("Error notifying IpClient Preconnection completed", e); 291 return false; 292 } finally { 293 Binder.restoreCallingIdentity(token); 294 } 295 } 296 297 /** 298 * Update the bssid, L2 key and group hint layer2 information. 299 */ updateLayer2Information(Layer2Information info)300 public boolean updateLayer2Information(Layer2Information info) { 301 final long token = Binder.clearCallingIdentity(); 302 try { 303 mIpClient.updateLayer2Information(info.toStableParcelable()); 304 return true; 305 } catch (RemoteException e) { 306 log("Error updating layer2 information", e); 307 return false; 308 } finally { 309 Binder.restoreCallingIdentity(token); 310 } 311 } 312 } 313