/*
 * Arguments:
 *	argv[2] - wlan interface
 *	argv[3] - SSID
 *	argv[4] - Broadcast/Hidden
 *	argv[5] - Channel
 *	argv[6] - Security
 *	argv[7] - Key
 */
int SoftapController::setSoftap(int argc, char *argv[]) {
    int ret = 0;
    char buf[1024];
    int channel = AP_CHANNEL_DEFAULT;

    ALOGD("%s - %s - %s - %s - %s - %s",argv[2],argv[3],argv[4],argv[5],argv[6],argv[7]);

    if (argc < 4) {
        ALOGE("Softap set - missing arguments");
        return -1;
    }

    FILE* fp = fopen(HOSTAPD_CONF_TEMPLATE_FILE, "r");
    if (!fp) {
       ALOGE("Softap set - hostapd template file read failed");
       return -1;
    }

    FILE* fp2 = fopen(HOSTAPD_CONF_FILE, "w");
    if (!fp2) {
       ALOGE("Softap set - hostapd.conf file read failed");
       fclose(fp);
       return -1;
    }
    while (fgets(buf, sizeof(buf), fp)) {
        if((strncmp(buf, "ssid=",5) == 0) ||
           (strncmp(buf, "wpa=",4) == 0) ||
           (strncmp(buf, "wpa_passphrase=",15) == 0) ||
           (strncmp(buf, "wpa_key_mgmt=",12) == 0) ||
           (strncmp(buf, "wpa_pairwise=",12) == 0) ||
           (strncmp(buf, "rsn_pairwise=",12) == 0) ||
           (strncmp(buf, "interface=",10) == 0)) {
           continue;
        }
        fputs(buf,fp2);
    }

    // Update interface
    sprintf(buf, "interface=%s\n", AP_INTERFACE);
    fputs(buf, fp2);

    // Update interface path
    sprintf(buf, "ctrl_interface=%s\n", AP_INTERFACE_PATH);
    fputs(buf, fp2);

    // Update SSID
    sprintf(buf, "ssid=%s\n",argv[3]);
    fputs(buf, fp2);

    // Update Channel
    if (argc >= 5) {
        channel = atoi(argv[5]);
        if (channel <= 0) {
            channel = AP_CHANNEL_DEFAULT;
        }
        sprintf(buf, "channel=%d\n",channel);
    }

    // Update security
    if (argc > 7) {
        if(strncmp(argv[6],"wpa2-psk",8) == 0) {
            sprintf(buf, "wpa=2\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n"
                      "wpa_pairwise=CCMP\nrsn_pairwise=CCMP\n", argv[7]);
            fputs(buf, fp2);
        }

        if(strncmp(argv[6],"wpa-psk",7) == 0) {
            sprintf(buf, "wpa=1\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n"
                      "wpa_pairwise=TKIP\nrsn_pairwise=TKIP\n", argv[7]);
            fputs(buf, fp2);
        }
    }

    fclose(fp);
    fclose(fp2);

    if (chmod(HOSTAPD_CONF_FILE, 0660) < 0) {
        ALOGE("Error changing permissions of %s to 0660: %s",
                HOSTAPD_CONF_FILE, strerror(errno));
        unlink(HOSTAPD_CONF_FILE);
        return -1;
    }

    if (chown(HOSTAPD_CONF_FILE, AID_SYSTEM, AID_WIFI) < 0) {
        ALOGE("Error changing group ownership of %s to %d: %s",
                HOSTAPD_CONF_FILE, AID_WIFI, strerror(errno));
        unlink(HOSTAPD_CONF_FILE);
        return -1;
    }

    // we take the wakelock here because the stop/start is lengthy
    acquire_wake_lock(PARTIAL_WAKE_LOCK, AP_WAKE_LOCK);

    // restart hostapd to update configuration
    ret = stopHostapd();
    if (ret != 0)
        goto fail_switch;

    ret = startHostapd();
    if (ret != 0)
        goto fail_switch;

    ALOGD("hostapd set - Ok");
    return 0;

fail_switch:
    release_wake_lock(AP_WAKE_LOCK);
    ALOGD("hostapd set - failed. AP is off.");

    return ret;
}
/*
 * Arguments:
 *      argv[2] - wlan interface
 *      argv[3] - softap interface
 *      argv[4] - SSID
 *	argv[5] - Security
 *	argv[6] - Key
 *	argv[7] - Channel
 *	argv[8] - Preamble
 *	argv[9] - Max SCB
 */
