static void requestRadioPower(void *data, size_t datalen, RIL_Token t) { int onOff; int err=0; ATResponse *p_response = NULL; assert (datalen >= sizeof(int *)); onOff = ((int *)data)[0]; if (onOff == 0 && sState != RADIO_STATE_OFF) { if (first_cfun == 0) { stop_pppd(); wait_for_pppd_down(); err = at_send_command("AT+CFUN=0", &p_response); if (err < 0) goto error; } else { first_cfun = 0; } setRadioState(RADIO_STATE_OFF); } else if (onOff > 0 && sState == RADIO_STATE_OFF) { err = at_send_command("AT+CFUN=1", &p_response); if (err < 0|| p_response->success == 0) { // Some stacks return an error when there is no SIM, // but they really turn the RF portion on // So, if we get an error, let's check to see if it // turned on anyway if (getRadioPower() != 1) { goto error; } } setRadioState(RADIO_STATE_SIM_NOT_READY); } at_response_free(p_response); RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); return; error: at_response_free(p_response); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); }
int start_pppd(int unit) { FILE *fp; char options[80]; char *pppd_argv[] = { "/usr/sbin/pppd", "file", options, NULL}; char tmp[100], prefix[] = "wanXXXXXXXXXX_"; char buf[256]; /* although maximum length of pppoe_username/pppoe_passwd is 64. pppd accepts up to 256 characters. */ mode_t mask; int ret = 0; _dprintf("%s: unit=%d.\n", __FUNCTION__, unit); snprintf(prefix, sizeof(prefix), "wan%d_", unit); sprintf(options, "/tmp/ppp/options.wan%d", unit); mask = umask(0000); /* Generate options file */ if (!(fp = fopen(options, "w"))) { perror(options); umask(mask); return -1; } umask(mask); /* do not authenticate peer and do not use eap */ fprintf(fp, "noauth\n"); fprintf(fp, "refuse-eap\n"); handle_special_char_for_pppd(buf, sizeof(buf), nvram_safe_get(strcat_r(prefix, "pppoe_username", tmp))); fprintf(fp, "user '%s'\n", buf); handle_special_char_for_pppd(buf, sizeof(buf), nvram_safe_get(strcat_r(prefix, "pppoe_passwd", tmp))); fprintf(fp, "password '%s'\n", buf); if (nvram_match(strcat_r(prefix, "proto", tmp), "pptp")) { fprintf(fp, "plugin pptp.so\n"); fprintf(fp, "pptp_server '%s'\n", nvram_invmatch(strcat_r(prefix, "heartbeat_x", tmp), "") ? nvram_safe_get(strcat_r(prefix, "heartbeat_x", tmp)) : nvram_safe_get(strcat_r(prefix, "gateway_x", tmp))); /* see KB Q189595 -- historyless & mtu */ fprintf(fp, "nomppe-stateful mtu 1400\n"); if (nvram_match(strcat_r(prefix, "pptp_options_x", tmp), "-mppc")) { fprintf(fp, "nomppe nomppc\n"); } else if (nvram_match(strcat_r(prefix, "pptp_options_x", tmp), "+mppe-40")) { fprintf(fp, "require-mppe\n"); fprintf(fp, "require-mppe-40\n"); } else if (nvram_match(strcat_r(prefix, "pptp_options_x", tmp), "+mppe-56")) { fprintf(fp, "nomppe-40\n" "require-mppe\n" "require-mppe-56\n"); } else if (nvram_match(strcat_r(prefix, "pptp_options_x", tmp), "+mppe-128")) { fprintf(fp, "nomppe-40\n" "nomppe-56\n" "require-mppe\n" "require-mppe-128\n"); } } else { fprintf(fp, "nomppe nomppc\n"); } if (nvram_match(strcat_r(prefix, "proto", tmp), "pppoe")) { fprintf(fp, "plugin rp-pppoe.so nic-%s\n", nvram_safe_get(strcat_r(prefix, "ifname", tmp))); if (nvram_invmatch(strcat_r(prefix, "pppoe_service", tmp), "")) { fprintf(fp, "rp_pppoe_service '%s'\n", nvram_safe_get(strcat_r(prefix, "pppoe_service", tmp))); } if (nvram_invmatch(strcat_r(prefix, "pppoe_ac", tmp), "")) { fprintf(fp, "rp_pppoe_ac '%s'\n", nvram_safe_get(strcat_r(prefix, "pppoe_ac", tmp))); } #ifdef RTCONFIG_DSL if (nvram_match("dsl0_proto", "pppoa")) { FILE *fp_dsl_mac; char *dsl_mac = NULL; int timeout = 10; /* wait up to 10 seconds */ while (timeout--) { fp_dsl_mac = fopen("/tmp/adsl/tc_mac.txt","r"); if (fp_dsl_mac != NULL) { dsl_mac = fgets(tmp, sizeof(tmp), fp_dsl_mac); dsl_mac = strsep(&dsl_mac, "\r\n"); fclose(fp_dsl_mac); break; } usleep(1000*1000); } fprintf(fp, "rp_pppoe_sess %d:%s\n", 154, (dsl_mac && *dsl_mac) ? dsl_mac : "00:11:22:33:44:55"); } #endif fprintf(fp, "mru %s mtu %s\n", nvram_safe_get(strcat_r(prefix, "pppoe_mru", tmp)), nvram_safe_get(strcat_r(prefix, "pppoe_mtu", tmp))); } if (nvram_invmatch(strcat_r(prefix, "proto", tmp), "l2tp")) { ret = nvram_get_int(strcat_r(prefix, "pppoe_idletime", tmp)); if (ret && nvram_get_int(strcat_r(prefix, "pppoe_demand", tmp))) { fprintf(fp, "idle %d ", ret); if (nvram_invmatch(strcat_r(prefix, "pppoe_txonly_x", tmp), "0")) fprintf(fp, "tx_only "); fprintf(fp, "demand\n"); } fprintf(fp, "persist\n"); } fprintf(fp, "holdoff %d\n", nvram_get_int(strcat_r(prefix, "pppoe_holdoff", tmp)) ? : 10); fprintf(fp, "maxfail %d\n", nvram_get_int(strcat_r(prefix, "pppoe_maxfail", tmp))); if (nvram_get_int(strcat_r(prefix, "dnsenable_x", tmp))) fprintf(fp, "usepeerdns\n"); fprintf(fp, "ipcp-accept-remote ipcp-accept-local noipdefault\n"); fprintf(fp, "ktune\n"); /* pppoe set these options automatically */ /* looks like pptp also likes them */ fprintf(fp, "default-asyncmap nopcomp noaccomp\n"); /* pppoe disables "vj bsdcomp deflate" automagically */ /* ccp should still be enabled - mppe/mppc requires this */ fprintf(fp, "novj nobsdcomp nodeflate\n"); /* echo failures */ fprintf(fp, "lcp-echo-interval 6\n"); fprintf(fp, "lcp-echo-failure 10\n"); /* pptp has Echo Request/Reply, l2tp has Hello packets */ if (nvram_match(strcat_r(prefix, "proto", tmp), "pptp") || nvram_match(strcat_r(prefix, "proto", tmp), "l2tp")) fprintf(fp, "lcp-echo-adaptive\n"); fprintf(fp, "unit %d\n", unit); fprintf(fp, "linkname wan%d\n", unit); #ifdef RTCONFIG_IPV6 switch (get_ipv6_service()) { case IPV6_NATIVE_DHCP: case IPV6_MANUAL: if (nvram_match("ipv6_ifdev", "ppp")) fprintf(fp, "+ipv6\n"); break; } #endif /* user specific options */ fprintf(fp, "%s\n", nvram_safe_get(strcat_r(prefix, "pppoe_options_x", tmp))); fclose(fp); /* shut down previous instance if any */ stop_pppd(unit); nvram_set(strcat_r(prefix, "pppoe_ifname", tmp), ""); if (nvram_match(strcat_r(prefix, "proto", tmp), "l2tp")) { if (!(fp = fopen("/tmp/l2tp.conf", "w"))) { perror(options); return -1; } fprintf(fp, "# automagically generated\n" "global\n\n" "load-handler \"sync-pppd.so\"\n" "load-handler \"cmd.so\"\n\n" "section sync-pppd\n\n" "lac-pppd-opts \"file %s\"\n\n" "section peer\n" "port 1701\n" "peername %s\n" "hostname %s\n" "lac-handler sync-pppd\n" "persist yes\n" "maxfail %d\n" "holdoff %d\n" "hide-avps no\n" "section cmd\n\n", options, nvram_invmatch(strcat_r(prefix, "heartbeat_x", tmp), "") ? nvram_safe_get(strcat_r(prefix, "heartbeat_x", tmp)) : nvram_safe_get(strcat_r(prefix, "gateway_x", tmp)), nvram_invmatch(strcat_r(prefix, "hostname", tmp), "") ? nvram_safe_get(strcat_r(prefix, "hostname", tmp)) : "localhost", nvram_get_int(strcat_r(prefix, "pppoe_maxfail", tmp)) ? : 32767, nvram_get_int(strcat_r(prefix, "pppoe_holdoff", tmp)) ? : 10); fclose(fp); /* launch l2tp */ eval("/usr/sbin/l2tpd"); ret = 3; do { _dprintf("%s: wait l2tpd up at %d seconds...\n", __FUNCTION__, ret); usleep(1000*1000); } while (!pids("l2tpd") && ret--); /* start-session */ ret = eval("/usr/sbin/l2tp-control", "start-session 0.0.0.0"); /* pppd sync nodetach noaccomp nobsdcomp nodeflate */ /* nopcomp novj novjccomp file /tmp/ppp/options.l2tp */ } else
int main(int argc, char **argv) { struct pollfd pollfds[3]; int control = -1; int timeout; int status; #ifdef ANDROID_CHANGES control = android_get_control_and_arguments(&argc, &argv); shutdown(control, SHUT_WR); #endif srandom(time(NULL)); if (pipe(signals) == -1) { log_print(FATAL, "Pipe() %s", strerror(errno)); exit(SYSTEM_ERROR); } fcntl(signals[0], F_SETFD, FD_CLOEXEC); fcntl(signals[1], F_SETFD, FD_CLOEXEC); timeout = initialize(argc, argv); signal(SIGHUP, interrupt); signal(SIGINT, interrupt); signal(SIGTERM, interrupt); signal(SIGCHLD, interrupt); signal(SIGPIPE, SIG_IGN); atexit(stop_pppd); pollfds[0].fd = the_socket; pollfds[0].events = POLLIN; pollfds[1].fd = signals[0]; pollfds[1].events = POLLIN; pollfds[2].fd = control; pollfds[2].events = 0; while (timeout >= 0) { if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) { log_print(FATAL, "Poll() %s", strerror(errno)); exit(SYSTEM_ERROR); } if (pollfds[1].revents) { break; } if (pollfds[2].revents) { interrupt(SIGTERM); } timeout = pollfds[0].revents ? the_protocol->process() : the_protocol->timeout(); #ifdef ANDROID_CHANGES if (!access("/data/misc/vpn/abort", F_OK)) { interrupt(SIGTERM); } if (!timeout) { timeout = 5000; } #endif } if (timeout < 0) { status = -timeout; } else { int signal; read(signals[0], &signal, sizeof(int)); log_print(INFO, "Received signal %d", signal); if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid && WIFEXITED(status)) { status = WEXITSTATUS(status); log_print(INFO, "Pppd is terminated (status = %d)", status); status += PPPD_EXITED; pppd_pid = 0; } else { status = USER_REQUESTED; } } stop_pppd(); the_protocol->shutdown(); log_print(INFO, "Mtpd is terminated (status = %d)", status); return status; }