OSDN Git Service

DO NOT MERGE Revert "DO NOT MERGE Add DhcpStateMachine"
[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_add_route(const char *ifname, const char *destStr, uint32_t prefixLen, const char *gwStr);
30 int ifc_remove_host_routes(const char *ifname);
31 int ifc_get_default_route(const char *ifname);
32 int ifc_remove_default_route(const char *ifname);
33 int ifc_reset_connections(const char *ifname);
34
35 int dhcp_do_request(const char *ifname,
36                     const char *ipaddr,
37                     const char *gateway,
38                     uint32_t  *prefixLength,
39                     const char *dns1,
40                     const char *dns2,
41                     const char *server,
42                     uint32_t  *lease);
43 int dhcp_stop(const char *ifname);
44 int dhcp_release_lease(const char *ifname);
45 char *dhcp_get_errmsg();
46 }
47
48 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
49
50 namespace android {
51
52 /*
53  * The following remembers the jfieldID's of the fields
54  * of the DhcpInfo Java object, so that we don't have
55  * to look them up every time.
56  */
57 static struct fieldIds {
58     jclass dhcpInfoInternalClass;
59     jmethodID constructorId;
60     jfieldID ipaddress;
61     jfieldID gateway;
62     jfieldID prefixLength;
63     jfieldID dns1;
64     jfieldID dns2;
65     jfieldID serverAddress;
66     jfieldID leaseDuration;
67 } dhcpInfoInternalFieldIds;
68
69 static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
70 {
71     int result;
72
73     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
74     result = ::ifc_enable(nameStr);
75     env->ReleaseStringUTFChars(ifname, nameStr);
76     return (jint)result;
77 }
78
79 static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
80 {
81     int result;
82
83     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
84     result = ::ifc_disable(nameStr);
85     env->ReleaseStringUTFChars(ifname, nameStr);
86     return (jint)result;
87 }
88
89 static jint android_net_utils_addRoute(JNIEnv* env, jobject clazz, jstring ifname,
90           jstring dst, jint prefixLength, jstring gw)
91 {
92     int result;
93
94     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
95     const char *dstStr = env->GetStringUTFChars(dst, NULL);
96     const char *gwStr = NULL;
97     if (gw != NULL) {
98         gwStr = env->GetStringUTFChars(gw, NULL);
99     }
100     result = ::ifc_add_route(nameStr, dstStr, prefixLength, gwStr);
101     env->ReleaseStringUTFChars(ifname, nameStr);
102     env->ReleaseStringUTFChars(dst, dstStr);
103     if (gw != NULL) {
104         env->ReleaseStringUTFChars(gw, gwStr);
105     }
106     return (jint)result;
107 }
108
109 static jint android_net_utils_removeHostRoutes(JNIEnv* env, jobject clazz, jstring ifname)
110 {
111     int result;
112
113     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
114     result = ::ifc_remove_host_routes(nameStr);
115     env->ReleaseStringUTFChars(ifname, nameStr);
116     return (jint)result;
117 }
118
119 static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
120 {
121     int result;
122
123     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
124     result = ::ifc_get_default_route(nameStr);
125     env->ReleaseStringUTFChars(ifname, nameStr);
126     return (jint)result;
127 }
128
129 static jint android_net_utils_removeDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
130 {
131     int result;
132
133     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
134     result = ::ifc_remove_default_route(nameStr);
135     env->ReleaseStringUTFChars(ifname, nameStr);
136     return (jint)result;
137 }
138
139 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
140 {
141     int result;
142
143     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
144     result = ::ifc_reset_connections(nameStr);
145     env->ReleaseStringUTFChars(ifname, nameStr);
146     return (jint)result;
147 }
148
149 static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
150 {
151     int result;
152     char  ipaddr[PROPERTY_VALUE_MAX];
153     uint32_t prefixLength;
154     char gateway[PROPERTY_VALUE_MAX];
155     char    dns1[PROPERTY_VALUE_MAX];
156     char    dns2[PROPERTY_VALUE_MAX];
157     char  server[PROPERTY_VALUE_MAX];
158     uint32_t lease;
159
160     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
161     if (nameStr == NULL) return (jboolean)false;
162
163     result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
164                                         dns1, dns2, server, &lease);
165     env->ReleaseStringUTFChars(ifname, nameStr);
166     if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
167         env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
168         env->SetObjectField(info, dhcpInfoInternalFieldIds.gateway, env->NewStringUTF(gateway));
169         env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
170         env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1));
171         env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2));
172         env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
173                 env->NewStringUTF(server));
174         env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
175     }
176     return (jboolean)(result == 0);
177 }
178
179 static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
180 {
181     int result;
182
183     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
184     result = ::dhcp_stop(nameStr);
185     env->ReleaseStringUTFChars(ifname, nameStr);
186     return (jboolean)(result == 0);
187 }
188
189 static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
190 {
191     int result;
192
193     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
194     result = ::dhcp_release_lease(nameStr);
195     env->ReleaseStringUTFChars(ifname, nameStr);
196     return (jboolean)(result == 0);
197 }
198
199 static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
200 {
201     return env->NewStringUTF(::dhcp_get_errmsg());
202 }
203
204 // ----------------------------------------------------------------------------
205
206 /*
207  * JNI registration.
208  */
209 static JNINativeMethod gNetworkUtilMethods[] = {
210     /* name, signature, funcPtr */
211
212     { "enableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_enableInterface },
213     { "disableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_disableInterface },
214     { "addRoute", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)I",
215        (void *)android_net_utils_addRoute },
216     { "removeHostRoutes", "(Ljava/lang/String;)I",  (void *)android_net_utils_removeHostRoutes },
217     { "getDefaultRouteNative", "(Ljava/lang/String;)I",
218        (void *)android_net_utils_getDefaultRoute },
219     { "removeDefaultRoute", "(Ljava/lang/String;)I",  (void *)android_net_utils_removeDefaultRoute },
220     { "resetConnections", "(Ljava/lang/String;)I",  (void *)android_net_utils_resetConnections },
221     { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcp },
222     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
223     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
224     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
225 };
226
227 int register_android_net_NetworkUtils(JNIEnv* env)
228 {
229     jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
230     LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
231
232     dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
233     if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
234         dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V");
235         dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
236         dhcpInfoInternalFieldIds.gateway = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "gateway", "Ljava/lang/String;");
237         dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I");
238         dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
239         dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
240         dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
241         dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I");
242     }
243
244     return AndroidRuntime::registerNativeMethods(env,
245             NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
246 }
247
248 }; // namespace android