diff options
| author | Lennart Poettering <lennart@poettering.net> | 2009-03-01 20:34:07 +0100 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2009-03-01 21:38:22 +0100 | 
| commit | 784ac5b0da4f510232166406b3166fba0bef58e4 (patch) | |
| tree | b46c92114f90ed796729d978001ebc14c8481202 /src | |
| parent | cc8d51ad629891b5eb6b355c999c1c1b7e3fb34e (diff) | |
get additional device data from udev
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 6 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-sink.c | 2 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-source.c | 2 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.c | 51 | ||||
| -rw-r--r-- | src/modules/alsa/alsa-util.h | 1 | ||||
| -rw-r--r-- | src/modules/alsa/module-alsa-card.c | 1 | ||||
| -rw-r--r-- | src/modules/hal-util.c | 3 | ||||
| -rw-r--r-- | src/modules/udev-util.c | 142 | ||||
| -rw-r--r-- | src/modules/udev-util.h | 30 | 
9 files changed, 227 insertions, 11 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f5a1febe..9f2fa02a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1313,6 +1313,12 @@ libalsa_util_la_LIBADD += $(HAL_LIBS)  libalsa_util_la_CFLAGS += $(HAL_CFLAGS)  endif +if HAVE_UDEV +libalsa_util_la_SOURCES += modules/udev-util.h modules/udev-util.c +libalsa_util_la_LIBADD += $(UDEV_LIBS) +libalsa_util_la_CFLAGS += $(UDEV_CFLAGS) +endif +  if HAVE_DBUS  libalsa_util_la_SOURCES += modules/reserve.h modules/reserve.c modules/reserve-wrap.c modules/reserve-wrap.h  libalsa_util_la_LIBADD += $(DBUS_LIBS) libdbus-util.la diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c index 0aef1bd5..b6fcbb79 100644 --- a/src/modules/alsa/alsa-sink.c +++ b/src/modules/alsa/alsa-sink.c @@ -1667,6 +1667,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca          pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);      } +    pa_alsa_set_description(data.proplist); +      u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);      pa_sink_new_data_done(&data); diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c index 671df3fe..f56b96f3 100644 --- a/src/modules/alsa/alsa-source.c +++ b/src/modules/alsa/alsa-source.c @@ -1509,6 +1509,8 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p          pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);      } +    pa_alsa_set_description(data.proplist); +      u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);      pa_source_new_data_done(&data); diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c index 6740c069..2f06acd0 100644 --- a/src/modules/alsa/alsa-util.c +++ b/src/modules/alsa/alsa-util.c @@ -47,6 +47,10 @@  #include "hal-util.h"  #endif +#ifdef HAVE_UDEV +#include "udev-util.h" +#endif +  struct pa_alsa_fdlist {      unsigned num_fds;      struct pollfd *fds; @@ -1362,6 +1366,35 @@ void pa_alsa_redirect_errors_dec(void) {          snd_lib_error_set_handler(NULL);  } +void pa_alsa_set_description(pa_proplist *p) { +    const char *s; +    pa_assert(p); + +    if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION)) +        return; + +    if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) +        if (pa_streq(s, "internal")) { +            pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, _("Internal Audio")); +            return; +        } + +    if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME))) { +        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); +        return; +    } + +    if ((s = pa_proplist_gets(p, "alsa.card_name"))) { +        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); +        return; +    } + +    if ((s = pa_proplist_gets(p, "alsa.name"))) { +        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s); +        return; +    } +} +  void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {      char *cn, *lcn, *dn; @@ -1385,6 +1418,10 @@ void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {          pa_xfree(dn);      } +#ifdef HAVE_UDEV +    pa_udev_get_info(c, p, card); +#endif +  #ifdef HAVE_HAL      pa_hal_get_info(c, p, card);  #endif @@ -1411,7 +1448,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *      snd_pcm_class_t class;      snd_pcm_subclass_t subclass; -    const char *n, *id, *sdn, *cn = NULL; +    const char *n, *id, *sdn;      int card;      pa_assert(p); @@ -1426,6 +1463,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *          if (alsa_class_table[class])              pa_proplist_sets(p, "alsa.class", alsa_class_table[class]);      } +      subclass = snd_pcm_info_get_subclass(pcm_info);      if (subclass <= SND_PCM_SUBCLASS_LAST)          if (alsa_subclass_table[subclass]) @@ -1443,17 +1481,8 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *      pa_proplist_setf(p, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info)); -    if ((card = snd_pcm_info_get_card(pcm_info)) >= 0) { +    if ((card = snd_pcm_info_get_card(pcm_info)) >= 0)          pa_alsa_init_proplist_card(c, p, card); -        cn = pa_proplist_gets(p, "alsa.card_name"); -    } - -    if (cn && n && !strstr(cn, n) && !strstr(n, cn)) -        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s, %s", cn, n); -    else if (cn && (!n || strstr(cn, n))) -        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, cn); -    else if (n) -        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, n);  }  void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm) { diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h index 899532e2..1fb5996a 100644 --- a/src/modules/alsa/alsa-util.h +++ b/src/modules/alsa/alsa-util.h @@ -123,6 +123,7 @@ void pa_alsa_redirect_errors_dec(void);  void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info);  void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card);  void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm); +void pa_alsa_set_description(pa_proplist *p);  int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents); diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c index fc6b886b..74f3099b 100644 --- a/src/modules/alsa/module-alsa-card.c +++ b/src/modules/alsa/module-alsa-card.c @@ -318,6 +318,7 @@ int pa__init(pa_module *m) {      data.module = m;      pa_alsa_init_proplist_card(m->core, data.proplist, alsa_card_index);      pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_id); +    pa_alsa_set_description(data.proplist);      set_card_name(&data, ma, u->device_id);      if (reserve) diff --git a/src/modules/hal-util.c b/src/modules/hal-util.c index 82bbc57e..6959a706 100644 --- a/src/modules/hal-util.c +++ b/src/modules/hal-util.c @@ -89,6 +89,9 @@ int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) {      pa_proplist_sets(p, "hal.udi", udis[i]); +    /* The data HAL stores in info.product is not actually a product +     * string but simply the ALSA card name. We will hence not write +     * it to PA_PROP_DEVICE_PRODUCT_NAME */      t = libhal_device_get_property_string(hal, udis[i], "info.product", &error);      if (dbus_error_is_set(&error))          dbus_error_free(&error); diff --git a/src/modules/udev-util.c b/src/modules/udev-util.c new file mode 100644 index 00000000..a72bc8f8 --- /dev/null +++ b/src/modules/udev-util.c @@ -0,0 +1,142 @@ +/*** +  This file is part of PulseAudio. + +  Copyright 2009 Lennart Poettering + +  PulseAudio is free software; you can redistribute it and/or modify +  it under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2 of the +  License, or (at your option) any later version. + +  PulseAudio is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU Lesser General Public +  License along with PulseAudio; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <libudev.h> + +#include <pulse/xmalloc.h> +#include <pulse/proplist.h> + +#include <pulsecore/log.h> +#include <pulsecore/core-util.h> + +#include "udev-util.h" + +static int read_id(struct udev_device *d, const char *n) { +    const char *v; +    unsigned u; + +    pa_assert(d); +    pa_assert(n); + +    if (!(v = udev_device_get_property_value(d, n))) +        return -1; + +    if (pa_startswith(v, "0x")) +        v += 2; + +    if (!*v) +        return -1; + +    if (sscanf(v, "%04x", &u) != 1) +        return -1; + +    if (u > 0xFFFFU) +        return -1; + +    return u; +} + +int pa_udev_get_info(pa_core *core, pa_proplist *p, int card_idx) { +    int r = -1; +    struct udev *udev; +    struct udev_device *card; +    char *t; +    const char *v; +    int id; + +    pa_assert(core); +    pa_assert(p); +    pa_assert(card_idx >= 0); + +    if (!(udev = udev_new())) { +        pa_log_error("Failed to allocate udev context."); +        goto finish; +    } + +    t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx); +    card = udev_device_new_from_syspath(udev, t); +    pa_xfree(t); + +    if (!card) { +        pa_log_error("Failed to get card object."); +        goto finish; +    } + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS)) +        if ((v = udev_device_get_property_value(card, "ID_BUS")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_BUS, v); + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_ID)) +        if ((id = read_id(card, "ID_VENDOR_ID")) > 0 && *v) +            pa_proplist_setf(p, PA_PROP_DEVICE_VENDOR_ID, "%04x", id); + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_NAME)) { +        if ((v = udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); +        else if ((v = udev_device_get_property_value(card, "ID_VENDOR")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v); +    } + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_ID)) +        if ((id = read_id(card, "ID_MODEL_ID")) >= 0) +            pa_proplist_setf(p, PA_PROP_DEVICE_PRODUCT_ID, "%04x", id); + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_NAME)) { +        if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); +        else if ((v = udev_device_get_property_value(card, "ID_MODEL")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v); +    } + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_SERIAL)) +        if ((v = udev_device_get_property_value(card, "ID_SERIAL")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_SERIAL, v); + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_FORM_FACTOR)) +        if ((v = udev_device_get_property_value(card, "SOUND_FORM_FACTOR")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_FORM_FACTOR, v); + +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS_PATH)) +        if ((v = udev_device_get_devpath(card))) +            pa_proplist_sets(p, PA_PROP_DEVICE_BUS_PATH, v); + +    /* This is normaly not set by th udev rules but may be useful to +     * allow administrators to overwrite the device description.*/ +    if (!pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION)) +        if ((v = udev_device_get_property_value(card, "SOUND_DESCRIPTION")) && *v) +            pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, v); + +    r = 0; + +finish: + +    if (card) +        udev_device_unref(card); + +    if (udev) +        udev_unref(udev); + +    return r; +} diff --git a/src/modules/udev-util.h b/src/modules/udev-util.h new file mode 100644 index 00000000..86fbba7f --- /dev/null +++ b/src/modules/udev-util.h @@ -0,0 +1,30 @@ +#ifndef fooudevutilhfoo +#define fooudevutilhfoo + +/*** +  This file is part of PulseAudio. + +  Copyright 2009 Lennart Poettering + +  PulseAudio is free software; you can redistribute it and/or modify +  it under the terms of the GNU Lesser General Public License as +  published by the Free Software Foundation; either version 2 of the +  License, or (at your option) any later version. + +  PulseAudio is distributed in the hope that it will be useful, but +  WITHOUT ANY WARRANTY; without even the implied warranty of +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +  General Public License for more details. + +  You should have received a copy of the GNU Lesser General Public +  License along with PulseAudio; if not, write to the Free Software +  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +  USA. +***/ + + +#include <pulsecore/core.h> + +int pa_udev_get_info(pa_core *core, pa_proplist *p, int card); + +#endif  | 
