Merge pull request #10937 from parport0/master

Bluetooth fixes v2
This commit is contained in:
Autechre 2020-06-29 00:19:49 +02:00 committed by GitHub
commit 0267736465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 278 additions and 319 deletions

View File

@ -28,13 +28,7 @@ enum rarch_bluetooth_ctl_state
RARCH_BLUETOOTH_CTL_NONE = 0, RARCH_BLUETOOTH_CTL_NONE = 0,
RARCH_BLUETOOTH_CTL_DESTROY, RARCH_BLUETOOTH_CTL_DESTROY,
RARCH_BLUETOOTH_CTL_DEINIT, RARCH_BLUETOOTH_CTL_DEINIT,
RARCH_BLUETOOTH_CTL_SET_ACTIVE,
RARCH_BLUETOOTH_CTL_UNSET_ACTIVE,
RARCH_BLUETOOTH_CTL_IS_ACTIVE,
RARCH_BLUETOOTH_CTL_FIND_DRIVER, RARCH_BLUETOOTH_CTL_FIND_DRIVER,
RARCH_BLUETOOTH_CTL_SET_CB,
RARCH_BLUETOOTH_CTL_STOP,
RARCH_BLUETOOTH_CTL_START,
RARCH_BLUETOOTH_CTL_INIT RARCH_BLUETOOTH_CTL_INIT
}; };
@ -44,14 +38,11 @@ typedef struct bluetooth_driver
void (*free)(void *data); void (*free)(void *data);
bool (*start)(void *data); void (*scan)(void *data);
void (*stop)(void *data); void (*get_devices)(void *data, struct string_list *list);
bool (*device_is_connected)(void *data, unsigned i);
void (*scan)(void); void (*device_get_sublabel)(void *data, char *s, unsigned i, size_t len);
void (*get_devices)(struct string_list *list); bool (*connect_device)(void *data, unsigned i);
bool (*device_is_connected)(unsigned i);
void (*device_get_sublabel)(char *s, unsigned i, size_t len);
bool (*connect_device)(unsigned i);
const char *ident; const char *ident;
} bluetooth_driver_t; } bluetooth_driver_t;
@ -70,10 +61,6 @@ extern bluetooth_driver_t bluetooth_bluez;
**/ **/
const char* config_get_bluetooth_driver_options(void); const char* config_get_bluetooth_driver_options(void);
void driver_bluetooth_stop(void);
bool driver_bluetooth_start(void);
void driver_bluetooth_scan(void); void driver_bluetooth_scan(void);
void driver_bluetooth_get_devices(struct string_list *list); void driver_bluetooth_get_devices(struct string_list *list);

View File

