[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 3/5] xl: add PV sound condif parser
From: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> Add config parser for virtual sound devices Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@xxxxxxxx> Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- tools/xl/xl_parse.c | 246 ++++++++++++++++++++++++++++++++++++++++++++ tools/xl/xl_parse.h | 1 + 2 files changed, 247 insertions(+) diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index e6c54483e0..4d1ecd5fa7 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -19,6 +19,7 @@ #include <stdlib.h> #include <xen/hvm/e820.h> #include <xen/hvm/params.h> +#include <xen/io/sndif.h> #include <libxl.h> #include <libxl_utils.h> @@ -851,6 +852,249 @@ out: return rc; } +static int parse_vsnd_params(libxl_vsnd_params *params, char *token) +{ + char *oparg; + int i; + + if (MATCH_OPTION(XENSND_FIELD_SAMPLE_RATES, token, oparg)) { + libxl_string_list rates = NULL; + + split_string_into_string_list(oparg, ";", &rates); + + params->num_sample_rates = libxl_string_list_length(&rates); + params->sample_rates = calloc(params->num_sample_rates, + sizeof(*params->sample_rates)); + + for (i = 0; i < params->num_sample_rates; i++) { + params->sample_rates[i] = strtoul(rates[i], NULL, 0); + } + + libxl_string_list_dispose(&rates); + } else if (MATCH_OPTION(XENSND_FIELD_SAMPLE_FORMATS, token, oparg)) { + libxl_string_list formats = NULL; + + split_string_into_string_list(oparg, ";", &formats); + + params->num_sample_formats = libxl_string_list_length(&formats); + params->sample_formats = calloc(params->num_sample_formats, + sizeof(*params->sample_formats)); + + for (i = 0; i < params->num_sample_formats; i++) { + libxl_vsnd_pcm_format format; + + if (libxl_vsnd_pcm_format_from_string(formats[i], &format)) { + fprintf(stderr, "Invalid pcm format: %s\n", formats[i]); + exit(EXIT_FAILURE); + } + + params->sample_formats[i] = format; + } + + libxl_string_list_dispose(&formats); + } else if (MATCH_OPTION(XENSND_FIELD_CHANNELS_MIN, token, oparg)) { + params->channels_min = strtoul(oparg, NULL, 0); + } else if (MATCH_OPTION(XENSND_FIELD_CHANNELS_MAX, token, oparg)) { + params->channels_max = strtoul(oparg, NULL, 0); + } else if (MATCH_OPTION(XENSND_FIELD_BUFFER_SIZE, token, oparg)) { + params->buffer_size = strtoul(oparg, NULL, 0); + } else { + return 1; + } + + return 0; +} + +static int parse_vsnd_pcm_stream(libxl_device_vsnd *vsnd, char *param) +{ + if (vsnd->num_vsnd_pcms == 0) { + fprintf(stderr, "No vsnd pcm device\n"); + return -1; + } + + libxl_vsnd_pcm *pcm = &vsnd->pcms[vsnd->num_vsnd_pcms - 1]; + + if (pcm->num_vsnd_streams == 0) { + fprintf(stderr, "No vsnd stream\n"); + return -1; + } + + libxl_vsnd_stream *stream = &pcm->streams[pcm->num_vsnd_streams - 1]; + + if (parse_vsnd_params(&stream->params, param)) { + char *oparg; + + if (MATCH_OPTION(XENSND_FIELD_STREAM_UNIQUE_ID, param, oparg)) { + stream->unique_id = strdup(oparg); + } else if (MATCH_OPTION(XENSND_FIELD_TYPE, param, oparg)) { + if (libxl_vsnd_stream_type_from_string(oparg, &stream->type)) { + fprintf(stderr, "Invalid stream type: %s\n", oparg); + return -1; + } + } else { + fprintf(stderr, "Invalid parameter: %s\n", param); + return -1; + } + } + + return 0; +} + +static int parse_vsnd_pcm_param(libxl_device_vsnd *vsnd, char *param) +{ + if (vsnd->num_vsnd_pcms == 0) { + fprintf(stderr, "No pcm device\n"); + return -1; + } + + libxl_vsnd_pcm *pcm = &vsnd->pcms[vsnd->num_vsnd_pcms - 1]; + + if (parse_vsnd_params(&pcm->params, param)) { + char *oparg; + + if (MATCH_OPTION(XENSND_FIELD_DEVICE_NAME, param, oparg)) { + pcm->name = strdup(oparg); + } else { + fprintf(stderr, "Invalid parameter: %s\n", param); + return -1; + } + } + + return 0; +} + +static int parse_vsnd_card_param(libxl_device_vsnd *vsnd, char *param) +{ + if (parse_vsnd_params(&vsnd->params, param)) { + char *oparg; + + if (MATCH_OPTION("backend", param, oparg)) { + vsnd->backend_domname = strdup(oparg); + } else if (MATCH_OPTION(XENSND_FIELD_VCARD_SHORT_NAME, param, oparg)) { + vsnd->short_name = strdup(oparg); + } else if (MATCH_OPTION(XENSND_FIELD_VCARD_LONG_NAME, param, oparg)) { + vsnd->long_name = strdup(oparg); + } else { + fprintf(stderr, "Invalid parameter: %s\n", param); + return -1; + } + } + + return 0; +} + +static int parse_vsnd_create_item(libxl_device_vsnd *vsnd, const char *key) +{ + if (strcasecmp(key, "card") == 0) { + + } else if (strcasecmp(key, "pcm") == 0) { + ARRAY_EXTEND_INIT_NODEVID(vsnd->pcms, vsnd->num_vsnd_pcms, + libxl_vsnd_pcm_init); + } else if (strcasecmp(key, "stream") == 0) { + if (vsnd->num_vsnd_pcms == 0) { + ARRAY_EXTEND_INIT_NODEVID(vsnd->pcms, vsnd->num_vsnd_pcms, + libxl_vsnd_pcm_init); + } + + libxl_vsnd_pcm *pcm = &vsnd->pcms[vsnd->num_vsnd_pcms - 1]; + + ARRAY_EXTEND_INIT_NODEVID(pcm->streams, pcm->num_vsnd_streams, + libxl_vsnd_stream_init); + } else { + fprintf(stderr, "Invalid key: %s\n", key); + return -1; + } + + return 0; +} + +int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec) +{ + char *buf = strdup(spec); + char *token = strtok(buf, ","); + char *key = NULL; + int ret; + + while (token) { + while (*token == ' ') token++; + + if (!key) { + key = token; + ret = parse_vsnd_create_item(vsnd, key); + if (ret) goto out; + } else { + if (strcasecmp(key, "card") == 0) { + ret = parse_vsnd_card_param(vsnd, token); + if (ret) goto out; + } else if (strcasecmp(key, "pcm") == 0) { + ret = parse_vsnd_pcm_param(vsnd, token); + if (ret) goto out; + } else if (strcasecmp(key, "stream") == 0) { + ret = parse_vsnd_pcm_stream(vsnd, token); + if (ret) goto out; + } + } + token = strtok (NULL, ","); + } + + ret = 0; + +out: + free(buf); + return ret; +} + +static void parse_vsnd_card_config(const XLU_Config *config, + XLU_ConfigValue *card_value, + libxl_domain_config *d_config) +{ + int ret; + XLU_ConfigList *card_list; + libxl_device_vsnd *vsnd; + const char *card_item; + int item = 0; + + ret = xlu_cfg_value_get_list(config, card_value, &card_list, 0); + + if (ret) { + fprintf(stderr, "Failed to get vsnd card list: %s\n", strerror(ret)); + goto out; + } + + vsnd = ARRAY_EXTEND_INIT(d_config->vsnds, + d_config->num_vsnds, + libxl_device_vsnd_init); + + while ((card_item = xlu_cfg_get_listitem(card_list, item++)) != NULL) { + ret = parse_vsnd_item(vsnd, card_item); + if (ret) goto out; + } + + ret = 0; + +out: + + if (ret) exit(EXIT_FAILURE); +} + +static void parse_vsnd_config(const XLU_Config *config, + libxl_domain_config *d_config) +{ + XLU_ConfigList *vsnds; + + if (!xlu_cfg_get_list(config, "vsnd", &vsnds, 0, 0)) { + XLU_ConfigValue *card_value; + + d_config->num_vsnds = 0; + d_config->vsnds = NULL; + + while ((card_value = xlu_cfg_get_listitem2(vsnds, d_config->num_vsnds)) + != NULL) { + parse_vsnd_card_config(config, card_value, d_config); + } + } +} + void parse_config_data(const char *config_source, const char *config_data, int config_len, @@ -1726,6 +1970,8 @@ void parse_config_data(const char *config_source, } } + parse_vsnd_config(config, d_config); + if (!xlu_cfg_get_list (config, "channel", &channels, 0, 0)) { d_config->num_channels = 0; d_config->channels = NULL; diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h index cc459fb43f..9a948ea4f7 100644 --- a/tools/xl/xl_parse.h +++ b/tools/xl/xl_parse.h @@ -34,6 +34,7 @@ int parse_usbdev_config(libxl_device_usbdev *usbdev, char *token); int parse_cpurange(const char *cpu, libxl_bitmap *cpumap); int parse_nic_config(libxl_device_nic *nic, XLU_Config **config, char *token); int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token); +int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec); int match_option_size(const char *prefix, size_t len, char *arg, char **argopt); -- 2.17.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |