ucm: allow bind modifier to specific instances, other fixes

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2011-01-31 14:24:19 +01:00
parent a16008023e
commit 37c7e2843f
5 changed files with 67 additions and 17 deletions

View file

@ -467,14 +467,36 @@ static int is_modifier_supported(snd_use_case_mgr_t *uc_mgr,
struct use_case_modifier *modifier) struct use_case_modifier *modifier)
{ {
struct dev_list *device; struct dev_list *device;
struct list_head *pos; struct use_case_device *adev;
struct list_head *pos, *pos1;
char *cpos;
int dlen, len;
list_for_each(pos, &modifier->dev_list) { list_for_each(pos, &modifier->dev_list) {
device = list_entry(pos, struct dev_list, list); device = list_entry(pos, struct dev_list, list);
if (find(&uc_mgr->active_devices, cpos = strchr(device->name, '.');
struct use_case_device, active_list, name, device->name)) if (cpos) {
return 1; if (find(&uc_mgr->active_devices,
struct use_case_device, active_list,
name, device->name))
return 1;
} else {
dlen = strlen(device->name);
list_for_each(pos1, &uc_mgr->active_devices) {
adev = list_entry(pos1, struct use_case_device,
active_list);
cpos = strchr(adev->name, '.');
if (cpos)
len = cpos - adev->name;
else
len = strlen(adev->name);
if (len != dlen)
continue;
if (memcmp(adev->name, device->name, len))
continue;
return 1;
}
}
} }
return 0; return 0;
} }
@ -497,6 +519,7 @@ static struct use_case_modifier *
modifier = list_entry(pos, struct use_case_modifier, list); modifier = list_entry(pos, struct use_case_modifier, list);
strncpy(name, modifier->name, sizeof(name)); strncpy(name, modifier->name, sizeof(name));
name[sizeof(name)-1] = '\0';
cpos = strchr(name, '.'); cpos = strchr(name, '.');
if (!cpos) if (!cpos)
continue; continue;
@ -1397,8 +1420,8 @@ int snd_use_case_set(snd_use_case_mgr_t *uc_mgr,
const char *identifier, const char *identifier,
const char *value) const char *value)
{ {
char *str, *str1; char *str, *str1;
int err; int err;
pthread_mutex_lock(&uc_mgr->mutex); pthread_mutex_lock(&uc_mgr->mutex);
if (strcmp(identifier, "_verb") == 0) if (strcmp(identifier, "_verb") == 0)

View file

@ -56,6 +56,27 @@ int parse_string(snd_config_t *n, char **res)
return 0; return 0;
} }
/*
* Parse safe ID
*/
int parse_is_name_safe(char *name)
{
if (strchr(name, '.')) {
uc_error("char '.' now allowed in '%s'", name);
return 0;
}
return 1;
}
int parse_get_safe_id(snd_config_t *n, const char **id)
{
int err;
err = snd_config_get_id(n, id);
if (err < 0)
return err;
return parse_is_name_safe((char *)(*id));
}
/* /*
* Parse transition * Parse transition
@ -367,13 +388,13 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
/* /*
* Parse Modifier Use cases * Parse Modifier Use cases
* *
* # Each modifier is described in new section. N modifier are allowed * # Each modifier is described in new section. N modifiers are allowed
* SectionModifier."Capture Voice" { * SectionModifier."Capture Voice".0 {
* *
* Comment "Record voice call" * Comment "Record voice call"
* SupportedDevice [ * SupportedDevice [
* "x" * "x" # all x device instances
* "y" * "y.0" # device y instance 0 only
* ] * ]
* *
* EnableSequence [ * EnableSequence [
@ -411,6 +432,8 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
snd_config_t *n; snd_config_t *n;
int err; int err;
if (!parse_is_name_safe(name))
return -EINVAL;
/* allocate modifier */ /* allocate modifier */
modifier = calloc(1, sizeof(*modifier)); modifier = calloc(1, sizeof(*modifier));
if (modifier == NULL) if (modifier == NULL)
@ -421,7 +444,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
INIT_LIST_HEAD(&modifier->dev_list); INIT_LIST_HEAD(&modifier->dev_list);
INIT_LIST_HEAD(&modifier->value_list); INIT_LIST_HEAD(&modifier->value_list);
list_add_tail(&modifier->list, &verb->modifier_list); list_add_tail(&modifier->list, &verb->modifier_list);
err = snd_config_get_id(cfg, &id); err = parse_get_safe_id(cfg, &id);
if (err < 0) if (err < 0)
return err; return err;
modifier->name = malloc(strlen(name) + strlen(id) + 2); modifier->name = malloc(strlen(name) + strlen(id) + 2);
@ -496,7 +519,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
} }
if (list_empty(&modifier->dev_list)) { if (list_empty(&modifier->dev_list)) {
uc_error("error: %s: modifier missing supported device sequence"); uc_error("error: %s: modifier missing supported device sequence", modifier->name);
return -EINVAL; return -EINVAL;
} }
@ -541,6 +564,8 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr,
snd_config_t *n; snd_config_t *n;
int err; int err;
if (!parse_is_name_safe(name))
return -EINVAL;
device = calloc(1, sizeof(*device)); device = calloc(1, sizeof(*device));
if (device == NULL) if (device == NULL)
return -ENOMEM; return -ENOMEM;
@ -549,7 +574,7 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr,
INIT_LIST_HEAD(&device->transition_list); INIT_LIST_HEAD(&device->transition_list);
INIT_LIST_HEAD(&device->value_list); INIT_LIST_HEAD(&device->value_list);
list_add_tail(&device->list, &verb->device_list); list_add_tail(&device->list, &verb->device_list);
if (snd_config_get_id(cfg, &id) < 0) if (parse_get_safe_id(cfg, &id) < 0)
return -EINVAL; return -EINVAL;
device->name = malloc(strlen(name) + strlen(id) + 2); device->name = malloc(strlen(name) + strlen(id) + 2);
if (device->name == NULL) if (device->name == NULL)
@ -904,7 +929,7 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
uc_error("unknown field %s in master section"); uc_error("unknown field %s in master section");
} }
uc_dbg("use_case_name %s file %s end %d", use_case_name, file, end); uc_dbg("use_case_name %s file '%s'", use_case_name, file);
/* do we have both use case name and file ? */ /* do we have both use case name and file ? */
if (!file) { if (!file) {

View file

@ -192,7 +192,7 @@ struct snd_use_case_mgr {
#ifdef UC_MGR_DEBUG #ifdef UC_MGR_DEBUG
#define uc_dbg SNDERR #define uc_dbg SNDERR
#else #else
#define uc_dbg(fmt, arg...) #define uc_dbg(fmt, arg...) do { } while (0)
#endif #endif
void uc_mgr_error(const char *fmt, ...); void uc_mgr_error(const char *fmt, ...);

View file

@ -18,7 +18,7 @@ SectionDevice."Device1".0 {
} }
SectionModifier."Modifier1" { SectionModifier."Modifier1".0 {
SupportedDevice [ SupportedDevice [
"Device1" "Device1"
] ]

View file

@ -8,4 +8,6 @@ SectionUseCase."Case1" {
SectionDefaults [ SectionDefaults [
exec "my prg" exec "my prg"
msleep 1 msleep 1
cdev "hw:0"
cset "name='PCM Playback Volume' 50%"
] ]