/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

/*
 * WiFi load, scan, associate, unload stress test
 *
 * Repeatedly executes the following sequence:
 *
 *   1. Load WiFi driver
 *   2. Start supplicant
 *   3. Random delay
 *   4. Obtain supplicant status (optional)
 *   5. Stop supplicant
 *   6. Unload WiFi driver
 *
 * The "Obtain supplicant status" step is optional and is pseudo
 * randomly performed 50% of the time.  The default range of
 * delay after start supplicant is intentionally selected such
 * that the obtain supplicant status and stop supplicant steps
 * may be performed while the WiFi driver is still performing a scan
 * or associate.  The default values are given by DEFAULT_DELAY_MIN
 * and DEFAULT_DELAY_MAX.  Other values can be specified through the
 * use of the -d and -D command-line options.
 *
 * Each sequence is refered to as a pass and by default an unlimited
 * number of passes are performed.  An override of the range of passes
 * to be executed is available through the use of the -s (start) and
 * -e (end) command-line options.  Can also specify a single specific
 * pass via the -p option.  There is also a default time in which the
 * test executes, which is given by DEFAULT_DURATION and can be overriden
 * through the use of the -t command-line option.
 */

#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <math.h>
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>

#include <hardware_legacy/wifi.h>

#define LOG_TAG "wifiLoadScanAssocTest"
#include <utils/Log.h>
#include <testUtil.h>

#define DEFAULT_START_PASS     0
#define DEFAULT_END_PASS     999
#define DEFAULT_DURATION       FLT_MAX // A fairly long time, so that
                                       // range of passes will have
                                       // precedence
#define DEFAULT_DELAY_MIN      0.0     // Min delay after start supplicant
#define DEFAULT_DELAY_MAX     20.0     // Max delay after start supplicant
#define DELAY_EXP            150.0     // Exponent which determines the
                                       // amount by which values closer
                                       // to DELAY_MIN are favored.

#define CMD_STATUS           "wpa_cli status 2>&1"
#define CMD_STOP_FRAMEWORK   "stop 2>&1"
#define CMD_START_FRAMEWORK  "start 2>&1"

#define MAXSTR      100
#define MAXCMD      500

typedef unsigned int bool_t;
#define true (0 == 0)
#define false (!true)

// File scope variables
cpu_set_t availCPU;
unsigned int numAvailCPU;
float delayMin = DEFAULT_DELAY_MIN;
float delayMax = DEFAULT_DELAY_MAX;
bool_t driverLoadedAtStart;

// Command-line mutual exclusion detection flags.
// Corresponding flag set true once an option is used.
bool_t eFlag, sFlag, pFlag;

// File scope prototypes
static void init(void);
static void randDelay(void);
static void randBind(const cpu_set_t *availSet, int *chosenCPU);

/*
 * Main
 *
 * Performs the following high-level sequence of operations:
 *
 *   1. Command-line parsing
 *
 *   2. Initialization
 *
 *   3. Execute passes that repeatedly perform the WiFi load, scan,
 *      associate, unload sequence.
 *
 *   4. Restore state of WiFi driver to state it was at the
 *      start of the test.
 *
 *   5. Restart framework
 */