@ -18,48 +18,40 @@
#include "../bluetooth_driver.h" #include "../bluetooth_driver.h"
#include "../../retroarch.h" #include "../../retroarch.h"
/* TODO/FIXME - static globals - should go into userdata typedef struct
* struct for driver */ {
static bool bluetoothctl_cache[256] = {0}; bool bluetoothctl_cache[256];
static unsigned bluetoothctl_counter[256] = {0}; unsigned bluetoothctl_counter[256];
static struct string_list* lines = NULL; struct string_list* lines;
static char command[256] = {0}; char command[256];
} bluetoothctl_t;
static void *bluetoothctl_init(void) static void *bluetoothctl_init(void)
{ {
return (void*)-1; return calloc(1, sizeof(bluetoothctl_t));
} }
static void bluetoothctl_free(void *data) static void bluetoothctl_free(void *data)
{ {
(void)data; if (data)
free(data);
} }
static bool bluetoothctl_start(void *data) static void bluetoothctl_scan(void *data)
{
(void)data;
return true;
}
static void bluetoothctl_stop(void *data)
{
(void)data;
}
static void bluetoothctl_scan(void)
{ {
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
char line[512]; char line[512];
union string_list_elem_attr attr; union string_list_elem_attr attr;
FILE *dev_file = NULL; FILE *dev_file = NULL;
attr.i = 0; attr.i = 0;
if (lines) if (btctl->lines)
free(lines); free(btctl->lines);
lines = string_list_new(); btctl->lines = string_list_new();
pclose(popen("bluetoothctl -- power on", "r")); pclose(popen("bluetoothctl -- power on", "r"));
pclose(popen("bluetoothctl --timeout 15 scan on", "r")); pclose(popen("bluetoothctl --timeout 10 scan on", "r"));
runloop_msg_queue_push(msg_hash_to_str(MSG_BLUETOOTH_SCAN_COMPLETE), runloop_msg_queue_push(msg_hash_to_str(MSG_BLUETOOTH_SCAN_COMPLETE),
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
@ -73,26 +65,27 @@ static void bluetoothctl_scan(void)
if (len > 0 && line[len-1] == '\n') if (len > 0 && line[len-1] == '\n')
line[--len] = '\0'; line[--len] = '\0';
string_list_append(lines, line, attr); string_list_append(btctl->lines, line, attr);
} }
pclose(dev_file); pclose(dev_file);
} }
static void bluetoothctl_get_devices(struct string_list* devices) static void bluetoothctl_get_devices(void *data, struct string_list* devices)
{ {
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
unsigned i; unsigned i;
union string_list_elem_attr attr; union string_list_elem_attr attr;
attr.i = 0; attr.i = 0;
if (!lines) if (!btctl->lines)
return; return;
for (i = 0; i < lines->size; i++) for (i = 0; i < btctl->lines->size; i++)
{ {
char device[64]; char device[64];
const char *line = lines->elems[i].data; const char *line = btctl->lines->elems[i].data;
/* bluetoothctl devices outputs lines of the format: /* bluetoothctl devices outputs lines of the format:
* $ bluetoothctl devices * $ bluetoothctl devices
@ -103,17 +96,18 @@ static void bluetoothctl_get_devices(struct string_list* devices)
} }
} }
static bool bluetoothctl_device_is_connected(unsigned i) static bool bluetoothctl_device_is_connected(void *data, unsigned i)
{ {
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
char ln[512] = {0}; char ln[512] = {0};
char device[18] = {0}; char device[18] = {0};
const char *line = lines->elems[i].data; const char *line = btctl->lines->elems[i].data;
FILE *command_file = NULL; FILE *command_file = NULL;
if (bluetoothctl_counter[i] == 60) if (btctl->bluetoothctl_counter[i] == 60)
{ {
static struct string_list* list = NULL; static struct string_list* list = NULL;
bluetoothctl_counter[i] = 0; btctl->bluetoothctl_counter[i] = 0;
list = string_split(line, " "); list = string_split(line, " ");
if (!list) if (!list)
return false; return false;
@ -127,34 +121,35 @@ static bool bluetoothctl_device_is_connected(unsigned i)
strlcpy(device, list->elems[1].data, sizeof(device)); strlcpy(device, list->elems[1].data, sizeof(device));
string_list_free(list); string_list_free(list);
snprintf(command, sizeof(command), "\ snprintf(btctl->command, sizeof(btctl->command), "\
bluetoothctl -- info %s | grep 'Connected: yes'", bluetoothctl -- info %s | grep 'Connected: yes'",
device); device);
command_file = popen(command, "r"); command_file = popen(btctl->command, "r");
while (fgets(ln, 512, command_file)) while (fgets(ln, 512, command_file))
{ {
bluetoothctl_cache[i] = true; btctl->bluetoothctl_cache[i] = true;
return true; return true;
} }
pclose(command_file); pclose(command_file);
bluetoothctl_cache[i] = false; btctl->bluetoothctl_cache[i] = false;
} }
else else
{ {
bluetoothctl_counter[i]++; btctl->bluetoothctl_counter[i]++;
return bluetoothctl_cache[i]; return btctl->bluetoothctl_cache[i];
} }
return false; return false;
} }
static bool bluetoothctl_connect_device(unsigned idx) static bool bluetoothctl_connect_device(void *data, unsigned idx)
{ {
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
unsigned i; unsigned i;
char device[18] = {0}; char device[18] = {0};
const char *line = lines->elems[idx].data; const char *line = btctl->lines->elems[idx].data;
static struct string_list* list = NULL; static struct string_list* list = NULL;
/* bluetoothctl devices outputs lines of the format: /* bluetoothctl devices outputs lines of the format:
@ -174,43 +169,42 @@ static bool bluetoothctl_connect_device(unsigned idx)
strlcpy(device, list->elems[1].data, sizeof(device)); strlcpy(device, list->elems[1].data, sizeof(device));
string_list_free(list); string_list_free(list);
snprintf(command, sizeof(command), "\ snprintf(btctl->command, sizeof(btctl->command), "\
bluetoothctl -- trust %s", bluetoothctl -- trust %s",
device); device);
pclose(popen(command, "r")); pclose(popen(btctl->command, "r"));
snprintf(command, sizeof(command), "\ snprintf(btctl->command, sizeof(btctl->command), "\
bluetoothctl -- pair %s", bluetoothctl -- pair %s",
device); device);
pclose(popen(command, "r")); pclose(popen(btctl->command, "r"));
snprintf(command, sizeof(command), "\ snprintf(btctl->command, sizeof(btctl->command), "\
bluetoothctl -- connect %s", bluetoothctl -- connect %s",
device); device);
pclose(popen(command, "r")); pclose(popen(btctl->command, "r"));
bluetoothctl_counter[idx] = 0; btctl->bluetoothctl_counter[idx] = 0;
return true; return true;
} }
void bluetoothctl_device_get_sublabel (char *s, unsigned i, size_t len) void bluetoothctl_device_get_sublabel (void *data, char *s, unsigned i, size_t len)
{ {
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
/* bluetoothctl devices outputs lines of the format: /* bluetoothctl devices outputs lines of the format:
* $ bluetoothctl devices * $ bluetoothctl devices
* 'Device (mac address) (device name)' * 'Device (mac address) (device name)'
*/ */
const char *line = lines->elems[i].data; const char *line = btctl->lines->elems[i].data;
strlcpy(s, line+7, 18); strlcpy(s, line+7, 18);
} }
bluetooth_driver_t bluetooth_bluetoothctl = { bluetooth_driver_t bluetooth_bluetoothctl = {
bluetoothctl_init, bluetoothctl_init,
bluetoothctl_free, bluetoothctl_free,
bluetoothctl_start,
bluetoothctl_stop,
bluetoothctl_scan, bluetoothctl_scan,
bluetoothctl_get_devices, bluetoothctl_get_devices,
bluetoothctl_device_is_connected, bluetoothctl_device_is_connected,

View File

@ -49,37 +49,29 @@ typedef struct
#undef VECTOR_LIST_TYPE #undef VECTOR_LIST_TYPE
#undef VECTOR_LIST_NAME #undef VECTOR_LIST_NAME
/* TODO/FIXME - static globals - should go into userdata typedef struct
* struct for driver */ {
static struct device_info_vector_list *devices = NULL; struct device_info_vector_list *devices;
static char adapter[256] = {0}; char adapter[256];
static DBusConnection* dbus_connection = NULL; DBusConnection* dbus_connection;
static bool bluez_cache[256] = {0}; bool bluez_cache[256];
static int bluez_cache_counter[256] = {0}; int bluez_cache_counter[256];
} bluez_t;
static void *bluez_init (void) static void *bluez_init (void)
{ {
return (void*)-1; return calloc(1, sizeof(bluez_t));
} }
static void bluez_free (void *data) static void bluez_free (void *data)
{ {
(void)data; if (data)
} free(data);
static bool bluez_start (void *data)
{
(void)data;
return true;
}
static void bluez_stop (void *data)
{
(void)data;
} }
static int static int
set_bool_property ( set_bool_property (
bluez_t *bluez,
const char *path, const char *path,
const char *arg_adapter, const char *arg_adapter,
const char *arg_property, const char *arg_property,
@ -118,7 +110,7 @@ set_bool_property (
&req_iter, &req_subiter)) &req_iter, &req_subiter))
goto fault; goto fault;
reply = dbus_connection_send_with_reply_and_block(dbus_connection, reply = dbus_connection_send_with_reply_and_block(bluez->dbus_connection,
message, 1000, &err); message, 1000, &err);
if (!reply) if (!reply)
goto fault; goto fault;
@ -133,6 +125,7 @@ fault:
} }
static int get_bool_property( static int get_bool_property(
bluez_t *bluez,
const char *path, const char *path,
const char *arg_adapter, const char *arg_adapter,
const char *arg_property, const char *arg_property,
@ -155,7 +148,7 @@ static int get_bool_property(
DBUS_TYPE_INVALID)) DBUS_TYPE_INVALID))
return 1; return 1;
reply = dbus_connection_send_with_reply_and_block(dbus_connection, reply = dbus_connection_send_with_reply_and_block(bluez->dbus_connection,
message, 1000, &err); message, 1000, &err);
dbus_message_unref(message); dbus_message_unref(message);
@ -176,24 +169,24 @@ static int get_bool_property(
return 0; return 0;
} }
static int adapter_discovery (const char *method) static int adapter_discovery (bluez_t *bluez, const char *method)
{ {
DBusMessage *message = dbus_message_new_method_call( DBusMessage *message = dbus_message_new_method_call(
"org.bluez", adapter, "org.bluez", bluez->adapter,
"org.bluez.Adapter1", method); "org.bluez.Adapter1", method);
if (!message) if (!message)
return 1; return 1;
if (!dbus_connection_send(dbus_connection, message, NULL)) if (!dbus_connection_send(bluez->dbus_connection, message, NULL))
return 1; return 1;
dbus_connection_flush(dbus_connection); dbus_connection_flush(bluez->dbus_connection);
dbus_message_unref(message); dbus_message_unref(message);
return 0; return 0;
} }
static int get_managed_objects (DBusMessage **reply) static int get_managed_objects (bluez_t *bluez, DBusMessage **reply)
{ {
DBusMessage *message; DBusMessage *message;
DBusError err; DBusError err;
@ -205,7 +198,7 @@ static int get_managed_objects (DBusMessage **reply)
if (!message) if (!message)
return 1; return 1;
*reply = dbus_connection_send_with_reply_and_block(dbus_connection, *reply = dbus_connection_send_with_reply_and_block(bluez->dbus_connection,
message, -1, &err); message, -1, &err);
/* if (!reply) is done by the caller in this one */ /* if (!reply) is done by the caller in this one */
@ -213,7 +206,7 @@ static int get_managed_objects (DBusMessage **reply)
return 0; return 0;
} }
static int device_method (const char *path, const char *method) static int device_method (bluez_t *bluez, const char *path, const char *method)
{ {
DBusMessage *message, *reply; DBusMessage *message, *reply;
DBusError err; DBusError err;
@ -225,46 +218,18 @@ static int device_method (const char *path, const char *method)
if (!message) if (!message)
return 1; return 1;
reply = dbus_connection_send_with_reply_and_block(dbus_connection, reply = dbus_connection_send_with_reply_and_block(bluez->dbus_connection,
message, 10000, &err); message, 10000, &err);
if (!reply) if (!reply)
return 1; return 1;
dbus_connection_flush(dbus_connection); dbus_connection_flush(bluez->dbus_connection);
dbus_message_unref(message); dbus_message_unref(message);
return 0; return 0;
} }
static int device_remove (const char *path) static int get_default_adapter(bluez_t *bluez, DBusMessage *reply)
{
DBusMessage *message, *reply;
DBusError err;
dbus_error_init(&err);
message = dbus_message_new_method_call( "org.bluez", adapter,
"org.bluez.Adapter11", "RemoveDevice");
if (!message)
return 1;
if (!dbus_message_append_args(message,
DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID))
return 1;
reply = dbus_connection_send_with_reply_and_block(dbus_connection,
message, 10000, &err);
if (!reply)
return 1;
dbus_connection_flush(dbus_connection);
dbus_message_unref(message);
return 0;
}
static int get_default_adapter(DBusMessage *reply)
{ {
/* "...an application would discover the available adapters by /* "...an application would discover the available adapters by
* performing a ObjectManager.GetManagedObjects call and look for any * performing a ObjectManager.GetManagedObjects call and look for any
@ -329,7 +294,7 @@ static int get_default_adapter(DBusMessage *reply)
if (string_is_equal(interface_name, "org.bluez.Adapter1")) if (string_is_equal(interface_name, "org.bluez.Adapter1"))
{ {
strlcpy(adapter, obj_path, 256); strlcpy(bluez->adapter, obj_path, 256);
return 0; return 0;
} }
} while (dbus_message_iter_next(&array_2_iter)); } while (dbus_message_iter_next(&array_2_iter));
@ -339,7 +304,7 @@ static int get_default_adapter(DBusMessage *reply)
return 1; return 1;
} }
static int read_scanned_devices (DBusMessage *reply) static int read_scanned_devices (bluez_t *bluez, DBusMessage *reply)
{ {
device_info_t device; device_info_t device;
DBusMessageIter root_iter; DBusMessageIter root_iter;
@ -490,7 +455,7 @@ static int read_scanned_devices (DBusMessage *reply)
} }
} while (dbus_message_iter_next(&array_3_iter)); } while (dbus_message_iter_next(&array_3_iter));
if (!device_info_vector_list_append(devices, device)) if (!device_info_vector_list_append(bluez->devices, device))
return 1; return 1;
} while (dbus_message_iter_next(&array_2_iter)); } while (dbus_message_iter_next(&array_2_iter));
@ -499,138 +464,143 @@ static int read_scanned_devices (DBusMessage *reply)
return 0; return 0;
} }
static void bluez_dbus_connect (void) static void bluez_dbus_connect (bluez_t *bluez)
{ {
DBusError err; DBusError err;
dbus_error_init(&err); dbus_error_init(&err);
dbus_connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err); bluez->dbus_connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
} }
static void bluez_dbus_disconnect (void) static void bluez_dbus_disconnect (bluez_t *bluez)
{ {
if (!dbus_connection) if (!bluez->dbus_connection)
return; return;
dbus_connection_close(dbus_connection); dbus_connection_close(bluez->dbus_connection);
dbus_connection_unref(dbus_connection); dbus_connection_unref(bluez->dbus_connection);
dbus_connection = NULL; bluez->dbus_connection = NULL;
} }
static void bluez_scan (void) static void bluez_scan (void *data)
{ {
bluez_t *bluez = (bluez_t*)data;
DBusError err; DBusError err;
DBusMessage *reply; DBusMessage *reply;
bluez_dbus_connect(); bluez_dbus_connect(bluez);
if (get_managed_objects(&reply)) if (get_managed_objects(bluez, &reply))
return; return;
if (!reply) if (!reply)
return; return;
/* Get default adapter */ /* Get default adapter */
if (get_default_adapter(reply)) if (get_default_adapter(bluez, reply))
return; return;
dbus_message_unref(reply); dbus_message_unref(reply);
/* Power device on */ /* Power device on */
if (set_bool_property(adapter, "org.bluez.Adapter1", "Powered", 1)) if (set_bool_property(bluez, bluez->adapter, "org.bluez.Adapter1", "Powered", 1))
return; return;
/* Start discovery */ /* Start discovery */
if (adapter_discovery("StartDiscovery")) if (adapter_discovery(bluez, "StartDiscovery"))
return; return;
retro_sleep(10000); retro_sleep(10000);
/* Stop discovery */ /* Stop discovery */
if (adapter_discovery("StopDiscovery")) if (adapter_discovery(bluez, "StopDiscovery"))
return; return;
/* Get scanned devices */ /* Get scanned devices */
if (get_managed_objects(&reply)) if (get_managed_objects(bluez, &reply))
return; return;
if (!reply) if (!reply)
return; return;
if (devices) if (bluez->devices)
device_info_vector_list_free(devices); device_info_vector_list_free(bluez->devices);
devices = device_info_vector_list_new(); bluez->devices = device_info_vector_list_new();
read_scanned_devices(reply); read_scanned_devices(bluez, reply);
dbus_message_unref(reply); dbus_message_unref(reply);
bluez_dbus_disconnect(); bluez_dbus_disconnect(bluez);
} }
static void bluez_get_devices (struct string_list* devices_string_list) static void bluez_get_devices (void *data, struct string_list* devices_string_list)
{ {
bluez_t *bluez = (bluez_t*)data;
unsigned i; unsigned i;
union string_list_elem_attr attr; union string_list_elem_attr attr;
attr.i = 0; attr.i = 0;
if (!devices) if (!bluez->devices)
return; return;
for (i = 0; i < devices->count; i++) for (i = 0; i < bluez->devices->count; i++)
{ {
char device[64]; char device[64];
strlcpy(device, devices->data[i].name, sizeof(device)); strlcpy(device, bluez->devices->data[i].name, sizeof(device));
string_list_append(devices_string_list, device, attr); string_list_append(devices_string_list, device, attr);
} }
} }
static bool bluez_device_is_connected (unsigned i) static bool bluez_device_is_connected (void *data, unsigned i)
{ {
bluez_t *bluez = (bluez_t*)data;
int value; int value;
if (bluez_cache_counter[i] == 60) if (bluez->bluez_cache_counter[i] == 60)
{ {
bluez_cache_counter[i] = 0; bluez->bluez_cache_counter[i] = 0;
bluez_dbus_connect(); bluez_dbus_connect(bluez);
get_bool_property(devices->data[i].path, "org.bluez.Device1", if (get_bool_property(bluez, bluez->devices->data[i].path,
"Connected", &value); "org.bluez.Device1", "Connected", &value))
bluez_dbus_disconnect(); {
/* Device disappeared */
value = false;
}
bluez_dbus_disconnect(bluez);
bluez_cache[i] = value; bluez->bluez_cache[i] = value;
return value; return value;
} }
bluez_cache_counter[i]++; bluez->bluez_cache_counter[i]++;
return bluez_cache[i]; return bluez->bluez_cache[i];
} }
static void bluez_device_get_sublabel(char *s, unsigned i, size_t len) static void bluez_device_get_sublabel(void *data, char *s, unsigned i, size_t len)
{ {
strlcpy(s, devices->data[i].address, len); bluez_t *bluez = (bluez_t*)data;
strlcpy(s, bluez->devices->data[i].address, len);
} }
static bool bluez_connect_device(unsigned i) static bool bluez_connect_device(void *data, unsigned i)
{ {
bluez_dbus_connect(); bluez_t *bluez = (bluez_t*)data;
bluez_dbus_connect(bluez);
/* Remove the device */
device_remove(devices->data[i].path);
/* Trust the device */ /* Trust the device */
if (set_bool_property(devices->data[i].path, if (set_bool_property(bluez, bluez->devices->data[i].path,
"org.bluez.Device1", "Trusted", 1)) "org.bluez.Device1", "Trusted", 1))
return false; return false;
/* Pair the device */ /* Pair the device */
if (device_method(devices->data[i].path, "Pair")) device_method(bluez, bluez->devices->data[i].path, "Pair");
return false; /* Can be "Already Exists" */
/* Connect the device */ /* Connect the device */
if (device_method(devices->data[i].path, "Connect")) if (device_method(bluez, bluez->devices->data[i].path, "Connect"))
return false; return false;
bluez_dbus_disconnect(); bluez_dbus_disconnect(bluez);
bluez_cache_counter[i] = 0; bluez->bluez_cache_counter[i] = 0;
return true; return true;
} }
bluetooth_driver_t bluetooth_bluez = { bluetooth_driver_t bluetooth_bluez = {
bluez_init, bluez_init,
bluez_free, bluez_free,
bluez_start,
bluez_stop,
bluez_scan, bluez_scan,
bluez_get_devices, bluez_get_devices,
bluez_device_is_connected, bluez_device_is_connected,

View File

@ -263,11 +263,12 @@ uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_ACHIEVEMENTS]; return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_ACHIEVEMENTS];
case MENU_ENUM_LABEL_NETWORK_INFORMATION: case MENU_ENUM_LABEL_NETWORK_INFORMATION:
case MENU_ENUM_LABEL_NETWORK_SETTINGS: case MENU_ENUM_LABEL_NETWORK_SETTINGS:
case MENU_ENUM_LABEL_BLUETOOTH_SETTINGS:
case MENU_ENUM_LABEL_WIFI_SETTINGS: case MENU_ENUM_LABEL_WIFI_SETTINGS:
case MENU_ENUM_LABEL_NETWORK_INFO_ENTRY: case MENU_ENUM_LABEL_NETWORK_INFO_ENTRY:
case MENU_ENUM_LABEL_NETWORK_HOSTING_SETTINGS: case MENU_ENUM_LABEL_NETWORK_HOSTING_SETTINGS:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_NETWORK]; return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_NETWORK];
case MENU_ENUM_LABEL_BLUETOOTH_SETTINGS:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_BLUETOOTH];
case MENU_ENUM_LABEL_PLAYLIST_SETTINGS: case MENU_ENUM_LABEL_PLAYLIST_SETTINGS:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_PLAYLIST]; return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_PLAYLIST];
case MENU_ENUM_LABEL_USER_SETTINGS: case MENU_ENUM_LABEL_USER_SETTINGS:

