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