/* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2021 - Daniel De Matteis * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #include #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include "../driver.h" #include "../list_special.h" #include "../retroarch.h" #include "../runloop.h" #include "../verbosity.h" #include "wifi_driver.h" wifi_driver_t wifi_null = { NULL, /* init */ NULL, /* free */ NULL, /* start */ NULL, /* stop */ NULL, /* enable */ NULL, /* connection_info */ NULL, /* scan */ NULL, /* get_ssids */ NULL, /* ssid_is_online */ NULL, /* connect_ssid */ NULL, /* disconnect_ssid */ NULL, /* tether_start_stop */ "null", }; const wifi_driver_t *wifi_drivers[] = { #ifdef HAVE_LAKKA &wifi_connmanctl, #endif #ifdef HAVE_WIFI &wifi_nmcli, #endif &wifi_null, NULL, }; static wifi_driver_state_t wifi_driver_st = {0}; /* double alignment */ wifi_driver_state_t *wifi_state_get_ptr(void) { return &wifi_driver_st; } /** * config_get_wifi_driver_options: * * Get an enumerated list of all wifi driver names, * separated by '|'. * * Returns: string listing of all wifi driver names, * separated by '|'. **/ const char* config_get_wifi_driver_options(void) { return char_list_new_special(STRING_LIST_WIFI_DRIVERS, NULL); } void driver_wifi_scan(void) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) wifi_st->drv->scan(wifi_st->data); } bool driver_wifi_enable(bool enabled) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->enable(wifi_st->data, enabled); return false; } bool driver_wifi_connection_info(wifi_network_info_t *netinfo) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->connection_info(wifi_st->data, netinfo); return false; } wifi_network_scan_t* driver_wifi_get_ssids(void) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->get_ssids(wifi_st->data); return NULL; } bool driver_wifi_ssid_is_online(unsigned i) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->ssid_is_online(wifi_st->data, i); return false; } bool driver_wifi_connect_ssid(const wifi_network_info_t* net) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->connect_ssid(wifi_st->data, net); return false; } bool driver_wifi_disconnect_ssid(const wifi_network_info_t* net) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) return wifi_st->drv->disconnect_ssid(wifi_st->data, net); return false; } void driver_wifi_tether_start_stop(bool start, char* configfile) { wifi_driver_state_t *wifi_st = &wifi_driver_st; if (wifi_st && wifi_st->drv) wifi_st->drv->tether_start_stop(wifi_st->data, start, configfile); } bool wifi_driver_ctl(enum rarch_wifi_ctl_state state, void *data) { wifi_driver_state_t *wifi_st = &wifi_driver_st; settings_t *settings = config_get_ptr(); switch (state) { case RARCH_WIFI_CTL_DESTROY: wifi_st->active = false; wifi_st->drv = NULL; wifi_st->data = NULL; break; case RARCH_WIFI_CTL_SET_ACTIVE: wifi_st->active = true; break; case RARCH_WIFI_CTL_FIND_DRIVER: { const char *prefix = "wifi driver"; int i = (int)driver_find_index( "wifi_driver", settings->arrays.wifi_driver); if (i >= 0) wifi_st->drv = (const wifi_driver_t*)wifi_drivers[i]; else { if (verbosity_is_enabled()) { unsigned d; RARCH_ERR("Couldn't find any %s named \"%s\"\n", prefix, settings->arrays.wifi_driver); RARCH_LOG_OUTPUT("Available %ss are:\n", prefix); for (d = 0; wifi_drivers[d]; d++) RARCH_LOG_OUTPUT("\t%s\n", wifi_drivers[d]->ident); RARCH_WARN("Going to default to first %s...\n", prefix); } wifi_st->drv = (const wifi_driver_t*)wifi_drivers[0]; if (!wifi_st->drv) retroarch_fail(1, "find_wifi_driver()"); } } break; case RARCH_WIFI_CTL_UNSET_ACTIVE: wifi_st->active = false; break; case RARCH_WIFI_CTL_IS_ACTIVE: return wifi_st->active; case RARCH_WIFI_CTL_DEINIT: if (wifi_st->data && wifi_st->drv) { if (wifi_st->drv->free) wifi_st->drv->free(wifi_st->data); } wifi_st->data = NULL; break; case RARCH_WIFI_CTL_STOP: if ( wifi_st->drv && wifi_st->drv->stop && wifi_st->data) wifi_st->drv->stop(wifi_st->data); break; case RARCH_WIFI_CTL_START: if ( wifi_st->drv && wifi_st->data && wifi_st->drv->start) { bool wifi_allow = settings->bools.wifi_allow; if (wifi_allow) return wifi_st->drv->start(wifi_st->data); } return false; case RARCH_WIFI_CTL_INIT: /* Resource leaks will follow if wifi is initialized twice. */ if (wifi_st->data) return false; wifi_driver_ctl(RARCH_WIFI_CTL_FIND_DRIVER, NULL); if (wifi_st->drv && wifi_st->drv->init) { wifi_st->data = wifi_st->drv->init(); if (wifi_st->data) { wifi_st->drv->enable(wifi_st->data, settings->bools.wifi_enabled); } else { RARCH_ERR("Failed to initialize wifi driver. Will continue without wifi.\n"); wifi_driver_ctl(RARCH_WIFI_CTL_UNSET_ACTIVE, NULL); } } break; default: break; } return false; }