Merge pull request #11660 from davidgfnet/betterwifi2

Improving Wifi API and connman implementation
This commit is contained in:
Autechre 2020-12-04 04:08:38 +01:00 committed by GitHub
commit 6565fc9e9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 111 deletions

View File

@ -21,6 +21,7 @@
#include <compat/strl.h>
#include <compat/strcasestr.h>
#include <array/rbuf.h>
#include <lists/file_list.h>
#include <lists/dir_list.h>
#include <file/file_path.h>
@ -4527,7 +4528,7 @@ static void wifi_scan_callback(retro_task_t *task,
{
unsigned i;
file_list_t *file_list = NULL;
struct string_list *ssid_list = NULL;
wifi_network_scan_t *scan = NULL;
const char *path = NULL;
const char *label = NULL;
@ -4543,21 +4544,19 @@ static void wifi_scan_callback(retro_task_t *task,
file_list = menu_entries_get_selection_buf_ptr(0);
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list);
ssid_list = string_list_new();
scan = driver_wifi_get_ssids();
if (!scan)
return;
driver_wifi_get_ssids(ssid_list);
for (i = 0; i < ssid_list->size; i++)
for (i = 0; i < RBUF_LEN(scan->net_list); i++)
{
const char *ssid = ssid_list->elems[i].data;
const char *ssid = scan->net_list[i].ssid;
menu_entries_append_enum(file_list,
ssid,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI),
MENU_ENUM_LABEL_CONNECT_WIFI,
MENU_WIFI, 0, 0);
}
string_list_free(ssid_list);
}
#endif
@ -5459,17 +5458,17 @@ unsigned menu_displaylist_build_list(
settings_t *settings = config_get_ptr();
if (!string_is_equal(settings->arrays.wifi_driver, "null"))
{
struct string_list *ssid_list = string_list_new();
driver_wifi_get_ssids(ssid_list);
wifi_network_scan_t *scan = driver_wifi_get_ssids();
if (ssid_list->size == 0)
/* Temporary hack: scan periodically, until we have a submenu */
if (!scan || RBUF_LEN(scan->net_list) == 0 || time(NULL) > scan->scan_time + 120)
task_push_wifi_scan(wifi_scan_callback);
else
{
unsigned i;
for (i = 0; i < ssid_list->size; i++)
for (i = 0; i < RBUF_LEN(scan->net_list); i++)
{
const char *ssid = ssid_list->elems[i].data;
const char *ssid = scan->net_list[i].ssid;
if (menu_entries_append_enum(list,
ssid,
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_WIFI),

View File

@ -18937,10 +18937,10 @@ void driver_wifi_scan(void)
p_rarch->wifi_driver->scan(p_rarch->wifi_data);
}
void driver_wifi_get_ssids(struct string_list* ssids)
wifi_network_scan_t* driver_wifi_get_ssids()
{
struct rarch_state *p_rarch = &rarch_st;
p_rarch->wifi_driver->get_ssids(p_rarch->wifi_data, ssids);
return p_rarch->wifi_driver->get_ssids(p_rarch->wifi_data);
}
bool driver_wifi_ssid_is_online(unsigned i)

View File

@ -15,6 +15,8 @@
#include <compat/strl.h>
#include <file/file_path.h>
#include <array/rbuf.h>
#include <lists/string_list.h>
#include <string/stdstring.h>
#include <retro_miscellaneous.h>
#include <configuration.h>
@ -29,9 +31,7 @@
typedef struct
{
bool connman_cache[64];
unsigned connman_counter;
struct string_list* lines;
wifi_network_scan_t scan;
char command[256];
bool connmanctl_widgets_supported;
} connman_t;
@ -47,6 +47,9 @@ static void *connmanctl_init(void)
static void connmanctl_free(void *data)
{
connman_t *connman = (connman_t*)data;
if (connman->scan.net_list)
RBUF_FREE(connman->scan.net_list);
if (data)
free(data);
}
@ -164,15 +167,12 @@ static void connmanctl_tether_toggle(
static void connmanctl_scan(void *data)
{
char line[512];
union string_list_elem_attr attr;
FILE *serv_file = NULL;
settings_t *settings = config_get_ptr();
connman_t *connman = (connman_t*)data;
attr.i = RARCH_FILETYPE_UNSET;
if (connman->lines)
free(connman->lines);
connman->lines = string_list_new();
if (connman->scan.net_list)
RBUF_FREE(connman->scan.net_list);
if (connmanctl_tether_status(connman))
{
@ -195,74 +195,61 @@ static void connmanctl_scan(void *data)
serv_file = popen("connmanctl services", "r");
while (fgets(line, 512, serv_file))
{
int i;
struct string_list* list = NULL;
wifi_network_info_t entry;
size_t len = strlen(line);
if (len > 0 && line[len-1] == '\n')
line[--len] = '\0';
string_list_append(connman->lines, line, attr);
/* Parse lines directly and store net info directly */
memset(&entry, 0, sizeof(entry));
entry.connected = (line[2] == 'R' || line[2] == 'O');
entry.saved_password = (line[0] == '*');
/* connmanctl services outputs a 4 character prefixed lines,
* either whitespace or an identifier. i.e.:
* $ connmanctl services
* '*A0 SSID some_unique_id'
* ' SSID some_another_unique_id'
*/
list = string_split(&line[4], " ");
if (!list)
break;
if (list->size == 0)
continue;
for (i = 0; i < list->size-1; i++)
{
strlcat(entry.ssid, list->elems[i].data, sizeof(entry.ssid)-1);
strlcat(entry.ssid, " ", sizeof(entry.ssid)-1);
}
/* Store the connman network id here, for later */
strlcpy(entry.netid, list->elems[list->size-1].data, sizeof(entry.netid)-1);
string_list_free(list);
/* Filter only wifi nets */
if (!strncmp(entry.netid, "wifi_", 5))
RBUF_PUSH(connman->scan.net_list, entry);
}
connman->scan.scan_time = time(NULL);
pclose(serv_file);
}
static void connmanctl_get_ssids(void *data, struct string_list* ssids)
static wifi_network_scan_t* connmanctl_get_ssids(void *data)
{
unsigned i;
union string_list_elem_attr attr;
attr.i = RARCH_FILETYPE_UNSET;
connman_t *connman = (connman_t*)data;
if (!connman->lines)
return;
for (i = 0; i < connman->lines->size; i++)
{
char ssid[32];
const char *line = connman->lines->elems[i].data;
strlcpy(ssid, line+4, sizeof(ssid));
string_list_append(ssids, ssid, attr);
}
return &connman->scan;
}
static bool connmanctl_ssid_is_online(void *data, unsigned i)
{
char ln[512] = {0};
char service[128] = {0};
connman_t *connman = (connman_t*)data;
const char *line = connman->lines->elems[i].data;
FILE *command_file = NULL;
if (connman->connman_counter >= 64)
{
static struct string_list* list = NULL;
connman->connman_counter = 0;
list = string_split(line, " ");
if (!list)
return false;
if (list->size == 0)
{
string_list_free(list);
return false;
}
strlcpy(service, list->elems[list->size-1].data, sizeof(service));
string_list_free(list);
snprintf(connman->command, sizeof(connman->command), "\
connmanctl services %s | grep 'State = \\(online\\|ready\\)'",
service);
command_file = popen(connman->command, "r");
connman->connman_cache[i] = (fgets(ln, 512, command_file));
pclose(command_file);
}
else
{
connman->connman_counter++;
}
return connman->connman_cache[i];
return connman->scan.net_list[i].connected;
}
static bool connmanctl_connect_ssid(
@ -270,46 +257,19 @@ static bool connmanctl_connect_ssid(
{
unsigned i;
char ln[512] = {0};
char name[64] = {0};
char service[128] = {0};
char settings_dir[PATH_MAX_LENGTH] = {0};
char settings_path[PATH_MAX_LENGTH] = {0};
FILE *command_file = NULL;
FILE *settings_file = NULL;
connman_t *connman = (connman_t*)data;
const char *line = connman->lines->elems[idx].data;
wifi_network_info_t *netinfo = &connman->scan.net_list[idx];
settings_t *settings = config_get_ptr();
static struct string_list* list = NULL;
#ifdef HAVE_GFX_WIDGETS
bool widgets_active = connman->connmanctl_widgets_supported;
#endif
/* connmanctl services outputs a 4 character prefixed lines,
* either whitespace or an identifier. i.e.:
* $ connmanctl services
* '*A0 SSID some_unique_id'
* ' SSID some_another_unique_id'
*/
list = string_split(line+4, " ");
if (!list)
return false;
if (list->size == 0)
{
string_list_free(list);
return false;
}
for (i = 0; i < list->size-1; i++)
{
strlcat(name, list->elems[i].data, sizeof(name));
strlcat(name, " ", sizeof(name));
}
strlcpy(service, list->elems[list->size-1].data, sizeof(service));
string_list_free(list);
strlcat(settings_dir, LAKKA_CONNMAN_DIR, sizeof(settings_dir));
strlcat(settings_dir, service, sizeof(settings_dir));
strlcat(settings_dir, netinfo->netid, sizeof(settings_dir));
path_mkdir(settings_dir);
@ -317,12 +277,12 @@ static bool connmanctl_connect_ssid(
strlcat(settings_path, "/settings", sizeof(settings_path));
settings_file = fopen(settings_path, "w");
fprintf(settings_file, "[%s]\n", service);
fprintf(settings_file, "Name=%s\n", name);
fprintf(settings_file, "[%s]\n", netinfo->netid);
fprintf(settings_file, "Name=%s\n", netinfo->ssid);
fprintf(settings_file, "SSID=");
for (i = 0; i < strlen(name); i++)
fprintf(settings_file, "%02x", (unsigned int) name[i]);
for (i = 0; i < strlen(netinfo->ssid); i++)
fprintf(settings_file, "%02x", (unsigned int) netinfo->ssid[i]);
fprintf(settings_file, "\n");
fprintf(settings_file, "Favorite=%s\n", "true");
@ -345,7 +305,7 @@ static bool connmanctl_connect_ssid(
snprintf(connman->command, sizeof(connman->command), "\
connmanctl connect %s 2>&1",
service);
netinfo->netid);
command_file = popen(connman->command, "r");

View File

@ -22,7 +22,6 @@
#include <boolean.h>
#include <retro_common_api.h>
#include <lists/string_list.h>
RETRO_BEGIN_DECLS
@ -41,6 +40,21 @@ enum rarch_wifi_ctl_state
RARCH_WIFI_CTL_INIT
};
typedef struct wifi_network_info
{
char ssid[33];
bool connected;
bool saved_password;
char netid[160]; /* Do not use, internal */
/* TODO Add signal strength & other info */
} wifi_network_info_t;
typedef struct wifi_network_scan
{
time_t scan_time;
wifi_network_info_t *net_list; /* This is an rbuf array */
} wifi_network_scan_t;
typedef struct wifi_driver
{
void *(*init)(void);
@ -51,7 +65,7 @@ typedef struct wifi_driver
void (*stop)(void *data);
void (*scan)(void *data);
void (*get_ssids)(void *data, struct string_list *list);
wifi_network_scan_t* (*get_ssids)(void *data);
bool (*ssid_is_online)(void *data, unsigned i);
bool (*connect_ssid)(void *data, unsigned i, const char* passphrase);
void (*tether_start_stop)(void *data, bool start, char* configfile);
@ -78,7 +92,7 @@ bool driver_wifi_start(void);
void driver_wifi_scan(void);
void driver_wifi_get_ssids(struct string_list *list);
wifi_network_scan_t* driver_wifi_get_ssids();
bool driver_wifi_ssid_is_online(unsigned i);