blob: 48f497ae9aa360d2bb943f9927f5dc8ffee21591
1 | #define LOG_NDEBUG 0 |
2 | #define LOCAL_TAG "PPPOE_JNI" |
3 | |
4 | |
5 | /* |
6 | dalvik/libnativehelper/include/nativehelper/jni.h |
7 | */ |
8 | #include <jni.h> |
9 | |
10 | #include <JNIHelp.h> |
11 | |
12 | #include <android_runtime/AndroidRuntime.h> |
13 | |
14 | #include <utils/Log.h> |
15 | #include <stdio.h> |
16 | #include <stdlib.h> |
17 | |
18 | #include <unistd.h> |
19 | |
20 | #include <sys/socket.h> |
21 | #include <netinet/in.h> |
22 | |
23 | #include <sys/un.h> |
24 | #include "netwrapper.h" |
25 | #include "pppoe_status.h" |
26 | #include <android/log.h> |
27 | |
28 | #include "cutils/properties.h" |
29 | |
30 | #define PPPOE_PLUGIN_CMD_LEN_MAX 256 |
31 | #define PPPOE_CONNECT_CMD_LEN_MAX 512 |
32 | |
33 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) |
34 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) |
35 | #define TRACE() LOGI("[%s::%d]\n",__FUNCTION__,__LINE__) |
36 | using namespace android; |
37 | |
38 | |
39 | struct fields_t { |
40 | JavaVM *gJavaVM ; |
41 | JNIEnv* env; |
42 | jmethodID post_event; |
43 | }; |
44 | |
45 | static struct fields_t fields; |
46 | |
47 | extern int get_eth0_updown(); |
48 | extern int get_pppoe_status( const char *phy_if_name); |
49 | |
50 | static char pppoe_connect_cmd[PPPOE_CONNECT_CMD_LEN_MAX]; |
51 | |
52 | static char pppoe_disconnect_cmd[512] = "ppp-stop"; |
53 | static char pppoe_terminate_cmd[512] = "ppp-terminate"; |
54 | |
55 | static char pppoe_plugin_cmd[PPPOE_PLUGIN_CMD_LEN_MAX]; |
56 | |
57 | #define PPPD_OPTIONS_LEN 512 |
58 | static char pppd_options[PPPD_OPTIONS_LEN + 1] = {"debug logfd 1 noipdefault noauth default-asyncmap defaultroute show-password nodetach mtu 1492 mru 1492 noaccomp nodeflate nopcomp novj usepeerdns novjccomp lcp-echo-interval 20 lcp-echo-failure 3"}; |
59 | |
60 | |
61 | |
62 | static char* create_pppoe_plugin_cmd(char *pid_file, char *phy_if) |
63 | { |
64 | int len; |
65 | len = snprintf(pppoe_plugin_cmd, PPPOE_PLUGIN_CMD_LEN_MAX, |
66 | "'pppoe -p %s -I %s -T 80 -U -m 1412'", |
67 | pid_file, phy_if); |
68 | if ( len < 0 || len >= PPPOE_PLUGIN_CMD_LEN_MAX ) { |
69 | return NULL; |
70 | } |
71 | |
72 | return pppoe_plugin_cmd; |
73 | } |
74 | |
75 | |
76 | static char* create_pppoe_connect_cmd |
77 | (char *plugin_cmd, char *options, char *username, char *pwd) |
78 | { |
79 | int len; |
80 | len = snprintf(pppoe_connect_cmd, PPPOE_CONNECT_CMD_LEN_MAX, |
81 | "pppd pty %s %s user %s password %s &", |
82 | plugin_cmd, options, username, pwd); |
83 | if ( len < 0 || len >= PPPOE_CONNECT_CMD_LEN_MAX ) { |
84 | return NULL; |
85 | } |
86 | |
87 | return pppoe_connect_cmd; |
88 | } |
89 | |
90 | //#ifndef _ROOT_PATH |
91 | #define _ROOT_PATH "/data/misc" |
92 | #define CONFIG_FILE _ROOT_PATH "/etc/ppp/pppd_options.conf" |
93 | |
94 | |
95 | |
96 | /* Handy routine to read very long lines in text files. |
97 | * This means we read the whole line and avoid any nasty buffer overflows. */ |
98 | static ssize_t get_line(char **line, size_t *len, FILE *fp) |
99 | { |
100 | char *p; |
101 | size_t last = 0; |
102 | |
103 | while(!feof(fp)) { |
104 | if (*line == NULL || last != 0) { |
105 | *len += BUFSIZ; |
106 | *line = (char*)realloc(*line, *len); |
107 | } |
108 | p = *line + last; |
109 | memset(p, 0, BUFSIZ); |
110 | if (fgets(p, BUFSIZ, fp) == NULL) |
111 | break; |
112 | last += strlen(p); |
113 | if (last && (*line)[last - 1] == '\n') { |
114 | (*line)[last - 1] = '\0'; |
115 | break; |
116 | } |
117 | } |
118 | return last; |
119 | } |
120 | |
121 | static const char PPPOE_PHY_IF_PROP_NAME[] = "net.pppoe.phyif"; |
122 | |
123 | static jboolean com_amlogic_PppoeOperation_connect |
124 | (JNIEnv *env, jobject obj, jstring jstr_if_name, jstring jstr_account, jstring jstr_passwd) |
125 | { |
126 | char *p_ifname; |
127 | char *p_user; |
128 | char *p_passwd; |
129 | struct netwrapper_ctrl * ctrl; |
130 | char *p; |
131 | |
132 | FILE *f; |
133 | f = fopen(CONFIG_FILE, "r"); |
134 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"Try Open %s", CONFIG_FILE); |
135 | |
136 | if (f) { |
137 | char *line, *option, *p, *buffer = NULL; |
138 | size_t len = 0; |
139 | |
140 | get_line(&buffer, &len, f); |
141 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"get_line: [%s]", buffer); |
142 | if (buffer){ |
143 | strncpy(pppd_options, buffer, sizeof(pppd_options) - 1); |
144 | free(buffer); |
145 | } |
146 | fclose(f); |
147 | } |
148 | |
149 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
150 | p_user = (char *)env->GetStringUTFChars(jstr_account, NULL); |
151 | p_passwd = (char *)env->GetStringUTFChars(jstr_passwd, NULL); |
152 | |
153 | property_set(PPPOE_PHY_IF_PROP_NAME, p_ifname); |
154 | |
155 | p = create_pppoe_plugin_cmd((char*)PPPOE_PIDFILE, p_ifname); |
156 | if (!p) { |
157 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"failed to create plug_in command\n"); |
158 | return -1; |
159 | } |
160 | |
161 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"plug_in command: %s\n", p); |
162 | |
163 | p = create_pppoe_connect_cmd(p, pppd_options, p_user, p_passwd); |
164 | if (!p) { |
165 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"failed to create connect command\n"); |
166 | return -1; |
167 | } |
168 | |
169 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"connect command: %s\n", p); |
170 | |
171 | |
172 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.connect\n"); |
173 | |
174 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
175 | if (ctrl == NULL) { |
176 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
177 | return -1; |
178 | } |
179 | |
180 | netwrapper_ctrl_request(ctrl, pppoe_connect_cmd, strlen(pppoe_connect_cmd)); |
181 | |
182 | netwrapper_ctrl_close(ctrl); |
183 | |
184 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
185 | env->ReleaseStringUTFChars(jstr_account, p_user); |
186 | env->ReleaseStringUTFChars(jstr_passwd, p_passwd); |
187 | |
188 | return 1; |
189 | } |
190 | |
191 | |
192 | |
193 | jboolean com_amlogic_PppoeOperation_disconnect |
194 | (JNIEnv *env, jobject obj) |
195 | { |
196 | struct netwrapper_ctrl * ctrl; |
197 | |
198 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.disconnect\n"); |
199 | |
200 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
201 | if (ctrl == NULL) { |
202 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
203 | return -1; |
204 | } |
205 | |
206 | netwrapper_ctrl_request(ctrl, pppoe_disconnect_cmd, strlen(pppoe_disconnect_cmd)); |
207 | |
208 | netwrapper_ctrl_close(ctrl); |
209 | |
210 | return 1; |
211 | } |
212 | |
213 | jboolean com_amlogic_PppoeOperation_terminate |
214 | (JNIEnv *env, jobject obj) |
215 | { |
216 | struct netwrapper_ctrl * ctrl; |
217 | |
218 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.terminate\n"); |
219 | |
220 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
221 | if (ctrl == NULL) { |
222 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
223 | return -1; |
224 | } |
225 | |
226 | netwrapper_ctrl_request(ctrl, pppoe_terminate_cmd, strlen(pppoe_terminate_cmd)); |
227 | |
228 | netwrapper_ctrl_close(ctrl); |
229 | |
230 | return 1; |
231 | } |
232 | |
233 | jint com_amlogic_PppoeOperation_isNetAdded |
234 | (JNIEnv *env, jobject obj, jstring jstr_if_name) |
235 | { |
236 | char *p_ifname; |
237 | int status; |
238 | |
239 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.isNetAdded\n"); |
240 | |
241 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
242 | status = get_net_updown(p_ifname); |
243 | |
244 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
245 | |
246 | return status; |
247 | } |
248 | |
249 | jint com_amlogic_PppoeOperation_status |
250 | (JNIEnv *env, jobject obj, jstring jstr_if_name) |
251 | { |
252 | char *p_ifname; |
253 | int status; |
254 | |
255 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.status\n"); |
256 | |
257 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
258 | status = get_pppoe_status(p_ifname); |
259 | |
260 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
261 | |
262 | return status; |
263 | } |
264 | |
265 | |
266 | static JNINativeMethod gPppoeJNIMethods[] = { |
267 | /* name, signature, funcPtr */ |
268 | { "_connect", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", (void*) com_amlogic_PppoeOperation_connect }, |
269 | { "_disconnect", "()Z", (void*) com_amlogic_PppoeOperation_disconnect }, |
270 | { "_terminate", "()Z", (void*) com_amlogic_PppoeOperation_terminate }, |
271 | { "isNetAdded", "(Ljava/lang/String;)I", (void*) com_amlogic_PppoeOperation_isNetAdded }, |
272 | { "status", "(Ljava/lang/String;)I", (void*) com_amlogic_PppoeOperation_status }, |
273 | }; |
274 | |
275 | |
276 | #define PPPOE_CLASS_NAME "com/amlogic/pppoe/PppoeOperation" |
277 | |
278 | |
279 | int register_pppoe_jni(JNIEnv* env) |
280 | { |
281 | int ret; |
282 | jclass pppoe = env->FindClass(PPPOE_CLASS_NAME); |
283 | if (NULL == pppoe) { |
284 | LOGI("%s:Unable to find class %s", __FUNCTION__, PPPOE_CLASS_NAME); |
285 | return -1; |
286 | } |
287 | else { |
288 | LOGI("%s:class %s FOUND", __FUNCTION__, PPPOE_CLASS_NAME); |
289 | } |
290 | |
291 | TRACE(); |
292 | ret = android::AndroidRuntime::registerNativeMethods(env, |
293 | PPPOE_CLASS_NAME, gPppoeJNIMethods, NELEM(gPppoeJNIMethods)); |
294 | return ret; |
295 | } |
296 | |
297 | |
298 | JNIEXPORT jint |
299 | JNI_OnLoad(JavaVM* vm, void* reserved) |
300 | { |
301 | jint ret; |
302 | JNIEnv* env = NULL; |
303 | TRACE(); |
304 | if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || NULL == env) { |
305 | LOGE("GetEnv failed!"); |
306 | return -1; |
307 | } |
308 | fields.gJavaVM = vm; |
309 | fields.env = env; |
310 | TRACE(); |
311 | ret = register_pppoe_jni(env); |
312 | LOGI("register_pppoe_jni=%d\n", ret); |
313 | if (ret == 0) { |
314 | return JNI_VERSION_1_4; |
315 | } else { |
316 | return -1; |
317 | } |
318 | } |
319 | |
320 | |
321 | JNIEXPORT void |
322 | JNI_OnUnload(JavaVM* vm, void* reserved) |
323 | { |
324 | return; |
325 | } |
326 | |
327 | |
328 |