View File

@ -2691,12 +2691,13 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
return xmb->textures.list[XMB_TEXTURE_RELOAD]; return xmb->textures.list[XMB_TEXTURE_RELOAD];
case MENU_ENUM_LABEL_NETWORK_INFORMATION: case MENU_ENUM_LABEL_NETWORK_INFORMATION:
case MENU_ENUM_LABEL_NETWORK_SETTINGS: case MENU_ENUM_LABEL_NETWORK_SETTINGS:
case MENU_ENUM_LABEL_BLUETOOTH_SETTINGS:
case MENU_ENUM_LABEL_WIFI_SETTINGS: case MENU_ENUM_LABEL_WIFI_SETTINGS:
case MENU_ENUM_LABEL_NETWORK_INFO_ENTRY: case MENU_ENUM_LABEL_NETWORK_INFO_ENTRY:
case MENU_ENUM_LABEL_NETWORK_HOSTING_SETTINGS: case MENU_ENUM_LABEL_NETWORK_HOSTING_SETTINGS:
return xmb->textures.list[XMB_TEXTURE_NETWORK]; return xmb->textures.list[XMB_TEXTURE_NETWORK];
#endif #endif
case MENU_ENUM_LABEL_BLUETOOTH_SETTINGS:
return xmb->textures.list[XMB_TEXTURE_BLUETOOTH];
case MENU_ENUM_LABEL_SHUTDOWN: case MENU_ENUM_LABEL_SHUTDOWN:
return xmb->textures.list[XMB_TEXTURE_SHUTDOWN]; return xmb->textures.list[XMB_TEXTURE_SHUTDOWN];
case MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES: case MENU_ENUM_LABEL_CHEAT_APPLY_CHANGES:

