xl: add PV sound condif parser

Add config parser for virtual sound devices

Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
Oleksandr Grytsov authored and Wei Liu committed 2018-07-10 08:47:27 +01:00
1 parent b24fb566eb
commit 8d89d52c5a
2 files changed
+247

No files matched your search

+246
View File
@@ -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;
+1
View File
@@ -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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.