예제 #1
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;
}
예제 #2
0
int rtw_issue_driver_cmd(const char *ifname, char *cmd, char *buf, size_t buf_len)
{
	int sockfd;
	int ret;

#if 0
	if (ifc_init() < 0)
		return -1;	
	if (ifc_up(ifname)) {
		LOGD("failed to bring up interface %s: %s\n", ifname, strerror(errno));
		return -1;
	}
#endif
	
	sockfd = socket(PF_INET, SOCK_DGRAM, 0);
	if (sockfd< 0) {
		LOGE("%s socket[PF_INET,SOCK_DGRAM] error:%d %s", __FUNCTION__, errno, strerror(errno));
		ret = -1;
		goto bad;
	}

	ret = rtw_issue_driver_cmd_fd(
		sockfd
		, ifname
		, cmd
		, buf
		, buf_len
	);
	
	close(sockfd);
bad:
	return ret;
}
예제 #3
0
int startDhcpWimaxDaemon()
{
    char dhcp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 100; /* wait at most 10 seconds for completion */

    LOGI("NATIVE::startDhcpWimaxDaemon() - stopping dhcpWimax");
    stopDhcpWimax();
    LOGI("NATIVE::startDhcpWimaxDaemon() - dhcpWimax stopped");
    ifc_init();
    ifc_up("wimax0");
    LOGI("NATIVE::startDhcpWimaxDaemon() - wimax0 up!");

    property_set("ctl.start", WIMAX_DHCP_NAME);
    sched_yield();
    LOGI("NATIVE::startDhcpWimaxDaemon() - dhcp starting...");
   
    while (count-- > 0) {
        if (property_get("dhcp.wimax0.reason", dhcp_status, NULL)) {
            if (strcmp(dhcp_status, "BOUND") == 0 || strcmp(dhcp_status, "RENEW") == 0 || strcmp(dhcp_status, "PREINIT") == 0) {
                LOGI("NATIVE::startDhcpWimaxDaemon() - dhcp finished!");
                return 0;
            }
        }
        usleep(100000);
    }
    return -1;
}
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;
}
예제 #5
0
int SoftapController::startDriver(char *iface) {
    int ret;

    if (mSock < 0) {
        LOGE("Softap driver start - failed to open socket");
        return -1;
    }
    if (!iface || (iface[0] == '\0')) {
        LOGD("Softap driver start - wrong interface");
        iface = mIface;
    }

    *mBuf = 0;
    ret = setCommand(iface, "START");
    if (ret < 0) {
        LOGE("Softap driver start: %d", ret);
        return ret;
    }
#ifdef HAVE_HOSTAPD
    ifc_init();
    ret = ifc_up(iface);
    ifc_close();
#endif
    usleep(AP_DRIVER_START_DELAY);
    LOGD("Softap driver start: %d", ret);
    return ret;
}
int rtl871x_drv_rereg_nd_name(const char *ifname, const char *new_ifname)
{
	int sockfd;
	int ret;

#if 0
	if (ifc_init() < 0)
		return -1;	
	if (ifc_up(ifname)) {
		LOGD("failed to bring up interface %s: %s\n", ifname, strerror(errno));
		return -1;
	}
#endif
	
	sockfd = socket(PF_INET, SOCK_DGRAM, 0);
	if (sockfd< 0) {
		perror("socket[PF_INET,SOCK_DGRAM]");
		ret = -1;
		goto bad;
	}

	ret = rtl871x_drv_rereg_nd_name_fd(
		sockfd
		, ifname
		, get_priv_func_num(sockfd, ifname, "rereg_nd_name")
		, new_ifname
	);
	
	close(sockfd);
bad:
	return ret;
}
int SoftapController::startDriver(char *iface) {
    int ret;

    if (mSock < 0) {
        ALOGE("Softap driver start - failed to open socket");
        return ResponseCode::OperationFailed;
    }
    if (!iface || (iface[0] == '\0')) {
        ALOGD("Softap driver start - wrong interface");
        iface = mIface;
    }

    *mBuf = 0;
    ret = setCommand(iface, "START");
    if (ret < 0) {
        ALOGE("Softap driver start: %d", ret);
        return ResponseCode::ServiceStartFailed;
    }
#ifdef HAVE_HOSTAPD
    ifc_init();
    ret = ifc_up(iface);
    ifc_close();
#endif
    usleep(AP_DRIVER_START_DELAY);
    ALOGD("Softap driver start: %d", ret);
    return ResponseCode::SoftapStatusResult;
}
예제 #8
0
int ifc_enable(const char *ifname)
{
    int result;

    ifc_init();
    result = ifc_up(ifname);
    ifc_close();
    return result;
}
예제 #9
0
int META_WIFI_init(void)
{
    int count = 100;
	
    if(1 == wifi_init){
    	ERR("wifi is already initilized.\n");
    	return true;
    }
#if 0
    if (!wifi_is_loaded()){
        ERR("[META_WIFI] loading wifi driver ... ...\n");    	
        if (wifi_insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0) {
            ERR("[META_WIFI] failed to load wifi driver!!!\n");    	        	
            goto error;
        }
    }
#endif    
    usleep(200000); 
		
    wifi_set_power(1);


    sched_yield();
    
    while (count-- > 0) {
        if (ifc_init() == 0) {
            if (ifc_up("wlan0") == 0) {
                ifc_close();
                break;
            }
            ERR("[META_WIFI] ifc_up(wlan0) failed\n");
            ifc_close();
        } else {
            ERR("[META_WIFI] ifc_init() failed\n");
        }
        usleep(100000);
    }
    if (count == 0)
        goto error;

    if (wifi_skfd == -1)
        wifi_skfd = openNetHandle();

    if (wifi_skfd < 0) {
        META_WIFI_deinit();
        goto error;
    }

    wifi_init = 1;

    return true;

error:
    wifi_set_power(0);
    return false;
}
예제 #10
0
int do_dhcp(char *iname)
{
    if (ifc_set_addr(iname, 0)) {
        printerr("failed to set ip addr for %s to 0.0.0.0: %s\n", iname, strerror(errno));
        return -1;
    }

    if (ifc_up(iname)) {
        printerr("failed to bring up interface %s: %s\n", iname, strerror(errno));
        return -1;
    }

    return dhcp_init_ifc(iname);
}
예제 #11
0
int
ifc_configure(const char *ifname,
        in_addr_t address,
        in_addr_t netmask,
        in_addr_t gateway,
        in_addr_t dns1,
        in_addr_t dns2) {

#if 0
    char dns_prop_name[PROPERTY_KEY_MAX];
#endif

    ifc_init();

    if (ifc_up(ifname)) {
        printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_set_addr(ifname, address)) {
        printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_set_mask(ifname, netmask)) {
        printerr("failed to set netmask %s: %s\n", ipaddr_to_string(netmask), strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_create_default_route(ifname, gateway)) {
        printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno));
        ifc_close();
        return -1;
    }

    ifc_close();