View File

@ -877,8 +877,6 @@ static hid_driver_t *hid_drivers[] = {
static bluetooth_driver_t bluetooth_null = { static bluetooth_driver_t bluetooth_null = {
NULL, /* init */ NULL, /* init */
NULL, /* free */ NULL, /* free */
NULL, /* start */
NULL, /* stop */
NULL, /* scan */ NULL, /* scan */
NULL, /* get_devices */ NULL, /* get_devices */
NULL, /* device_is_connected */ NULL, /* device_is_connected */
@ -20471,31 +20469,46 @@ const char* config_get_bluetooth_driver_options(void)
void driver_bluetooth_scan(void) void driver_bluetooth_scan(void)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->bluetooth_driver->scan(); if ( (p_rarch->bluetooth_driver_active) &&
(p_rarch->bluetooth_driver->scan) )
p_rarch->bluetooth_driver->scan(p_rarch->bluetooth_data);
} }
void driver_bluetooth_get_devices(struct string_list* devices) void driver_bluetooth_get_devices(struct string_list* devices)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->bluetooth_driver->get_devices(devices); if ( (p_rarch->bluetooth_driver_active) &&
(p_rarch->bluetooth_driver->get_devices) )
p_rarch->bluetooth_driver->get_devices(p_rarch->bluetooth_data, devices);
} }
bool driver_bluetooth_device_is_connected(unsigned i) bool driver_bluetooth_device_is_connected(unsigned i)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
return p_rarch->bluetooth_driver->device_is_connected(i); if ( (p_rarch->bluetooth_driver_active) &&
(p_rarch->bluetooth_driver->device_is_connected) )
{
return p_rarch->bluetooth_driver->device_is_connected(p_rarch->bluetooth_data, i);
} else {
return false;
}
} }
void driver_bluetooth_device_get_sublabel(char *s, unsigned i, size_t len) void driver_bluetooth_device_get_sublabel(char *s, unsigned i, size_t len)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->bluetooth_driver->device_get_sublabel(s, i, len); if ( (p_rarch->bluetooth_driver_active) &&
(p_rarch->bluetooth_driver->device_get_sublabel) )
p_rarch->bluetooth_driver->device_get_sublabel(p_rarch->bluetooth_data, s, i, len);
} }
bool driver_bluetooth_connect_device(unsigned i) bool driver_bluetooth_connect_device(unsigned i)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
return p_rarch->bluetooth_driver->connect_device(i); if (p_rarch->bluetooth_driver_active)
return p_rarch->bluetooth_driver->connect_device(p_rarch->bluetooth_data, i);
else
return false;
} }
bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data) bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
@ -20506,12 +20519,9 @@ bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
switch (state) switch (state)
{ {
case RARCH_BLUETOOTH_CTL_DESTROY: case RARCH_BLUETOOTH_CTL_DESTROY:
p_rarch->bluetooth_driver_active = false;
p_rarch->bluetooth_driver = NULL; p_rarch->bluetooth_driver = NULL;
p_rarch->bluetooth_data = NULL; p_rarch->bluetooth_data = NULL;
break; p_rarch->bluetooth_driver_active = false;
case RARCH_BLUETOOTH_CTL_SET_ACTIVE:
p_rarch->bluetooth_driver_active = true;
break; break;
case RARCH_BLUETOOTH_CTL_FIND_DRIVER: case RARCH_BLUETOOTH_CTL_FIND_DRIVER:
{ {
@ -20548,11 +20558,6 @@ bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
} }
} }
break; break;
case RARCH_BLUETOOTH_CTL_UNSET_ACTIVE:
p_rarch->bluetooth_driver_active = false;
break;
case RARCH_BLUETOOTH_CTL_IS_ACTIVE:
return p_rarch->bluetooth_driver_active;
case RARCH_BLUETOOTH_CTL_DEINIT: case RARCH_BLUETOOTH_CTL_DEINIT:
if (p_rarch->bluetooth_data && p_rarch->bluetooth_driver) if (p_rarch->bluetooth_data && p_rarch->bluetooth_driver)
{ {
@ -20561,29 +20566,7 @@ bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
} }
p_rarch->bluetooth_data = NULL; p_rarch->bluetooth_data = NULL;
break; p_rarch->bluetooth_driver_active = false;
case RARCH_BLUETOOTH_CTL_STOP:
if ( p_rarch->bluetooth_driver
&& p_rarch->bluetooth_driver->stop
&& p_rarch->bluetooth_data)
p_rarch->bluetooth_driver->stop(p_rarch->bluetooth_data);
break;
case RARCH_BLUETOOTH_CTL_START:
if ( p_rarch->bluetooth_driver
&& p_rarch->bluetooth_data
&& p_rarch->bluetooth_driver->start)
{
bool bluetooth_allow = settings->bools.bluetooth_allow;
if (bluetooth_allow)
return p_rarch->bluetooth_driver->start(p_rarch->bluetooth_data);
}
return false;
case RARCH_BLUETOOTH_CTL_SET_CB:
{
/*struct retro_bluetooth_callback *cb =
(struct retro_bluetooth_callback*)data;
bluetooth_cb = *cb;*/
}
break; break;
case RARCH_BLUETOOTH_CTL_INIT: case RARCH_BLUETOOTH_CTL_INIT:
/* Resource leaks will follow if bluetooth is initialized twice. */ /* Resource leaks will follow if bluetooth is initialized twice. */
@ -20592,16 +20575,20 @@ bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_FIND_DRIVER, NULL); bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_FIND_DRIVER, NULL);
p_rarch->bluetooth_data = p_rarch->bluetooth_driver->init(); if (p_rarch->bluetooth_driver && p_rarch->bluetooth_driver->init)
if (!p_rarch->bluetooth_data)
{ {
RARCH_ERR("Failed to initialize bluetooth driver. Will continue without bluetooth.\n"); p_rarch->bluetooth_driver_active = true;
bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_UNSET_ACTIVE, NULL); p_rarch->bluetooth_data = p_rarch->bluetooth_driver->init();
if (!p_rarch->bluetooth_data)
{
RARCH_ERR("Failed to initialize bluetooth driver. Will continue without bluetooth.\n");
p_rarch->bluetooth_driver_active = false;
}
} else {
p_rarch->bluetooth_driver_active = false;
} }
/*if (bluetooth_cb.initialized)
bluetooth_cb.initialized();*/
break; break;
default: default:
break; break;
@ -20629,31 +20616,31 @@ const char* config_get_wifi_driver_options(void)
void driver_wifi_scan(void) void driver_wifi_scan(void)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->wifi_driver->scan(); p_rarch->wifi_driver->scan(p_rarch->wifi_data);
} }
void driver_wifi_get_ssids(struct string_list* ssids) void driver_wifi_get_ssids(struct string_list* ssids)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->wifi_driver->get_ssids(ssids); p_rarch->wifi_driver->get_ssids(p_rarch->wifi_data, ssids);
} }
bool driver_wifi_ssid_is_online(unsigned i) bool driver_wifi_ssid_is_online(unsigned i)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
return p_rarch->wifi_driver->ssid_is_online(i); return p_rarch->wifi_driver->ssid_is_online(p_rarch->wifi_data, i);
} }
bool driver_wifi_connect_ssid(unsigned i, const char* passphrase) bool driver_wifi_connect_ssid(unsigned i, const char* passphrase)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
return p_rarch->wifi_driver->connect_ssid(i, passphrase); return p_rarch->wifi_driver->connect_ssid(p_rarch->wifi_data, i, passphrase);
} }
void driver_wifi_tether_start_stop(bool start, char* configfile) void driver_wifi_tether_start_stop(bool start, char* configfile)
{ {
struct rarch_state *p_rarch = &rarch_st; struct rarch_state *p_rarch = &rarch_st;
p_rarch->wifi_driver->tether_start_stop(start, configfile); p_rarch->wifi_driver->tether_start_stop(p_rarch->wifi_data, start, configfile);
} }
bool wifi_driver_ctl(enum rarch_wifi_ctl_state state, void *data) bool wifi_driver_ctl(enum rarch_wifi_ctl_state state, void *data)
@ -20750,12 +20737,15 @@ bool wifi_driver_ctl(enum rarch_wifi_ctl_state state, void *data)
wifi_driver_ctl(RARCH_WIFI_CTL_FIND_DRIVER, NULL); wifi_driver_ctl(RARCH_WIFI_CTL_FIND_DRIVER, NULL);
p_rarch->wifi_data = p_rarch->wifi_driver->init(); if (p_rarch->wifi_driver && p_rarch->wifi_driver->init)
if (!p_rarch->wifi_data)
{ {
RARCH_ERR("Failed to initialize wifi driver. Will continue without wifi.\n"); p_rarch->wifi_data = p_rarch->wifi_driver->init();
wifi_driver_ctl(RARCH_WIFI_CTL_UNSET_ACTIVE, NULL);
if (!p_rarch->wifi_data)
{
RARCH_ERR("Failed to initialize wifi driver. Will continue without wifi.\n");
wifi_driver_ctl(RARCH_WIFI_CTL_UNSET_ACTIVE, NULL);
}
} }
/*if (wifi_cb.initialized) /*if (wifi_cb.initialized)
@ -33813,6 +33803,12 @@ static void drivers_init(struct rarch_state *p_rarch, int flags)
} }
} }
if (flags & DRIVER_BLUETOOTH_MASK)
bluetooth_driver_ctl(RARCH_BLUETOOTH_CTL_INIT, NULL);
if ((flags & DRIVER_WIFI_MASK))
wifi_driver_ctl(RARCH_WIFI_CTL_INIT, NULL);
if (flags & DRIVER_LOCATION_MASK) if (flags & DRIVER_LOCATION_MASK)
{ {
/* Only initialize location driver if we're ever going to use it. */ /* Only initialize location driver if we're ever going to use it. */

