RetroArch/network/wifi_driver.c

246 lines
7.0 KiB
C

/* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#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;
}