#if 0
    snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", ifname);
    property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : "");
    snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", ifname);
    property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : "");
#endif

    return 0;
}
예제 #12
0
int
ifc_configure(const char *ifname,
        in_addr_t address,
        uint32_t prefixLength,
        in_addr_t gateway,
        in_addr_t dns1,
        in_addr_t dns2) {

    char dns_prop_name[PROPERTY_KEY_MAX];

    ifc_init();

    if (ifc_up(ifname)) {
        printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_set_addr(ifname, address)) {
        printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_set_prefixLength(ifname, prefixLength)) {
        printerr("failed to set prefixLength %d: %s\n", prefixLength, strerror(errno));
        ifc_close();
        return -1;
    }
    if (ifc_create_default_route(ifname, gateway)) {
        printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno));
        ifc_close();
        return -1;
    }

    ifc_close();

    snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", ifname);
    property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : "");
    snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", ifname);
    property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : "");
    snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.gw", ifname);
    property_set(dns_prop_name, gateway ? ipaddr_to_string(gateway) : "");

    return 0;
}
예제 #13
0
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;
}
예제 #14
0
int wifi_start_supplicant()
{
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    const prop_info *pi;
    unsigned serial = 0;
#endif

    /* Check whether already running */
    if (property_get(SUPP_PROP_NAME, supp_status, NULL)
            && strcmp(supp_status, "running") == 0) {
        return 0;
    }

    /* Before starting the daemon, make sure its config file exists */
    if (ensure_config_file_exists() < 0) {
        LOGE("Wi-Fi will not be enabled");
        return -1;
    }

    /* Clear out any stale socket files that might be left over. */
    wpa_ctrl_cleanup();

#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    /*
     * Get a reference to the status property, so we can distinguish
     * the case where it goes stopped => running => stopped (i.e.,
     * it start up, but fails right away) from the case in which
     * it starts in the stopped state and never manages to start
     * running at all.
     */
    pi = __system_property_find(SUPP_PROP_NAME);
    if (pi != NULL) {
        serial = pi->serial;
    }
#endif
    /* The ar6k driver needs the interface up in order to scan! */
    if (!strncmp(DRIVER_MODULE_NAME, "ar6000", 6)) {
        ifc_init();
        ifc_up("wlan0");
        sleep(1);
    }

    property_set("ctl.start", SUPPLICANT_NAME);
    sched_yield();

    while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
        if (pi == NULL) {
            pi = __system_property_find(SUPP_PROP_NAME);
        }
        if (pi != NULL) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
                return 0;
            } else if (pi->serial != serial &&
                    strcmp(supp_status, "stopped") == 0) {
                return -1;
            }
        }
#else
        if (property_get(SUPP_PROP_NAME, supp_status, NULL)) {
            if (strcmp(supp_status, "running") == 0)
                return 0;
        }