int
main(int argc, char *argv[])
{
    FILE *fp;
    int rv, opt;
    int cpu;
    char *chptr;
    unsigned int pass;
    char cmd[MAXCMD];
    float duration = DEFAULT_DURATION;
    unsigned int startPass = DEFAULT_START_PASS, endPass = DEFAULT_END_PASS;
    struct timeval startTime, currentTime, delta;

    testSetLogCatTag(LOG_TAG);

    // Parse command line arguments
    while ((opt = getopt(argc, argv, "d:D:s:e:p:t:?")) != -1) {
        switch (opt) {
        case 'd': // Minimum Delay
            delayMin = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (delayMin < 0.0)) {
                testPrintE("Invalid command-line specified minimum delay "
                    "of: %s", optarg);
                exit(1);
            }
            break;

        case 'D': // Maximum Delay
            delayMax = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (delayMax < 0.0)) {
                testPrintE("Invalid command-line specified maximum delay "
                    "of: %s", optarg);
                exit(2);
            }
            break;

        case 't': // Duration
            duration = strtod(optarg, &chptr);
            if ((*chptr != '\0') || (duration < 0.0)) {
                testPrintE("Invalid command-line specified duration of: %s",
                    optarg);
                exit(3);
            }
            break;

        case 's': // Starting Pass
            if (sFlag || pFlag) {
                testPrintE("Invalid combination of command-line options,");
                if (sFlag) {
                    testPrintE("  -s flag specified multiple times.");
                } else {
                    testPrintE("  -s and -p flags are mutually exclusive.");
                }
                exit(10);
            }
            sFlag = true;
            startPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified starting pass "
                    "of: %s", optarg);
                exit(4);
            }
            break;

        case 'e': // Ending Pass
            if (eFlag || pFlag) {
                testPrintE("Invalid combination of command-line options,");
                if (sFlag) {
                    testPrintE("  -e flag specified multiple times.");
                } else {
                    testPrintE("  -e and -p flags are mutually exclusive.");
                }
                exit(11);
            }
            eFlag = true;
            endPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified ending pass "
                    "of: %s", optarg);
                exit(5);
            }
            break;

        case 'p': // Single Specific Pass
            if (pFlag || sFlag || eFlag) {
                testPrintE("Invalid combination of command-line options,");
                if (pFlag) {
                    testPrintE("  -p flag specified multiple times.");
                } else {
                    testPrintE("  -p and -%c flags are mutually exclusive.",
                        (sFlag) ? 's' : 'e');
                }
                exit(12);
            }
            pFlag = true;
            endPass = startPass = strtoul(optarg, &chptr, 10);
            if (*chptr != '\0') {
                testPrintE("Invalid command-line specified pass "
                    "of: %s", optarg);
                exit(13);
            }
            break;

        case '?':
        default:
            testPrintE("  %s [options]", basename(argv[0]));
            testPrintE("    options:");
            testPrintE("      -s Starting pass");
            testPrintE("      -e Ending pass");
            testPrintE("      -p Specific single pass");
            testPrintE("      -t Duration");
            testPrintE("      -d Delay min");
            testPrintE("      -D Delay max");
            exit(((optopt == 0) || (optopt == '?')) ? 0 : 6);
        }
    }
    if (delayMax < delayMin) {
        testPrintE("Unexpected maximum delay less than minimum delay");
        testPrintE("  delayMin: %f delayMax: %f", delayMin, delayMax);
        exit(7);
    }
    if (endPass < startPass) {
        testPrintE("Unexpected ending pass before starting pass");
        testPrintE("  startPass: %u endPass: %u", startPass, endPass);
        exit(8);
    }
    if (argc != optind) {
        testPrintE("Unexpected command-line postional argument");
        testPrintE("  %s [-s start_pass] [-e end_pass] [-d duration]",
            basename(argv[0]));
        exit(9);
    }
    testPrintI("duration: %g", duration);
    testPrintI("startPass: %u", startPass);
    testPrintI("endPass: %u", endPass);
    testPrintI("delayMin: %f", delayMin);
    testPrintI("delayMax: %f", delayMax);

    init();

    // For each pass
    gettimeofday(&startTime, NULL);
    for (pass = startPass; pass <= endPass; pass++) {
        // Stop if duration of work has already been performed
        gettimeofday(&currentTime, NULL);
        delta = tvDelta(&startTime, &currentTime);
        if (tv2double(&delta) > duration) { break; }

        testPrintI("==== Starting pass: %u", pass);

        // Use a pass dependent sequence of random numbers
        srand48(pass);

        // Load WiFi Driver
        randBind(&availCPU, &cpu);
        if ((rv = wifi_load_driver()) != 0) {
            testPrintE("CPU: %i wifi_load_driver() failed, rv: %i\n",
                cpu, rv);
            exit(20);
        }
        testPrintI("CPU: %i wifi_load_driver succeeded", cpu);

        // Start Supplicant
        randBind(&availCPU, &cpu);
        if ((rv = wifi_start_supplicant(false)) != 0) {
            testPrintE("CPU: %i wifi_start_supplicant() failed, rv: %i\n",
                cpu, rv);
            exit(21);
        }
        testPrintI("CPU: %i wifi_start_supplicant succeeded", cpu);

        // Sleep a random amount of time
        randDelay();

        /*
         * Obtain WiFi Status
         * Half the time skip this step, which helps increase the
         * level of randomization.
         */
        if (testRandBool()) {
            rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STATUS);
            if (rv >= (signed) sizeof(cmd) - 1) {
                testPrintE("Command too long for: %s\n", CMD_STATUS);
                exit(22);
            }
            testExecCmd(cmd);
        }

        // Stop Supplicant
        randBind(&availCPU, &cpu);
        if ((rv = wifi_stop_supplicant()) != 0) {
            testPrintE("CPU: %i wifi_stop_supplicant() failed, rv: %i\n",
                cpu, rv);
            exit(23);
        }
        testPrintI("CPU: %i wifi_stop_supplicant succeeded", cpu);

        // Unload WiFi Module
        randBind(&availCPU, &cpu);
        if ((rv = wifi_unload_driver()) != 0) {
            testPrintE("CPU: %i wifi_unload_driver() failed, rv: %i\n",
                cpu, rv);
            exit(24);
        }
        testPrintI("CPU: %i wifi_unload_driver succeeded", cpu);

        testPrintI("==== Completed pass: %u", pass);
    }

    // If needed restore WiFi driver to state it was in at the
    // start of the test.  It is assumed that it the driver
    // was loaded, then the wpa_supplicant was also running.
    if (driverLoadedAtStart) {
        // Load driver
        if ((rv = wifi_load_driver()) != 0) {
            testPrintE("main load driver failed, rv: %i", rv);
            exit(25);
        }

        // Start supplicant
        if ((rv = wifi_start_supplicant(false)) != 0) {
            testPrintE("main start supplicant failed, rv: %i", rv);
            exit(26);
        }

        // Obtain WiFi Status
        rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STATUS);
        if (rv >= (signed) sizeof(cmd) - 1) {
            testPrintE("Command too long for: %s\n", CMD_STATUS);
            exit(22);
        }
        testExecCmd(cmd);
    }

    // Start framework
    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK);
    if (rv >= (signed) sizeof(cmd) - 1) {
        testPrintE("Command too long for: %s\n", CMD_START_FRAMEWORK);
        exit(27);
    }
    testExecCmd(cmd);

    testPrintI("Successfully completed %u passes", pass - startPass);

    return 0;
}

