blob: 04d38682d9b2a4ffde2310cc8a4251832ec0f440 [file] [log] [blame]
Iliyan Malchev4765c432012-06-11 14:36:16 -07001/*
Duy Truongeb337332013-01-17 10:33:22 -08002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Iliyan Malchev4765c432012-06-11 14:36:16 -07003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
Duy Truongeb337332013-01-17 10:33:22 -080013 * * Neither the name of The Linux Foundation nor the names of its
Iliyan Malchev4765c432012-06-11 14:36:16 -070014 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <sys/ioctl.h>
31#include <sys/stat.h>
32#include <linux/ioctl.h>
33#include <fcntl.h>
34#include <string.h>
35#include <stdio.h>
36#include <errno.h>
37#include <stdlib.h>
38
Mingming Yinbbd94ad2012-11-29 20:04:36 -080039#ifndef ANDROID
40#include <stdint.h>
41#define strlcat g_strlcat
42#endif
43
Iliyan Malchev4765c432012-06-11 14:36:16 -070044#include "alsa_ucm.h"
45#include "msm8960_use_cases.h"
46
47/* Function prototypes */
48static void print_help_menu(void);
49static void alsaucm_test_cmd_svr(void);
50static int process_cmd(char *cmdStr);
51
52/* Global data */
53snd_use_case_mgr_t *uc_mgr;
54
55/* Defines */
56enum ucm_cmd_id {
57 UCM_OPEN = 0,
58 UCM_SET,
59 UCM_LISTCARDS,
60 UCM_LIST,
61 UCM_GET,
62 UCM_GETI,
63 UCM_RESET,
64 UCM_RELOAD,
65 UCM_HELP,
66 UCM_QUIT,
67 UCM_UNKNOWN
68};
69
70struct cmd {
71 enum ucm_cmd_id code;
72 const char *cmd_str;
73};
74
75static struct cmd cmds[] = {
76 { UCM_OPEN, "open" },
77 { UCM_SET, "set" },
78 { UCM_LISTCARDS, "listcards" },
79 { UCM_LIST, "list" },
80 { UCM_GET, "get" },
81 { UCM_GETI, "geti" },
82 { UCM_RESET, "reset" },
83 { UCM_RELOAD, "reload" },
84 { UCM_HELP, "help" },
85 { UCM_QUIT, "quit" },
86 { UCM_UNKNOWN, NULL }
87};
88
89static void alsaucm_test_cmd_svr(void)
90{
91 int fd;
92 ssize_t read_count;
93 char cmdstr[256] = {'\0'};
94 char ch;
95 char *exit_str = "quit";
96
97 if (mknod("/data/alsaucm_test", S_IFIFO | 0666, 0) == 0) {
98 fd = open("/data/alsaucm_test", O_RDONLY);
99 while (1) {
100 read_count = read(fd, &ch, 1);
101 if (read_count == 0) {
102 sleep(2);
103 continue;
104 } else if (read_count < 0) {
105 fprintf(stderr, "alsaucm_test: error reading cmd\n");
106 break;
107 }
108
109 if (ch != '\n') {
110 strlcat(cmdstr, &ch , (2+strlen(cmdstr)));
111 continue;
112 } else {
113 if (!strncmp(cmdstr, exit_str, strlen(cmdstr))) {
114 /* free UCM instace */
115 if (uc_mgr) {
116 snd_use_case_mgr_close(uc_mgr);
117 uc_mgr = NULL;
118 }
119 break;
120 } else {
121 process_cmd(cmdstr);
122 memset(cmdstr, 0, sizeof(cmdstr));
123 }
124 }
125 }
126 printf("alsaucm_test: exit server mode\n");
127 close(fd);
128 remove("/data/alsaucm_test");
129 } else {
130 fprintf(stderr, "alsaucm_test: Failed to create server\n");
131 }
132}
133
134
135static void print_help_menu(void)
136{
137 printf("\nAvailable commands:\n"
138 " open NAME open card NAME\n"
139 " reset reset sound card to default state\n"
140 " reload reload configuration\n"
141 " listcards list available cards\n"
142 " list IDENTIFIER list command\n"
143 " get IDENTIFIER get string value\n"
144 " geti IDENTIFIER get integer value\n"
145 " set IDENTIFIER VALUE set string value\n"
146 " help help\n"
147 " quit quit\n");
148}
149
150int main(int argc, char **argv)
151{
152 char *help_str = "help";
153 argc--;
154 argv++;
155
156 if (argc > 0) {
157 if (!strncmp(argv[0], help_str, strlen(argv[0])))
158 print_help_menu();
159 } else
160 alsaucm_test_cmd_svr();
161 return 0;
162}
163
164static int process_cmd(char *cmdStr)
165{
166 const char **list = NULL , *str = NULL;
167 long lval;
168 int err, i;
169 char *command = NULL;
170 int count = 0;
171 char *identifier = NULL, *value = NULL;
172 struct cmd *cmd = NULL;
173
174 command = strtok_r(cmdStr, " ", &value);
175 identifier = strtok_r(NULL, " ", &value);
176
177 if (command == NULL) {
178 fprintf(stderr, "NULL pointer encountered. Invalid value for command");
179 return -1;
180 }
181
182 for (cmd = cmds; cmd->cmd_str != NULL; cmd++) {
183 if (strncmp(cmd->cmd_str, command, strlen(cmd->cmd_str)) == 0)
184 break;
185 }
186
187 if (cmd->cmd_str == NULL) {
188 fprintf(stderr, "Unknown command '%s'\n", command);
189 return -EINVAL;
190 }
191
192 if ((identifier == NULL) && ((cmd->code != UCM_HELP) &&
193 (cmd->code != UCM_LISTCARDS) && (cmd->code != UCM_RESET) &&
194 (cmd->code != UCM_RELOAD)))
195 {
196 fprintf(stderr, "NULL pointer encountered. Invalid value for identifier");
197 return -1;
198 }
199
200 switch (cmd->code) {
201 case UCM_HELP:
202 print_help_menu();
203 break;
204
205 case UCM_OPEN:
206 if (uc_mgr) {
207 snd_use_case_mgr_close(uc_mgr);
208 uc_mgr = NULL;
209 }
210
211 err = snd_use_case_mgr_open(&uc_mgr, identifier);
212 if (err < 0) {
213 fprintf(stderr, "%s: error failed to open sound card %s: %d\n", cmd->cmd_str, identifier, err);
214 return err;
215 }
Iliyan Malchev4765c432012-06-11 14:36:16 -0700216 break;
217
218 case UCM_LISTCARDS:
219 err = snd_use_case_card_list(&list);
220 if (err < 0) {
221 fprintf(stderr, "%s: error failed to get card list: %d\n", cmd->cmd_str, err);
222 return err;
223 }
224 if (err == 0) {
225 printf("list is empty\n");
226 return 0;
227 }
228
229 for (i = 0; i < err; i++)
230 printf(" %i: %s\n", i+1, list[i]);
231 snd_use_case_free_list(list, err);
232 break;
233
234 case UCM_RESET:
235 if (!uc_mgr) {
236 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
237 return -EINVAL;
238 }
239
240 err = snd_use_case_mgr_reset(uc_mgr);
241 if (err < 0) {
242 fprintf(stderr, "%s: error failed to reset sound card %d\n", cmd->cmd_str, err);
243 return err;
244 }
245 break;
246
247 case UCM_RELOAD:
248 if (!uc_mgr) {
249 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
250 return -EINVAL;
251 }
252
253 err = snd_use_case_mgr_reload(uc_mgr);
254 if (err < 0) {
255 fprintf(stderr, "%s: error failed to reload manager %d\n", cmd->cmd_str, err);
256 return err;
257 }
258 break;
259
260 case UCM_LIST:
261 if (!uc_mgr) {
262 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
263 return -EINVAL;
264 }
265
266 err = snd_use_case_get_list(uc_mgr, identifier, &list);
267 if (err < 0) {
268 fprintf(stderr, "%s: error failed to get list %s: %d\n", cmd->cmd_str, identifier, err);
269 return err;
270 }
271 if (err == 0) {
272 printf("list is empty\n");
273 return 0;
274 }
275 for (i = 0; i < err; i++) {
276 printf(" %i: %s\n", i+1, list[i]);
277 }
278 snd_use_case_free_list(list, err);
279 break;
280
281 case UCM_SET:
282 if (!uc_mgr) {
283 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
284 return -EINVAL;
285 }
286
287 err = snd_use_case_set(uc_mgr, identifier, value);
288 if (err < 0) {
289 fprintf(stderr, "%s: error failed to set %s=%s: %d\n", cmd->cmd_str, identifier, value, err);
290 return err;
291 }
292 break;
293
294 case UCM_GET:
295 if (!uc_mgr) {
296 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
297 return -EINVAL;
298 }
299
300 err = snd_use_case_get(uc_mgr, identifier, &str);
301 if (err < 0) {
302 fprintf(stderr, "%s: error failed to get %s: %d\n", cmd->cmd_str, identifier, err);
303 return err;
304 }
305 printf(" %s=%s\n", identifier, str);
306 free((void *)str);
307 break;
308
309 case UCM_GETI:
310 if (!uc_mgr) {
311 fprintf(stderr, "No card is opened before. %s command can't be executed\n", cmd->cmd_str);
312 return -EINVAL;
313 }
314
315 err = snd_use_case_geti(uc_mgr, identifier, &lval);
316 if (err < 0) {
317 fprintf(stderr, "%s: error failed to get integer %s: %d\n", cmd->cmd_str, identifier, err);
318 return lval;
319 }
320 printf(" %s=%li\n", identifier, lval);
321 break;
322
323 default:
324 break;
325 }
326 return 0;
327}
328