Bluetooth: add option to remove pairing

Pressing the START button removes the device pairing. Useful in case
the device (e.g. gamepad) was paired with a different adapter/computer
and needs to be paired again with current adapter/computer.

To pair again, RetroArch needs to be restarted, so the device list is
populated again.

Upstream of patch used by Lakka at build time
1943ad296e/packages/libretro/retroarch/patches/retroarch-98-remove_bluetooth_pairing.patch
This commit is contained in:
Tomáš Kelemen (vudiq) 2021-11-17 21:25:06 +01:00
parent a60df14d81
commit a2f9273979
No known key found for this signature in database
GPG Key ID: 5CE55E600E0B3B22
8 changed files with 98 additions and 0 deletions

View File

@ -43,6 +43,7 @@ typedef struct bluetooth_driver
bool (*device_is_connected)(void *data, unsigned i);
void (*device_get_sublabel)(void *data, char *s, unsigned i, size_t len);
bool (*connect_device)(void *data, unsigned i);
bool (*remove_device)(void *data, unsigned i);
const char *ident;
} bluetooth_driver_t;
@ -71,6 +72,8 @@ void driver_bluetooth_device_get_sublabel(char *s, unsigned i, size_t len);
bool driver_bluetooth_connect_device(unsigned i);
bool driver_bluetooth_remove_device(unsigned i);
bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data);
extern const bluetooth_driver_t *bluetooth_drivers[];

View File

@ -191,6 +191,45 @@ static bool bluetoothctl_connect_device(void *data, unsigned idx)
return true;
}
static bool bluetoothctl_remove_device(void *data, unsigned idx)
{
unsigned i;
bluetoothctl_t *btctl = (bluetoothctl_t*) data;
char device[18] = {0};
const char *line = btctl->lines->elems[idx].data;
static struct string_list* list = NULL;
/* bluetoothctl devices outputs lines of the format:
* $ bluetoothctl devices
* 'Device (mac address) (device name)'
*/
list = string_split(line, " ");
if (!list)
return false;
if (list->size == 0)
{
string_list_free(list);
return false;
}
strlcpy(device, list->elems[1].data, sizeof(device));
string_list_free(list);
snprintf(btctl->command, sizeof(btctl->command), "\
echo -e \"disconnect %s\\nremove %s\\n\" | bluetoothctl",
device, device);
pclose(popen(btctl->command, "r"));
runloop_msg_queue_push(msg_hash_to_str(MSG_BLUETOOTH_PAIRING_REMOVED),
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO);
btctl->bluetoothctl_counter[idx] = 0;
return true;
}
static void bluetoothctl_device_get_sublabel(
void *data, char *s, unsigned i, size_t len)
{
@ -211,5 +250,6 @@ bluetooth_driver_t bluetooth_bluetoothctl = {
bluetoothctl_device_is_connected,
bluetoothctl_device_get_sublabel,
bluetoothctl_connect_device,
bluetoothctl_remove_device,
"bluetoothctl",
};

View File

@ -604,6 +604,27 @@ static bool bluez_connect_device(void *data, unsigned i)
return true;
}
static bool bluez_remove_device(void *data, unsigned i)
{
bluez_t *bluez = (bluez_t*)data;
bluez_dbus_connect(bluez);
/* Disconnect the device */
device_method(bluez, bluez->devices->data[i].path, "Disconnect");
/* Remove the device */
if (device_method(bluez, bluez->devices->data[i].path, "RemoveDevice"))
return false;
runloop_msg_queue_push(msg_hash_to_str(MSG_BLUETOOTH_PAIRING_REMOVED),
1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT,
MESSAGE_QUEUE_CATEGORY_INFO);
bluez_dbus_disconnect(bluez);
bluez->bluez_cache_counter[i] = 0;
return true;
}
bluetooth_driver_t bluetooth_bluez = {
bluez_init,
bluez_free,
@ -612,5 +633,6 @@ bluetooth_driver_t bluetooth_bluez = {
bluez_device_is_connected,
bluez_device_get_sublabel,
bluez_connect_device,
bluez_remove_device,
"bluez",
};

View File

@ -53,6 +53,7 @@ static bluetooth_driver_t bluetooth_null = {
NULL, /* device_is_connected */
NULL, /* device_get_sublabel */
NULL, /* connect_device */
NULL, /* remove_device */
"null",
};

View File

@ -11889,6 +11889,10 @@ MSG_HASH(
MSG_BLUETOOTH_SCAN_COMPLETE,
"Bluetooth scan complete."
)
MSG_HASH(
MSG_BLUETOOTH_PAIRING_REMOVED,
"Pairing removed. Restart RetroArch to connect/pair again."
)
MSG_HASH(
MSG_WIFI_SCAN_COMPLETE,
"Wi-Fi scan complete."

View File

@ -48,6 +48,10 @@
#include "../../config.def.h"
#ifdef HAVE_BLUETOOTH
#include "../../bluetooth/bluetooth_driver.h"
#endif
#ifdef HAVE_NETWORKING
#include "../../core_updater_list.h"
#endif
@ -539,6 +543,16 @@ static int action_start_load_core(
return ret;
}
#ifdef HAVE_BLUETOOTH
static int action_start_bluetooth(const char *path, const char *label,
unsigned menu_type, size_t idx, size_t entry_idx)
{
driver_bluetooth_remove_device((unsigned)idx);
return 0;
}
#endif
#ifdef HAVE_NETWORKING
static int action_start_core_updater_entry(
const char *path, const char *label,
@ -711,6 +725,11 @@ static int menu_cbs_init_bind_start_compare_label(menu_file_list_cbs_t *cbs)
case MENU_ENUM_LABEL_MANUAL_CONTENT_SCAN_CORE_NAME:
BIND_ACTION_START(cbs, action_start_manual_content_scan_core_name);
break;
#ifdef HAVE_BLUETOOTH
case MENU_ENUM_LABEL_CONNECT_BLUETOOTH:
BIND_ACTION_START(cbs, action_start_bluetooth);
break;
#endif
default:
return -1;
}

View File

@ -386,6 +386,7 @@ enum msg_hash_enums
MSG_TOGGLE_CONTENT_METADATA,
MSG_NO_THUMBNAIL_AVAILABLE,
MSG_PRESS_AGAIN_TO_QUIT,
MSG_BLUETOOTH_PAIRING_REMOVED,
MSG_BLUETOOTH_SCAN_COMPLETE,
MSG_WIFI_SCAN_COMPLETE,
MSG_WIFI_CONNECTING_TO,

View File

@ -9977,6 +9977,14 @@ bool driver_bluetooth_connect_device(unsigned i)
return false;
}
bool driver_bluetooth_remove_device(unsigned i)
{
struct rarch_state *p_rarch = &rarch_st;
if (p_rarch->bluetooth_driver_active)
return p_rarch->bluetooth_driver->remove_device(p_rarch->bluetooth_data, i);
return false;
}
bool bluetooth_driver_ctl(enum rarch_bluetooth_ctl_state state, void *data)
{
struct rarch_state *p_rarch = &rarch_st;