1 /*
2 * Copyright (C) 2016 EPAM Systems Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; version 2.1 only. with the special
7 * exception on linking described in file LICENSE.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 */
14
15 #include <stdlib.h>
16
17 #include <libxl.h>
18 #include <libxl_utils.h>
19 #include <libxlutil.h>
20
21 #include <xen/io/sndif.h>
22
23 #include "xl.h"
24 #include "xl_utils.h"
25 #include "xl_parse.h"
26
main_vsndattach(int argc,char ** argv)27 int main_vsndattach(int argc, char **argv)
28 {
29 int opt;
30 int rc;
31 uint32_t domid;
32 libxl_device_vsnd vsnd;
33
34 SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-attach", 2) {
35 /* No options */
36 }
37
38 libxl_device_vsnd_init(&vsnd);
39 domid = find_domain(argv[optind++]);
40
41 for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) {
42 rc = parse_vsnd_item(&vsnd, *argv);
43 if (rc) goto out;
44 }
45
46 if (dryrun_only) {
47 char *json = libxl_device_vsnd_to_json(ctx, &vsnd);
48 printf("vsnd: %s\n", json);
49 rc = 0;
50 free(json);
51 goto out;
52 }
53
54 if (libxl_device_vsnd_add(ctx, domid, &vsnd, 0)) {
55 fprintf(stderr, "libxl_device_vsnd_add failed.\n");
56 rc = ERROR_FAIL; goto out;
57 }
58
59 rc = 0;
60
61 out:
62 libxl_device_vsnd_dispose(&vsnd);
63 return rc;
64 }
65
print_params(libxl_vsnd_params * params)66 static void print_params(libxl_vsnd_params *params)
67 {
68 int i;
69
70 if (params->channels_min) {
71 printf(", "XENSND_FIELD_CHANNELS_MIN": %u", params->channels_min);
72 }
73
74 if (params->channels_max) {
75 printf(", "XENSND_FIELD_CHANNELS_MAX": %u", params->channels_max);
76 }
77
78 if (params->buffer_size) {
79 printf(", "XENSND_FIELD_BUFFER_SIZE": %u", params->buffer_size);
80 }
81
82 if (params->num_sample_rates) {
83 printf(", "XENSND_FIELD_SAMPLE_RATES": ");
84 for (i = 0; i < params->num_sample_rates - 1; i++) {
85 printf("%u;", params->sample_rates[i]);
86 }
87 printf("%u", params->sample_rates[i]);
88 }
89
90 if (params->num_sample_formats) {
91 printf(", "XENSND_FIELD_SAMPLE_RATES": ");
92 for (i = 0; i < params->num_sample_formats - 1; i++) {
93 printf("%s;", libxl_vsnd_pcm_format_to_string(params->sample_formats[i]));
94 }
95 printf("%s", libxl_vsnd_pcm_format_to_string(params->sample_formats[i]));
96 }
97
98 printf("\n");
99 }
100
main_vsndlist(int argc,char ** argv)101 int main_vsndlist(int argc, char **argv)
102 {
103 int opt;
104 int i, j, k, n;
105 libxl_device_vsnd *vsnds;
106 libxl_vsndinfo vsndinfo;
107
108 SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-list", 1) {
109 /* No options */
110 }
111
112 for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
113 uint32_t domid;
114
115 if (libxl_domain_qualifier_to_domid(ctx, *argv, &domid) < 0) {
116 fprintf(stderr, "%s is an invalid domain identifier\n", *argv);
117 continue;
118 }
119
120 vsnds = libxl_device_vsnd_list(ctx, domid, &n);
121
122 if (!vsnds) continue;
123
124 for (i = 0; i < n; i++) {
125 libxl_vsndinfo_init(&vsndinfo);
126 if (libxl_device_vsnd_getinfo(ctx, domid, &vsnds[i],
127 &vsndinfo) == 0) {
128 printf("\ndevid: %d, be-domid: %d, handle: %d, state: %d, "
129 "be-path: %s, fe-path: %s\n",
130 vsndinfo.devid, vsndinfo.backend_id,
131 vsndinfo.frontend_id, vsndinfo.state,
132 vsndinfo.backend, vsndinfo.frontend);
133
134 printf(XENSND_FIELD_VCARD_SHORT_NAME": \"%s\", "
135 XENSND_FIELD_VCARD_LONG_NAME": \"%s\"",
136 vsnds[i].short_name, vsnds[i].long_name);
137 print_params(&vsnds[i].params);
138
139 for (j = 0; j < vsndinfo.num_vsnd_pcms; j++) {
140 libxl_vsnd_pcm *pcm = &vsnds[i].pcms[j];
141
142 printf("\tpcm: %d, "XENSND_FIELD_DEVICE_NAME": \"%s\"", j, pcm->name);
143 print_params(&pcm->params);
144
145 for(k = 0; k < vsnds[i].pcms[j].num_vsnd_streams; k++) {
146 libxl_vsnd_stream *stream = &vsnds[i].pcms[j].streams[k];
147 libxl_streaminfo *info = &vsndinfo.pcms[j].streams[k];
148
149 printf("\t\tstream: %d, "XENSND_FIELD_STREAM_UNIQUE_ID": \"%s\", "
150 XENSND_FIELD_TYPE": %s", k, stream->unique_id,
151 libxl_vsnd_stream_type_to_string(stream->type));
152 print_params(&stream->params);
153 printf("\t\t\t"XENSND_FIELD_EVT_CHNL": %d, "XENSND_FIELD_RING_REF": %d\n",
154 info->req_evtch, info->req_rref);
155 }
156 }
157 }
158 libxl_vsndinfo_dispose(&vsndinfo);
159 }
160 libxl_device_vsnd_list_free(vsnds, n);
161 }
162 return 0;
163 }
164
main_vsnddetach(int argc,char ** argv)165 int main_vsnddetach(int argc, char **argv)
166 {
167 uint32_t domid, devid;
168 int opt, rc;
169 libxl_device_vsnd vsnd;
170
171 SWITCH_FOREACH_OPT(opt, "", NULL, "vsnd-detach", 2) {
172 /* No options */
173 }
174
175 domid = find_domain(argv[optind++]);
176 devid = atoi(argv[optind++]);
177
178 libxl_device_vsnd_init(&vsnd);
179
180 if (libxl_devid_to_device_vsnd(ctx, domid, devid, &vsnd)) {
181 fprintf(stderr, "Error: Device %d not connected.\n", devid);
182 rc = ERROR_FAIL;
183 goto out;
184 }
185
186 rc = libxl_device_vsnd_remove(ctx, domid, &vsnd, 0);
187 if (rc) {
188 fprintf(stderr, "libxl_device_vsnd_remove failed.\n");
189 rc = ERROR_FAIL;
190 goto out;
191 }
192
193 rc = 0;
194
195 out:
196 libxl_device_vsnd_dispose(&vsnd);
197 return rc;
198 }
199
200
201 /*
202 * Local variables:
203 * mode: C
204 * c-basic-offset: 4
205 * indent-tabs-mode: nil
206 * End:
207 */
208