/*
 * Initialize
 *
 * Perform testcase initialization, which includes:
 *
 *   1. Determine which CPUs are available for use
 *
 *   2. Determine total number of available CPUs
 *
 *   3. Stop framework
 *
 *   4. Determine whether WiFi driver is loaded and if so
 *      stop wpa_supplicant and unload WiFi driver.
 */
void
init(void)
{
    int rv;
    unsigned int n1;
    char cmd[MAXCMD];

    // Use whichever CPUs are available at start of test
    rv = sched_getaffinity(0, sizeof(availCPU), &availCPU);
    if (rv != 0) {
        testPrintE("init sched_getaffinity failed, rv: %i errno: %i",
            rv, errno);
        exit(40);
    }

    // How many CPUs are available
    numAvailCPU = 0;
    for (n1 = 0; n1 < CPU_SETSIZE; n1++) {
        if (CPU_ISSET(n1, &availCPU)) { numAvailCPU++; }
    }
    testPrintI("numAvailCPU: %u", numAvailCPU);

    // Stop framework
    rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK);
    if (rv >= (signed) sizeof(cmd) - 1) {
        testPrintE("Command too long for: %s\n", CMD_STOP_FRAMEWORK);
        exit(41);
    }
    testExecCmd(cmd);

    // Is WiFi driver loaded?
    // If so stop the wpa_supplicant and unload the driver.
    driverLoadedAtStart = is_wifi_driver_loaded();
    testPrintI("driverLoadedAtStart: %u", driverLoadedAtStart);
    if (driverLoadedAtStart) {
        // Stop wpa_supplicant
        // Might already be stopped, in which case request should
        // return immediately with success.
        if ((rv = wifi_stop_supplicant()) != 0) {
            testPrintE("init stop supplicant failed, rv: %i", rv);
            exit(42);
        }
        testPrintI("Stopped wpa_supplicant");

        if ((rv = wifi_unload_driver()) != 0) {
            testPrintE("init unload driver failed, rv: %i", rv);
            exit(43);
        }
        testPrintI("WiFi driver unloaded");
    }

}

/*
 * Random Delay
 *
 * Delays for a random amount of time within the range given
 * by the file scope variables delayMin and delayMax.  The
 * selected amount of delay can come from any part of the
 * range, with a bias towards values closer to delayMin.
 * The amount of bias is determined by the setting of DELAY_EXP.
 * The setting of DELAY_EXP should always be > 1.0, with higher
 * values causing a more significant bias toward the value
 * of delayMin.
 */
void randDelay(void)
{
    const unsigned long nanosecspersec = 1000000000;
    float            fract, biasedFract, amt;
    struct timeval   startTime, endTime;

    // Obtain start time
    gettimeofday(&startTime, NULL);

    // Determine random amount to sleep.
    // Values closer to delayMin are prefered by an amount
    // determined by the value of DELAY_EXP.
    fract = testRandFract();
    biasedFract = pow(DELAY_EXP, fract) / pow(DELAY_EXP, 1.0);
    amt = delayMin + ((delayMax - delayMin) * biasedFract);

    // Delay
    testDelay(amt);

    // Obtain end time and display delta
    gettimeofday(&endTime, NULL);
    testPrintI("delay: %.2f",
        (float) (tv2double(&endTime) - tv2double(&startTime)));
}

static void
randBind(const cpu_set_t *availSet, int *chosenCPU)
{
    int rv;
    cpu_set_t cpuset;
    int chosenAvail, avail, cpu, currentCPU;

    // Randomly bind to a CPU
    // Lower 16 bits from random number generator thrown away,
    // because the low-order bits tend to have the same sequence for
    // different seed values.
    chosenAvail = testRandMod(numAvailCPU);
    CPU_ZERO(&cpuset);
    avail = 0;
    for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
        if (CPU_ISSET(cpu, availSet)) {
            if (chosenAvail == avail) {
                CPU_SET(cpu, &cpuset);
                break;
            }
            avail++;
        }
    }
    assert(cpu < CPU_SETSIZE);
    sched_setaffinity(0, sizeof(cpuset), &cpuset);

    // Confirm executing on requested CPU
    if ((currentCPU = sched_getcpu()) < 0) {
        testPrintE("randBind sched_getcpu() failed, rv: %i errno: %i",
                   currentCPU, errno);
        exit(80);

    }
    if (currentCPU != cpu) {
        testPrintE("randBind executing on unexpected CPU %i, expected %i",
            currentCPU, cpu);
        exit(81);
    }

    // Let the caller know which CPU was chosen
    *chosenCPU = cpu;
}
