Initial Contribution

This commit is contained in:
The Android Open Source Project
2008-10-21 07:00:00 -07:00
commit 54a942fddf
7 changed files with 1739 additions and 0 deletions

View File

@@ -0,0 +1,243 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.os.RemoteException;
/**
* Class that answers queries about the state of network connectivity. It also
* notifies applications when network connectivity changes. Get an instance
* of this class by calling
* {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
* <p>
* The primary responsibilities of this class are to:
* <ol>
* <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
* <li>Send broadcast intents when network connectivity changes</li>
* <li>Attempt to "fail over" to another network when connectivity to a network
* is lost</li>
* <li>Provide an API that allows applications to query the coarse-grained or fine-grained
* state of the available networks</li>
* </ol>
*/
public class ConnectivityManager
{
/**
* A change in network connectivity has occurred. A connection has either
* been established or lost. The NetworkInfo for the affected network is
* sent as an extra; it should be consulted to see what kind of
* connectivity event occurred.
* <p/>
* If this is a connection that was the result of failing over from a
* disconnected network, then the FAILOVER_CONNECTION boolean extra is
* set to true.
* <p/>
* For a loss of connectivity, if the connectivity manager is attempting
* to connect (or has already connected) to another network, the
* NetworkInfo for the new network is also passed as an extra. This lets
* any receivers of the broadcast know that they should not necessarily
* tell the user that no data traffic will be possible. Instead, the
* reciever should expect another broadcast soon, indicating either that
* the failover attempt succeeded (and so there is still overall data
* connectivity), or that the failover attempt failed, meaning that all
* connectivity has been lost.
* <p/>
* For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
* is set to {@code true} if there are no connected networks at all.
*/
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
/**
* The lookup key for a {@link NetworkInfo} object. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
*/
public static final String EXTRA_NETWORK_INFO = "networkInfo";
/**
* The lookup key for a boolean that indicates whether a connect event
* is for a network to which the connectivity manager was failing over
* following a disconnect on another network.
* Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
*/
public static final String EXTRA_IS_FAILOVER = "isFailover";
/**
* The lookup key for a {@link NetworkInfo} object. This is supplied when
* there is another network that it may be possible to connect to. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
*/
public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
/**
* The lookup key for a boolean that indicates whether there is a
* complete lack of connectivity, i.e., no network is available.
* Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
*/
public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
/**
* The lookup key for a string that indicates why an attempt to connect
* to a network failed. The string has no particular structure. It is
* intended to be used in notifications presented to users. Retrieve
* it with {@link android.content.Intent#getStringExtra(String)}.
*/
public static final String EXTRA_REASON = "reason";
/**
* The lookup key for a string that provides optionally supplied
* extra information about the network state. The information
* may be passed up from the lower networking layers, and its
* meaning may be specific to a particular network type. Retrieve
* it with {@link android.content.Intent#getStringExtra(String)}.
*/
public static final String EXTRA_EXTRA_INFO = "extraInfo";
public static final int TYPE_MOBILE = 0;
public static final int TYPE_WIFI = 1;
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
private IConnectivityManager mService;
static public boolean isNetworkTypeValid(int networkType) {
return networkType == TYPE_WIFI || networkType == TYPE_MOBILE;
}
public void setNetworkPreference(int preference) {
try {
mService.setNetworkPreference(preference);
} catch (RemoteException e) {
}
}
public int getNetworkPreference() {
try {
return mService.getNetworkPreference();
} catch (RemoteException e) {
return -1;
}
}
public NetworkInfo getActiveNetworkInfo() {
try {
return mService.getActiveNetworkInfo();
} catch (RemoteException e) {
return null;
}
}
public NetworkInfo getNetworkInfo(int networkType) {
try {
return mService.getNetworkInfo(networkType);
} catch (RemoteException e) {
return null;
}
}
public NetworkInfo[] getAllNetworkInfo() {
try {
return mService.getAllNetworkInfo();
} catch (RemoteException e) {
return null;
}
}
/** {@hide} */
public boolean setRadios(boolean turnOn) {
try {
return mService.setRadios(turnOn);
} catch (RemoteException e) {
return false;
}
}
/** {@hide} */
public boolean setRadio(int networkType, boolean turnOn) {
try {
return mService.setRadio(networkType, turnOn);
} catch (RemoteException e) {
return false;
}
}
/**
* Tells the underlying networking system that the caller wants to
* begin using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature to be used
* @return an integer value representing the outcome of the request.
* The interpretation of this value is specific to each networking
* implementation+feature combination, except that the value {@code -1}
* always indicates failure.
*/
public int startUsingNetworkFeature(int networkType, String feature) {
try {
return mService.startUsingNetworkFeature(networkType, feature);
} catch (RemoteException e) {
return -1;
}
}
/**
* Tells the underlying networking system that the caller is finished
* using the named feature. The interpretation of {@code feature}
* is completely up to each networking implementation.
* @param networkType specifies which network the request pertains to
* @param feature the name of the feature that is no longer needed
* @return an integer value representing the outcome of the request.
* The interpretation of this value is specific to each networking
* implementation+feature combination, except that the value {@code -1}
* always indicates failure.
*/
public int stopUsingNetworkFeature(int networkType, String feature) {
try {
return mService.stopUsingNetworkFeature(networkType, feature);
} catch (RemoteException e) {
return -1;
}
}
/**
* Ensure that a network route exists to deliver traffic to the specified
* host via the specified network interface. An attempt to add a route that
* already exists is ignored, but treated as successful.
* @param networkType the type of the network over which traffic to the specified
* host is to be routed
* @param hostAddress the IP address of the host to which the route is desired
* @return {@code true} on success, {@code false} on failure
*/
public boolean requestRouteToHost(int networkType, int hostAddress) {
try {
return mService.requestRouteToHost(networkType, hostAddress);
} catch (RemoteException e) {
return false;
}
}
/**
* Don't allow use of default constructor.
*/
@SuppressWarnings({"UnusedDeclaration"})
private ConnectivityManager() {
}
/**
* {@hide}
*/
public ConnectivityManager(IConnectivityManager service) {
if (service == null) {
throw new IllegalArgumentException(
"ConnectivityManager() cannot be constructed with null service");
}
mService = service;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.os.Parcelable;
import android.os.Parcel;
/**
* A simple object for retrieving the results of a DHCP request.
*/
public class DhcpInfo implements Parcelable {
public int ipAddress;
public int gateway;
public int netmask;
public int dns1;
public int dns2;
public int serverAddress;
public int leaseDuration;
public DhcpInfo() {
super();
}
public String toString() {
StringBuffer str = new StringBuffer();
str.append("ipaddr "); putAddress(str, ipAddress);
str.append(" gateway "); putAddress(str, gateway);
str.append(" netmask "); putAddress(str, netmask);
str.append(" dns1 "); putAddress(str, dns1);
str.append(" dns2 "); putAddress(str, dns2);
str.append(" DHCP server "); putAddress(str, serverAddress);
str.append(" lease ").append(leaseDuration).append(" seconds");
return str.toString();
}
private static void putAddress(StringBuffer buf, int addr) {
buf.append(addr & 0xff).append('.').
append((addr >>>= 8) & 0xff).append('.').
append((addr >>>= 8) & 0xff).append('.').
append((addr >>>= 8) & 0xff);
}
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(ipAddress);
dest.writeInt(gateway);
dest.writeInt(netmask);
dest.writeInt(dns1);
dest.writeInt(dns2);
dest.writeInt(serverAddress);
dest.writeInt(leaseDuration);
}
/** Implement the Parcelable interface {@hide} */
public static final Creator<DhcpInfo> CREATOR =
new Creator<DhcpInfo>() {
public DhcpInfo createFromParcel(Parcel in) {
DhcpInfo info = new DhcpInfo();
info.ipAddress = in.readInt();
info.gateway = in.readInt();
info.netmask = in.readInt();
info.dns1 = in.readInt();
info.dns2 = in.readInt();
info.serverAddress = in.readInt();
info.leaseDuration = in.readInt();
return info;
}
public DhcpInfo[] newArray(int size) {
return new DhcpInfo[size];
}
};
}

View File

@@ -0,0 +1,47 @@
/**
* Copyright (c) 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.net.NetworkInfo;
/**
* Interface that answers queries about, and allows changing, the
* state of network connectivity.
*/
/** {@hide} */
interface IConnectivityManager
{
void setNetworkPreference(int pref);
int getNetworkPreference();
NetworkInfo getActiveNetworkInfo();
NetworkInfo getNetworkInfo(int networkType);
NetworkInfo[] getAllNetworkInfo();
boolean setRadios(boolean onOff);
boolean setRadio(int networkType, boolean turnOn);
int startUsingNetworkFeature(int networkType, in String feature);
int stopUsingNetworkFeature(int networkType, in String feature);
boolean requestRouteToHost(int networkType, int hostAddress);
}

View File

@@ -0,0 +1,305 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import android.os.Parcelable;
import android.os.Parcel;
import java.util.EnumMap;
/**
* Describes the status of a network interface of a given type
* (currently either Mobile or Wifi).
*/
public class NetworkInfo implements Parcelable {
/**
* Coarse-grained network state. This is probably what most applications should
* use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
* The mapping between the two is as follows:
* <br/><br/>
* <table>
* <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
* <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
* <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
* <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
* <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
* <tr><td><code>CONNECTED</code></td><td<code>CONNECTED</code></td></tr>
* <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
* <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
* <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
* <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
* </table>
*/
public enum State {
CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
}
/**
* The fine-grained state of a network connection. This level of detail
* is probably of interest to few applications. Most should use
* {@link android.net.NetworkInfo.State State} instead.
*/
public enum DetailedState {
/** Ready to start data connection setup. */
IDLE,
/** Searching for an available access point. */
SCANNING,
/** Currently setting up data connection. */
CONNECTING,
/** Network link established, performing authentication. */
AUTHENTICATING,
/** Awaiting response from DHCP server in order to assign IP address information. */
OBTAINING_IPADDR,
/** IP traffic should be available. */
CONNECTED,
/** IP traffic is suspended */
SUSPENDED,
/** Currently tearing down data connection. */
DISCONNECTING,
/** IP traffic not available. */
DISCONNECTED,
/** Attempt to connect failed. */
FAILED
}
/**
* This is the map described in the Javadoc comment above. The positions
* of the elements of the array must correspond to the ordinal values
* of <code>DetailedState</code>.
*/
private static final EnumMap<DetailedState, State> stateMap =
new EnumMap<DetailedState, State>(DetailedState.class);
static {
stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
}
private int mNetworkType;
private State mState;
private DetailedState mDetailedState;
private String mReason;
private String mExtraInfo;
private boolean mIsFailover;
/**
* Indicates whether network connectivity is possible:
*/
private boolean mIsAvailable;
public NetworkInfo(int type) {
if (!ConnectivityManager.isNetworkTypeValid(type)) {
throw new IllegalArgumentException("Invalid network type: " + type);
}
this.mNetworkType = type;
setDetailedState(DetailedState.IDLE, null, null);
mState = State.UNKNOWN;
mIsAvailable = true;
}
/**
* Reports the type of network (currently mobile or Wi-Fi) to which the
* info in this object pertains.
* @return the network type
*/
public int getType() {
return mNetworkType;
}
/**
* Indicates whether network connectivity exists or is in the process
* of being established. This is good for applications that need to
* do anything related to the network other than read or write data.
* For the latter, call {@link #isConnected()} instead, which guarantees
* that the network is fully usable.
* @return {@code true} if network connectivity exists or is in the process
* of being established, {@code false} otherwise.
*/
public boolean isConnectedOrConnecting() {
return mState == State.CONNECTED || mState == State.CONNECTING;
}
/**
* Indicates whether network connectivity exists and it is possible to establish
* connections and pass data.
* @return {@code true} if network connectivity exists, {@code false} otherwise.
*/
public boolean isConnected() {
return mState == State.CONNECTED;
}
/**
* Indicates whether network connectivity is possible. A network is unavailable
* when a persistent or semi-persistent condition prevents the possibility
* of connecting to that network. Examples include
* <ul>
* <li>The device is out of the coverage area for any network of this type.</li>
* <li>The device is on a network other than the home network (i.e., roaming), and
* data roaming has been disabled.</li>
* <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
* </ul>
* @return {@code true} if the network is available, {@code false} otherwise
*/
public boolean isAvailable() {
return mIsAvailable;
}
/**
* Sets if the network is available, ie, if the connectivity is possible.
* @param isAvailable the new availability value.
*
* {@hide}
*/
public void setIsAvailable(boolean isAvailable) {
mIsAvailable = isAvailable;
}
/**
* Indicates whether the current attempt to connect to the network
* resulted from the ConnectivityManager trying to fail over to this
* network following a disconnect from another network.
* @return {@code true} if this is a failover attempt, {@code false}
* otherwise.
*/
public boolean isFailover() {
return mIsFailover;
}
/** {@hide} */
public void setFailover(boolean isFailover) {
mIsFailover = isFailover;
}
/**
* Reports the current coarse-grained state of the network.
* @return the coarse-grained state
*/
public State getState() {
return mState;
}
/**
* Reports the current fine-grained state of the network.
* @return the fine-grained state
*/
public DetailedState getDetailedState() {
return mDetailedState;
}
/**
* Sets the fine-grained state of the network.
* @param detailedState the {@link DetailedState}.
* @param reason a {@code String} indicating the reason for the state change,
* if one was supplied. May be {@code null}.
* @param extraInfo an optional {@code String} providing addditional network state
* information passed up from the lower networking layers.
*
* {@hide}
*/
void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
this.mDetailedState = detailedState;
this.mState = stateMap.get(detailedState);
this.mReason = reason;
this.mExtraInfo = extraInfo;
}
/**
* Report the reason an attempt to establish connectivity failed,
* if one is available.
* @return the reason for failure, or null if not available
*/
public String getReason() {
return mReason;
}
/**
* Report the extra information about the network state, if any was
* provided by the lower networking layers.,
* if one is available.
* @return the extra information, or null if not available
*/
public String getExtraInfo() {
return mExtraInfo;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("NetworkInfo: ");
builder.append("type: ").append(getTypeName()).append(", state: ").append(mState).
append("/").append(mDetailedState).
append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
append(", failover: ").append(mIsFailover).
append(", isAvailable: ").append(mIsAvailable);
return builder.toString();
}
public String getTypeName() {
switch (mNetworkType) {
case ConnectivityManager.TYPE_WIFI:
return "WIFI";
case ConnectivityManager.TYPE_MOBILE:
return "MOBILE";
default:
return "<invalid>";
}
}
/** Implement the Parcelable interface {@hide} */
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface {@hide} */
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mNetworkType);
dest.writeString(mState.name());
dest.writeString(mDetailedState.name());
dest.writeInt(mIsFailover ? 1 : 0);
dest.writeInt(mIsAvailable ? 1 : 0);
dest.writeString(mReason);
dest.writeString(mExtraInfo);
}
/** Implement the Parcelable interface {@hide} */
public static final Creator<NetworkInfo> CREATOR =
new Creator<NetworkInfo>() {
public NetworkInfo createFromParcel(Parcel in) {
int netType = in.readInt();
NetworkInfo netInfo = new NetworkInfo(netType);
netInfo.mState = State.valueOf(in.readString());
netInfo.mDetailedState = DetailedState.valueOf(in.readString());
netInfo.mIsFailover = in.readInt() != 0;
netInfo.mIsAvailable = in.readInt() != 0;
netInfo.mReason = in.readString();
netInfo.mExtraInfo = in.readString();
return netInfo;
}
public NetworkInfo[] newArray(int size) {
return new NetworkInfo[size];
}
};
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Native methods for managing network interfaces.
*
* {@hide}
*/
public class NetworkUtils {
/** Bring the named network interface down. */
public native static int disableInterface(String interfaceName);
/** Add a route to the specified host via the named interface. */
public native static int addHostRoute(String interfaceName, int hostaddr);
/** Add a default route for the named interface. */
public native static int setDefaultRoute(String interfaceName, int gwayAddr);
/** Return the gateway address for the default route for the named interface. */
public native static int getDefaultRoute(String interfaceName);
/** Remove host routes that uses the named interface. */
public native static int removeHostRoutes(String interfaceName);
/** Remove the default route for the named interface. */
public native static int removeDefaultRoute(String interfaceName);
/** Reset any sockets that are connected via the named interface. */
public native static int resetConnections(String interfaceName);
/**
* Start the DHCP client daemon, in order to have it request addresses
* for the named interface, and then configure the interface with those
* addresses. This call blocks until it obtains a result (either success
* or failure) from the daemon.
* @param interfaceName the name of the interface to configure
* @param ipInfo if the request succeeds, this object is filled in with
* the IP address information.
* @return {@code true} for success, {@code false} for failure
*/
public native static boolean runDhcp(String interfaceName, DhcpInfo ipInfo);
/**
* Shut down the DHCP client daemon.
* @param interfaceName the name of the interface for which the daemon
* should be stopped
* @return {@code true} for success, {@code false} for failure
*/
public native static boolean stopDhcp(String interfaceName);
/**
* Return the last DHCP-related error message that was recorded.
* <p/>NOTE: This string is not localized, but currently it is only
* used in logging.
* @return the most recent error message, if any
*/
public native static String getDhcpError();
/**
* When static IP configuration has been specified, configure the network
* interface according to the values supplied.
* @param interfaceName the name of the interface to configure
* @param ipInfo the IP address, default gateway, and DNS server addresses
* with which to configure the interface.
* @return {@code true} for success, {@code false} for failure
*/
public static boolean configureInterface(String interfaceName, DhcpInfo ipInfo) {
return configureNative(interfaceName,
ipInfo.ipAddress,
ipInfo.netmask,
ipInfo.gateway,
ipInfo.dns1,
ipInfo.dns2);
}
private native static boolean configureNative(
String interfaceName, int ipAddress, int netmask, int gateway, int dns1, int dns2);
/**
* Look up a host name and return the result as an int. Works if the argument
* is an IP address in dot notation. Obviously, this can only be used for IPv4
* addresses.
* @param hostname the name of the host (or the IP address)
* @return the IP address as an {@code int} in network byte order
*/
public static int lookupHost(String hostname) {
InetAddress inetAddress;
try {
inetAddress = InetAddress.getByName(hostname);
} catch (UnknownHostException e) {
return -1;
}
byte[] addrBytes;
int addr;
addrBytes = inetAddress.getAddress();
addr = ((addrBytes[3] & 0xff) << 24)
| ((addrBytes[2] & 0xff) << 16)
| ((addrBytes[1] & 0xff) << 8)
| (addrBytes[0] & 0xff);
return addr;
}
}