#endif
        usleep(100000);
    }
    return -1;
}
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;
}
int wifi_start_supplicant(int p2p_supported)
{
    char supp_status[PROPERTY_VALUE_MAX] = {'\0'};
    int count = 200; /* wait at most 20 seconds for completion */
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    const prop_info *pi;
    unsigned serial = 0, i;
#endif

    if (p2p_supported) {
        strcpy(supplicant_name, P2P_SUPPLICANT_NAME);
        strcpy(supplicant_prop_name, P2P_PROP_NAME);

        /* Ensure p2p config file is created */
        if (ensure_config_file_exists(P2P_CONFIG_FILE) < 0) {
            ALOGE("Failed to create a p2p config file");
            return -1;
        }

    } else {
        strcpy(supplicant_name, SUPPLICANT_NAME);
        strcpy(supplicant_prop_name, SUPP_PROP_NAME);
    }

    /* Check whether already running */
    if (property_get(supplicant_name, supp_status, NULL)
            && strcmp(supp_status, "running") == 0) {
        return 0;
    }

    /* Before starting the daemon, make sure its config file exists */
    if (ensure_config_file_exists(SUPP_CONFIG_FILE) < 0) {
        ALOGE("Wi-Fi will not be enabled");
        return -1;
    }

    if (ensure_entropy_file_exists() < 0) {
        ALOGE("Wi-Fi entropy file was not created");
    }

#ifdef USES_TI_MAC80211
    if (p2p_supported && add_remove_p2p_interface(1) < 0) {
        ALOGE("Wi-Fi - could not create p2p interface");
        return -1;
    }
#endif

    /* Clear out any stale socket files that might be left over. */
    wpa_ctrl_cleanup();

    /* Reset sockets used for exiting from hung state */
    exit_sockets[0] = exit_sockets[1] = -1;

#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
    /*
     * Get a reference to the status property, so we can distinguish
     * the case where it goes stopped => running => stopped (i.e.,
     * it start up, but fails right away) from the case in which
     * it starts in the stopped state and never manages to start
     * running at all.
     */
    pi = __system_property_find(supplicant_prop_name);
    if (pi != NULL) {
        serial = __system_property_serial(pi);
    }
#endif

#ifdef WIFI_DRIVER_MODULE_PATH
    /* The ar6k driver needs the interface up in order to scan! */
    if (!strncmp(DRIVER_MODULE_NAME, "ar6000", 6)) {
        ifc_init();
        ifc_up("eth0");
        sleep(2);
    }
#endif

    property_get("wifi.interface", primary_iface, WIFI_TEST_INTERFACE);

    property_set("ctl.start", supplicant_name);
    sched_yield();

    while (count-- > 0) {
#ifdef HAVE_LIBC_SYSTEM_PROPERTIES
        if (pi == NULL) {
            pi = __system_property_find(supplicant_prop_name);
        }
        if (pi != NULL) {
            __system_property_read(pi, NULL, supp_status);
            if (strcmp(supp_status, "running") == 0) {
                return 0;
            } else if (__system_property_serial(pi) != serial &&
                    strcmp(supp_status, "stopped") == 0) {
                return -1;
            }
        }
#else
        if (property_get(supplicant_prop_name, supp_status, NULL)) {
            if (strcmp(supp_status, "running") == 0)
                return 0;
        }
#endif
        usleep(100000);
    }
    return -1;
}
int ThrottleController::setInterfaceThrottle(const char *iface, int rxKbps, int txKbps) {
    char cmd[512];
    char ifn[65];
    int rc;

    memset(ifn, 0, sizeof(ifn));
    strncpy(ifn, iface, sizeof(ifn)-1);

    if (txKbps == -1) {
        reset(ifn);
        return 0;
    }

    /*
     *
     * Target interface configuration
     *
     */

    /*
     * Add root qdisc for the interface
     */
    sprintf(cmd, "qdisc add dev %s root handle 1: htb default 1 r2q 1000", ifn);
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add root qdisc (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Add our egress throttling class
     */
    sprintf(cmd, "class add dev %s parent 1: classid 1:1 htb rate %dkbit", ifn, txKbps);
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add egress throttling class (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Bring up the IFD device
     */
    ifc_init();
    if (ifc_up("ifb0")) {
        ALOGE("Failed to up ifb0 (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Add root qdisc for IFD
     */
    sprintf(cmd, "qdisc add dev ifb0 root handle 1: htb default 1 r2q 1000");
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add root ifb qdisc (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Add our ingress throttling class
     */
    sprintf(cmd, "class add dev ifb0 parent 1: classid 1:1 htb rate %dkbit", rxKbps);
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add ingress throttling class (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Add ingress qdisc for pkt redirection
     */
    sprintf(cmd, "qdisc add dev %s ingress", ifn);
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add ingress qdisc (%s)", strerror(errno));
        goto fail;
    }

    /*
     * Add filter to link <ifn> -> ifb0
     */
    sprintf(cmd, "filter add dev %s parent ffff: protocol ip prio 10 u32 match "
            "u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0", ifn);
    if (runTcCmd(cmd)) {
        ALOGE("Failed to add ifb filter (%s)", strerror(errno));
        goto fail;
    }

    return 0;
fail:
    reset(ifn);
    return -1;
}