blob: 385c1005fedc5fa63539d0244b3da4cb24bebcfb
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 | #include "../../ppp/pppd/pathnames.h" |
91 | #define CONFIG_FILE _ROOT_PATH "/etc/ppp/pppd_options.conf" |
92 | |
93 | |
94 | |
95 | /* Handy routine to read very long lines in text files. |
96 | * This means we read the whole line and avoid any nasty buffer overflows. */ |
97 | static ssize_t get_line(char **line, size_t *len, FILE *fp) |
98 | { |
99 | char *p; |
100 | size_t last = 0; |
101 | |
102 | while(!feof(fp)) { |
103 | if (*line == NULL || last != 0) { |
104 | *len += BUFSIZ; |
105 | *line = (char*)realloc(*line, *len); |
106 | } |
107 | p = *line + last; |
108 | memset(p, 0, BUFSIZ); |
109 | if (fgets(p, BUFSIZ, fp) == NULL) |
110 | break; |
111 | last += strlen(p); |
112 | if (last && (*line)[last - 1] == '\n') { |
113 | (*line)[last - 1] = '\0'; |
114 | break; |
115 | } |
116 | } |
117 | return last; |
118 | } |
119 | |
120 | static const char PPPOE_PHY_IF_PROP_NAME[] = "net.pppoe.phyif"; |
121 | |
122 | static jboolean com_amlogic_PppoeOperation_connect |
123 | (JNIEnv *env, jobject obj, jstring jstr_if_name, jstring jstr_account, jstring jstr_passwd) |
124 | { |
125 | char *p_ifname; |
126 | char *p_user; |
127 | char *p_passwd; |
128 | struct netwrapper_ctrl * ctrl; |
129 | char *p; |
130 | |
131 | FILE *f; |
132 | f = fopen(CONFIG_FILE, "r"); |
133 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"Try Open %s", CONFIG_FILE); |
134 | |
135 | if (f) { |
136 | char *line, *option, *p, *buffer = NULL; |
137 | size_t len = 0; |
138 | |
139 | get_line(&buffer, &len, f); |
140 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"get_line: [%s]", buffer); |
141 | if (buffer){ |
142 | strncpy(pppd_options, buffer, sizeof(pppd_options) - 1); |
143 | free(buffer); |
144 | } |
145 | fclose(f); |
146 | } |
147 | |
148 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
149 | p_user = (char *)env->GetStringUTFChars(jstr_account, NULL); |
150 | p_passwd = (char *)env->GetStringUTFChars(jstr_passwd, NULL); |
151 | |
152 | property_set(PPPOE_PHY_IF_PROP_NAME, p_ifname); |
153 | |
154 | p = create_pppoe_plugin_cmd((char*)PPPOE_PIDFILE, p_ifname); |
155 | if (!p) { |
156 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"failed to create plug_in command\n"); |
157 | return -1; |
158 | } |
159 | |
160 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"plug_in command: %s\n", p); |
161 | |
162 | p = create_pppoe_connect_cmd(p, pppd_options, p_user, p_passwd); |
163 | if (!p) { |
164 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"failed to create connect command\n"); |
165 | return -1; |
166 | } |
167 | |
168 | __android_log_print(ANDROID_LOG_INFO, LOCAL_TAG,"connect command: %s\n", p); |
169 | |
170 | |
171 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.connect\n"); |
172 | |
173 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
174 | if (ctrl == NULL) { |
175 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
176 | return -1; |
177 | } |
178 | |
179 | netwrapper_ctrl_request(ctrl, pppoe_connect_cmd, strlen(pppoe_connect_cmd)); |
180 | |
181 | netwrapper_ctrl_close(ctrl); |
182 | |
183 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
184 | env->ReleaseStringUTFChars(jstr_account, p_user); |
185 | env->ReleaseStringUTFChars(jstr_passwd, p_passwd); |
186 | |
187 | return 1; |
188 | } |
189 | |
190 | |
191 | |
192 | jboolean com_amlogic_PppoeOperation_disconnect |
193 | (JNIEnv *env, jobject obj) |
194 | { |
195 | struct netwrapper_ctrl * ctrl; |
196 | |
197 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.disconnect\n"); |
198 | |
199 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
200 | if (ctrl == NULL) { |
201 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
202 | return -1; |
203 | } |
204 | |
205 | netwrapper_ctrl_request(ctrl, pppoe_disconnect_cmd, strlen(pppoe_disconnect_cmd)); |
206 | |
207 | netwrapper_ctrl_close(ctrl); |
208 | |
209 | return 1; |
210 | } |
211 | |
212 | jboolean com_amlogic_PppoeOperation_terminate |
213 | (JNIEnv *env, jobject obj) |
214 | { |
215 | struct netwrapper_ctrl * ctrl; |
216 | |
217 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.terminate\n"); |
218 | |
219 | ctrl = netwrapper_ctrl_open(PPPOE_WRAPPER_CLIENT_PATH, PPPOE_WRAPPER_SERVER_PATH); |
220 | if (ctrl == NULL) { |
221 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG, "Failed to connect to pppd\n"); |
222 | return -1; |
223 | } |
224 | |
225 | netwrapper_ctrl_request(ctrl, pppoe_terminate_cmd, strlen(pppoe_terminate_cmd)); |
226 | |
227 | netwrapper_ctrl_close(ctrl); |
228 | |
229 | return 1; |
230 | } |
231 | |
232 | jint com_amlogic_PppoeOperation_isNetAdded |
233 | (JNIEnv *env, jobject obj, jstring jstr_if_name) |
234 | { |
235 | char *p_ifname; |
236 | int status; |
237 | |
238 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.isNetAdded\n"); |
239 | |
240 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
241 | status = get_net_updown(p_ifname); |
242 | |
243 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
244 | |
245 | return status; |
246 | } |
247 | |
248 | jint com_amlogic_PppoeOperation_status |
249 | (JNIEnv *env, jobject obj, jstring jstr_if_name) |
250 | { |
251 | char *p_ifname; |
252 | int status; |
253 | |
254 | __android_log_print(ANDROID_LOG_ERROR, LOCAL_TAG,"ppp.status\n"); |
255 | |
256 | p_ifname = (char *)env->GetStringUTFChars(jstr_if_name, NULL); |
257 | status = get_pppoe_status(p_ifname); |
258 | |
259 | env->ReleaseStringUTFChars(jstr_if_name, p_ifname); |
260 | |
261 | return status; |
262 | } |
263 | |
264 | |
265 | static JNINativeMethod gPppoeJNIMethods[] = { |
266 | /* name, signature, funcPtr */ |
267 | { "_connect", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", (void*) com_amlogic_PppoeOperation_connect }, |
268 | { "_disconnect", "()Z", (void*) com_amlogic_PppoeOperation_disconnect }, |
269 | { "_terminate", "()Z", (void*) com_amlogic_PppoeOperation_terminate }, |
270 | { "isNetAdded", "(Ljava/lang/String;)I", (void*) com_amlogic_PppoeOperation_isNetAdded }, |
271 | { "status", "(Ljava/lang/String;)I", (void*) com_amlogic_PppoeOperation_status }, |
272 | }; |
273 | |
274 | |
275 | #define PPPOE_CLASS_NAME "com/amlogic/pppoe/PppoeOperation" |
276 | |
277 | |
278 | int register_pppoe_jni(JNIEnv* env) |
279 | { |
280 | int ret; |
281 | jclass pppoe = env->FindClass(PPPOE_CLASS_NAME); |
282 | if (NULL == pppoe) { |
283 | LOGI("%s:Unable to find class %s", __FUNCTION__, PPPOE_CLASS_NAME); |
284 | return -1; |
285 | } |
286 | else { |
287 | LOGI("%s:class %s FOUND", __FUNCTION__, PPPOE_CLASS_NAME); |
288 | } |
289 | |
290 | TRACE(); |
291 | ret = android::AndroidRuntime::registerNativeMethods(env, |
292 | PPPOE_CLASS_NAME, gPppoeJNIMethods, NELEM(gPppoeJNIMethods)); |
293 | return ret; |
294 | } |
295 | |
296 | |
297 | JNIEXPORT jint |
298 | JNI_OnLoad(JavaVM* vm, void* reserved) |
299 | { |
300 | jint ret; |
301 | JNIEnv* env = NULL; |
302 | TRACE(); |
303 | if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || NULL == env) { |
304 | LOGE("GetEnv failed!"); |
305 | return -1; |
306 | } |
307 | fields.gJavaVM = vm; |
308 | fields.env = env; |
309 | TRACE(); |
310 | ret = register_pppoe_jni(env); |
311 | LOGI("register_pppoe_jni=%d\n", ret); |
312 | if (ret == 0) { |
313 | return JNI_VERSION_1_4; |
314 | } else { |
315 | return -1; |
316 | } |
317 | } |
318 | |
319 | |
320 | JNIEXPORT void |
321 | JNI_OnUnload(JavaVM* vm, void* reserved) |
322 | { |
323 | return; |
324 | } |
325 | |
326 | |
327 |