OSDN Git Service

Use resetConnections with resetMask.
[android-x86/frameworks-base.git] / core / jni / android_net_NetUtils.cpp
1 /*
2  * Copyright 2008, 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 #define LOG_TAG "NetUtils"
18
19 #include "jni.h"
20 #include <utils/misc.h>
21 #include <android_runtime/AndroidRuntime.h>
22 #include <utils/Log.h>
23 #include <arpa/inet.h>
24 #include <cutils/properties.h>
25
26 extern "C" {
27 int ifc_enable(const char *ifname);
28 int ifc_disable(const char *ifname);
29 int ifc_reset_connections(const char *ifname, int reset_mask);
30
31 int dhcp_do_request(const char *ifname,
32                     const char *ipaddr,
33                     const char *gateway,
34                     uint32_t  *prefixLength,
35                     const char *dns1,
36                     const char *dns2,
37                     const char *server,
38                     uint32_t  *lease);
39
40 int dhcp_do_request_renew(const char *ifname,
41                     const char *ipaddr,
42                     const char *gateway,
43                     uint32_t  *prefixLength,
44                     const char *dns1,
45                     const char *dns2,
46                     const char *server,
47                     uint32_t  *lease);
48
49 int dhcp_stop(const char *ifname);
50 int dhcp_release_lease(const char *ifname);
51 char *dhcp_get_errmsg();
52 }
53
54 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
55
56 namespace android {
57
58 /*
59  * The following remembers the jfieldID's of the fields
60  * of the DhcpInfo Java object, so that we don't have
61  * to look them up every time.
62  */
63 static struct fieldIds {
64     jclass dhcpInfoInternalClass;
65     jmethodID constructorId;
66     jfieldID ipaddress;
67     jfieldID prefixLength;
68     jfieldID dns1;
69     jfieldID dns2;
70     jfieldID serverAddress;
71     jfieldID leaseDuration;
72 } dhcpInfoInternalFieldIds;
73
74 static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
75 {
76     int result;
77
78     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
79     result = ::ifc_enable(nameStr);
80     env->ReleaseStringUTFChars(ifname, nameStr);
81     return (jint)result;
82 }
83
84 static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
85 {
86     int result;
87
88     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
89     result = ::ifc_disable(nameStr);
90     env->ReleaseStringUTFChars(ifname, nameStr);
91     return (jint)result;
92 }
93
94 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
95       jstring ifname, jint mask)
96 {
97     int result;
98
99     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
100
101     LOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
102           env, clazz, nameStr, mask);
103
104     result = ::ifc_reset_connections(nameStr, mask);
105     env->ReleaseStringUTFChars(ifname, nameStr);
106     return (jint)result;
107 }
108
109 static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
110         jobject info, bool renew)
111 {
112     int result;
113     char  ipaddr[PROPERTY_VALUE_MAX];
114     uint32_t prefixLength;
115     char gateway[PROPERTY_VALUE_MAX];
116     char    dns1[PROPERTY_VALUE_MAX];
117     char    dns2[PROPERTY_VALUE_MAX];
118     char  server[PROPERTY_VALUE_MAX];
119     uint32_t lease;
120
121     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
122     if (nameStr == NULL) return (jboolean)false;
123
124     if (renew) {
125         result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
126                 dns1, dns2, server, &lease);
127     } else {
128         result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
129                 dns1, dns2, server, &lease);
130     }
131
132     env->ReleaseStringUTFChars(ifname, nameStr);
133     if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
134         env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
135
136         // set the gateway
137         jclass cls = env->FindClass("java/net/InetAddress");
138         jmethodID method = env->GetStaticMethodID(cls, "getByName",
139                 "(Ljava/lang/String;)Ljava/net/InetAddress;");
140         jvalue args[1];
141         args[0].l = env->NewStringUTF(gateway);
142         jobject inetAddressObject = env->CallStaticObjectMethodA(cls, method, args);
143
144         if (!env->ExceptionOccurred()) {
145             cls = env->FindClass("android/net/RouteInfo");
146             method = env->GetMethodID(cls, "<init>", "(Ljava/net/InetAddress;)V");
147             args[0].l = inetAddressObject;
148             jobject routeInfoObject = env->NewObjectA(cls, method, args);
149
150             cls = env->FindClass("android/net/DhcpInfoInternal");
151             method = env->GetMethodID(cls, "addRoute", "(Landroid/net/RouteInfo;)V");
152             args[0].l = routeInfoObject;
153             env->CallVoidMethodA(info, method, args);
154         } else {
155             // if we have an exception (host not found perhaps), just don't add the route
156             env->ExceptionClear();
157         }
158
159         env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
160         env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1));
161         env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2));
162         env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
163                 env->NewStringUTF(server));
164         env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
165     }
166     return (jboolean)(result == 0);
167 }
168
169 static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
170 {
171     return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
172 }
173
174 static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
175 {
176     return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
177 }
178
179
180 static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
181 {
182     int result;
183
184     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
185     result = ::dhcp_stop(nameStr);
186     env->ReleaseStringUTFChars(ifname, nameStr);
187     return (jboolean)(result == 0);
188 }
189
190 static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
191 {
192     int result;
193
194     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
195     result = ::dhcp_release_lease(nameStr);
196     env->ReleaseStringUTFChars(ifname, nameStr);
197     return (jboolean)(result == 0);
198 }
199
200 static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
201 {
202     return env->NewStringUTF(::dhcp_get_errmsg());
203 }
204
205 // ----------------------------------------------------------------------------
206
207 /*
208  * JNI registration.
209  */
210 static JNINativeMethod gNetworkUtilMethods[] = {
211     /* name, signature, funcPtr */
212
213     { "enableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_enableInterface },
214     { "disableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_disableInterface },
215     { "resetConnections", "(Ljava/lang/String;I)I",  (void *)android_net_utils_resetConnections },
216     { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcp },
217     { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcpRenew },
218     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
219     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
220     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
221 };
222
223 int register_android_net_NetworkUtils(JNIEnv* env)
224 {
225     jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
226     LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
227
228     dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
229     if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
230         dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V");
231         dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
232         dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I");
233         dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
234         dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
235         dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
236         dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I");
237     }
238
239     return AndroidRuntime::registerNativeMethods(env,
240             NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
241 }
242
243 }; // namespace android