From 37c7e2843ff8cc2e1f470a29cde30c9e955c6d76 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 31 Jan 2011 14:24:19 +0100 Subject: [PATCH] ucm: allow bind modifier to specific instances, other fixes Signed-off-by: Jaroslav Kysela --- src/ucm/main.c | 37 +++++++++++++++++++++++++------ src/ucm/parser.c | 41 ++++++++++++++++++++++++++++------- src/ucm/ucm_local.h | 2 +- test/ucm/TestHDA/Case1.conf | 2 +- test/ucm/TestHDA/TestHDA.conf | 2 ++ 5 files changed, 67 insertions(+), 17 deletions(-) diff --git a/src/ucm/main.c b/src/ucm/main.c index 030c9b1c..377f5609 100644 --- a/src/ucm/main.c +++ b/src/ucm/main.c @@ -467,14 +467,36 @@ static int is_modifier_supported(snd_use_case_mgr_t *uc_mgr, struct use_case_modifier *modifier) { 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) { device = list_entry(pos, struct dev_list, list); - if (find(&uc_mgr->active_devices, - struct use_case_device, active_list, name, device->name)) - return 1; - + cpos = strchr(device->name, '.'); + if (cpos) { + 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; } @@ -497,6 +519,7 @@ static struct use_case_modifier * modifier = list_entry(pos, struct use_case_modifier, list); strncpy(name, modifier->name, sizeof(name)); + name[sizeof(name)-1] = '\0'; cpos = strchr(name, '.'); if (!cpos) continue; @@ -1397,8 +1420,8 @@ int snd_use_case_set(snd_use_case_mgr_t *uc_mgr, const char *identifier, const char *value) { - char *str, *str1; - int err; + char *str, *str1; + int err; pthread_mutex_lock(&uc_mgr->mutex); if (strcmp(identifier, "_verb") == 0) diff --git a/src/ucm/parser.c b/src/ucm/parser.c index 010191ce..e8d24613 100644 --- a/src/ucm/parser.c +++ b/src/ucm/parser.c @@ -56,6 +56,27 @@ int parse_string(snd_config_t *n, char **res) 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 @@ -367,13 +388,13 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, /* * Parse Modifier Use cases * - * # Each modifier is described in new section. N modifier are allowed - * SectionModifier."Capture Voice" { + * # Each modifier is described in new section. N modifiers are allowed + * SectionModifier."Capture Voice".0 { * * Comment "Record voice call" * SupportedDevice [ - * "x" - * "y" + * "x" # all x device instances + * "y.0" # device y instance 0 only * ] * * EnableSequence [ @@ -411,6 +432,8 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr, snd_config_t *n; int err; + if (!parse_is_name_safe(name)) + return -EINVAL; /* allocate modifier */ modifier = calloc(1, sizeof(*modifier)); 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->value_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) return err; 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)) { - uc_error("error: %s: modifier missing supported device sequence"); + uc_error("error: %s: modifier missing supported device sequence", modifier->name); return -EINVAL; } @@ -541,6 +564,8 @@ static int parse_device_index(snd_use_case_mgr_t *uc_mgr, snd_config_t *n; int err; + if (!parse_is_name_safe(name)) + return -EINVAL; device = calloc(1, sizeof(*device)); if (device == NULL) 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->value_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; device->name = malloc(strlen(name) + strlen(id) + 2); 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_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 ? */ if (!file) { diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h index 13e82da9..1b00ea21 100644 --- a/src/ucm/ucm_local.h +++ b/src/ucm/ucm_local.h @@ -192,7 +192,7 @@ struct snd_use_case_mgr { #ifdef UC_MGR_DEBUG #define uc_dbg SNDERR #else -#define uc_dbg(fmt, arg...) +#define uc_dbg(fmt, arg...) do { } while (0) #endif void uc_mgr_error(const char *fmt, ...); diff --git a/test/ucm/TestHDA/Case1.conf b/test/ucm/TestHDA/Case1.conf index 3d8cddf8..81b24458 100644 --- a/test/ucm/TestHDA/Case1.conf +++ b/test/ucm/TestHDA/Case1.conf @@ -18,7 +18,7 @@ SectionDevice."Device1".0 { } -SectionModifier."Modifier1" { +SectionModifier."Modifier1".0 { SupportedDevice [ "Device1" ] diff --git a/test/ucm/TestHDA/TestHDA.conf b/test/ucm/TestHDA/TestHDA.conf index 9b93b96e..41dd74c8 100644 --- a/test/ucm/TestHDA/TestHDA.conf +++ b/test/ucm/TestHDA/TestHDA.conf @@ -8,4 +8,6 @@ SectionUseCase."Case1" { SectionDefaults [ exec "my prg" msleep 1 + cdev "hw:0" + cset "name='PCM Playback Volume' 50%" ] -- 2.47.1