Merge "ALURE support has been enabled." into tizen
[platform/core/api/sound-pool.git] / test / proxy / src / proxy.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "proxy.h"
18 #include "logger.h"
19
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24
25 #define DEFAULT_MAX_STREAMS_PER_POOL_CNT 25
26 #define MICROSECS_PER_MILLISEC 1000
27
28 #define MAX_POOL_CNT 100
29 static sound_pool_h pools[MAX_POOL_CNT] = { NULL };
30
31 /* Messages to be used for callbacks output (for pool state changing) */
32 static char *messages[MAX_POOL_CNT] = { NULL };
33 /* Scripts will be launched from callbacks (for stream state changing) */
34 static char *scripts[MAX_POOL_CNT] = { NULL };
35
36 #define MAX_STREAM_CNT 1000
37 /* Messages to be used for callbacks output (for pool state changing) */
38 static char *stream_messages[MAX_POOL_CNT][MAX_STREAM_CNT] = { NULL };
39 /* Messages to be used for callbacks output (for stream state changing) */
40 static char *stream_scripts[MAX_POOL_CNT][MAX_STREAM_CNT] = { NULL };
41
42 static int __proxy_sound_pool_execute_script(const char *pars);
43
44 const char *__stringify_sound_pool_error(sound_pool_error_e error)
45 {
46         switch (error) {
47         case SOUND_POOL_ERROR_NONE:
48                 return "SOUND_POOL_ERROR_NONE";
49                 break;
50         case SOUND_POOL_ERROR_NOT_SUPPORTED:
51                 return "SOUND_POOL_ERROR_NOT_SUPPORTED";
52                 break;
53         case SOUND_POOL_ERROR_MSG_TOO_LONG:
54                 return "SOUND_POOL_ERROR_MSG_TOO_LONG";
55                 break;
56         case SOUND_POOL_ERROR_NO_DATA:
57                 return "SOUND_POOL_ERROR_NO_DATA";
58                 break;
59         case SOUND_POOL_ERROR_KEY_NOT_AVAILABLE:
60                 return "SOUND_POOL_ERROR_KEY_NOT_AVAILABLE";
61                 break;
62         case SOUND_POOL_ERROR_OUT_OF_MEMORY:
63                 return "SOUND_POOL_ERROR_OUT_OF_MEMORY";
64                 break;
65         case SOUND_POOL_ERROR_INVALID_PARAMETER:
66                 return "SOUND_POOL_ERROR_INVALID_PARAMETER";
67                 break;
68         case SOUND_POOL_ERROR_INVALID_OPERATION:
69                 return "SOUND_POOL_ERROR_INVALID_OPERATION";
70                 break;
71         case SOUND_POOL_ERROR_PERMISSION_DENIED:
72                 return "SOUND_POOL_ERROR_PERMISSION_DENIED";
73                 break;
74         default:
75                 return "";
76                 break;
77         }
78
79         return NULL;
80 }
81
82 const char *__stringify_stream_state(sound_pool_stream_state_e state)
83 {
84         switch (state) {
85         case SOUND_POOL_STREAM_STATE_NONE:
86                 return "SOUND_POOL_STREAM_STATE_NONE";
87                 break;
88         case SOUND_POOL_STREAM_STATE_PLAYING:
89                 return "SOUND_POOL_STREAM_STATE_PLAYING";
90                 break;
91         case SOUND_POOL_STREAM_STATE_PAUSED:
92                 return "SOUND_POOL_STREAM_STATE_PAUSED";
93                 break;
94         case SOUND_POOL_STREAM_STATE_SUSPENDED:
95                 return "SOUND_POOL_STREAM_STATE_SUSPENDED";
96                 break;
97         case SOUND_POOL_STREAM_STATE_STOPPED:
98                 return "SOUND_POOL_STREAM_STATE_STOPPED";
99                 break;
100         case SOUND_POOL_STREAM_STATE_FINISHED:
101                 return "SOUND_POOL_STREAM_STATE_FINISHED";
102                 break;
103         default:
104                 return "";
105                 break;
106         }
107
108         return NULL;
109 }
110
111 static void __sp_cb_msg(sound_pool_h pool, sound_pool_state_e prev_state,
112                 sound_pool_state_e cur_state, void *data)
113 {
114         const char *msg = (const char *)data;
115         _logger_log_info("Sound pool state was changing from %s to %s: %s",
116                         prev_state == SOUND_POOL_STATE_ACTIVE ?
117                                         "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE",
118                         cur_state == SOUND_POOL_STATE_ACTIVE ?
119                                         "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE",
120                         msg ? msg : "No message");
121 }
122
123 static void __sp_cb_scr(sound_pool_h pool, sound_pool_state_e prev_state,
124                 sound_pool_state_e cur_state, void *data)
125 {
126         const char *scr = (const char *)data;
127         _logger_log_info("Sound pool state was changing from %s to %s; "
128                         "Executing: %s...",
129                         prev_state == SOUND_POOL_STATE_ACTIVE ? "SOUND_POOL_STATE_ACTIVE" :
130                                         "SOUND_POOL_STATE_INACTIVE",
131                         cur_state == SOUND_POOL_STATE_ACTIVE ? "SOUND_POOL_STATE_ACTIVE" :
132                                         "SOUND_POOL_STATE_INACTIVE",
133                         scr ? scr : "No script");
134         __proxy_sound_pool_execute_script(scr);
135 }
136
137 static void __s_cb_msg(sound_pool_h pool, const char *tag, unsigned id,
138                 sound_pool_stream_state_e prev_state,
139                 sound_pool_stream_state_e cur_state, void *data)
140 {
141         const char *msg = (const char *)data;
142         _logger_log_info("Stream state was changing from %s to %s: %s",
143                         __stringify_stream_state(prev_state),
144                         __stringify_stream_state(cur_state),
145                         msg ? msg : "No message");
146 }
147
148 static void __s_cb_scr(sound_pool_h pool, const char *tag, unsigned id,
149                 sound_pool_stream_state_e prev_state,
150                 sound_pool_stream_state_e cur_state, void *data)
151 {
152         const char *scr = (const char *)data;
153         _logger_log_info("Sound pool state was changing from %s to %s; "
154                         "Executing: %s...", __stringify_stream_state(prev_state),
155                         __stringify_stream_state(cur_state),
156                         scr ? scr : "No script");
157         __proxy_sound_pool_execute_script(scr);
158 }
159
160 /* CMD_EXIT */
161 static int __exit()
162 {
163         return EXIT;
164 }
165
166 /* CMD_HELP */
167 static int __print_cmd_help_msg()
168 {
169         printf("\nTest suite usage help:\n");
170
171         printf(CMD_HELP "\n");
172         printf("\t- Shows this help.\n");
173
174         printf(CMD_CREATE_POOL "\n");
175         printf("\t- creates pool with specific identifier.\n");
176
177         printf(CMD_DESTROY_POOL "\n");
178         printf("\t- destroys pool with specific identifier.\n");
179
180         printf(CMD_ACTIVATE_POOL "\n");
181         printf("\t- activates pool with specific identifier.\n");
182
183         printf(CMD_DEACTIVATE_POOL "\n");
184         printf("\t- deactivates pool with specific identifier.\n");
185
186         printf(CMD_GET_POOL_STATE "\n");
187         printf("\t- shows state of the pool with specific identifier.\n");
188
189         printf(CMD_SET_POOL_VOLUME "\n");
190         printf("\t- use this command to set volume for the specific sound pool.\n");
191
192         printf(CMD_GET_POOL_VOLUME "\n");
193         printf("\t- shows volume of the sound pool with specific identifier.\n");
194
195         printf(CMD_SET_POOL_CB_MSG "\n");
196         printf("\t- sets callback which will show the message when sound pool "
197                         "state is changed.\n");
198
199         printf(CMD_SET_POOL_CB_SCRIPT "\n");
200         printf("\t- sets callback which will execute the script when sound pool "
201                         "state is changed.\n");
202
203         printf(CMD_UNSET_POOL_CB "\n");
204         printf("\t- unsets the callback for the sound pool.\n");
205
206         printf(CMD_LIST_POOL "\n");
207         printf("\t- shows ids of all pools had been created and their states.\n");
208
209         printf(CMD_LOAD_SOURCE "\n");
210         printf("\t- loads the source with specific source tag.\n");
211
212         printf(CMD_UNLOAD_SOURCE "\n");
213         printf("\t- unloads the source with specific source tag.\n");
214
215         printf(CMD_PLAY_STREAM "\n");
216         printf("\t- creates the stream with unique identifier and starts playback.\n"
217                         "\t  Source tag to be used for stream creation should be specified.\n");
218
219         printf(CMD_STOP_STREAM "\n");
220         printf("\t- stops the stream playback. Stream unique identifier should be\n"
221                         "\t  specified after command. After stopping the stream became invalid.\n");
222
223         printf(CMD_PAUSE_STREAM "\n");
224         printf("\t- pauses the stream playback. Stream unique identifier should be\n"
225                         "\t  specified after command.\n");
226
227         printf(CMD_RESUME_STREAM "\n");
228         printf("\t- resumes the stream was paused before. Stream unique identifier\n"
229                         "\t  should be specified after command.\n");
230
231         printf(CMD_SET_STREAM_VOLUME "\n");
232         printf("\t- use this command to set volume parameter of the stream.\n");
233
234         printf(CMD_GET_STREAM_VOLUME "\n");
235         printf("\t- shows volume of the stream in the pool with specified "
236                         "identifiers.\n");
237
238         printf(CMD_SET_STREAM_LOOP "\n");
239         printf("\t- use this command to set loop parameter of the stream.\n");
240
241         printf(CMD_GET_STREAM_LOOP "\n");
242         printf("\t- shows loop count of the stream in the pool with specified "
243                         "identifiers.\n");
244
245         printf(CMD_SET_STREAM_PRIORITY "\n");
246         printf("\t- use this command to set priority parameter of the stream.\n");
247
248         printf(CMD_GET_STREAM_PRIORITY "\n");
249         printf("\t- shows priority rank of the stream in the pool with specified "
250                         "identifiers.\n");
251
252         printf(CMD_GET_STREAM_STATE "\n");
253         printf("\t- shows state of the stream in the pool with specified "
254                         "identifiers.\n");
255
256         printf(CMD_SET_STREAM_CB_MSG "\n");
257         printf("\t- sets callback which will show the message when sound stream "
258                         "state is changed.\n");
259
260         printf(CMD_SET_STREAM_CB_SCRIPT "\n");
261         printf("\t- sets callback which will execute the script (from file) when "
262                         "sound stream state is changed.\n");
263
264         printf(CMD_UNSET_STREAM_CB "\n");
265         printf("\t- unsets the callback for the sound stream.\n");
266
267         printf(CMD_EXECUTE_SCRIPT "\n");
268         printf("\t- executes the script from the file in filesystem. Script has to\n"
269                         "\t  be compiled with commands supported by testsuite, one command\n"
270                         "\t  per single line.\n");
271
272         printf(CMD_SLEEP "\n");
273         printf("\t- suspends execution of the main thread for the specific amount "
274                         "of milleseconds.\n");
275
276         printf(CMD_EXIT "\n");
277         printf("\t- exits from the test suite.\n");
278
279         printf("\n");
280
281         return OK;
282 }
283
284 /* CMD_CREATE_POOL */
285 static int __proxy_sound_pool_create(const char *pars)
286 {
287         _logger_log_info(CMD_CREATE_POOL " command was called");
288
289         unsigned int max_streams = DEFAULT_MAX_STREAMS_PER_POOL_CNT;
290         if (pars != NULL)
291                 sscanf(pars, " %u", &max_streams);
292
293         _logger_log_info("Creating the pool...");
294
295         sound_pool_h pool = NULL;
296         int ret = sound_pool_create(max_streams, &pool);
297
298         if (ret == SOUND_POOL_ERROR_NONE) {
299                 _logger_log_info("sound_pool_create(%u, pool) returned %s value",
300                                 max_streams, __stringify_sound_pool_error(ret));
301
302                 size_t idx = 0;
303                 while (idx < MAX_POOL_CNT) {
304                         if (pools[idx++] == NULL) {
305                                 pools[--idx] = pool;
306                                 break;
307                         }
308                 }
309
310                 if (idx == MAX_POOL_CNT) {
311                         _printf(CMD_COLOR_RED, "Limit of possible pools is exceeded. Destroy "
312                                         "some pools before creating of new ones.\n");
313
314                         _logger_log_warn("Pool can't be created due to test suite "
315                                         "restrictions. Destroying the pool...");
316
317                         ret = sound_pool_destroy(pool);
318                         if (ret == SOUND_POOL_ERROR_NONE)
319                                 _logger_log_info("sound_pool_destroy(pool) returned %s value",
320                                                 __stringify_sound_pool_error(ret));
321                         else
322                                 _logger_log_err("sound_pool_destroy(pool) returned %s value",
323                                                 __stringify_sound_pool_error(ret));
324
325                         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
326                 }
327
328                 if (!pool)
329                         _logger_log_warn("Created pool is NULL");
330                 else
331                         _logger_log_info("Identifier of the pool has been created is %zu", idx);
332         } else {
333                 _logger_log_err("sound_pool_create(%u, pool) returned %s value",
334                                 max_streams, __stringify_sound_pool_error(ret));
335         }
336
337         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
338 }
339
340 /* CMD_DESTROY_POOL */
341 static int __proxy_sound_pool_destroy(const char *pars)
342 {
343         int ret = SOUND_POOL_ERROR_NONE;
344         size_t idx = 0;
345         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
346                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool to be "
347                                 "destroyed after command! Format: " CMD_DESTROY_POOL " <id>\n");
348                 return FAIL;
349         }
350
351         if (idx > (MAX_POOL_CNT - 1)) {
352                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
353                                 MAX_POOL_CNT - 1);
354                 return FAIL;
355         }
356
357         _logger_log_info(CMD_DESTROY_POOL " command was called");
358         _logger_log_info("Destroying the pool by %zu identifier...", idx);
359
360         if (pools[idx] == NULL)
361                 _logger_log_warn("Pool to be destroyed is NULL");
362
363         ret = sound_pool_destroy(pools[idx]);
364
365         if (ret == SOUND_POOL_ERROR_NONE)
366                 _logger_log_info("sound_pool_destroy(pool) returned %s value",
367                                 __stringify_sound_pool_error(ret));
368         else
369                 _logger_log_err("sound_pool_destroy(pool) returned %s value",
370                                 __stringify_sound_pool_error(ret));
371
372         pools[idx] = NULL;
373
374         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
375 }
376
377 /* CMD_ACTIVATE_POOL */
378 static int __proxy_sound_pool_activate(const char *pars)
379 {
380         int ret = SOUND_POOL_ERROR_NONE;
381         size_t idx = 0;
382         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
383                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool "
384                                 "to be activated after command name! Format: "
385                                 CMD_ACTIVATE_POOL " <id>\n");
386                 return FAIL;
387         }
388
389         if (idx > (MAX_POOL_CNT - 1)) {
390                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
391                                 MAX_POOL_CNT - 1);
392                 return FAIL;
393         }
394
395         _logger_log_info(CMD_ACTIVATE_POOL " command was called");
396         _logger_log_info("Activating the pool by %zu identifier...", idx);
397
398         if (pools[idx] == NULL)
399                 _logger_log_warn("Pool to be activated is NULL");
400
401         ret = sound_pool_activate(pools[idx]);
402
403         if (ret == SOUND_POOL_ERROR_NONE)
404                 _logger_log_info("sound_pool_set_state(pool, "
405                                 "SOUND_POOL_STATE_ACTIVE) returned %s value",
406                                 __stringify_sound_pool_error(ret));
407         else
408                 _logger_log_err("sound_pool_set_state(pool, "
409                                 "SOUND_POOL_STATE_ACTIVE) returned %s value",
410                                 __stringify_sound_pool_error(ret));
411
412         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
413 }
414
415 /* CMD_DEACTIVATE_POOL */
416 static int __proxy_sound_pool_deactivate(const char *pars)
417 {
418         size_t idx = 0;
419         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
420                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool "
421                                 "to be deactivated after command name! Format: "
422                                 CMD_DEACTIVATE_POOL " <id>\n");
423                 return FAIL;
424         }
425
426         if (idx > (MAX_POOL_CNT - 1)) {
427                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
428                                 MAX_POOL_CNT - 1);
429                 return FAIL;
430         }
431
432         _logger_log_info(CMD_DEACTIVATE_POOL " command was called");
433         _logger_log_info("Deactivating the pool by %zu identifier...", idx);
434
435         if (pools[idx] == NULL)
436                 _logger_log_warn("Pool to be deactivated is NULL");
437
438         int ret = sound_pool_deactivate(pools[idx]);
439
440         if (ret == SOUND_POOL_ERROR_NONE)
441                 _logger_log_info("sound_pool_set_state(pool, "
442                                 "SOUND_POOL_STATE_INACTIVE) returned %s value",
443                                 __stringify_sound_pool_error(ret));
444         else
445                 _logger_log_err("sound_pool_set_state(pool, "
446                                 "SOUND_POOL_STATE_INACTIVE) returned %s value",
447                                 __stringify_sound_pool_error(ret));
448
449         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
450 }
451
452 /* CMD_GET_POOL_STATE */
453 static int __proxy_sound_pool_get_state(const char *pars)
454 {
455         size_t idx = 0;
456         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
457                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool "
458                                 "to get state for, after command name! Format: "
459                                 CMD_GET_POOL_STATE " <id>\n");
460                 return FAIL;
461         }
462
463         if (idx > (MAX_POOL_CNT - 1)) {
464                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
465                                 MAX_POOL_CNT - 1);
466                 return FAIL;
467         }
468
469         _logger_log_info(CMD_GET_POOL_STATE " command was called");
470         _logger_log_info("Getting the pool state by %zu identifier...", idx);
471
472         if (pools[idx] == NULL)
473                 _logger_log_warn("Pool to get state for is NULL");
474
475         sound_pool_state_e state = SOUND_POOL_STATE_INACTIVE;
476         int ret = sound_pool_get_state(pools[idx], &state);
477
478         const char *str_state = (state == SOUND_POOL_STATE_ACTIVE ?
479                         "SOUND_POOL_STATE_ACTIVE" : "SOUND_POOL_STATE_INACTIVE");
480
481         if (ret == SOUND_POOL_ERROR_NONE)
482                 _logger_log_info("sound_pool_get_state(pool, state) returned %s value,"
483                                 " state is %s", __stringify_sound_pool_error(ret), str_state);
484         else
485                 _logger_log_err("sound_pool_get_state(pool, state) returned %s value,"
486                                 " state is %s", __stringify_sound_pool_error(ret), str_state);
487
488         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
489 }
490
491 /* CMD_SET_POOL_VOLUME */
492 static int __proxy_sound_pool_set_volume(const char *pars)
493 {
494         size_t idx = 0;
495         float volume = .0f;
496         if ((pars == NULL) || (sscanf(pars, " %zu %f", &idx, &volume) < 2)) {
497                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
498                                 "pool and new volume float value to set volume for whole pool! "
499                                 "Format: " CMD_SET_POOL_VOLUME " <id> <volume>\n");
500                 return FAIL;
501         }
502
503         if (idx > (MAX_POOL_CNT - 1)) {
504                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
505                                 MAX_POOL_CNT - 1);
506                 return FAIL;
507         }
508
509         _logger_log_info(CMD_SET_POOL_VOLUME " command was called");
510         _logger_log_info("Set %f volume value for pool with %zu identifier...",
511                         volume, idx);
512
513         if (pools[idx] == NULL)
514                 _logger_log_warn("Pool to get state for is NULL");
515
516         if (volume < .0f || volume > 1.0f)
517                 _logger_log_warn("Volume is set as %f, not in [0, 1.0] range", volume);
518
519         int ret = sound_pool_set_volume(pools[idx], volume);
520
521         if (ret == SOUND_POOL_ERROR_NONE)
522                 _logger_log_info("sound_pool_set_global_volume(pool, %f) "
523                                 "returned %s value", volume, __stringify_sound_pool_error(ret));
524         else
525                 _logger_log_err("sound_pool_set_global_volume(pool, %f) "
526                                 "returned %s value", volume, __stringify_sound_pool_error(ret));
527
528         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
529 }
530
531 /* CMD_GET_POOL_VOLUME */
532 static int __proxy_sound_pool_get_volume(const char *pars)
533 {
534         size_t idx = 0;
535         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
536                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool "
537                                 "to get volume for, after command name! Format: "
538                                 CMD_GET_POOL_VOLUME " <id>\n");
539                 return FAIL;
540         }
541
542         if (idx > (MAX_POOL_CNT - 1)) {
543                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
544                                 MAX_POOL_CNT - 1);
545                 return FAIL;
546         }
547
548         _logger_log_info(CMD_GET_POOL_VOLUME " command was called");
549         _logger_log_info("Getting the pool global volume for pool with %zu "
550                         "identifier...", idx);
551
552         if (pools[idx] == NULL)
553                 _logger_log_warn("Pool to get state for is NULL");
554
555         float volume = .0f;
556         int ret = sound_pool_get_volume(pools[idx], &volume);
557
558         if (ret == SOUND_POOL_ERROR_NONE)
559                 _logger_log_info("sound_pool_get_global_volume(pool, volume) returned "
560                                 "%s value, volume is %f", __stringify_sound_pool_error(ret),
561                                 volume);
562         else
563                 _logger_log_err("sound_pool_get_global_volume(pool, volume) returned "
564                                 "%s value, volume is %f", __stringify_sound_pool_error(ret),
565                                 volume);
566
567         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
568 }
569
570 /* CMD_SET_POOL_CB_MSG */
571 static int __proxy_sound_pool_set_state_change_callback_message(const char *pars)
572 {
573         size_t idx = 0;
574
575         char msg[MAX_MSG_LEN] = { '\0' };
576
577         if ((pars == NULL) || (sscanf(pars, " %zu %"MAX_MSG_LEN_STR"[^ ]", &idx, msg) < 2)) {
578                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
579                                 "pool and message to be shown each time when state of the pool "
580                                 " is changed! Message should be a single word. Format: "
581                                 CMD_SET_POOL_CB_MSG " <id> <message>\n");
582                 return FAIL;
583         }
584
585         if (idx > (MAX_POOL_CNT - 1)) {
586                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
587                                 MAX_POOL_CNT - 1);
588                 return FAIL;
589         }
590
591         _logger_log_info(CMD_SET_POOL_CB_MSG " command was called");
592         _logger_log_info("Set state changing callback (%s message) for pool with "
593                         "%zu identifier...", msg, idx);
594
595         if (pools[idx] == NULL)
596                 _logger_log_warn("Pool to set callback for is NULL");
597
598         if (messages[idx])
599                 free(messages[idx]);
600         messages[idx] = strndup(msg, MAX_MSG_LEN);
601
602         int ret = sound_pool_set_state_change_callback(pools[idx], __sp_cb_msg,
603                         messages[idx]);
604
605         if (ret == SOUND_POOL_ERROR_NONE)
606                 _logger_log_info("sound_pool_set_state_change_callback(pool, cb, "
607                                 "\"%s\") returned %s value", msg, __stringify_sound_pool_error(ret));
608         else
609                 _logger_log_err("sound_pool_set_state_change_callback(pool, cb, "
610                                 "\"%s\") returned %s value", msg, __stringify_sound_pool_error(ret));
611
612         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
613 }
614
615 /* CMD_SET_POOL_CB_SCRIPT */
616 static int __proxy_sound_pool_set_state_change_callback_script(const char *pars)
617 {
618         size_t idx = 0;
619
620         char scr[MAX_MSG_LEN] = { '\0' };
621
622         if ((pars == NULL) || (sscanf(pars, " %zu %"MAX_MSG_LEN_STR"[^ ]", &idx, scr) < 2)) {
623                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
624                                 "pool and script file name to be executed each time when state "
625                                 "of the pool will be changed! Format: "
626                                 CMD_SET_POOL_CB_SCRIPT " <id> <script file>\n");
627                 return FAIL;
628         }
629
630         if (idx > (MAX_POOL_CNT - 1)) {
631                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
632                                 MAX_POOL_CNT - 1);
633                 return FAIL;
634         }
635
636         _logger_log_info(CMD_SET_POOL_CB_SCRIPT " command was called");
637         _logger_log_info("Set state changing callback (%s script) for pool with "
638                         "%zu identifier...", scr, idx);
639
640         if (pools[idx] == NULL)
641                 _logger_log_warn("Pool to set callback for is NULL");
642
643         if (scripts[idx])
644                 free(scripts[idx]);
645         scripts[idx] = strndup(scr, MAX_MSG_LEN);
646
647         int ret = sound_pool_set_state_change_callback(pools[idx], __sp_cb_scr,
648                         scripts[idx]);
649
650         if (ret == SOUND_POOL_ERROR_NONE)
651                 _logger_log_info("sound_pool_set_state_change_callback(pool, cb, "
652                                 "\"%s\") returned %s value", scr, __stringify_sound_pool_error(ret));
653         else
654                 _logger_log_err("sound_pool_set_state_change_callback(pool, cb, "
655                                 "\"%s\") returned %s value", scr, __stringify_sound_pool_error(ret));
656
657         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
658 }
659
660 /* CMD_UNSET_POOL_CB */
661 static int __proxy_sound_pool_unset_state_change_callback(const char *pars)
662 {
663         size_t idx = 0;
664         if ((pars == NULL) || (sscanf(pars, " %zu", &idx) < 1)) {
665                 _printf(CMD_COLOR_RED, "You have to specify identifier of the pool! "
666                                 "Format: " CMD_UNSET_POOL_CB " <id>\n");
667                 return FAIL;
668         }
669
670         if (idx > (MAX_POOL_CNT - 1)) {
671                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
672                                 MAX_POOL_CNT - 1);
673                 return FAIL;
674         }
675
676         _logger_log_info(CMD_UNSET_POOL_CB " command was called");
677         _logger_log_info("Unset state changing callback for pool with "
678                         "%zu identifier...", idx);
679
680         if (pools[idx] == NULL)
681                 _logger_log_warn("Pool to unset callback for is NULL");
682
683         int ret = sound_pool_unset_state_change_callback(pools[idx]);
684
685         if (messages[idx] != NULL)
686                 free(messages[idx]);
687         messages[idx] = NULL;
688
689         if (scripts[idx] != NULL)
690                 free(scripts[idx]);
691         scripts[idx] = NULL;
692
693         if (ret == SOUND_POOL_ERROR_NONE)
694                 _logger_log_info("sound_pool_unset_state_change_callback(pool) "
695                                 "returned %s value", __stringify_sound_pool_error(ret));
696         else
697                 _logger_log_err("sound_pool_unset_state_change_callback(pool) "
698                                 "returned %s value", __stringify_sound_pool_error(ret));
699
700         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
701 }
702
703 /* CMD_LIST_POOL */
704 static int __proxy_sound_pool_list()
705 {
706         _logger_log_info("Getting the pool identifiers...");
707
708         const size_t buffer_size = 1024;
709         char buffer[buffer_size];
710         buffer[0] = '\0';
711
712         size_t idx = 0;
713         size_t len = 0;
714         while (idx < MAX_POOL_CNT) {
715                 len = strnlen(buffer, buffer_size);
716                 if (pools[idx++] != NULL) {
717                         size_t add_len = 1;
718                         size_t id = idx - 1;
719                         do
720                                 add_len++;
721                         while ((id = id / 10) > 0);
722                         id = idx - 1;
723                         if (len + add_len + 1 > buffer_size)
724                                 break;
725                         snprintf(buffer + len, buffer_size, "%zu ", id);
726                 }
727         }
728
729         _printf(CMD_COLOR_GREEN, "Pools identifiers: %s\n", buffer);
730         _logger_log_info("Pools identifiers: %s", buffer);
731
732         _logger_log_info("Pool identifiers were retrieved...");
733
734         return OK;
735 }
736
737 /* CMD_LOAD_SOURCE */
738 static int __proxy_sound_pool_load_source_from_file(const char *pars)
739 {
740         size_t idx = 0;
741
742         char fname[MAX_PATH_LEN] = {'\0'};
743         char tag[MAX_PATH_LEN] = {'\0'};
744
745         if ((pars == NULL) || sscanf(pars, " %zu %"MAX_PATH_LEN_STR"[^ ] "
746                         "%"MAX_PATH_LEN_STR"[^ ]", &idx, fname, tag) < 2) {
747                 _printf(CMD_COLOR_RED, "You have to specify at least pool identifier and "
748                                 "file name to be loaded! Format: " CMD_LOAD_SOURCE " <pool id> "
749                                 "<file name> <source tag>\n");
750                 return FAIL;
751         }
752
753         if (idx > (MAX_POOL_CNT - 1)) {
754                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
755                                 MAX_POOL_CNT - 1);
756                 return FAIL;
757         }
758
759         if (pools[idx] == NULL)
760                 _logger_log_warn("Pool with specified identifier is NULL");
761
762         /* If tag wasn't specified by the user, we will use file path as a tag */
763         if (tag[0] == '\0')
764                 strncpy(tag, fname, MAX_PATH_LEN);
765
766         _logger_log_info(CMD_LOAD_SOURCE " command was called");
767         _logger_log_info("Loading source to the pool with %zu identifier from %s file. "
768                         "Tag '%s' will be assigned for the loaded source...", idx, fname, tag);
769
770         int ret = sound_pool_load_source_from_file(pools[idx], fname, tag);
771
772         if (ret == SOUND_POOL_ERROR_NONE)
773                 _logger_log_info("sound_pool_load_source_from_file(pool, \"%s\", "
774                                 "\"%s\") returned %s value", fname, tag,
775                                 __stringify_sound_pool_error(ret));
776         else
777                 _logger_log_err("sound_pool_load_source_from_file(pool, \"%s\", "
778                                 "\"%s\") returned %s value", fname, tag,
779                                 __stringify_sound_pool_error(ret));
780
781         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
782 }
783
784 /* CMD_UNLOAD_SOURCE */
785 static int __proxy_sound_pool_unload_source(const char *pars)
786 {
787         size_t idx = 0;
788
789         char tag[MAX_PATH_LEN] = {'\0'};
790
791         if ((pars == NULL) || sscanf(pars, " %zu %"MAX_PATH_LEN_STR"[^ ]", &idx, tag) < 2) {
792                 _printf(CMD_COLOR_RED, "You have to specify both pool identifier and "
793                                 "source tag to be unloaded! Format: " CMD_UNLOAD_SOURCE
794                                 " <pool id> <source tag>\n");
795                 return FAIL;
796         }
797
798         if (idx > (MAX_POOL_CNT - 1)) {
799                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
800                                 MAX_POOL_CNT - 1);
801                 return FAIL;
802         }
803
804         if (pools[idx] == NULL)
805                 _logger_log_warn("Pool with specified identifier is NULL");
806
807         _logger_log_info(CMD_UNLOAD_SOURCE " command was called");
808         _logger_log_info("Unloading source by '%s' tag from the pool with %zu "
809                         "identifier...", tag, idx);
810
811         int ret = sound_pool_unload_source(pools[idx], tag);
812
813         if (ret == SOUND_POOL_ERROR_NONE)
814                 _logger_log_info("sound_pool_unload_source(pool, \"%s\") returned "
815                                 "%s value", tag, __stringify_sound_pool_error(ret));
816         else
817                 _logger_log_err("sound_pool_unload_source(pool, \"%s\") returned "
818                                 "%s value", tag, __stringify_sound_pool_error(ret));
819
820         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
821 }
822
823 /* CMD_PLAY_STREAM */
824 static int __proxy_sound_pool_play_stream(const char *pars)
825 {
826         size_t idx = 0;
827         int loop = 0;
828         float volume = 1.0f;
829         int rank = 0;
830
831         char tag[MAX_PATH_LEN] = {'\0'};
832
833         if ((pars == NULL) || sscanf(pars, " %zu %"MAX_PATH_LEN_STR"[^ ] %i %f %i",
834                                              &idx, tag, &loop, &volume, &rank) < 2) {
835                 _printf(CMD_COLOR_RED, "You have to specify at least pool identifier and "
836                                 "source tag to be played in stream! Format: " CMD_PLAY_STREAM
837                                 " <pool id> <source tag> <loop> <volume> <priority rank>... \n");
838                 return FAIL;
839         }
840
841         if (idx > (MAX_POOL_CNT - 1)) {
842                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
843                                 MAX_POOL_CNT - 1);
844                 return FAIL;
845         }
846
847         if (pools[idx] == NULL)
848                 _logger_log_warn("Pool with specified identifier is NULL");
849
850         _logger_log_info(CMD_PLAY_STREAM " command was called");
851         _logger_log_info("Playing stream based on source with '%s' tag from the pool "
852                         "with %zu identifier...", tag, idx);
853
854         int stream_idx = 0;
855         int ret = sound_pool_stream_play(pools[idx], tag, loop, volume, rank, NULL,
856                         NULL, &stream_idx);
857
858         if (ret == SOUND_POOL_ERROR_NONE) {
859                 _logger_log_info("sound_pool_play_stream(pool, \"%s\", %i, %f, %i,"
860                                 " NULL, NULL, &stream_idx) returned %s value. "
861                                 "Generated identifier is %i", tag, loop, volume, rank,
862                                 __stringify_sound_pool_error(ret), stream_idx);
863                 _printf(CMD_COLOR_GREEN, "Generated stream identifier is %i\n", stream_idx);
864         } else {
865                 _logger_log_err("sound_pool_play_stream(pool, \"%s\", %i, %f, %i,"
866                                 " NULL, NULL, &stream_idx) returned %s value",
867                                 tag, loop, volume, rank, __stringify_sound_pool_error(ret));
868         }
869
870         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
871 }
872
873 /* CMD_PAUSE_STREAM */
874 static int __proxy_sound_pool_pause_stream(const char *pars)
875 {
876         size_t idx = 0;
877         size_t stream_idx = 0;
878
879         if ((pars == NULL) || (sscanf(pars, " %zu %i", &idx, &stream_idx) < 2)) {
880                 _printf(CMD_COLOR_RED, "You have to specify both pool identifier and "
881                                 "stream to be paused identifier! Format: " CMD_PAUSE_STREAM
882                                 " <pool id> <stream id>\n");
883                 return FAIL;
884         }
885
886         if (idx > (MAX_POOL_CNT - 1)) {
887                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
888                                 MAX_POOL_CNT - 1);
889                 return FAIL;
890         }
891
892         if (pools[idx] == NULL)
893                 _logger_log_warn("Pool with specified identifier is NULL");
894
895         _logger_log_info(CMD_PAUSE_STREAM " command was called");
896
897         int ret = sound_pool_stream_pause(pools[idx], stream_idx);
898
899         if (ret == SOUND_POOL_ERROR_NONE)
900                 _logger_log_info("sound_pool_pause_stream(pool, %i) returned %s "
901                                 "value", stream_idx, __stringify_sound_pool_error(ret));
902         else
903                 _logger_log_err("sound_pool_pause_stream(pool, %i) returned %s "
904                                 "value", stream_idx, __stringify_sound_pool_error(ret));
905
906         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
907 }
908
909 /* CMD_RESUME_STREAM */
910 static int __proxy_sound_pool_resume_stream(const char *pars)
911 {
912         size_t idx = 0;
913         size_t stream_idx = 0;
914
915         if ((pars == NULL) || (sscanf(pars, " %zu %i", &idx, &stream_idx) < 2)) {
916                 _printf(CMD_COLOR_RED, "You have to specify both pool identifier and "
917                                 "stream to be resumed identifier! Format: " CMD_RESUME_STREAM
918                                 " <pool id> <stream id>\n");
919                 return FAIL;
920         }
921
922         if (idx > (MAX_POOL_CNT - 1)) {
923                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
924                                 MAX_POOL_CNT - 1);
925                 return FAIL;
926         }
927
928         if (pools[idx] == NULL)
929                 _logger_log_warn("Pool with specified identifier is NULL");
930
931         _logger_log_info(CMD_RESUME_STREAM " command was called");
932
933         int ret = sound_pool_stream_resume(pools[idx], stream_idx);
934
935         if (ret == SOUND_POOL_ERROR_NONE)
936                 _logger_log_info("sound_pool_resume_stream(pool, %i) returned %s "
937                                 "value", stream_idx, __stringify_sound_pool_error(ret));
938         else
939                 _logger_log_err("sound_pool_resume_stream(pool, %i) returned %s "
940                                 "value", stream_idx, __stringify_sound_pool_error(ret));
941
942         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
943 }
944
945 /* CMD_STOP_STREAM */
946 static int __proxy_sound_pool_stop_stream(const char *pars)
947 {
948         size_t idx = 0;
949         size_t stream_idx = 0;
950
951         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
952                 _printf(CMD_COLOR_RED, "You have to specify both pool identifier and "
953                                 "stream to be stopped identifier! Format: " CMD_STOP_STREAM
954                                 " <pool id> <stream id>\n");
955                 return FAIL;
956         }
957
958         if (idx > (MAX_POOL_CNT - 1)) {
959                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
960                                 MAX_POOL_CNT - 1);
961                 return FAIL;
962         }
963
964         if (pools[idx] == NULL)
965                 _logger_log_warn("Pool with specified identifier is NULL");
966
967         _logger_log_info(CMD_STOP_STREAM " command was called");
968
969         int ret = sound_pool_stream_stop(pools[idx], stream_idx);
970
971         if (ret == SOUND_POOL_ERROR_NONE)
972                 _logger_log_info("sound_pool_stop_stream(pool, %i) returned %s "
973                                 "value", stream_idx, __stringify_sound_pool_error(ret));
974         else
975                 _logger_log_err("sound_pool_stop_stream(pool, %i) returned %s "
976                                 "value", stream_idx, __stringify_sound_pool_error(ret));
977
978         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
979 }
980
981 /* CMD_SET_STREAM_VOLUME */
982 static int __proxy_sound_pool_stream_set_volume(const char *pars)
983 {
984         size_t idx = 0;
985         size_t stream_idx = 0;
986         float volume_val = 1.0f;
987
988         if ((pars == NULL)
989                         || (sscanf(pars, " %zu %zu %f", &idx, &stream_idx, &volume_val) < 3)) {
990                 _printf(CMD_COLOR_RED, "You have to specify all following parameters: "
991                                 "pool identifier, stream identifier! Format: "
992                                 CMD_SET_STREAM_VOLUME " <pool id> <stream id> <volume>\n");
993                 return FAIL;
994         }
995
996         if (idx > (MAX_POOL_CNT - 1)) {
997                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
998                                 MAX_POOL_CNT - 1);
999                 return FAIL;
1000         }
1001
1002         if (pools[idx] == NULL)
1003                 _logger_log_warn("Pool with specified identifier is NULL");
1004
1005         if (volume_val < .0f || volume_val > 1.0f)
1006                 _logger_log_warn("Volume has to be specified in 0.0~1.0 range");
1007
1008         _logger_log_info(CMD_SET_STREAM_VOLUME " command was called");
1009
1010         int ret = sound_pool_stream_set_volume(pools[idx], stream_idx, volume_val);
1011
1012         if (ret == SOUND_POOL_ERROR_NONE)
1013                 _logger_log_info("sound_pool_stream_set_volume(pool, %i, %f) "
1014                                 "returned %s value", stream_idx, volume_val,
1015                                 __stringify_sound_pool_error(ret));
1016         else
1017                 _logger_log_err("sound_pool_stream_set_volume(pool, %i, %f) "
1018                                 "returned %s value", stream_idx, volume_val,
1019                                 __stringify_sound_pool_error(ret));
1020
1021         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1022 }
1023
1024 /* CMD_GET_STREAM_VOLUME */
1025 static int __proxy_sound_pool_stream_get_volume(const char *pars)
1026 {
1027         size_t idx = 0;
1028         size_t stream_idx = 0;
1029         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
1030                 _printf(CMD_COLOR_RED, "You have to specify both pool and stream "
1031                                 "identifiers after command name! Format: "
1032                                 CMD_GET_STREAM_VOLUME " <pool id> <stream id>\n");
1033                 return FAIL;
1034         }
1035
1036         if (idx > (MAX_POOL_CNT - 1)) {
1037                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1038                                 MAX_POOL_CNT - 1);
1039                 return FAIL;
1040         }
1041
1042         _logger_log_info(CMD_GET_STREAM_VOLUME " command was called");
1043         _logger_log_info("Getting the %zu stream from %zu pool volume value...",
1044                         stream_idx, idx);
1045
1046         if (pools[idx] == NULL)
1047                 _logger_log_warn("Pool to get state for is NULL");
1048
1049         float volume = .0f;
1050         int ret = sound_pool_stream_get_volume(pools[idx], stream_idx, &volume);
1051
1052         if (ret == SOUND_POOL_ERROR_NONE)
1053                 _logger_log_info("sound_pool_stream_get_volume(pool, %zu, volume) "
1054                                 "returned %s value, volume is %f", stream_idx,
1055                                 __stringify_sound_pool_error(ret), volume);
1056         else
1057                 _logger_log_err("sound_pool_stream_get_volume(pool, %zu, volume) "
1058                                 "returned %s value, volume is %f", stream_idx,
1059                                 __stringify_sound_pool_error(ret), volume);
1060
1061         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1062 }
1063
1064 /* CMD_SET_STREAM_LOOP */
1065 static int __proxy_sound_pool_stream_set_loop(const char *pars)
1066 {
1067         size_t idx = 0;
1068         size_t stream_idx = 0;
1069         int loop_val = 1;
1070
1071         if ((pars == NULL)
1072                         || (sscanf(pars, " %zu %zu %i", &idx, &stream_idx, &loop_val) < 3)) {
1073                 _printf(CMD_COLOR_RED, "You have to specify all following parameters: "
1074                                 "pool identifier, stream identifier, and loop number! Format: "
1075                                 CMD_SET_STREAM_LOOP " <pool id> <stream id> <loop num>\n");
1076                 return FAIL;
1077         }
1078
1079         if (idx > (MAX_POOL_CNT - 1)) {
1080                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1081                                 MAX_POOL_CNT - 1);
1082                 return FAIL;
1083         }
1084
1085         if (pools[idx] == NULL)
1086                 _logger_log_warn("Pool with specified identifier is NULL");
1087
1088         if (loop_val < 0)
1089                 _logger_log_warn("Loop number should to be greater than 0, but it's"
1090                                 "value is %i", loop_val);
1091
1092         _logger_log_info(CMD_SET_STREAM_LOOP " command was called");
1093
1094         int ret = sound_pool_stream_set_loop(pools[idx], stream_idx, loop_val);
1095
1096         if (ret == SOUND_POOL_ERROR_NONE)
1097                 _logger_log_info("sound_pool_stream_set_loop(pool, %zu, %i) "
1098                                 "returned %s value", stream_idx, loop_val,
1099                                 __stringify_sound_pool_error(ret));
1100         else
1101                 _logger_log_err("sound_pool_stream_set_loop(pool, %zu, %i) "
1102                                 "returned %s value", stream_idx, loop_val,
1103                                 __stringify_sound_pool_error(ret));
1104
1105         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1106 }
1107
1108 /* CMD_GET_STREAM_LOOP */
1109 static int __proxy_sound_pool_stream_get_loop(const char *pars)
1110 {
1111         size_t idx = 0;
1112         size_t stream_idx = 0;
1113         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
1114                 _printf(CMD_COLOR_RED, "You have to specify both pool and stream "
1115                                 "identifiers after command name! Format: "
1116                                 CMD_GET_STREAM_LOOP " <pool id> <stream id>\n");
1117                 return FAIL;
1118         }
1119
1120         if (idx > (MAX_POOL_CNT - 1)) {
1121                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1122                                 MAX_POOL_CNT - 1);
1123                 return FAIL;
1124         }
1125
1126         _logger_log_info(CMD_GET_STREAM_LOOP " command was called");
1127         _logger_log_info("Getting the stream state by %zu identifier in %zu "
1128                         "pool...", stream_idx, idx);
1129
1130         if (pools[idx] == NULL)
1131                 _logger_log_warn("Pool where stream should be located is NULL");
1132
1133         unsigned loop = 0;
1134         int ret = sound_pool_stream_get_loop(pools[idx], stream_idx, &loop);
1135
1136         if (ret == SOUND_POOL_ERROR_NONE)
1137                 _logger_log_info("sound_pool_stream_get_loop(pool, %zu, loop) "
1138                                 "returned %s value, loop value is %i", stream_idx,
1139                                 __stringify_sound_pool_error(ret), loop);
1140         else
1141                 _logger_log_err("sound_pool_stream_get_loop(pool, %zu, loop) "
1142                                 "returned %s value, loop value is %i", stream_idx,
1143                                 __stringify_sound_pool_error(ret), loop);
1144
1145         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1146 }
1147
1148 /* CMD_SET_STREAM_PRIORITY */
1149 static int __proxy_sound_pool_stream_set_priority(const char *pars)
1150 {
1151         size_t idx = 0;
1152         size_t stream_idx = 0;
1153         int rank_val = 0;
1154
1155         if ((pars == NULL)
1156                         || (sscanf(pars, " %zu %zu %i", &idx, &stream_idx, &rank_val) < 3)) {
1157                 _printf(CMD_COLOR_RED, "You have to specify all following parameters: "
1158                                 "pool identifier, stream identifier, and priority rank! Format: "
1159                                 CMD_SET_STREAM_PRIORITY " <pool id> <stream id> <rank>\n");
1160                 return FAIL;
1161         }
1162
1163         if (idx > (MAX_POOL_CNT - 1)) {
1164                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1165                                 MAX_POOL_CNT - 1);
1166                 return FAIL;
1167         }
1168
1169         if (pools[idx] == NULL)
1170                 _logger_log_warn("Pool with specified identifier is NULL");
1171
1172         if (rank_val < 0)
1173                 _logger_log_warn("Priority rank should to be greater or equal 0, but "
1174                                 "it's value is %i", rank_val);
1175
1176         _logger_log_info(CMD_SET_STREAM_PRIORITY " command was called");
1177
1178         int ret = sound_pool_stream_set_priority(pools[idx], stream_idx, rank_val);
1179
1180         if (ret == SOUND_POOL_ERROR_NONE)
1181                 _logger_log_info("sound_pool_stream_set_priority(pool, %zu, %i) "
1182                                 "returned %s value", stream_idx, rank_val,
1183                                 __stringify_sound_pool_error(ret));
1184         else
1185                 _logger_log_err("sound_pool_stream_set_priority(pool, %zu, %i) "
1186                                 "returned %s value", stream_idx, rank_val,
1187                                 __stringify_sound_pool_error(ret));
1188
1189         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1190 }
1191
1192 /* CMD_GET_STREAM_PRIORITY */
1193 static int __proxy_sound_pool_stream_get_priority(const char *pars)
1194 {
1195         size_t idx = 0;
1196         size_t stream_idx = 0;
1197         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
1198                 _printf(CMD_COLOR_RED, "You have to specify both pool and stream "
1199                                 "identifiers after command name! Format: "
1200                                 CMD_GET_STREAM_PRIORITY " <pool id> <stream id>\n");
1201                 return FAIL;
1202         }
1203
1204         if (idx > (MAX_POOL_CNT - 1)) {
1205                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1206                                 MAX_POOL_CNT - 1);
1207                 return FAIL;
1208         }
1209
1210         _logger_log_info(CMD_GET_STREAM_PRIORITY " command was called");
1211         _logger_log_info("Getting the stream priority rank by %zu identifier in "
1212                         "%zu pool...", stream_idx, idx);
1213
1214         if (pools[idx] == NULL)
1215                 _logger_log_warn("Pool where stream should be located is NULL");
1216
1217         unsigned rank = 0;
1218         int ret = sound_pool_stream_get_priority(pools[idx], stream_idx, &rank);
1219
1220         if (ret == SOUND_POOL_ERROR_NONE)
1221                 _logger_log_info("sound_pool_stream_get_priority(pool, %zu, rank) "
1222                                 "returned %s value, rank value is %i", stream_idx,
1223                                 __stringify_sound_pool_error(ret), rank);
1224         else
1225                 _logger_log_err("sound_pool_stream_get_priority(pool, %zu, rank) "
1226                                 "returned %s value, rank value is %i", stream_idx,
1227                                 __stringify_sound_pool_error(ret), rank);
1228
1229         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1230 }
1231
1232 /* CMD_GET_STREAM_STATE */
1233 static int __proxy_sound_pool_get_stream_state(const char *pars)
1234 {
1235         size_t idx = 0;
1236         size_t stream_idx = 0;
1237         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
1238                 _printf(CMD_COLOR_RED, "You have to specify both pool and stream "
1239                                 "identifiers after command name! Format: "
1240                                 CMD_GET_STREAM_STATE " <pool id> <stream id>\n");
1241                 return FAIL;
1242         }
1243
1244         if (idx > (MAX_POOL_CNT - 1)) {
1245                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1246                                 MAX_POOL_CNT - 1);
1247                 return FAIL;
1248         }
1249
1250         _logger_log_info(CMD_GET_STREAM_STATE " command was called");
1251         _logger_log_info("Getting the stream state by %zu identifier in %zu "
1252                         "pool...", stream_idx, idx);
1253
1254         if (pools[idx] == NULL)
1255                 _logger_log_warn("Pool where stream should be located is NULL");
1256
1257         sound_pool_stream_state_e state = SOUND_POOL_STREAM_STATE_NONE;
1258         int ret = sound_pool_stream_get_state(pools[idx], stream_idx,  &state);
1259
1260         if (ret == SOUND_POOL_ERROR_NONE)
1261                 _logger_log_info("sound_pool_get_stream_state(pool, %zu, state) "
1262                                 "returned %s value, state is %s", stream_idx,
1263                                 __stringify_sound_pool_error(ret),
1264                                 __stringify_stream_state(state));
1265         else
1266                 _logger_log_err("sound_pool_get_stream_state(pool, %zu, state) "
1267                                 "returned %s value, state is %s", stream_idx,
1268                                 __stringify_sound_pool_error(ret),
1269                                 __stringify_stream_state(state));
1270
1271         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1272 }
1273
1274 /* CMD_SET_STREAM_CB_MSG */
1275 static int __proxy_sound_pool_set_stream_state_change_callback_message(const char *pars)
1276 {
1277         size_t idx = 0;
1278         size_t stream_idx = 0;
1279
1280         char msg[MAX_MSG_LEN] = { '\0' };
1281
1282         if ((pars == NULL) || sscanf(pars, " %zu %zu %"MAX_MSG_LEN_STR"[^ ]",
1283                                              &idx, &stream_idx, msg) < 3) {
1284                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
1285                                 "pool and stream, plus message to be shown each time when "
1286                                 "state of the stream is changed! Message should be a single "
1287                                 "word. Format: "
1288                                 CMD_SET_STREAM_CB_MSG " <pool id> <stream id> <message>\n");
1289                 return FAIL;
1290         }
1291
1292         if (idx > (MAX_POOL_CNT - 1)) {
1293                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1294                                 MAX_POOL_CNT - 1);
1295                 return FAIL;
1296         }
1297
1298         if (stream_idx > (MAX_STREAM_CNT - 1)) {
1299                 _printf(CMD_COLOR_RED, "Stream identifier value can't be greater than %d\n",
1300                                 MAX_STREAM_CNT - 1);
1301                 return FAIL;
1302         }
1303
1304         _logger_log_info(CMD_SET_STREAM_CB_MSG " command was called");
1305         _logger_log_info("Set state changing callback (%s message) for stream %zu "
1306                         "in pool with %zu identifier...", msg, stream_idx, idx);
1307
1308         if (pools[idx] == NULL)
1309                 _logger_log_warn("Pool with stream to set callback for is NULL");
1310
1311         if (stream_messages[idx][stream_idx])
1312                 free(stream_messages[idx][stream_idx]);
1313         stream_messages[idx][stream_idx] = strndup(msg, MAX_MSG_LEN);
1314
1315         int ret = sound_pool_stream_set_state_change_callback(pools[idx], stream_idx,
1316                         __s_cb_msg, stream_messages[idx][stream_idx]);
1317
1318         if (ret == SOUND_POOL_ERROR_NONE)
1319                 _logger_log_info("sound_pool_set_stream_state_change_callback(pool, "
1320                                 "%zu, cb, \"%s\") returned %s value", stream_idx, msg,
1321                                 __stringify_sound_pool_error(ret));
1322         else
1323                 _logger_log_err("sound_pool_set_stream_state_change_callback(pool, "
1324                                 "%zu, cb, \"%s\") returned %s value", stream_idx, msg,
1325                                 __stringify_sound_pool_error(ret));
1326
1327         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1328 }
1329
1330 /* CMD_SET_STREAM_CB_SCRIPT */
1331 static int __proxy_sound_pool_set_stream_state_change_callback_script(const char *pars)
1332 {
1333         size_t idx = 0;
1334         size_t stream_idx = 0;
1335
1336         char scr[MAX_MSG_LEN] = { '\0' };
1337
1338         if ((pars == NULL) || sscanf(pars, " %zu %zu %"MAX_MSG_LEN_STR"[^ ]",
1339                                                  &idx, &stream_idx, scr) < 3) {
1340                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
1341                                 "pool and stream, plus file with script to be executed each "
1342                                 "time when state of the stream is changed! Message should be a "
1343                                 "single word. Format: " CMD_SET_STREAM_CB_SCRIPT
1344                                 " <pool id> <stream id> <script file>\n");
1345                 return FAIL;
1346         }
1347
1348         if (idx > (MAX_POOL_CNT - 1)) {
1349                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1350                                 MAX_POOL_CNT - 1);
1351                 return FAIL;
1352         }
1353
1354         if (stream_idx > (MAX_STREAM_CNT - 1)) {
1355                 _printf(CMD_COLOR_RED, "Stream identifier value can't be greater than %d\n",
1356                                 MAX_STREAM_CNT - 1);
1357                 return FAIL;
1358         }
1359
1360         _logger_log_info(CMD_SET_STREAM_CB_SCRIPT " command was called");
1361         _logger_log_info("Set state changing callback (%s script) for stream %zu "
1362                         "in pool with %zu identifier...", scr, stream_idx, idx);
1363
1364         if (pools[idx] == NULL)
1365                 _logger_log_warn("Pool with stream to set callback for is NULL");
1366
1367         if (stream_scripts[idx][stream_idx])
1368                 free(stream_scripts[idx][stream_idx]);
1369         stream_scripts[idx][stream_idx] = strndup(scr, MAX_MSG_LEN);
1370
1371         int ret = sound_pool_stream_set_state_change_callback(pools[idx], stream_idx,
1372                         __s_cb_scr, stream_scripts[idx][stream_idx]);
1373
1374         if (ret == SOUND_POOL_ERROR_NONE)
1375                 _logger_log_info("sound_pool_set_stream_state_change_callback(pool, "
1376                                 "%zu, cb, \"%s\") returned %s value", stream_idx, scr,
1377                                 __stringify_sound_pool_error(ret));
1378         else
1379                 _logger_log_err("sound_pool_set_stream_state_change_callback(pool, "
1380                                 "%zu, cb, \"%s\") returned %s value", stream_idx, scr,
1381                                 __stringify_sound_pool_error(ret));
1382
1383         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1384 }
1385
1386 /* CMD_UNSET_STREAM_CB */
1387 static int __proxy_sound_pool_unset_stream_state_change_callback(const char *pars)
1388 {
1389         size_t idx = 0;
1390         size_t stream_idx = 0;
1391         if ((pars == NULL) || (sscanf(pars, " %zu %zu", &idx, &stream_idx) < 2)) {
1392                 _printf(CMD_COLOR_RED, "You have to specify both identifier of the "
1393                                 " pool and stream! Format: " CMD_UNSET_STREAM_CB
1394                                 " <pool id> <stream id>\n");
1395                 return FAIL;
1396         }
1397
1398         if (idx > (MAX_POOL_CNT - 1)) {
1399                 _printf(CMD_COLOR_RED, "Pool identifier value can't be greater than %d\n",
1400                                 MAX_POOL_CNT - 1);
1401                 return FAIL;
1402         }
1403
1404         _logger_log_info(CMD_UNSET_STREAM_CB " command was called");
1405         _logger_log_info("Unset state changing callback for the stream %zu in pool "
1406                         "with %zu identifier...", stream_idx, idx);
1407
1408         if (pools[idx] == NULL)
1409                 _logger_log_warn("Pool to unset callback for is NULL");
1410
1411         int ret = sound_pool_stream_unset_state_change_callback(pools[idx], stream_idx);
1412
1413         if (stream_idx > (MAX_STREAM_CNT - 1)) {
1414                 _printf(CMD_COLOR_RED, "Stream identifier value can't be greater than %d\n",
1415                                 MAX_STREAM_CNT - 1);
1416                 return FAIL;
1417         }
1418
1419         if (stream_messages[idx][stream_idx] != NULL)
1420                 free(stream_messages[idx][stream_idx]);
1421         stream_messages[idx][stream_idx] = NULL;
1422
1423         if (stream_scripts[idx][stream_idx] != NULL)
1424                 free(stream_scripts[idx][stream_idx]);
1425         stream_scripts[idx][stream_idx] = NULL;
1426
1427         if (ret == SOUND_POOL_ERROR_NONE)
1428                 _logger_log_info("sound_pool_unset_stream_state_change_callback(pool, "
1429                                 "%zu) returned %s value", stream_idx,
1430                                 __stringify_sound_pool_error(ret));
1431         else
1432                 _logger_log_info("sound_pool_unset_stream_state_change_callback(pool, "
1433                                 "%zu) returned %s value", stream_idx,
1434                                 __stringify_sound_pool_error(ret));
1435
1436         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1437 }
1438
1439 /* CMD_SLEEP */
1440 static int __proxy_sleep(const char *pars)
1441 {
1442         int ret = SOUND_POOL_ERROR_NONE;
1443
1444         useconds_t stime = 0;
1445
1446         if ((pars == NULL) || (sscanf(pars, " %u", &stime) < 1)) {
1447                 _printf(CMD_COLOR_RED, "You have to specify number of milliseconds "
1448                                 "for the pause duration! Format: " CMD_SLEEP " <millisecs>\n");
1449                 return FAIL;
1450         }
1451
1452         _logger_log_info(CMD_SLEEP " command was called");
1453         _logger_log_info("Start main thread sleep for %u milliseconds...", stime);
1454         stime *= MICROSECS_PER_MILLISEC;
1455         usleep(stime);
1456         _logger_log_info("Main thread sleep has been finished...", stime);
1457
1458         return (ret == SOUND_POOL_ERROR_NONE ? OK : FAIL);
1459 }
1460
1461 /* CMD_EXECUTE_SCRIPT */
1462 static int __proxy_sound_pool_execute_script(const char *pars)
1463 {
1464         char script_file[MAX_PATH_LEN] = {'\0'};
1465
1466         if ((pars == NULL) || (sscanf(pars, " %"MAX_PATH_LEN_STR"[^ ]", script_file) < 1)) {
1467                 _printf(CMD_COLOR_RED, "You have to specify script file name to be "
1468                                 "executed after command name! Format: " CMD_EXECUTE_SCRIPT " "
1469                                 "<script file>\n");
1470                 return FAIL;
1471         }
1472
1473         _logger_log_info(CMD_EXECUTE_SCRIPT " command was called");
1474         _logger_log_info("Loading script from file...");
1475         FILE *fd = fopen(script_file, "r");
1476
1477         if (fd) {
1478                 _logger_log_info("File has been loaded...");
1479                 _logger_log_info("Reading lines...");
1480                 size_t line_len = 0;
1481                 char *line = NULL;
1482                 while ((line_len = getline(&line, &line_len, fd)) != -1) {
1483                         line[strnlen(line, MAX_COMMAND_LINE_LEN) - 1] = '\0';
1484                         _logger_log_info("Executing line: %s", line);
1485                         if (_exec_cmd(line) != OK)
1486                                 _logger_log_warn("Unknown or unsupported command! "
1487                                                 "Line was skipped.");
1488                 }
1489                 _logger_log_info("Lines were read...");
1490         } else {
1491                 _logger_log_err("File wasn't loaded...");
1492                 return FAIL;
1493         }
1494
1495         _logger_log_info("Close file...");
1496
1497         if (fd)
1498                 fclose(fd);
1499
1500         return OK;
1501 }
1502
1503 /* Number of parameters supported by each command */
1504 static int cmd_pars[MAX_COMMAND_LINE_LEN] = { /* CMD_EXIT */ 0,
1505                 /* CMD_HELP */ 0, /* CMD_CREATE_POOL */ 1, /* CMD_DESTROY_POOL */ 1,
1506                 /* CMD_ACTIVATE_POOL */ 1, /* CMD_DEACTIVATE_POOL */ 1,
1507                 /* CMD_GET_POOL_STATE */ 1, /* CMD_SET_POOL_VOLUME */ 2,
1508                 /* CMD_GET_POOL_VOLUME */ 2, /* CMD_SET_POOL_CB_MSG */ 2,
1509                 /* CMD_SET_POOL_CB_SCRIPT */ 2, /* CMD_UNSET_POOL_CB */ 1,
1510                 /* CMD_LIST_POOL */ 0, /* CMD_LOAD_SOURCE */ 3,
1511                 /* CMD_LOAD_MEDIA_PACKAGE */ 3, /* CMD_UNLOAD_SOURCE */ 2,
1512                 /* CMD_PLAY_STREAM */ 5, /* CMD_STOP_STREAM */ 2,
1513                 /* CMD_PAUSE_STREAM */ 2, /* CMD_RESUME_STREAM */ 2,
1514                 /* CMD_SET_STREAM_VOLUME */ 3, /* CMD_GET_STREAM_VOLUME */ 2,
1515                 /* CMD_SET_STREAM_LOOP */ 3, /* CMD_GET_STREAM_LOOP */ 2,
1516                 /* CMD_SET_STREAM_PRIORITY */ 3, /* CMD_GET_STREAM_PRIORITY */ 2,
1517                 /* CMD_GET_STREAM_STATE */ 2, /* CMD_SET_STREAM_CB_MSG */ 3,
1518                 /* CMD_SET_STREAM_CB_SCRIPT */ 3, /* CMD_UNSET_STREAM_CB */ 2,
1519                 /* CMD_EXECUTE_SCRIPT */ 1, /* CMD_SLEEP */ 1 };
1520
1521 /* Command -> Function mapping */
1522 static int (*cmd_fcns[MAX_COMMAND_LINE_LEN])() = {
1523                 /* CMD_EXIT */ __exit,
1524                 /* CMD_HELP */ __print_cmd_help_msg,
1525                 /* CMD_CREATE_POOL */ __proxy_sound_pool_create,
1526                 /* CMD_DESTROY_POOL */ __proxy_sound_pool_destroy,
1527                 /* CMD_ACTIVATE_POOL */ __proxy_sound_pool_activate,
1528                 /* CMD_DEACTIVATE_POOL */ __proxy_sound_pool_deactivate,
1529                 /* CMD_GET_POOL_STATE */ __proxy_sound_pool_get_state,
1530                 /* CMD_SET_POOL_VOLUME */ __proxy_sound_pool_set_volume,
1531                 /* CMD_GET_POOL_VOLUME */ __proxy_sound_pool_get_volume,
1532                 /* CMD_SET_POOL_CB_MSG */ __proxy_sound_pool_set_state_change_callback_message,
1533                 /* CMD_SET_POOL_CB_SCRIPT */ __proxy_sound_pool_set_state_change_callback_script,
1534                 /* CMD_UNSET_POOL_CB */ __proxy_sound_pool_unset_state_change_callback,
1535                 /* CMD_LIST_POOL */ __proxy_sound_pool_list,
1536                 /* CMD_LOAD_SOURCE */ __proxy_sound_pool_load_source_from_file,
1537                 /* CMD_LOAD_MEDIA_PACKAGE */ NULL,
1538                 /* CMD_UNLOAD_SOURCE */ __proxy_sound_pool_unload_source,
1539                 /* CMD_PLAY_STREAM */ __proxy_sound_pool_play_stream,
1540                 /* CMD_STOP_STREAM */ __proxy_sound_pool_stop_stream,
1541                 /* CMD_PAUSE_STREAM */ __proxy_sound_pool_pause_stream,
1542                 /* CMD_RESUME_STREAM */ __proxy_sound_pool_resume_stream,
1543                 /* CMD_SET_STREAM_VOLUME */ __proxy_sound_pool_stream_set_volume,
1544                 /* CMD_GET_STREAM_VOLUME */ __proxy_sound_pool_stream_get_volume,
1545                 /* CMD_SET_STREAM_LOOP */ __proxy_sound_pool_stream_set_loop,
1546                 /* CMD_GET_STREAM_LOOP */ __proxy_sound_pool_stream_get_loop,
1547                 /* CMD_SET_STREAM_PRIORITY */ __proxy_sound_pool_stream_set_priority,
1548                 /* CMD_GET_STREAM_PRIORITY */ __proxy_sound_pool_stream_get_priority,
1549                 /* CMD_GET_STREAM_STATE */ __proxy_sound_pool_get_stream_state,
1550                 /* CMD_SET_STREAM_CB_MSG */ __proxy_sound_pool_set_stream_state_change_callback_message,
1551                 /* CMD_SET_STREAM_CB_SCRIPT */ __proxy_sound_pool_set_stream_state_change_callback_script,
1552                 /* CMD_UNSET_STREAM_CB */ __proxy_sound_pool_unset_stream_state_change_callback,
1553                 /* CMD_EXECUTE_SCRIPT */ __proxy_sound_pool_execute_script,
1554                 /* CMD_SLEEP */ __proxy_sleep };
1555
1556 int _exec_cmd(const char *cmd_line)
1557 {
1558         /* User just pressed enter: */
1559         if (strlen(cmd_line) == 0) return OK;
1560
1561         size_t trim_len = 0;
1562         while((cmd_line + trim_len)[0] == ' ')
1563                 trim_len++;
1564
1565         char *cmd = cmd_line + trim_len;
1566
1567         /* Macro for checking command correctness */
1568 #   define CHECK_CMD(ccmd, line) \
1569                         (strncmp(ccmd, line, strnlen(ccmd, MAX_COMMAND_LINE_LEN)) == 0)
1570
1571         int idx = 0;
1572         for (; idx < CMD_COUNT; ++idx) {
1573                 if (CHECK_CMD(cmd_list[idx], cmd)) {
1574                         if (cmd_pars[idx] > 0) {
1575                                 if (cmd_fcns[idx])
1576                                         return cmd_fcns[idx](cmd + strlen(cmd_list[idx]));
1577                         } else {
1578                                 return cmd_fcns[idx]();
1579                         }
1580                 }
1581         }
1582
1583         return UCMD;
1584 }