From aac3c14d4337e102238ad2c3484c18370269c60e Mon Sep 17 00:00:00 2001 From: Sriman Achanta Date: Fri, 23 Jan 2026 12:02:37 -0500 Subject: [PATCH] Use wireless status to block disconnected devices and monitor HID/USB changes --- spa/plugins/alsa/alsa-udev.c | 48 +++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 9 deletions(-) diff --git a/spa/plugins/alsa/alsa-udev.c b/spa/plugins/alsa/alsa-udev.c index c66e4e2c0..2957f304d 100644 --- a/spa/plugins/alsa/alsa-udev.c +++ b/spa/plugins/alsa/alsa-udev.c @@ -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;