Use wireless status to block disconnected devices and monitor HID/USB changes

This commit is contained in:
Sriman Achanta 2026-01-23 12:02:37 -05:00 committed by Sriman Achanta
parent 9bde703969
commit aac3c14d43

View file

@ -663,6 +663,20 @@ static int emit_added_object_info(struct impl *this, struct card *card)
snprintf(path, sizeof(path), "hw:%u", card->card_nr);
if (!card->wireless_status_path) {
const char *syspath = udev_device_get_syspath(udev_device);
if (syspath)
card->wireless_status_path = find_wireless_status_path(this, syspath);
}
if (card->wireless_status_path) {
enum wireless_status status = read_wireless_status(card->wireless_status_path);
if (status == WIRELESS_STATUS_DISCONNECTED) {
card->wireless_disconnected = true;
return -ENODEV;
}
}
if ((res = check_pcm_device_availability(this, card, &num_pcm_devices)) < 0)
return res;
if ((res = check_compress_offload_device_availability(this, card, &num_compress_offload_devices)) < 0)
@ -908,8 +922,9 @@ static void process_card(struct impl *this, enum action action, struct card *car
switch (action) {
case ACTION_CHANGE: {
update_wireless_status(this, card);
check_access(this, card);
if (card->accessible && !card->emitted) {
if (card->accessible && !card->wireless_disconnected && !card->emitted) {
int res = emit_added_object_info(this, card);
if (res < 0) {
if (card->ignored)
@ -928,7 +943,7 @@ static void process_card(struct impl *this, enum action action, struct card *car
card->card_nr);
card->unavailable = false;
}
} else if (!card->accessible && card->emitted) {
} else if ((!card->accessible || card->wireless_disconnected) && card->emitted) {
card->emitted = false;
if (card->pcm_device_id != ID_DEVICE_NOT_SUPPORTED)
@ -1089,24 +1104,35 @@ static void impl_on_fd_events(struct spa_source *source)
{
struct impl *this = source->data;
struct udev_device *udev_device;
const char *action;
const char *action, *subsystem, *syspath;
struct card *card;
udev_device = udev_monitor_receive_device(this->umonitor);
if (udev_device == NULL)
return;
if ((action = udev_device_get_action(udev_device)) == NULL)
action = udev_device_get_action(udev_device);
if (action == NULL)
action = "change";
spa_log_debug(this->log, "action %s", action);
subsystem = udev_device_get_subsystem(udev_device);
start_inotify(this);
if (spa_streq(action, "add") || spa_streq(action, "change")) {
process_udev_device(this, ACTION_CHANGE, udev_device);
} else if (spa_streq(action, "remove")) {
process_udev_device(this, ACTION_REMOVE, udev_device);
if (spa_streq(subsystem, "sound")) {
if (spa_streq(action, "add") || spa_streq(action, "change"))
process_udev_device(this, ACTION_CHANGE, udev_device);
else if (spa_streq(action, "remove"))
process_udev_device(this, ACTION_REMOVE, udev_device);
} else if (spa_streq(subsystem, "hid") || spa_streq(subsystem, "usb")) {
if (spa_streq(action, "change")) {
syspath = udev_device_get_syspath(udev_device);
card = find_card_by_wireless_status_path(this, syspath);
if (card)
process_card(this, ACTION_CHANGE, card);
}
}
udev_device_unref(udev_device);
}
@ -1123,6 +1149,10 @@ static int start_monitor(struct impl *this)
udev_monitor_filter_add_match_subsystem_devtype(this->umonitor,
"sound", NULL);
udev_monitor_filter_add_match_subsystem_devtype(this->umonitor,
"hid", NULL);
udev_monitor_filter_add_match_subsystem_devtype(this->umonitor,
"usb", NULL);
udev_monitor_enable_receiving(this->umonitor);
this->source.func = impl_on_fd_events;