View File

@ -27,26 +27,28 @@
#include "../../gfx/gfx_widgets.h" #include "../../gfx/gfx_widgets.h"
#endif #endif
static bool connman_cache[256] = {0}; typedef struct
static unsigned connman_counter = 0; {
static struct string_list* lines = NULL; bool connman_cache[256];
static char command[256] = {0}; unsigned connman_counter;
static bool connmanctl_widgets_supported = false; struct string_list* lines;
char command[256];
bool connmanctl_widgets_supported;
} connman_t;
static void *connmanctl_init(void) static void *connmanctl_init(void)
{ {
connman_t *connman = (connman_t*)calloc(1, sizeof(connman_t));
#ifdef HAVE_GFX_WIDGETS #ifdef HAVE_GFX_WIDGETS
connmanctl_widgets_supported = gfx_widgets_ready(); connman->connmanctl_widgets_supported = gfx_widgets_ready();
#endif #endif
return (void*)-1; return connman;
} }
static void connmanctl_free(void *data) static void connmanctl_free(void *data)
{ {
(void)data; if (data)
#ifdef HAVE_GFX_WIDGETS free(data);
connmanctl_widgets_supported = gfx_widgets_ready();
#endif
} }
static bool connmanctl_start(void *data) static bool connmanctl_start(void *data)
@ -60,7 +62,7 @@ static void connmanctl_stop(void *data)
(void)data; (void)data;
} }
static bool connmanctl_tether_status(void) static bool connmanctl_tether_status(connman_t *connman)
{ {
/* Returns true if the tethering is active /* Returns true if the tethering is active
* false when tethering is not active * false when tethering is not active
@ -75,14 +77,14 @@ static bool connmanctl_tether_status(void)
* the matching lines. * the matching lines.
* Expected result is either 1 (active) or 0 (not active) * Expected result is either 1 (active) or 0 (not active)
*/ */
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl technologies | \ connmanctl technologies | \
grep \"/net/connman/technology/wifi\" -A 10 | \ grep \"/net/connman/technology/wifi\" -A 10 | \
grep \"^ Tethering =\" -m 1 | \ grep \"^ Tethering =\" -m 1 | \
grep \"True\" | \ grep \"True\" | \
wc -l"); wc -l");
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
fgets(ln, sizeof(ln), command_file); fgets(ln, sizeof(ln), command_file);
@ -91,7 +93,7 @@ static bool connmanctl_tether_status(void)
ln[ln_size] = '\0'; ln[ln_size] = '\0';
RARCH_LOG("[CONNMANCTL] Tether Status: command: \"%s\", output: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Tether Status: command: \"%s\", output: \"%s\"\n",
command, ln); connman->command, ln);
pclose(command_file); pclose(command_file);
@ -105,24 +107,24 @@ static bool connmanctl_tether_status(void)
} }
static void connmanctl_tether_toggle( static void connmanctl_tether_toggle(
bool switch_on, char* apname, char* passkey) connman_t *connman, bool switch_on, char* apname, char* passkey)
{ {
/* Starts / stops the tethering service on wi-fi device */ /* Starts / stops the tethering service on wi-fi device */
char output[256] = {0}; char output[256] = {0};
FILE *command_file = NULL; FILE *command_file = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
#ifdef HAVE_GFX_WIDGETS #ifdef HAVE_GFX_WIDGETS
bool widgets_active = connmanctl_widgets_supported; bool widgets_active = connman->connmanctl_widgets_supported;
#endif #endif
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl tether wifi %s %s %s", connmanctl tether wifi %s %s %s",
switch_on ? "on" : "off", apname, passkey); switch_on ? "on" : "off", apname, passkey);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
RARCH_LOG("[CONNMANCTL] Tether toggle: command: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Tether toggle: command: \"%s\"\n",
command); connman->command);
while (fgets(output, sizeof(output), command_file)) while (fgets(output, sizeof(output), command_file))
{ {
@ -147,38 +149,39 @@ static void connmanctl_tether_toggle(
if (switch_on) if (switch_on)
{ {
if (!connmanctl_tether_status()) if (!connmanctl_tether_status(connman))
configuration_set_bool(settings, configuration_set_bool(settings,
settings->bools.localap_enable, false); settings->bools.localap_enable, false);
} }
else else
{ {
if (connmanctl_tether_status()) if (connmanctl_tether_status(connman))
configuration_set_bool(settings, configuration_set_bool(settings,
settings->bools.localap_enable, true); settings->bools.localap_enable, true);
} }
} }
static void connmanctl_scan(void) static void connmanctl_scan(void *data)
{ {
char line[512]; char line[512];
union string_list_elem_attr attr; union string_list_elem_attr attr;
FILE *serv_file = NULL; FILE *serv_file = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
connman_t *connman = (connman_t*)data;
attr.i = RARCH_FILETYPE_UNSET; attr.i = RARCH_FILETYPE_UNSET;
if (lines) if (connman->lines)
free(lines); free(connman->lines);
lines = string_list_new(); connman->lines = string_list_new();
if (connmanctl_tether_status()) if (connmanctl_tether_status(connman))
{ {
runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_SWITCHING_OFF), runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_SWITCHING_OFF),
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO); MESSAGE_QUEUE_CATEGORY_INFO);
configuration_set_bool(settings, configuration_set_bool(settings,
settings->bools.localap_enable, false); settings->bools.localap_enable, false);
connmanctl_tether_toggle(false, "", ""); connmanctl_tether_toggle(connman, false, "", "");
} }
pclose(popen("connmanctl enable wifi", "r")); pclose(popen("connmanctl enable wifi", "r"));
@ -196,41 +199,43 @@ static void connmanctl_scan(void)
if (len > 0 && line[len-1] == '\n') if (len > 0 && line[len-1] == '\n')
line[--len] = '\0'; line[--len] = '\0';
string_list_append(lines, line, attr); string_list_append(connman->lines, line, attr);
} }
pclose(serv_file); pclose(serv_file);
} }
static void connmanctl_get_ssids(struct string_list* ssids) static void connmanctl_get_ssids(void *data, struct string_list* ssids)
{ {
unsigned i; unsigned i;
union string_list_elem_attr attr; union string_list_elem_attr attr;
attr.i = RARCH_FILETYPE_UNSET; attr.i = RARCH_FILETYPE_UNSET;
connman_t *connman = (connman_t*)data;
if (!lines) if (!connman->lines)
return; return;
for (i = 0; i < lines->size; i++) for (i = 0; i < connman->lines->size; i++)
{ {
char ssid[32]; char ssid[32];
const char *line = lines->elems[i].data; const char *line = connman->lines->elems[i].data;
strlcpy(ssid, line+4, sizeof(ssid)); strlcpy(ssid, line+4, sizeof(ssid));
string_list_append(ssids, ssid, attr); string_list_append(ssids, ssid, attr);
} }
} }
static bool connmanctl_ssid_is_online(unsigned i) static bool connmanctl_ssid_is_online(void *data, unsigned i)
{ {
char ln[512] = {0}; char ln[512] = {0};
char service[128] = {0}; char service[128] = {0};
const char *line = lines->elems[i].data; connman_t *connman = (connman_t*)data;
const char *line = connman->lines->elems[i].data;
FILE *command_file = NULL; FILE *command_file = NULL;
if (connman_counter == 60) if (connman->connman_counter == 60)
{ {
static struct string_list* list = NULL; static struct string_list* list = NULL;
connman_counter = 0; connman->connman_counter = 0;
list = string_split(line, " "); list = string_split(line, " ");
if (!list) if (!list)
return false; return false;
@ -244,30 +249,31 @@ static bool connmanctl_ssid_is_online(unsigned i)
strlcpy(service, list->elems[list->size-1].data, sizeof(service)); strlcpy(service, list->elems[list->size-1].data, sizeof(service));
string_list_free(list); string_list_free(list);
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl services %s | grep 'State = \\(online\\|ready\\)'", connmanctl services %s | grep 'State = \\(online\\|ready\\)'",
service); service);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
while (fgets(ln, 512, command_file)) while (fgets(ln, 512, command_file))
{ {
connman_cache[i] = true; connman->connman_cache[i] = true;
return true; return true;
} }
pclose(command_file); pclose(command_file);
connman_cache[i] = false; connman->connman_cache[i] = false;
} }
else else
{ {
connman_counter++; connman->connman_counter++;
return connman_cache[i]; return connman->connman_cache[i];
} }
return false; return false;
} }
static bool connmanctl_connect_ssid(unsigned idx, const char* passphrase) static bool connmanctl_connect_ssid(
void *data, unsigned idx, const char* passphrase)
{ {
unsigned i; unsigned i;
char ln[512] = {0}; char ln[512] = {0};
@ -277,11 +283,12 @@ static bool connmanctl_connect_ssid(unsigned idx, const char* passphrase)
char settings_path[PATH_MAX_LENGTH] = {0}; char settings_path[PATH_MAX_LENGTH] = {0};
FILE *command_file = NULL; FILE *command_file = NULL;
FILE *settings_file = NULL; FILE *settings_file = NULL;
const char *line = lines->elems[idx].data; connman_t *connman = (connman_t*)data;
const char *line = connman->lines->elems[idx].data;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
static struct string_list* list = NULL; static struct string_list* list = NULL;
#ifdef HAVE_GFX_WIDGETS #ifdef HAVE_GFX_WIDGETS
bool widgets_active = connmanctl_widgets_supported; bool widgets_active = connman->connmanctl_widgets_supported;
#endif #endif
/* connmanctl services outputs a 4 character prefixed lines, /* connmanctl services outputs a 4 character prefixed lines,
* either whitespace or an identifier. i.e.: * either whitespace or an identifier. i.e.:
@ -331,23 +338,23 @@ static bool connmanctl_connect_ssid(unsigned idx, const char* passphrase)
fprintf(settings_file, "IPv4.method=%s\n", "dhcp"); fprintf(settings_file, "IPv4.method=%s\n", "dhcp");
fclose(settings_file); fclose(settings_file);
if (connmanctl_tether_status()) if (connmanctl_tether_status(connman))
{ {
runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_SWITCHING_OFF), runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_SWITCHING_OFF),
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO); MESSAGE_QUEUE_CATEGORY_INFO);
configuration_set_bool(settings, configuration_set_bool(settings,
settings->bools.localap_enable, false); settings->bools.localap_enable, false);
connmanctl_tether_toggle(false, "", ""); connmanctl_tether_toggle(connman, false, "", "");
} }
pclose(popen("systemctl restart connman", "r")); pclose(popen("systemctl restart connman", "r"));
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl connect %s 2>&1", connmanctl connect %s 2>&1",
service); service);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
while (fgets(ln, sizeof(ln), command_file)) while (fgets(ln, sizeof(ln), command_file))
{ {
@ -363,7 +370,8 @@ static bool connmanctl_connect_ssid(unsigned idx, const char* passphrase)
return true; return true;
} }
static void connmanctl_get_connected_ssid(char* ssid, size_t buffersize) static void connmanctl_get_connected_ssid(
connman_t *connman, char* ssid, size_t buffersize)
{ {
size_t ssid_size; size_t ssid_size;
/* Stores the SSID of the currently connected Wi-Fi /* Stores the SSID of the currently connected Wi-Fi
@ -378,13 +386,13 @@ static void connmanctl_get_connected_ssid(char* ssid, size_t buffersize)
* only 'wifi_' services, then greps the one with * only 'wifi_' services, then greps the one with
* 'R' (Ready) or 'O' (Online) flag and cuts out the ssid * 'R' (Ready) or 'O' (Online) flag and cuts out the ssid
*/ */
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl services | \ connmanctl services | \
grep wifi_ | \ grep wifi_ | \
grep \"^..\\(R\\|O\\)\" | \ grep \"^..\\(R\\|O\\)\" | \
cut -d' ' -f 2"); cut -d' ' -f 2");
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
fgets(ssid, buffersize, command_file); fgets(ssid, buffersize, command_file);
@ -397,10 +405,11 @@ static void connmanctl_get_connected_ssid(char* ssid, size_t buffersize)
ssid[ssid_size] = '\0'; ssid[ssid_size] = '\0';
RARCH_LOG("[CONNMANCTL] Get Connected SSID: command: \"%s\", output: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Get Connected SSID: command: \"%s\", output: \"%s\"\n",
command, (ssid_size + 1) ? ssid : "<nothing_found>"); connman->command, (ssid_size + 1) ? ssid : "<nothing_found>");
} }
static void connmanctl_get_connected_servicename(char* servicename, size_t buffersize) static void connmanctl_get_connected_servicename(
connman_t *connman, char* servicename, size_t buffersize)
{ {
/* Stores the service name of currently connected Wi-Fi /* Stores the service name of currently connected Wi-Fi
* network in servicename * network in servicename
@ -420,7 +429,7 @@ static void connmanctl_get_connected_servicename(char* servicename, size_t buffe
* the next while loop for parsing if the service * the next while loop for parsing if the service
* is currently online/ready * is currently online/ready
*/ */
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
for serv in %s/wifi_*/ ; do \ for serv in %s/wifi_*/ ; do \
if [ -d $serv ] ; then \ if [ -d $serv ] ; then \
basename $serv ; \ basename $serv ; \
@ -428,10 +437,10 @@ static void connmanctl_get_connected_servicename(char* servicename, size_t buffe
done", done",
LAKKA_CONNMAN_DIR); LAKKA_CONNMAN_DIR);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
RARCH_LOG("[CONNMANCTL] Testing configured services for activity: command: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Testing configured services for activity: command: \"%s\"\n",
command); connman->command);
while (fgets(temp, buffersize, command_file)) while (fgets(temp, buffersize, command_file))
{ {
@ -452,13 +461,13 @@ static void connmanctl_get_connected_servicename(char* servicename, size_t buffe
* status and count the lines. Expected results are * status and count the lines. Expected results are
* 0 = is not active, 1 = is active * 0 = is not active, 1 = is active
*/ */
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl services %s | \ connmanctl services %s | \
grep \"^ State = \\(online\\|ready\\)\" | \ grep \"^ State = \\(online\\|ready\\)\" | \
wc -l", wc -l",
temp); temp);
service_file = popen(command, "r"); service_file = popen(connman->command, "r");
fgets(ln, sizeof(ln), service_file); fgets(ln, sizeof(ln), service_file);
ln_size = strlen(ln) - 1; ln_size = strlen(ln) - 1;
@ -489,7 +498,7 @@ static void connmanctl_get_connected_servicename(char* servicename, size_t buffe
pclose(command_file); pclose(command_file);
} }
static void connmanctl_tether_start_stop(bool start, char* configfile) static void connmanctl_tether_start_stop(void *data, bool start, char* configfile)
{ {
/* Start / stop wrapper for the tethering service /* Start / stop wrapper for the tethering service
* It also checks, if we are currently connected * It also checks, if we are currently connected
@ -504,8 +513,9 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
char ln[512] = {0}; char ln[512] = {0};
char ssid[64] = {0}; char ssid[64] = {0};
char service[256] = {0}; char service[256] = {0};
connman_t *connman = (connman_t*)data;
#ifdef HAVE_GFX_WIDGETS #ifdef HAVE_GFX_WIDGETS
bool widgets_active = connmanctl_widgets_supported; bool widgets_active = connman->connmanctl_widgets_supported;
#endif #endif
RARCH_LOG("[CONNMANCTL] Tether start stop: begin\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: begin\n");
@ -514,7 +524,7 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
{ {
RARCH_LOG("[CONNMANCTL] Tether start stop: request to start access point\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: request to start access point\n");
if (connmanctl_tether_status()) /* check if already tethering and bail out if so */ if (connmanctl_tether_status(connman)) /* check if already tethering and bail out if so */
{ {
RARCH_LOG("[CONNMANCTL] Tether start stop: AP already running\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: AP already running\n");
runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_ALREADY_RUNNING), runloop_msg_queue_push(msg_hash_to_str(MSG_LOCALAP_ALREADY_RUNNING),
@ -561,17 +571,17 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
RARCH_LOG("[CONNMANCTL] Tether start stop: config \"%s\" exists, reading it\n", RARCH_LOG("[CONNMANCTL] Tether start stop: config \"%s\" exists, reading it\n",
configfile); configfile);
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
grep -m 1 \"^APNAME=\" %s | cut -d '=' -f 2- && \ grep -m 1 \"^APNAME=\" %s | cut -d '=' -f 2- && \
grep -m 1 \"^PASSWORD=\" %s | cut -d '=' -f 2-", grep -m 1 \"^PASSWORD=\" %s | cut -d '=' -f 2-",
configfile, configfile); configfile, configfile);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
int i = 0; int i = 0;
RARCH_LOG("[CONNMANCTL] Tether start stop: parsing command: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Tether start stop: parsing command: \"%s\"\n",
command); connman->command);
while (fgets(ln, sizeof(ln), command_file)) while (fgets(ln, sizeof(ln), command_file))
{ {
@ -631,11 +641,11 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
/* check if connected to a wi-fi network */ /* check if connected to a wi-fi network */
RARCH_LOG("[CONNMANCTL] Tether start stop: checking if not connected to a wi-fi network...\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: checking if not connected to a wi-fi network...\n");
connmanctl_get_connected_ssid(ssid, sizeof(ssid)); connmanctl_get_connected_ssid(connman, ssid, sizeof(ssid));
if (strlen(ssid) != 0) if (strlen(ssid) != 0)
{ {
connmanctl_get_connected_servicename(service, sizeof(service)); connmanctl_get_connected_servicename(connman, service, sizeof(service));
if (strlen(service) != 0) if (strlen(service) != 0)
{ {
@ -651,14 +661,14 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
NULL, MESSAGE_QUEUE_ICON_DEFAULT, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO); MESSAGE_QUEUE_CATEGORY_INFO);
snprintf(command, sizeof(command), "\ snprintf(connman->command, sizeof(connman->command), "\
connmanctl disconnect %s", connmanctl disconnect %s",
service); service);
command_file = popen(command, "r"); command_file = popen(connman->command, "r");
RARCH_LOG("[CONNMANCTL] Tether start stop: disconnecting from service \"%s\", command: \"%s\"\n", RARCH_LOG("[CONNMANCTL] Tether start stop: disconnecting from service \"%s\", command: \"%s\"\n",
service, command); service, connman->command);
while (fgets(ln, sizeof(ln), command_file)) while (fgets(ln, sizeof(ln), command_file))
{ {
@ -683,11 +693,11 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
} }
} }
snprintf(command, sizeof(command), snprintf(connman->command, sizeof(connman->command),
msg_hash_to_str(MSG_LOCALAP_STARTING), msg_hash_to_str(MSG_LOCALAP_STARTING),
apname, passkey); apname, passkey);
runloop_msg_queue_push(command, runloop_msg_queue_push(connman->command,
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO); MESSAGE_QUEUE_CATEGORY_INFO);
} }
@ -695,7 +705,7 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
{ {
RARCH_LOG("[CONNMANCTL] Tether start stop: request to stop access point\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: request to stop access point\n");
if (!connmanctl_tether_status()) /* check if not tethering and when not, bail out */ if (!connmanctl_tether_status(connman)) /* check if not tethering and when not, bail out */
{ {
RARCH_LOG("[CONNMANCTL] Tether start stop: access point is not running\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: access point is not running\n");
@ -714,7 +724,7 @@ static void connmanctl_tether_start_stop(bool start, char* configfile)
RARCH_LOG("[CONNMANCTL] Tether start stop: calling tether_toggle()\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: calling tether_toggle()\n");
/* call the tether toggle function */ /* call the tether toggle function */
connmanctl_tether_toggle(start, apname, passkey); connmanctl_tether_toggle(connman, start, apname, passkey);
RARCH_LOG("[CONNMANCTL] Tether start stop: end\n"); RARCH_LOG("[CONNMANCTL] Tether start stop: end\n");
} }

View File

@ -50,11 +50,11 @@ typedef struct wifi_driver
bool (*start)(void *data); bool (*start)(void *data);
void (*stop)(void *data); void (*stop)(void *data);
void (*scan)(void); void (*scan)(void *data);
void (*get_ssids)(struct string_list *list); void (*get_ssids)(void *data, struct string_list *list);
bool (*ssid_is_online)(unsigned i); bool (*ssid_is_online)(void *data, unsigned i);
bool (*connect_ssid)(unsigned i, const char* passphrase); bool (*connect_ssid)(void *data, unsigned i, const char* passphrase);
void (*tether_start_stop)(bool start, char* configfile); void (*tether_start_stop)(void *data, bool start, char* configfile);
const char *ident; const char *ident;
} wifi_driver_t; } wifi_driver_t;