int SoftapController::setSoftap(int argc, char *argv[]) {
    int ret = 0;
    char buf[1024];
    int sta_chan, is_g_mode;


    LOGD("%s - %s - %s - %s - %s - %s",argv[2],argv[3],argv[4],argv[5],argv[6],argv[7]);

    if (argc < 4) {
        LOGE("Softap set - missing arguments");
        return -1;
    }

    FILE* fp = fopen(HOSTAPD_CONF_TEMPLATE_FILE, "r");
    if (!fp) {
       LOGE("Softap set - hostapd template file read failed");
       return -1;
    }

    FILE* fp2 = fopen(HOSTAPD_CONF_FILE, "w");
    if (!fp2) {
       LOGE("Softap set - hostapd.conf file read failed");
       fclose(fp);
       return -1;
    }
    while (fgets(buf, sizeof(buf), fp)) {
        if((strncmp(buf, "ssid=",5) == 0) ||
           (strncmp(buf, "wpa=",4) == 0) ||
           (strncmp(buf, "wpa_passphrase=",15) == 0) ||
           (strncmp(buf, "wpa_key_mgmt=",12) == 0) ||
           (strncmp(buf, "wpa_pairwise=",12) == 0) ||
           (strncmp(buf, "rsn_pairwise=",12) == 0) ||
           (strncmp(buf, "interface=",10) == 0)) {
           continue;
        }
        fputs(buf,fp2);
    }

    // Update interface
    sprintf(buf, "interface=%s\n", AP_INTERFACE);
    fputs(buf, fp2);

    // Update SSID
    sprintf(buf, "ssid=%s\n",argv[4]);
    fputs(buf, fp2);

    // Update security
    if(strncmp(argv[5],"wpa2-psk",8) == 0) {
        sprintf(buf, "wpa=2\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n"
                  "wpa_pairwise=CCMP\nrsn_pairwise=CCMP\n", argv[6]);
        fputs(buf, fp2);
    }

    if(strncmp(argv[5],"wpa-psk",7) == 0) {
        sprintf(buf, "wpa=1\nwpa_passphrase=%s\nwpa_key_mgmt=WPA-PSK\n"
                  "wpa_pairwise=TKIP\nrsn_pairwise=TKIP\n", argv[6]);
        fputs(buf, fp2);
    }

    // Choose the correct channel - based on the current channel of the STA
    if (getStaChanAndMode(&sta_chan, &is_g_mode) != 0 || sta_chan == 0) {
        /* default to channel 11 on G */
        sta_chan = 11;
        is_g_mode = 1;
    }

    LOGD("AP starting on channel %d g_mode: %d", sta_chan, is_g_mode);
    sprintf(buf, "hw_mode=%s\nchannel=%d\n", is_g_mode ? "g" : "a", sta_chan);
    fputs(buf, fp2);

    fclose(fp);
    fclose(fp2);

    // we take the wakelock here because the stop/start is lengthy
    acquire_wake_lock(PARTIAL_WAKE_LOCK, AP_WAKE_LOCK);

    // switch interface to wlan1
    ret = switchInterface(true);
    if (ret != 0)
        goto fail_switch;

    // restart hostapd to update configuration
    ret = stopHostapd();
    if (ret != 0)
        goto fail;

    ret = startHostapd();
    if (ret != 0)
        goto fail;

    LOGD("hostapd set - Ok");
    return 0;

fail:
    switchInterface(false);
fail_switch:
    release_wake_lock(AP_WAKE_LOCK);
    LOGD("hostapd set - failed. AP is off.");

    return ret;
}