int ifc_configure(const char *ifname, in_addr_t address, in_addr_t gateway) { in_addr_t netmask = ~0; (void) gateway; ifc_init(); if (ifc_up(ifname)) { LOGE("%s() Failed to turn on interface %s: %s", __func__, ifname, strerror(errno)); ifc_close(); return -1; } if (ifc_set_addr(ifname, address)) { LOGE("%s() Failed to set ipaddr %s: %s", __func__, ipaddr_to_string(address), strerror(errno)); ifc_down(ifname); ifc_close(); return -1; } if (ifc_set_mask(ifname, netmask)) { LOGE("%s() failed to set netmask %s: %s", __func__, ipaddr_to_string(netmask), strerror(errno)); ifc_down(ifname); ifc_close(); return -1; } ifc_close(); return 0; }
int set_iface(const char *iface, int on) { int u4Count = 0; if(ifc_init() != 0) { LOGE("[%s] interface set %d failed", iface, on); return -1; } if(on) { while(ifc_up(iface) == -1) { LOGD("[%s] interface is not ready, wait %dus", iface, SET_IFACE_DELAY); sched_yield(); usleep(SET_IFACE_DELAY); if (++u4Count >= SET_IFACE_POLLING_LOOP) { LOGE("[%s] interface set %d failed", iface, on); ifc_close(); return -1; } } LOGD("[%s] interface is up", iface); init_iface(iface); } else { ifc_down(iface); LOGD("[%s] interface is down", iface); } ifc_close(); return 0; }
int ifc_disable(const char *ifname) { int result; ifc_init(); result = ifc_down(ifname); ifc_set_addr(ifname, 0); ifc_close(); return result; }
int ifc_disable(const char *ifname) { unsigned addr, count; int result; ifc_init(); result = ifc_down(ifname); ifc_set_addr(ifname, 0); for (count=0, addr=1; ((addr != 0) && (count < 255)); count++) { if (ifc_get_addr(ifname, &addr) < 0) break; if (addr) ifc_set_addr(ifname, 0); } ifc_close(); return result; }
/* CHECK There are several error cases if PDP deactivation fails * 24.008: 8, 25, 36, 38, 39, 112 */ void requestDeactivateDefaultPDP(void *data, size_t datalen, RIL_Token t) { int e2napState = getE2napState(); int cid = atoi(((const char **) data)[0]); (void) datalen; if (cid != s_ActiveCID) { ALOGD("%s() Not tearing down cid:%d since cid:%d is active", __func__, cid, s_ActiveCID); goto done; } s_DeactCalled = 1; if (e2napState == E2NAP_STATE_CONNECTING) ALOGW("%s() Tear down connection while connection setup in progress", __func__); if (e2napState != E2NAP_STATE_DISCONNECTED) { if (disconnect()) goto error; e2napState = getE2napState(); if (e2napState != E2NAP_STATE_DISCONNECTED) goto error; /* Bring down the interface as well. */ if (ifc_init()) goto error; if (ifc_down(ril_iface)) goto error; ifc_close(); } done: RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); }
int ipc_gprs_connection_disable(struct ril_gprs_connection *gprs_connection) { struct ipc_client *ipc_client; char *interface; int rc; ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client; if(gprs_connection->interface == NULL) { interface = ipc_client_gprs_get_iface(ipc_client, gprs_connection->cid); if(interface == NULL) { // This is not a critical issue, fallback to rmnet LOGE("Failed to get interface name!"); asprintf(&interface, "rmnet%d", gprs_connection->cid); } } else { interface = gprs_connection->interface; } LOGD("Using net interface: %s\n", interface); rc = ifc_down(interface); if(gprs_connection->interface == NULL) free(interface); if(rc < 0) { LOGE("ifc_down failed"); } if(ipc_client_gprs_handlers_available(ipc_client)) { rc = ipc_client_gprs_deactivate(ipc_client); if(rc < 0) { // This is not a critical issue LOGE("Failed to deactivate interface!"); } } return 0; }
int SoftapController::stopDriver(char *iface) { int ret; if (mSock < 0) { LOGE("Softap driver stop - failed to open socket"); return -1; } if (!iface || (iface[0] == '\0')) { LOGD("Softap driver stop - wrong interface"); iface = mIface; } *mBuf = 0; #ifdef HAVE_HOSTAPD ifc_init(); ret = ifc_down(iface); ifc_close(); if (ret < 0) { LOGE("Softap %s down: %d", iface, ret); } #endif ret = setCommand(iface, "STOP"); LOGD("Softap driver stop: %d", ret); return ret; }
int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, int argc, char **argv) { if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (!strcmp(argv[1], "list")) { DIR *d; struct dirent *de; if (!(d = opendir("/sys/class/net"))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); return 0; } while((de = readdir(d))) { if (de->d_name[0] == '.') continue; cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); } closedir(d); cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); return 0; } else if (!strcmp(argv[1], "readrxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readrxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg; asprintf(&msg, "%lu", rx); cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "readtxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readtxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg = NULL; asprintf(&msg, "%lu", tx); cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "getthrottle")) { if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface getthrottle <interface> <rx|tx>", false); return 0; } int val = 0; int rc = 0; int voldRc = ResponseCode::InterfaceRxThrottleResult; if (!strcmp(argv[3], "rx")) { rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); } else { rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); voldRc = ResponseCode::InterfaceTxThrottleResult; } if (rc) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); } else { char *msg = NULL; asprintf(&msg, "%u", val); cli->sendMsg(voldRc, msg, false); free(msg); return 0; } return 0; } else if (!strcmp(argv[1], "setthrottle")) { if (argc != 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); return 0; } if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); } return 0; } else { /* * These commands take a minimum of 3 arguments */ if (argc < 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (!strcmp(argv[1], "getcfg")) { struct in_addr addr, mask; unsigned char hwaddr[6]; unsigned flags = 0; ifc_init(); memset(hwaddr, 0, sizeof(hwaddr)); if (ifc_get_info(argv[2], &addr.s_addr, &mask.s_addr, &flags)) { cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); return 0; } if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { LOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); } char *addr_s = strdup(inet_ntoa(addr)); char *mask_s = strdup(inet_ntoa(mask)); const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; updown = (flags & IFF_UP) ? "up" : "down"; brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; running = (flags & IFF_RUNNING) ? " running" : ""; multi = (flags & IFF_MULTICAST) ? " multicast" : ""; char *flag_s; asprintf(&flag_s, "[%s%s%s%s%s%s]", updown, brdcst, loopbk, ppp, running, multi); char *msg = NULL; asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %s %s", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], addr_s, mask_s, flag_s); cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); free(addr_s); free(mask_s); free(flag_s); free(msg); return 0; } else if (!strcmp(argv[1], "setcfg")) { // arglist: iface addr mask [flags] if (argc < 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } LOGD("Setting iface cfg"); struct in_addr addr, mask; unsigned flags = 0; if (!inet_aton(argv[3], &addr)) { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid address", false); return 0; } if (!inet_aton(argv[4], &mask)) { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid netmask", false); return 0; } ifc_init(); if (ifc_set_addr(argv[2], addr.s_addr)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); return 0; } if (ifc_set_mask(argv[2], mask.s_addr)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set netmask", true); return 0; } /* Process flags */ /* read from "[XX" arg to "YY]" arg */ bool bStarted = false; for (int i = 5; i < argc; i++) { char *flag = argv[i]; if (!bStarted) { if (*flag == '[') { flag++; bStarted = true; } else { continue; } } int len = strlen(flag); if (flag[len-1] == ']') { i = argc; // stop after this loop flag[len-1] = 0; } if (!strcmp(flag, "up")) { LOGD("Trying to bring up %s", argv[2]); if (ifc_up(argv[2])) { LOGE("Error upping interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); return 0; } } else if (!strcmp(flag, "down")) { LOGD("Trying to bring down %s", argv[2]); if (ifc_down(argv[2])) { LOGE("Error downing interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); return 0; } } else if (!strcmp(flag, "broadcast")) { LOGD("broadcast flag ignored"); } else if (!strcmp(flag, "multicast")) { LOGD("multicast flag ignored"); } else { cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); return 0; } } cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); return 0; } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); return 0; } } return 0; }
/* CHECK There are several error cases if PDP deactivation fails * 24.008: 8, 25, 36, 38, 39, 112 */ void requestDeactivateDefaultPDP(void *data, size_t datalen, RIL_Token t) { ATResponse *p_response = NULL; int enap = 0; int err, i; char *line; (void) data; (void) datalen; err = at_send_command_singleline("AT*ENAP?", "*ENAP:", &p_response); if (err != AT_NOERROR) goto error; line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &enap); if (err < 0) goto error; if (enap == ENAP_T_CONN_IN_PROG) LOGE("%s() Tear down connection while connection setup in progress", __func__); if (enap == ENAP_T_CONNECTED) { err = at_send_command("AT*ENAP=0"); /* TODO: can return CME error */ if (err != AT_NOERROR && at_get_error_type(err) != CME_ERROR) goto error; for (i = 0; i < MBM_ENAP_WAIT_TIME; i++) { at_response_free(p_response); p_response = NULL; err = at_send_command_singleline("AT*ENAP?", "*ENAP:", &p_response); if (err != AT_NOERROR) goto error; line = p_response->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto error; err = at_tok_nextint(&line, &enap); if (err < 0) goto error; if (enap == 0) break; sleep(1); } if (enap != ENAP_T_NOT_CONNECTED) goto error; /* Bring down the interface as well. */ if (ifc_init()) goto error; if (ifc_down(ril_iface)) goto error; ifc_close(); } RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0); at_response_free(p_response); return; error: RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); at_response_free(p_response); }
void requestSetupDefaultPDP(void *data, size_t datalen, RIL_Token t) { in_addr_t addr; in_addr_t gateway; const char *apn, *user, *pass, *auth; char *addresses = NULL; char *gateways = NULL; char *dnses = NULL; const char *type = NULL; RIL_Data_Call_Response_v6 response; int err = -1; int cme_err, i; int e2napState = setE2napState(-1); int e2napCause = setE2napCause(-1); (void) data; (void) datalen; memset(&response, 0, sizeof(response)); apn = ((const char **) data)[2]; user = ((const char **) data)[3]; pass = ((const char **) data)[4]; auth = ((const char **) data)[5]; type = getNWType(((const char **) data)[6]); s_lastPdpFailCause = PDP_FAIL_ERROR_UNSPECIFIED; LOGD("%s() requesting data connection to APN '%s'", __func__, apn); if (ifc_init()) { LOGE("%s() FAILED to set up ifc!", __func__); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } if (ifc_down(ril_iface)) { LOGE("%s() Failed to bring down %s!", __func__, ril_iface); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } err = at_send_command("AT+CGDCONT=%d,\"IP\",\"%s\"", RIL_CID_IP, apn); if (err != AT_NOERROR) { cme_err = at_get_cme_error(err); LOGE("%s() CGDCONT failed: %d, cme: %d", __func__, err, cme_err); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } if (networkAuth(auth, user, pass, RIL_CID_IP)) { RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } /* Start data on PDP context for IP */ err = at_send_command("AT*ENAP=1,%d", RIL_CID_IP); if (err != AT_NOERROR) { cme_err = at_get_cme_error(err); LOGE("requestSetupDefaultPDP: ENAP failed: %d cme: %d", err, cme_err); goto error; } for (i = 0; i < MBM_ENAP_WAIT_TIME; i++) { e2napState = getE2napState(); if (e2napState == E2NAP_ST_CONNECTED || e2napState == E2NAP_ST_DISCONNECTED) { LOGD("%s() %s", __func__, e2napStateToString(e2napState)); break; } usleep(200 * 1000); } e2napState = getE2napState(); e2napCause = getE2napCause(); if (e2napState == E2NAP_ST_DISCONNECTED) goto error; if (parse_ip_information(&addresses, &gateways, &dnses, &addr, &gateway) < 0) { LOGE("%s() Failed to parse network interface data", __func__); goto error; } e2napState = getE2napState(); response.addresses = addresses; response.gateways = gateways; response.dnses = dnses; LOGI("%s() Setting up interface %s,%s,%s", __func__, response.addresses, response.gateways, response.dnses); if (e2napState == E2NAP_ST_DISCONNECTED) goto error; /* we got disconnected */ response.ifname = ril_iface; response.active = 2; response.type = (char *) type; response.status = 0; response.cid = 1; response.suggestedRetryTime = -1; /* Don't use android netutils. We use our own and get the routing correct. * Carl Nordbeck */ if (ifc_configure(ril_iface, addr, gateway)) LOGE("%s() Failed to configure the interface %s", __func__, ril_iface); e2napState = getE2napState(); LOGI("IP Address %s, %s", addresses, e2napStateToString(e2napState)); if (e2napState == E2NAP_ST_DISCONNECTED) goto error; /* we got disconnected */ RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); free(addresses); free(gateways); free(dnses); return; error: response.status = getE2NAPFailCause(); mbm_check_error_cause(); /* Restore enap state and wait for enap to report disconnected*/ at_send_command("AT*ENAP=0"); for (i = 0; i < MBM_ENAP_WAIT_TIME; i++) { e2napState = getE2napState(); if (e2napState == E2NAP_ST_DISCONNECTED) break; usleep(200 * 1000); } if (response.status > 0) RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); else RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); free(addresses); free(gateways); free(dnses); }
int CommandListener::InterfaceCmd::runCommand(SocketClient *cli, int argc, char **argv) { if (argc < 2) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (!strcmp(argv[1], "list")) { DIR *d; struct dirent *de; if (!(d = opendir("/sys/class/net"))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to open sysfs dir", true); return 0; } while((de = readdir(d))) { if (de->d_name[0] == '.') continue; cli->sendMsg(ResponseCode::InterfaceListResult, de->d_name, false); } closedir(d); cli->sendMsg(ResponseCode::CommandOkay, "Interface list completed", false); return 0; } else if (!strcmp(argv[1], "readrxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readrxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg; asprintf(&msg, "%lu", rx); cli->sendMsg(ResponseCode::InterfaceRxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "readtxcounter")) { if (argc != 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface readtxcounter <interface>", false); return 0; } unsigned long rx = 0, tx = 0; if (readInterfaceCounters(argv[2], &rx, &tx)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to read counters", true); return 0; } char *msg = NULL; asprintf(&msg, "%lu", tx); cli->sendMsg(ResponseCode::InterfaceTxCounterResult, msg, false); free(msg); return 0; } else if (!strcmp(argv[1], "getthrottle")) { if (argc != 4 || (argc == 4 && (strcmp(argv[3], "rx") && (strcmp(argv[3], "tx"))))) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface getthrottle <interface> <rx|tx>", false); return 0; } int val = 0; int rc = 0; int voldRc = ResponseCode::InterfaceRxThrottleResult; if (!strcmp(argv[3], "rx")) { rc = ThrottleController::getInterfaceRxThrottle(argv[2], &val); } else { rc = ThrottleController::getInterfaceTxThrottle(argv[2], &val); voldRc = ResponseCode::InterfaceTxThrottleResult; } if (rc) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to get throttle", true); } else { char *msg = NULL; asprintf(&msg, "%u", val); cli->sendMsg(voldRc, msg, false); free(msg); return 0; } return 0; } else if (!strcmp(argv[1], "setthrottle")) { if (argc != 5) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface setthrottle <interface> <rx_kbps> <tx_kbps>", false); return 0; } if (ThrottleController::setInterfaceThrottle(argv[2], atoi(argv[3]), atoi(argv[4]))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set throttle", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Interface throttling set", false); } return 0; } else if (!strcmp(argv[1], "driver")) { int rc; char *rbuf; if (argc < 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface driver <interface> <cmd> <args>", false); return 0; } rc = sInterfaceCtrl->interfaceCommand(argc, argv, &rbuf); if (rc) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to execute command", true); } else { cli->sendMsg(ResponseCode::CommandOkay, rbuf, false); } return 0; } else { /* * These commands take a minimum of 3 arguments */ if (argc < 3) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } // 0 1 2 3 4 5 6 7 // interface route add/remove iface default/secondary dest prefix gateway if (!strcmp(argv[1], "route")) { int prefix_length = 0; if (argc < 8) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } if (sscanf(argv[6], "%d", &prefix_length) != 1) { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route prefix", false); return 0; } if (!strcmp(argv[2], "add")) { if (!strcmp(argv[4], "default")) { if (ifc_add_route(argv[3], argv[5], prefix_length, argv[7])) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to add route to default table", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Route added to default table", false); } } else if (!strcmp(argv[4], "secondary")) { return sSecondaryTableCtrl->addRoute(cli, argv[3], argv[5], prefix_length, argv[7]); } else { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route type, expecting 'default' or 'secondary'", false); return 0; } } else if (!strcmp(argv[2], "remove")) { if (!strcmp(argv[4], "default")) { if (ifc_remove_route(argv[3], argv[5], prefix_length, argv[7])) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to remove route from default table", true); } else { cli->sendMsg(ResponseCode::CommandOkay, "Route removed from default table", false); } } else if (!strcmp(argv[4], "secondary")) { return sSecondaryTableCtrl->removeRoute(cli, argv[3], argv[5], prefix_length, argv[7]); } else { cli->sendMsg(ResponseCode::CommandParameterError, "Invalid route type, expecting 'default' or 'secondary'", false); return 0; } } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); } return 0; } if (!strcmp(argv[1], "getcfg")) { struct in_addr addr; int prefixLength; unsigned char hwaddr[6]; unsigned flags = 0; ifc_init(); memset(hwaddr, 0, sizeof(hwaddr)); if (ifc_get_info(argv[2], &addr.s_addr, &prefixLength, &flags)) { cli->sendMsg(ResponseCode::OperationFailed, "Interface not found", true); ifc_close(); return 0; } if (ifc_get_hwaddr(argv[2], (void *) hwaddr)) { ALOGW("Failed to retrieve HW addr for %s (%s)", argv[2], strerror(errno)); } char *addr_s = strdup(inet_ntoa(addr)); const char *updown, *brdcst, *loopbk, *ppp, *running, *multi; updown = (flags & IFF_UP) ? "up" : "down"; brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; running = (flags & IFF_RUNNING) ? " running" : ""; multi = (flags & IFF_MULTICAST) ? " multicast" : ""; char *flag_s; asprintf(&flag_s, "%s%s%s%s%s%s", updown, brdcst, loopbk, ppp, running, multi); char *msg = NULL; asprintf(&msg, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x %s %d %s", hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5], addr_s, prefixLength, flag_s); cli->sendMsg(ResponseCode::InterfaceGetCfgResult, msg, false); free(addr_s); free(flag_s); free(msg); ifc_close(); return 0; } else if (!strcmp(argv[1], "setcfg")) { // arglist: iface [addr prefixLength] flags if (argc < 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false); return 0; } ALOGD("Setting iface cfg"); struct in_addr addr; unsigned flags = 0; int index = 5; ifc_init(); if (!inet_aton(argv[3], &addr)) { // Handle flags only case index = 3; } else { if (ifc_set_addr(argv[2], addr.s_addr)) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set address", true); ifc_close(); return 0; } // Set prefix length on a non zero address if (addr.s_addr != 0 && ifc_set_prefixLength(argv[2], atoi(argv[4]))) { cli->sendMsg(ResponseCode::OperationFailed, "Failed to set prefixLength", true); ifc_close(); return 0; } } /* Process flags */ for (int i = index; i < argc; i++) { char *flag = argv[i]; if (!strcmp(flag, "up")) { ALOGD("Trying to bring up %s", argv[2]); if (ifc_up(argv[2])) { ALOGE("Error upping interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to up interface", true); ifc_close(); return 0; } } else if (!strcmp(flag, "down")) { ALOGD("Trying to bring down %s", argv[2]); if (ifc_down(argv[2])) { ALOGE("Error downing interface"); cli->sendMsg(ResponseCode::OperationFailed, "Failed to down interface", true); ifc_close(); return 0; } } else if (!strcmp(flag, "broadcast")) { // currently ignored } else if (!strcmp(flag, "multicast")) { // currently ignored } else if (!strcmp(flag, "running")) { // currently ignored } else if (!strcmp(flag, "loopback")) { // currently ignored } else if (!strcmp(flag, "point-to-point")) { // currently ignored } else { cli->sendMsg(ResponseCode::CommandParameterError, "Flag unsupported", false); ifc_close(); return 0; } } cli->sendMsg(ResponseCode::CommandOkay, "Interface configuration set", false); ifc_close(); return 0; } else if (!strcmp(argv[1], "clearaddrs")) { // arglist: iface ALOGD("Clearing all IP addresses on %s", argv[2]); ifc_clear_addresses(argv[2]); cli->sendMsg(ResponseCode::CommandOkay, "Interface IP addresses cleared", false); return 0; } else if (!strcmp(argv[1], "ipv6privacyextensions")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface ipv6privacyextensions <interface> <enable|disable>", false); return 0; } char *tmp; asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/use_tempaddr", argv[2]); if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "2" : "0", 1) < 0) { free(tmp); cli->sendMsg(ResponseCode::OperationFailed, "Failed to set ipv6 privacy extensions", true); return 0; } free(tmp); cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false); return 0; } else if (!strcmp(argv[1], "ipv6")) { if (argc != 4) { cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: interface ipv6 <interface> <enable|disable>", false); return 0; } char *tmp; asprintf(&tmp, "/proc/sys/net/ipv6/conf/%s/disable_ipv6", argv[2]); if (writeFile(tmp, !strncmp(argv[3], "enable", 7) ? "0" : "1", 1) < 0) { free(tmp); cli->sendMsg(ResponseCode::OperationFailed, "Failed to change IPv6 state", true); return 0; } free(tmp); cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false); return 0; } else { cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown interface cmd", false); return 0; } } return 0; }
void onConnectionStateChanged(const char *s) { int m_state = -1, m_cause = -1, err; int commas; err = at_tok_start((char **) &s); if (err < 0) return; /* Count number of commas */ err = at_tok_charcounter((char *) s, ',', &commas); if (err < 0) return; err = at_tok_nextint((char **) &s, &m_state); if (err < 0 || m_state < E2NAP_STATE_DISCONNECTED || m_state > E2NAP_STATE_CONNECTING) { m_state = -1; return; } err = at_tok_nextint((char **) &s, &m_cause); /* The <cause> will only be indicated/considered when <state> * is disconnected */ if (err < 0 || m_cause < E2NAP_CAUSE_SUCCESS || m_cause > E2NAP_CAUSE_MAXIMUM || m_state != E2NAP_STATE_DISCONNECTED) m_cause = -1; if (commas == 3) { int m_state2 = -1, m_cause2 = -1; err = at_tok_nextint((char **) &s, &m_state2); if (err < 0 || m_state2 < E2NAP_STATE_DISCONNECTED || m_state2 > E2NAP_STATE_CONNECTED) { m_state = -1; return; } if (m_state2 == E2NAP_STATE_DISCONNECTED) { err = at_tok_nextint((char **) &s, &m_cause2); if (err < 0 || m_cause2 < E2NAP_CAUSE_SUCCESS || m_cause2 > E2NAP_CAUSE_MAXIMUM) { m_cause2 = -1; } } if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); if (m_state == E2NAP_STATE_CONNECTING || m_state2 == E2NAP_STATE_CONNECTING) { s_e2napState = E2NAP_STATE_CONNECTING; } else if (m_state == E2NAP_STATE_CONNECTED) { s_e2napCause = m_cause2; s_e2napState = E2NAP_STATE_CONNECTED; } else if (m_state2 == E2NAP_STATE_CONNECTED) { s_e2napCause = m_cause; s_e2napState = E2NAP_STATE_CONNECTED; } else { s_e2napCause = m_cause; s_e2napState = E2NAP_STATE_DISCONNECTED; } if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } else { if ((err = pthread_mutex_lock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to take e2nap mutex: %s", __func__, strerror(err)); s_e2napState = m_state; s_e2napCause = m_cause; if ((err = pthread_mutex_unlock(&s_e2nap_mutex)) != 0) ALOGE("%s() failed to release e2nap mutex: %s", __func__, strerror(err)); } mbm_check_error_cause(); if (m_state == E2NAP_STATE_DISCONNECTED) { /* Bring down the interface as well. */ if (!(ifc_init())) { ifc_down(ril_iface); ifc_close(); } else ALOGE("%s() Failed to set up ifc!", __func__); } if ((m_state == E2NAP_STATE_DISCONNECTED) && (s_DeactCalled == 0)) { enqueueRILEvent(RIL_EVENT_QUEUE_PRIO, onPDPContextListChanged, NULL, NULL); } s_DeactCalled = 0; }
void requestSetupDefaultPDP(void *data, size_t datalen, RIL_Token t) { in_addr_t addr; in_addr_t gateway; const char *apn, *user, *pass, *auth; char *addresses = NULL; char *gateways = NULL; char *dnses = NULL; const char *type = NULL; RIL_Data_Call_Response_v6 response; int e2napState = getE2napState(); int err = -1; int cme_err, i, prof; (void) data; (void) datalen; prof = atoi(((const char **) data)[1]); apn = ((const char **) data)[2]; user = ((const char **) data)[3]; pass = ((const char **) data)[4]; auth = ((const char **) data)[5]; type = getNWType(((const char **) data)[6]); s_lastPdpFailCause = PDP_FAIL_ERROR_UNSPECIFIED; memset(&response, 0, sizeof(response)); response.ifname = ril_iface; response.cid = prof + 1; response.active = 0; response.type = (char *) type; response.suggestedRetryTime = -1; /* Handle case where Android framework tries to setup multiple PDPs when sending/receiving MMS. Tear down the default context if any attempt is made to setup a new context with different DataProfile. Requires changes to Android framework (RILConstants.java and GsmDataConnectionTracker.java). This need to be in place until the framework properly handles priorities on APNs */ if (e2napState > E2NAP_STATE_DISCONNECTED) { if (prof > RIL_DATA_PROFILE_DEFAULT) { ALOGD("%s() tearing down default cid:%d to allow cid:%d", __func__, s_ActiveCID, prof + 1); s_DeactCalled = 1; if (disconnect()) { goto down; } else { e2napState = getE2napState(); if (e2napState != E2NAP_STATE_DISCONNECTED) goto error; if (ifc_init()) goto error; if (ifc_down(ril_iface)) goto error; ifc_close(); requestOrSendPDPContextList(NULL); } } else { ALOGE("%s() denying data connection to APN '%s' Multiple PDP not supported!", __func__, apn); response.status = PDP_FAIL_INSUFFICIENT_RESOURCES; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); return; } } down: e2napState = setE2napState(E2NAP_STATE_UNKNOWN); ALOGD("%s() requesting data connection to APN '%s'", __func__, apn); if (ifc_init()) { ALOGE("%s() Failed to set up ifc!", __func__); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } if (ifc_down(ril_iface)) { ALOGE("%s() Failed to bring down %s!", __func__, ril_iface); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } err = at_send_command("AT+CGDCONT=%d,\"IP\",\"%s\"", RIL_CID_IP, apn); if (err != AT_NOERROR) { cme_err = at_get_cme_error(err); ALOGE("%s() CGDCONT failed: %d, cme: %d", __func__, err, cme_err); RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } if (networkAuth(auth, user, pass, RIL_CID_IP)) { RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); return; } /* Start data on PDP context for IP */ err = at_send_command("AT*ENAP=1,%d", RIL_CID_IP); if (err != AT_NOERROR) { cme_err = at_get_cme_error(err); ALOGE("requestSetupDefaultPDP: ENAP failed: %d cme: %d", err, cme_err); goto error; } for (i = 0; i < MBM_ENAP_CONNECT_TIME * 5; i++) { e2napState = getE2napState(); if (e2napState == E2NAP_STATE_CONNECTED || e2napState == E2NAP_STATE_DISCONNECTED || RADIO_STATE_UNAVAILABLE == getRadioState()) { ALOGD("%s() %s", __func__, e2napStateToString(e2napState)); break; } usleep(200 * 1000); } e2napState = getE2napState(); if (e2napState != E2NAP_STATE_CONNECTED) goto error; if (parse_ip_information(&addresses, &gateways, &dnses, &addr, &gateway) < 0) { ALOGE("%s() Failed to parse network interface data", __func__); goto error; } response.addresses = addresses; response.gateways = gateways; response.dnses = dnses; ALOGI("%s() Setting up interface %s,%s,%s", __func__, response.addresses, response.gateways, response.dnses); e2napState = getE2napState(); if (e2napState == E2NAP_STATE_DISCONNECTED) goto error; /* we got disconnected */ /* Don't use android netutils. We use our own and get the routing correct. * Carl Nordbeck */ if (ifc_configure(ril_iface, addr, gateway)) ALOGE("%s() Failed to configure the interface %s", __func__, ril_iface); ALOGI("IP Address %s, %s", addresses, e2napStateToString(e2napState)); e2napState = getE2napState(); if (e2napState == E2NAP_STATE_DISCONNECTED) goto error; /* we got disconnected */ response.active = 2; response.status = 0; s_ActiveCID = response.cid; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); free(addresses); free(gateways); free(dnses); startPollFastDormancy(); return; error: mbm_check_error_cause(); response.status = s_lastPdpFailCause; /* Restore enap state and wait for enap to report disconnected*/ disconnect(); RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); free(addresses); free(gateways); free(dnses); }