View File

@@ -0,0 +1,235 @@
/*
* Copyright 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "NetUtils"
#include "jni.h"
#include <utils/misc.h>
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
#include <arpa/inet.h>
extern "C" {
int ifc_disable(const char *ifname);
int ifc_add_host_route(const char *ifname, uint32_t addr);
int ifc_remove_host_routes(const char *ifname);
int ifc_set_default_route(const char *ifname, uint32_t gateway);
int ifc_get_default_route(const char *ifname);
int ifc_remove_default_route(const char *ifname);
int ifc_reset_connections(const char *ifname);
int ifc_configure(const char *ifname, in_addr_t ipaddr, in_addr_t netmask, in_addr_t gateway, in_addr_t dns1, in_addr_t dns2);
int dhcp_do_request(const char *ifname,
in_addr_t *ipaddr,
in_addr_t *gateway,
in_addr_t *mask,
in_addr_t *dns1,
in_addr_t *dns2,
in_addr_t *server,
uint32_t *lease);
int dhcp_stop(const char *ifname);
char *dhcp_get_errmsg();
}
#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
namespace android {
/*
* The following remembers the jfieldID's of the fields
* of the DhcpInfo Java object, so that we don't have
* to look them up every time.
*/
static struct fieldIds {
jclass dhcpInfoClass;
jmethodID constructorId;
jfieldID ipaddress;
jfieldID gateway;
jfieldID netmask;
jfieldID dns1;
jfieldID dns2;
jfieldID serverAddress;
jfieldID leaseDuration;
} dhcpInfoFieldIds;
static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_disable(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_addHostRoute(JNIEnv* env, jobject clazz, jstring ifname, jint addr)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_add_host_route(nameStr, addr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_removeHostRoutes(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_remove_host_routes(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_setDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname, jint gateway)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_set_default_route(nameStr, gateway);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_get_default_route(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_removeDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_remove_default_route(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_reset_connections(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jint)result;
}
static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
{
int result;
in_addr_t ipaddr, gateway, mask, dns1, dns2, server;
uint32_t lease;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::dhcp_do_request(nameStr, &ipaddr, &gateway, &mask,
&dns1, &dns2, &server, &lease);
env->ReleaseStringUTFChars(ifname, nameStr);
if (result == 0 && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
}
return (jboolean)(result == 0);
}
static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
{
int result;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::dhcp_stop(nameStr);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jboolean)(result == 0);
}
static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
{
return env->NewStringUTF(::dhcp_get_errmsg());
}
static jboolean android_net_utils_configureInterface(JNIEnv* env,
jobject clazz,
jstring ifname,
jint ipaddr,
jint mask,
jint gateway,
jint dns1,
jint dns2)
{
int result;
uint32_t lease;
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
result = ::ifc_configure(nameStr, ipaddr, mask, gateway, dns1, dns2);
env->ReleaseStringUTFChars(ifname, nameStr);
return (jboolean)(result == 0);
}
// ----------------------------------------------------------------------------
/*
* JNI registration.
*/
static JNINativeMethod gNetworkUtilMethods[] = {
/* name, signature, funcPtr */
{ "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
{ "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute },
{ "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes },
{ "setDefaultRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute },
{ "getDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute },
{ "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute },
{ "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z", (void *)android_net_utils_runDhcp },
{ "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
{ "configureNative", "(Ljava/lang/String;IIIII)Z", (void *)android_net_utils_configureInterface },
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
};
int register_android_net_NetworkUtils(JNIEnv* env)
{
jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo");
if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V");
dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I");
dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I");
dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I");
dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I");
dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I");
}
return AndroidRuntime::registerNativeMethods(env,
NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
}
}; // namespace android