From 891bdbcba8cccd8b59c481944c8c6812ff59840d Mon Sep 17 00:00:00 2001 From: Jisung Kang Date: Fri, 28 Apr 2023 23:27:34 +0000 Subject: [PATCH] [NETWORK_SWITCH] Made much more robust for final day of final comp (hopefully) --- .gitignore | 3 ++ lowcar/devices/KoalaBear/KoalaBear.cpp | 4 +- network_switch/network_switch.c | 69 ++++++++++++++++++++++---- network_switch/network_switch.sh | 60 ++++++++++++++++++++-- 4 files changed, 119 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index ce06f4ae..4688eb29 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ lowcar/Device # ignore the entire net_handler/pbc_gen folder net_handler/pbc_gen +# ignore network_switch/exit_status.txt +network_switch/exit_status.txt + # Log files *.log diff --git a/lowcar/devices/KoalaBear/KoalaBear.cpp b/lowcar/devices/KoalaBear/KoalaBear.cpp index 513723bd..ce63f9a5 100644 --- a/lowcar/devices/KoalaBear/KoalaBear.cpp +++ b/lowcar/devices/KoalaBear/KoalaBear.cpp @@ -31,11 +31,11 @@ uint16_t torque_read_data; //******************************* KOALABEAR CONSTANTS AND PARAMS ****************************// // ----------------------> CHANGE THIS TO IMPLEMENT MAX SPEED FOR KARTS <---------------------- -#define MAX_DUTY_CYCLE 0.75 // maximum duty cycle to cap how fast the motors can go: range (0, 1] +#define MAX_DUTY_CYCLE 1.0 // maximum duty cycle to cap how fast the motors can go: range (0, 1] // -------------------------------------------------------------------------------------------- // --------------------> CHANGE THIS TO IMPLEMENT ACCELERATION FOR KARTS <--------------------- -#define ACCEL 0.7 // acceleration of motors, in duty cycle units per second squared +#define ACCEL 2.0 // acceleration of motors, in duty cycle units per second squared // -------------------------------------------------------------------------------------------- // default values for PID controllers; PID control is explained in the Wiki! diff --git a/network_switch/network_switch.c b/network_switch/network_switch.c index 67139d4f..9968778d 100644 --- a/network_switch/network_switch.c +++ b/network_switch/network_switch.c @@ -1,11 +1,14 @@ #include #include #include +#include #include "../logger/logger.h" #include "../runtime_util/runtime_util.h" #include "../shm_wrapper/shm_wrapper.h" + #define SLEEP_DELAY 1 +#define INITIAL_SWITCH 2 // Retrieves router name and password from the file name: router_txt void get_router_name_password(char* router_name, char* router_password, char* router_txt) { @@ -22,16 +25,32 @@ int main() { shm_init(); chdir("../network_switch"); log_printf(INFO, "NETWORK_SWITCH initialized."); - bool prev_switch = false; + int prev_switch = 2; + + char bash_exe[] = "/usr/bin/bash"; + char script_name[] = "network_switch.sh"; char local_router[32]; char local_password[32]; + char *local_args[5]; char team_router[] = "teamrouter.txt"; get_router_name_password(local_router, local_password, team_router); + local_args[0] = bash_exe; + local_args[1] = script_name; + local_args[2] = local_router; + local_args[3] = local_password; + local_args[4] = NULL; + char pie_router[32]; char pie_password[32]; + char *pie_args[5]; char pie_router_file[] = "pierouter.txt"; get_router_name_password(pie_router, pie_password, pie_router_file); + pie_args[0] = bash_exe; + pie_args[1] = script_name; + pie_args[2] = pie_router; + pie_args[3] = pie_password; + pie_args[4] = NULL; while (1) { dev_id_t dev_ids[MAX_DEVICES]; @@ -58,19 +77,49 @@ int main() { device_t* device = get_device(dev_ids[idx].type); param_val_t param_data[MAX_PARAMS]; device_read(idx, NET_HANDLER, DATA, get_readable_param_bitmap(device->type), param_data); - bool curr_switch = param_data[device->num_params - 1].p_b; // network switch value is the last parameter - if (curr_switch != prev_switch) { - if (!curr_switch) { // switch to pioneers if curr_switch is false - snprintf(total_command, sizeof(total_command), "./network_switch.sh %s %s", pie_router, pie_password); - system(total_command); + bool curr_switch_bool = param_data[device->num_params - 1].p_b; // network switch value is the last parameter + int curr_switch; + if (curr_switch_bool) { + curr_switch = 1; + } else if (!curr_switch_bool) { + curr_switch = 0; + } + while (curr_switch != prev_switch) { + int status; + if (curr_switch == 0) { // switch to pioneers if curr_switch is false + pid_t pid; + if ((pid = fork()) < 0) { + log_printf(ERROR, "network_switch: Failed to fork"); + sleep(SLEEP_DELAY); + } else if (pid == 0) { + execv(bash_exe, pie_args); // call the bash script with pioneers router arguments + } else { + waitpid(pid, &status, 0); + } } else { // switch to student's router if curr_switch is true - snprintf(total_command, sizeof(total_command), "./network_switch.sh %s %s", local_router, local_password); - system(total_command); + pid_t pid; + if ((pid = fork()) < 0) { + log_printf(ERROR, "network_switch: Failed to fork"); + sleep(SLEEP_DELAY); + } else if (pid == 0) { + execv(bash_exe, local_args); // call the bash script with local router arguments + } else { + waitpid(pid, &status, 0); + } + } + char buf[5]; + FILE* exit_status = fopen("exit_status.txt", "r"); + fgets(buf, 5, exit_status); // retrieve the output of the bash script in the exit_status.txt + if (strcmp(buf, "1") == 0) { // if output is 1, we successfully connected. Set previous switch = current switch + log_printf(WARN, "SUCCESSFULLY CONNECTED TO NETWORK"); + prev_switch = curr_switch; + } else { // if output is not 1, we loop again to call the bash script again + log_printf(WARN, "FAILED TO CONNECT TO NETWORK"); } - prev_switch = curr_switch; + fclose(exit_status); } } } sleep(SLEEP_DELAY); } -} \ No newline at end of file +} diff --git a/network_switch/network_switch.sh b/network_switch/network_switch.sh index 6b2211bd..5116ce21 100755 --- a/network_switch/network_switch.sh +++ b/network_switch/network_switch.sh @@ -1,8 +1,58 @@ #!/bin/bash -# move into folder with all the network names the potato connected to previously -cd /etc/NetworkManager/system-connections -sudo rm * # remove all network names -sudo nmcli d wifi connect $1 password $2 # connect to wifi determined by network switch +# script takes two arguments, the first being the name of the network to connect to, +# the second being the password to that network -# keep trying to connect until wifi is connected, check by looping through output of nmcli d \ No newline at end of file +# script returns 1 if successfully connected, 0 if unsuccessful + +# forget all networks by removing all network configuration files in nmcli folders +sudo rm /etc/NetworkManager/system-connections/* + +# initiate rescan of networks; this command only starts the scan, it doesn't wait for scan to complete +sudo nmcli dev wifi rescan + +# wait 3 seconds, look for the network name in the output of nmcli d wifi list +# repeat a maximum of 3 times (arbitrarily chosen nmumbers) +pass=0 +for i in {1..3}; do + # if passed, break early + if [[ $pass == 1 ]]; then + break; + fi + + sleep 3 + printf "Try number $i ...\n" + + while read line; do + if [[ $line == *"$1"* ]]; then + pass=1 + break + fi + done <<< "$(nmcli d wifi list)" +done + +printf "Going to connect!\n" + +# connect to the network; again do not proceed before action is complete +sudo nmcli d wifi connect $1 password $2 + +# we use the command nmcli -t -f CONNECTION,STATE device to get the state of NetworkManager +# we look for a line that is exactly :connected +# for example, if successfully connect to pioneers, the output will contain: +# pioneers:connected +pass=0 +while read line; do + if [[ $line == "$1:connected" ]]; then + pass=1 + break + fi +done <<< "$(nmcli -t -f CONNECTION,STATE device)" + +# write "1" or "0" to exit_status.txt to give the C program the result of this script +if [[ $pass == 1 ]]; then + printf "1" > exit_status.txt +else + printf "0" > exit_status.txt +fi + +exit $pass