1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 /*
7 * Basic playback flow:
8 * cras_client_create - Create new structure and set to defaults.
9 * cras_client_connect - Connect client to server - sets up server_fd to
10 * communicate with the audio server. After the client connects, the server
11 * will send back a message containing the client id.
12 * cras_client_add_stream - Add a playback or capture stream. Creates a
13 * client_stream struct and send a file descriptor to server. That file
14 * descriptor and aud_fd are a pair created from socketpair().
15 * client_connected - The server will send a connected message to indicate that
16 * the client should start receving audio events from aud_fd. This message
17 * also specifies the shared memory region to use to share audio samples.
18 * This region will be shmat'd.
19 * running - Once the connections are established, the client will listen for
20 * requests on aud_fd and fill the shm region with the requested number of
21 * samples. This happens in the aud_cb specified in the stream parameters.
22 */
23
24 #ifndef _GNU_SOURCE
25 #define _GNU_SOURCE /* For ppoll() */
26 #endif
27
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <limits.h>
31 #include <poll.h>
32 #include <pthread.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <sys/eventfd.h>
36 #include <sys/ipc.h>
37 #include <sys/mman.h>
38 #include <sys/param.h>
39 #include <sys/signal.h>
40 #include <sys/socket.h>
41 #include <sys/timerfd.h>
42 #include <sys/types.h>
43 #include <sys/un.h>
44 #include <syslog.h>
45 #include <unistd.h>
46
47 #include "cras_client.h"
48 #include "cras_config.h"
49 #include "cras_file_wait.h"
50 #include "cras_messages.h"
51 #include "cras_observer_ops.h"
52 #include "cras_shm.h"
53 #include "cras_types.h"
54 #include "cras_util.h"
55 #include "utlist.h"
56
57 static const size_t MAX_CMD_MSG_LEN = 256;
58 static const size_t SERVER_SHUTDOWN_TIMEOUT_US = 500000;
59 static const size_t SERVER_CONNECT_TIMEOUT_MS = 1000;
60 static const size_t HOTWORD_FRAME_RATE = 16000;
61 static const size_t HOTWORD_BLOCK_SIZE = 320;
62
63 /* Commands sent from the user to the running client. */
64 enum {
65 CLIENT_STOP,
66 CLIENT_ADD_STREAM,
67 CLIENT_REMOVE_STREAM,
68 CLIENT_SET_STREAM_VOLUME_SCALER,
69 CLIENT_SERVER_CONNECT,
70 CLIENT_SERVER_CONNECT_ASYNC,
71 };
72
73 struct command_msg {
74 unsigned len;
75 unsigned msg_id;
76 cras_stream_id_t stream_id;
77 };
78
79 struct set_stream_volume_command_message {
80 struct command_msg header;
81 float volume_scaler;
82 };
83
84 /* Adds a stream to the client.
85 * stream - The stream to add.
86 * stream_id_out - Filled with the stream id of the new stream.
87 * dev_idx - Index of the device to attach the newly created stream.
88 * NO_DEVICE means not to pin the stream to a device.
89 */
90 struct add_stream_command_message {
91 struct command_msg header;
92 struct client_stream *stream;
93 cras_stream_id_t *stream_id_out;
94 uint32_t dev_idx;
95 };
96
97 /* Commands send from a running stream to the client. */
98 enum {
99 CLIENT_STREAM_EOF,
100 };
101
102 struct stream_msg {
103 unsigned msg_id;
104 cras_stream_id_t stream_id;
105 };
106
107 enum CRAS_THREAD_STATE {
108 CRAS_THREAD_STOP, /* Isn't (shouldn't be) running. */
109 CRAS_THREAD_WARMUP, /* Is started, but not fully functional: waiting
110 * for resources to be ready for example. */
111 CRAS_THREAD_RUNNING, /* Is running and fully functional. */
112 };
113
114 /* Manage information for a thread. */
115 struct thread_state {
116 pthread_t tid;
117 enum CRAS_THREAD_STATE state;
118 };
119
120 /* Parameters used when setting up a capture or playback stream. See comment
121 * above cras_client_create_stream_params in the header for descriptions. */
122 struct cras_stream_params {
123 enum CRAS_STREAM_DIRECTION direction;
124 size_t buffer_frames;
125 size_t cb_threshold;
126 enum CRAS_STREAM_TYPE stream_type;
127 uint32_t flags;
128 uint64_t effects;
129 void *user_data;
130 cras_playback_cb_t aud_cb;
131 cras_unified_cb_t unified_cb;
132 cras_error_cb_t err_cb;
133 struct cras_audio_format format;
134 };
135
136 /* Represents an attached audio stream.
137 * id - Unique stream identifier.
138 * aud_fd - After server connects audio messages come in here.
139 * direction - playback, capture, both, or loopback (see CRAS_STREAM_DIRECTION).
140 * flags - Currently not used.
141 * volume_scaler - Amount to scale the stream by, 0.0 to 1.0.
142 * tid - Thread id of the audio thread spawned for this stream.
143 * running - Audio thread runs while this is non-zero.
144 * wake_fds - Pipe to wake the audio thread.
145 * client - The client this stream is attached to.
146 * config - Audio stream configuration.
147 * capture_shm - Shared memory used to exchange audio samples with the server.
148 * play_shm - Shared memory used to exchange audio samples with the server.
149 * prev, next - Form a linked list of streams attached to a client.
150 */
151 struct client_stream {
152 cras_stream_id_t id;
153 int aud_fd; /* audio messages from server come in here. */
154 enum CRAS_STREAM_DIRECTION direction;
155 uint32_t flags;
156 float volume_scaler;
157 struct thread_state thread;
158 int wake_fds[2]; /* Pipe to wake the thread */
159 struct cras_client *client;
160 struct cras_stream_params *config;
161 struct cras_audio_shm capture_shm;
162 int capture_shm_size;
163 struct cras_audio_shm play_shm;
164 int play_shm_size;
165 struct client_stream *prev, *next;
166 };
167
168 /* State of the socket. */
169 typedef enum cras_socket_state {
170 CRAS_SOCKET_STATE_DISCONNECTED,
171 /* Not connected. Also used to cleanup the current connection
172 * before restarting the connection attempt. */
173 CRAS_SOCKET_STATE_WAIT_FOR_SOCKET,
174 /* Waiting for the socket file to exist. Socket file existence
175 * is monitored using cras_file_wait. */
176 CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE,
177 /* Waiting for the socket to have something at the other end. */
178 CRAS_SOCKET_STATE_FIRST_MESSAGE,
179 /* Waiting for the first messages from the server and set our
180 * client ID. */
181 CRAS_SOCKET_STATE_CONNECTED,
182 /* The socket is connected and working. */
183 CRAS_SOCKET_STATE_ERROR_DELAY,
184 /* There was an error during one of the above states. Sleep for
185 * a bit before continuing. If this state could not be initiated
186 * then we move to the DISCONNECTED state and notify via the
187 * connection callback. */
188 } cras_socket_state_t;
189
190 /* Represents a client used to communicate with the audio server.
191 * id - Unique identifier for this client, negative until connected.
192 * server_fd - Incoming messages from server.
193 * server_fd_state - State of the server's socket.
194 * server_event_fd - Eventfd to wait on until a connection is established.
195 * stream_fds - Pipe for attached streams.
196 * command_fds - Pipe for user commands to thread.
197 * command_reply_fds - Pipe for acking/nacking command messages from thread.
198 * sock_file - Server communication socket file.
199 * sock_file_wait - Structure used to monitor existence of the socket file.
200 * sock_file_exists - Set to true when the socket file exists.
201 * running - The client thread will run while this is non zero.
202 * next_stream_id - ID to give the next stream.
203 * stream_start_cond - Condition used during stream startup.
204 * stream_start_lock - Lock used during stream startup.
205 * tid - Thread ID of the client thread started by "cras_client_run_thread".
206 * last_command_result - Passes back the result of the last user command.
207 * streams - Linked list of streams attached to this client.
208 * server_state - RO shared memory region holding server state.
209 * debug_info_callback - Function to call when debug info is received.
210 * get_hotword_models_cb_t - Function to call when hotword models info is ready.
211 * server_err_cb - Function to call when failed to read messages from server.
212 * server_err_user_arg - User argument for server_err_cb.
213 * server_connection_cb - Function to called when a connection state changes.
214 * server_connection_user_arg - User argument for server_connection_cb.
215 * thread_priority_cb - Function to call for setting audio thread priority.
216 * observer_ops - Functions to call when system state changes.
217 * observer_context - Context passed to client in state change callbacks.
218 */
219 struct cras_client {
220 int id;
221 int server_fd;
222 cras_socket_state_t server_fd_state;
223 int server_event_fd;
224 int stream_fds[2];
225 int command_fds[2];
226 int command_reply_fds[2];
227 const char *sock_file;
228 struct cras_file_wait *sock_file_wait;
229 bool sock_file_exists;
230 struct thread_state thread;
231 cras_stream_id_t next_stream_id;
232 pthread_cond_t stream_start_cond;
233 pthread_mutex_t stream_start_lock;
234 int last_command_result;
235 struct client_stream *streams;
236 const struct cras_server_state *server_state;
237 void (*debug_info_callback)(struct cras_client *);
238 get_hotword_models_cb_t get_hotword_models_cb;
239 cras_server_error_cb_t server_err_cb;
240 cras_connection_status_cb_t server_connection_cb;
241 void *server_connection_user_arg;
242 cras_thread_priority_cb_t thread_priority_cb;
243 struct cras_observer_ops observer_ops;
244 void *observer_context;
245 };
246
247 /*
248 * Holds the client pointer plus internal book keeping.
249 *
250 * client - The client
251 * server_state_rwlock - lock to make the client's server_state thread-safe.
252 */
253 struct client_int {
254 struct cras_client client;
255 pthread_rwlock_t server_state_rwlock;
256 };
257
258 #define to_client_int(cptr) \
259 ((struct client_int *)((char *)cptr - offsetof(struct client_int, client)))
260
261 /*
262 * Holds the hotword stream format, params, and ID used when waiting for a
263 * hotword. The structure is created by cras_client_enable_hotword_callback and
264 * destroyed by cras_client_disable_hotword_callback.
265 */
266 struct cras_hotword_handle {
267 struct cras_audio_format *format;
268 struct cras_stream_params *params;
269 cras_stream_id_t stream_id;
270 cras_hotword_trigger_cb_t trigger_cb;
271 cras_hotword_error_cb_t err_cb;
272 void *user_data;
273 };
274
275 /*
276 * Local Helpers
277 */
278
279 static int client_thread_rm_stream(struct cras_client *client,
280 cras_stream_id_t stream_id);
281 static int handle_message_from_server(struct cras_client *client);
282 static int reregister_notifications(struct cras_client *client);
283
284 /*
285 * Unlock the server_state_rwlock if lock_rc is 0.
286 *
287 * Args:
288 * client - The CRAS client pointer.
289 * lock_rc - The result of server_state_rdlock or
290 * server_state_wrlock.
291 */
server_state_unlock(const struct cras_client * client,int lock_rc)292 static void server_state_unlock(const struct cras_client *client,
293 int lock_rc)
294 {
295 struct client_int *client_int;
296
297 if (!client)
298 return;
299 client_int = to_client_int(client);
300 if (lock_rc == 0)
301 pthread_rwlock_unlock(&client_int->server_state_rwlock);
302 }
303
304 /*
305 * Lock the server_state_rwlock for reading.
306 *
307 * Also checks that the server_state pointer is valid.
308 *
309 * Args:
310 * client - The CRAS client pointer.
311 * Returns:
312 * 0 for success, positive error code on error.
313 * Returns EINVAL if the server state pointer is NULL.
314 */
server_state_rdlock(const struct cras_client * client)315 static int server_state_rdlock(const struct cras_client *client)
316 {
317 struct client_int *client_int;
318 int lock_rc;
319
320 if (!client)
321 return EINVAL;
322 client_int = to_client_int(client);
323 lock_rc = pthread_rwlock_rdlock(&client_int->server_state_rwlock);
324 if (lock_rc != 0)
325 return lock_rc;
326 if (!client->server_state) {
327 pthread_rwlock_unlock(&client_int->server_state_rwlock);
328 return EINVAL;
329 }
330 return 0;
331 }
332
333 /*
334 * Lock the server_state_rwlock for writing.
335 *
336 * Args:
337 * client - The CRAS client pointer.
338 * Returns:
339 * 0 for success, positive error code on error.
340 */
server_state_wrlock(const struct cras_client * client)341 static int server_state_wrlock(const struct cras_client *client)
342 {
343 struct client_int *client_int;
344
345 if (!client)
346 return EINVAL;
347 client_int = to_client_int(client);
348 return pthread_rwlock_wrlock(&client_int->server_state_rwlock);
349 }
350
351 /* Get the stream pointer from a stream id. */
stream_from_id(const struct cras_client * client,unsigned int id)352 static struct client_stream *stream_from_id(const struct cras_client *client,
353 unsigned int id)
354 {
355 struct client_stream *out;
356
357 DL_SEARCH_SCALAR(client->streams, out, id, id);
358 return out;
359 }
360
361 /*
362 * Fill a pollfd structure with the current server fd and events.
363 */
server_fill_pollfd(const struct cras_client * client,struct pollfd * poll_fd)364 void server_fill_pollfd(const struct cras_client *client,
365 struct pollfd *poll_fd)
366 {
367 int events = 0;
368
369 poll_fd->fd = client->server_fd;
370 switch (client->server_fd_state) {
371 case CRAS_SOCKET_STATE_DISCONNECTED:
372 break;
373 case CRAS_SOCKET_STATE_WAIT_FOR_SOCKET:
374 case CRAS_SOCKET_STATE_FIRST_MESSAGE:
375 case CRAS_SOCKET_STATE_CONNECTED:
376 case CRAS_SOCKET_STATE_ERROR_DELAY:
377 events = POLLIN;
378 break;
379 case CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE:
380 events = POLLOUT;
381 break;
382 }
383 poll_fd->events = events;
384 poll_fd->revents = 0;
385 }
386
387 /*
388 * Change the server_fd_state.
389 */
server_fd_move_to_state(struct cras_client * client,cras_socket_state_t state)390 static void server_fd_move_to_state(struct cras_client *client,
391 cras_socket_state_t state)
392 {
393 if (state == client->server_fd_state)
394 return;
395
396 client->server_fd_state = state;
397 }
398
399 /*
400 * Action to take when in state ERROR_DELAY.
401 *
402 * In this state we want to sleep for a few seconds before retrying the
403 * connection to the audio server.
404 *
405 * If server_fd is negative: create a timer and setup server_fd with the
406 * timer's fd. If server_fd is not negative and there is input, then assume
407 * that the timer has expired, and restart the connection by moving to
408 * WAIT_FOR_SOCKET state.
409 */
error_delay_next_action(struct cras_client * client,int poll_revents)410 static int error_delay_next_action(struct cras_client *client,
411 int poll_revents)
412 {
413 int rc;
414 struct itimerspec timeout;
415
416 if (client->server_fd == -1) {
417 client->server_fd = timerfd_create(
418 CLOCK_MONOTONIC,
419 TFD_NONBLOCK|TFD_CLOEXEC);
420 if (client->server_fd == -1) {
421 rc = -errno;
422 syslog(LOG_ERR,
423 "cras_client: Could not create timerfd: %s",
424 strerror(-rc));
425 return rc;
426 }
427
428 /* Setup a relative timeout of 2 seconds. */
429 memset(&timeout, 0, sizeof(timeout));
430 timeout.it_value.tv_sec = 2;
431 rc = timerfd_settime(client->server_fd, 0, &timeout, NULL);
432 if (rc != 0) {
433 rc = -errno;
434 syslog(LOG_ERR,
435 "cras_client: Could not set timeout: %s",
436 strerror(-rc));
437 return rc;
438 }
439 return 0;
440 } else if ((poll_revents & POLLIN) == 0) {
441 return 0;
442 }
443
444 /* Move to the next state: close the timer fd first. */
445 close(client->server_fd);
446 client->server_fd = -1;
447 server_fd_move_to_state(client, CRAS_SOCKET_STATE_WAIT_FOR_SOCKET);
448 return 0;
449 }
450
451 /*
452 * Action to take when in WAIT_FOR_SOCKET state.
453 *
454 * In this state we are waiting for the socket file to exist. The existence of
455 * the socket file is continually monitored using the cras_file_wait structure
456 * and a separate fd. When the sock_file_exists boolean is modified, the state
457 * machine is invoked.
458 *
459 * If the socket file exists, then we move to the WAIT_FOR_WRITABLE state.
460 */
wait_for_socket_next_action(struct cras_client * client)461 static void wait_for_socket_next_action(struct cras_client *client)
462 {
463 if (client->sock_file_exists)
464 server_fd_move_to_state(
465 client, CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE);
466 }
467
468 /*
469 * Action to take when in WAIT_FOR_WRITABLE state.
470 *
471 * In this state we are initiating a connection the server and waiting for the
472 * server to ready for incoming messages.
473 *
474 * Create the socket to the server, and wait while a connect request results in
475 * -EINPROGRESS. Otherwise, we assume that the socket file will be deleted by
476 * the server and the server_fd_state will be changed in
477 * sock_file_wait_dispatch().
478 */
wait_for_writable_next_action(struct cras_client * client,int poll_revents)479 static int wait_for_writable_next_action(struct cras_client *client,
480 int poll_revents)
481 {
482 int rc;
483 struct sockaddr_un address;
484
485 if (client->server_fd == -1) {
486 client->server_fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
487 if (client->server_fd < 0) {
488 rc = -errno;
489 syslog(LOG_ERR, "cras_client: server socket failed: %s",
490 strerror(-rc));
491 return rc;
492 }
493 }
494 else if ((poll_revents & POLLOUT) == 0) {
495 return 0;
496 }
497
498 /* We make the file descriptor non-blocking when we do connect(), so we
499 * don't block indefinitely. */
500 cras_make_fd_nonblocking(client->server_fd);
501
502 memset(&address, 0, sizeof(struct sockaddr_un));
503 address.sun_family = AF_UNIX;
504 strcpy(address.sun_path, client->sock_file);
505 rc = connect(client->server_fd, (struct sockaddr *)&address,
506 sizeof(struct sockaddr_un));
507 if (rc != 0) {
508 rc = -errno;
509 /* For -EINPROGRESS, we wait for POLLOUT on the server_fd.
510 * Otherwise CRAS is not running and we assume that the socket
511 * file will be deleted and recreated. Notification of that will
512 * happen via the sock_file_wait_dispatch(). */
513 if (rc == -ECONNREFUSED) {
514 /* CRAS is not running, don't log this error and just
515 * stay in this state waiting sock_file_wait_dispatch()
516 * to move the state machine. */
517 close(client->server_fd);
518 client->server_fd = -1;
519 }
520 else if (rc != -EINPROGRESS) {
521 syslog(LOG_ERR,
522 "cras_client: server connect failed: %s",
523 strerror(-rc));
524 return rc;
525 }
526 return 0;
527 }
528
529 cras_make_fd_blocking(client->server_fd);
530 server_fd_move_to_state(client, CRAS_SOCKET_STATE_FIRST_MESSAGE);
531 return 0;
532 }
533
534 /*
535 * Action to take when transitioning to the CONNECTED state.
536 */
connect_transition_action(struct cras_client * client)537 static int connect_transition_action(struct cras_client *client)
538 {
539 eventfd_t event_value;
540 int rc;
541
542 rc = reregister_notifications(client);
543 if (rc < 0)
544 return rc;
545
546 server_fd_move_to_state(client, CRAS_SOCKET_STATE_CONNECTED);
547 /* Notify anyone waiting on this state change that we're
548 * connected. */
549 eventfd_read(client->server_event_fd, &event_value);
550 eventfd_write(client->server_event_fd, 1);
551 if (client->server_connection_cb)
552 client->server_connection_cb(
553 client, CRAS_CONN_STATUS_CONNECTED,
554 client->server_connection_user_arg);
555 return 0;
556 }
557
558 /*
559 * Action to take when in the FIRST_MESSAGE state.
560 *
561 * We are waiting for the first message from the server. When our client ID has
562 * been set, then we can move to the CONNECTED state.
563 */
first_message_next_action(struct cras_client * client,int poll_revents)564 static int first_message_next_action(struct cras_client *client,
565 int poll_revents)
566 {
567 int rc;
568
569 if (client->server_fd < 0)
570 return -EINVAL;
571
572 if ((poll_revents & POLLIN) == 0)
573 return 0;
574
575 rc = handle_message_from_server(client);
576 if (rc < 0) {
577 syslog(LOG_ERR, "handle first message: %s", strerror(-rc));
578 } else if (client->id >= 0) {
579 rc = connect_transition_action(client);
580 } else {
581 syslog(LOG_ERR, "did not get ID after first message!");
582 rc = -EINVAL;
583 }
584 return rc;
585 }
586
587 /*
588 * Play nice and shutdown the server socket.
589 */
shutdown_and_close_socket(int sockfd)590 static inline int shutdown_and_close_socket(int sockfd)
591 {
592 int rc;
593 uint8_t buffer[CRAS_CLIENT_MAX_MSG_SIZE];
594 struct timeval tv;
595
596 tv.tv_sec = 0;
597 tv.tv_usec = SERVER_SHUTDOWN_TIMEOUT_US;
598 setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
599
600 rc = shutdown(sockfd, SHUT_WR);
601 if (rc < 0)
602 return rc;
603 /* Wait until the socket is closed by the peer. */
604 for (;;) {
605 rc = recv(sockfd, buffer, sizeof(buffer), 0);
606 if (rc <= 0)
607 break;
608 }
609 return close(sockfd);
610 }
611
612 /*
613 * Action to take when disconnecting from the server.
614 *
615 * Clean up the server socket, and the server_state pointer. Move to the next
616 * logical state.
617 */
disconnect_transition_action(struct cras_client * client,bool force)618 static void disconnect_transition_action(struct cras_client *client, bool force)
619 {
620 eventfd_t event_value;
621 cras_socket_state_t old_state = client->server_fd_state;
622 struct client_stream *s;
623 int lock_rc;
624
625 /* Stop all playing streams.
626 * TODO(muirj): Pause and resume streams. */
627 DL_FOREACH(client->streams, s) {
628 s->config->err_cb(client, s->id, -ENOTCONN,
629 s->config->user_data);
630 client_thread_rm_stream(client, s->id);
631 }
632
633 /* Clean up the server_state pointer. */
634 lock_rc = server_state_wrlock(client);
635 if (client->server_state) {
636 munmap((void *)client->server_state,
637 sizeof(*client->server_state));
638 client->server_state = NULL;
639 }
640 server_state_unlock(client, lock_rc);
641
642 /* Our ID is unknown now. */
643 client->id = -1;
644
645 /* Clean up the server fd. */
646 if (client->server_fd >= 0) {
647 if (!force)
648 shutdown_and_close_socket(client->server_fd);
649 else
650 close(client->server_fd);
651 client->server_fd = -1;
652 }
653
654 /* Reset the server_event_fd value to 0 (and cause subsequent threads
655 * waiting on the connection to wait). */
656 eventfd_read(client->server_event_fd, &event_value);
657
658 switch (old_state) {
659 case CRAS_SOCKET_STATE_DISCONNECTED:
660 /* Do nothing: already disconnected. */
661 break;
662 case CRAS_SOCKET_STATE_ERROR_DELAY:
663 /* We're disconnected and there was a failure to setup
664 * automatic reconnection, so call the server error
665 * callback now. */
666 server_fd_move_to_state(
667 client, CRAS_SOCKET_STATE_DISCONNECTED);
668 if (client->server_connection_cb)
669 client->server_connection_cb(
670 client, CRAS_CONN_STATUS_FAILED,
671 client->server_connection_user_arg);
672 else if (client->server_err_cb)
673 client->server_err_cb(
674 client, client->server_connection_user_arg);
675 break;
676 case CRAS_SOCKET_STATE_WAIT_FOR_SOCKET:
677 case CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE:
678 case CRAS_SOCKET_STATE_FIRST_MESSAGE:
679 /* We are running this state transition while a connection is
680 * in progress for an error case. When there is no error, we
681 * come into this function in the DISCONNECTED state. */
682 server_fd_move_to_state(
683 client, CRAS_SOCKET_STATE_ERROR_DELAY);
684 break;
685 case CRAS_SOCKET_STATE_CONNECTED:
686 /* Disconnected from CRAS (for an error), wait for the socket
687 * file to be (re)created. */
688 server_fd_move_to_state(
689 client, CRAS_SOCKET_STATE_WAIT_FOR_SOCKET);
690 /* Notify the caller that we aren't connected anymore. */
691 if (client->server_connection_cb)
692 client->server_connection_cb(
693 client, CRAS_CONN_STATUS_DISCONNECTED,
694 client->server_connection_user_arg);
695 break;
696 }
697 }
698
server_fd_dispatch(struct cras_client * client,int poll_revents)699 static int server_fd_dispatch(struct cras_client *client, int poll_revents)
700 {
701 int rc = 0;
702 cras_socket_state_t old_state;
703
704 if ((poll_revents & POLLHUP) != 0) {
705 /* Error or disconnect: cleanup and make a state change now. */
706 disconnect_transition_action(client, true);
707 }
708 old_state = client->server_fd_state;
709
710 switch (client->server_fd_state) {
711 case CRAS_SOCKET_STATE_DISCONNECTED:
712 /* Assume that we've taken the necessary actions. */
713 return -ENOTCONN;
714 case CRAS_SOCKET_STATE_ERROR_DELAY:
715 rc = error_delay_next_action(client, poll_revents);
716 break;
717 case CRAS_SOCKET_STATE_WAIT_FOR_SOCKET:
718 wait_for_socket_next_action(client);
719 break;
720 case CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE:
721 rc = wait_for_writable_next_action(client, poll_revents);
722 break;
723 case CRAS_SOCKET_STATE_FIRST_MESSAGE:
724 rc = first_message_next_action(client, poll_revents);
725 break;
726 case CRAS_SOCKET_STATE_CONNECTED:
727 if ((poll_revents & POLLIN) != 0)
728 rc = handle_message_from_server(client);
729 break;
730 }
731
732 if (rc != 0) {
733 /* If there is an error, then start-over. */
734 rc = server_fd_dispatch(client, POLLHUP);
735 } else if (old_state != client->server_fd_state) {
736 /* There was a state change, process the new state now. */
737 rc = server_fd_dispatch(client, 0);
738 }
739 return rc;
740 }
741
742 /*
743 * Start connecting to the server if we aren't already.
744 */
server_connect(struct cras_client * client)745 static int server_connect(struct cras_client *client)
746 {
747 if (client->server_fd_state != CRAS_SOCKET_STATE_DISCONNECTED)
748 return 0;
749 /* Start waiting for the server socket to exist. */
750 server_fd_move_to_state(client, CRAS_SOCKET_STATE_WAIT_FOR_SOCKET);
751 return server_fd_dispatch(client, 0);
752 }
753
754 /*
755 * Disconnect from the server if we haven't already.
756 */
server_disconnect(struct cras_client * client)757 static void server_disconnect(struct cras_client *client)
758 {
759 if (client->server_fd_state == CRAS_SOCKET_STATE_DISCONNECTED)
760 return;
761 /* Set the disconnected state first so that the disconnect
762 * transition doesn't move the server state to ERROR_DELAY. */
763 server_fd_move_to_state(client, CRAS_SOCKET_STATE_DISCONNECTED);
764 disconnect_transition_action(client, false);
765 }
766
767 /*
768 * Called when something happens to the socket file.
769 */
sock_file_wait_callback(void * context,cras_file_wait_event_t event,const char * filename)770 static void sock_file_wait_callback(void *context, cras_file_wait_event_t event,
771 const char *filename)
772 {
773 struct cras_client *client = (struct cras_client *)context;
774 switch (event) {
775 case CRAS_FILE_WAIT_EVENT_CREATED:
776 client->sock_file_exists = 1;
777 switch (client->server_fd_state) {
778 case CRAS_SOCKET_STATE_DISCONNECTED:
779 case CRAS_SOCKET_STATE_ERROR_DELAY:
780 case CRAS_SOCKET_STATE_FIRST_MESSAGE:
781 case CRAS_SOCKET_STATE_CONNECTED:
782 break;
783 case CRAS_SOCKET_STATE_WAIT_FOR_SOCKET:
784 case CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE:
785 /* The socket file exists. Tell the server state
786 * machine. */
787 server_fd_dispatch(client, 0);
788 break;
789 }
790 break;
791 case CRAS_FILE_WAIT_EVENT_DELETED:
792 client->sock_file_exists = 0;
793 switch (client->server_fd_state) {
794 case CRAS_SOCKET_STATE_DISCONNECTED:
795 break;
796 case CRAS_SOCKET_STATE_WAIT_FOR_SOCKET:
797 case CRAS_SOCKET_STATE_WAIT_FOR_WRITABLE:
798 case CRAS_SOCKET_STATE_ERROR_DELAY:
799 case CRAS_SOCKET_STATE_FIRST_MESSAGE:
800 case CRAS_SOCKET_STATE_CONNECTED:
801 /* Restart the connection process. */
802 server_disconnect(client);
803 server_connect(client);
804 break;
805 }
806 break;
807 case CRAS_FILE_WAIT_EVENT_NONE:
808 break;
809 }
810 }
811
812 /*
813 * Service the sock_file_wait's fd.
814 *
815 * If the socket file is deleted, then cause a disconnect from the server.
816 * Otherwise, start a reconnect depending on the server_fd_state.
817 */
sock_file_wait_dispatch(struct cras_client * client,int poll_revents)818 static int sock_file_wait_dispatch(struct cras_client *client,
819 int poll_revents)
820 {
821 int rc;
822
823 if ((poll_revents & POLLIN) == 0)
824 return 0;
825
826 rc = cras_file_wait_dispatch(client->sock_file_wait);
827 if (rc == -EAGAIN || rc == -EWOULDBLOCK)
828 rc = 0;
829 else if (rc != 0)
830 syslog(LOG_ERR, "cras_file_wait_dispatch: %s", strerror(-rc));
831 return rc;
832 }
833
834 /*
835 * Waits until we have heard back from the server so that we know we are
836 * connected.
837 *
838 * The connected success/failure message is always the first message the server
839 * sends. Return non zero if client is connected to the server. A return code
840 * of zero means that the client is not connected to the server.
841 */
check_server_connected_wait(struct cras_client * client,struct timespec * timeout)842 static int check_server_connected_wait(struct cras_client *client,
843 struct timespec *timeout)
844 {
845 int rc = 0;
846 struct pollfd poll_fd;
847
848 poll_fd.fd = client->server_event_fd;
849 poll_fd.events = POLLIN;
850 poll_fd.revents = 0;
851
852 /* The server_event_fd is only read and written by the functions
853 * that connect to the server. When a connection is established the
854 * eventfd has a value of 1 and cras_poll will return immediately
855 * with 1. When there is no connection to the server, then this
856 * function waits until the timeout has expired or a non-zero value
857 * is written to the server_event_fd. */
858 while (rc == 0)
859 rc = cras_poll(&poll_fd, 1, timeout, NULL);
860 return rc > 0;
861 }
862
863 /* Returns non-zero if the thread is running (not stopped). */
thread_is_running(struct thread_state * thread)864 static inline int thread_is_running(struct thread_state *thread)
865 {
866 return thread->state != CRAS_THREAD_STOP;
867 }
868
869 /*
870 * Opens the server socket and connects to it.
871 * Args:
872 * client - Client pointer created with cras_client_create().
873 * timeout - Connection timeout.
874 * Returns:
875 * 0 for success, negative error code on failure.
876 */
connect_to_server(struct cras_client * client,struct timespec * timeout,bool use_command_thread)877 static int connect_to_server(struct cras_client *client,
878 struct timespec *timeout,
879 bool use_command_thread)
880 {
881 int rc;
882 struct pollfd poll_fd[2];
883 struct timespec connected_timeout;
884
885 if (!client)
886 return -EINVAL;
887
888 if (thread_is_running(&client->thread) && use_command_thread) {
889 rc = cras_client_connect_async(client);
890 if (rc == 0) {
891 rc = check_server_connected_wait(client, timeout);
892 return rc ? 0 : -ESHUTDOWN;
893 }
894 }
895
896 connected_timeout.tv_sec = 0;
897 connected_timeout.tv_nsec = 0;
898 if (check_server_connected_wait(client, &connected_timeout))
899 return 0;
900
901 poll_fd[0].fd = cras_file_wait_get_fd(client->sock_file_wait);
902 poll_fd[0].events = POLLIN;
903
904 rc = server_connect(client);
905 while(rc == 0) {
906 // Wait until we've connected or until there is a timeout.
907 // Meanwhile handle incoming actions on our fds.
908
909 server_fill_pollfd(client, &(poll_fd[1]));
910 rc = cras_poll(poll_fd, 2, timeout, NULL);
911 if (rc <= 0)
912 continue;
913
914 if (poll_fd[0].revents) {
915 rc = sock_file_wait_dispatch(
916 client, poll_fd[0].revents);
917 continue;
918 }
919
920 if (poll_fd[1].revents) {
921 rc = server_fd_dispatch(client, poll_fd[1].revents);
922 if (rc == 0 &&
923 client->server_fd_state ==
924 CRAS_SOCKET_STATE_CONNECTED)
925 break;
926 }
927 }
928
929 if (rc != 0)
930 syslog(LOG_ERR, "cras_client: Connect server failed: %s",
931 strerror(-rc));
932
933 return rc;
934 }
935
connect_to_server_wait_retry(struct cras_client * client,int timeout_ms,bool use_command_thread)936 static int connect_to_server_wait_retry(struct cras_client *client,
937 int timeout_ms,
938 bool use_command_thread)
939 {
940 struct timespec timeout_value;
941 struct timespec *timeout;
942
943 if (timeout_ms < 0) {
944 timeout = NULL;
945 } else {
946 timeout = &timeout_value;
947 ms_to_timespec(timeout_ms, timeout);
948 }
949
950 /* If connected, wait for the first message from the server
951 * indicating it's ready. */
952 return connect_to_server(client, timeout, use_command_thread);
953 }
954
955 /*
956 * Tries to connect to the server. Waits for the initial message from the
957 * server. This will happen near instantaneously if the server is already
958 * running.
959 */
connect_to_server_wait(struct cras_client * client,bool use_command_thread)960 static int connect_to_server_wait(struct cras_client *client,
961 bool use_command_thread)
962 {
963 return connect_to_server_wait_retry(
964 client, SERVER_CONNECT_TIMEOUT_MS, use_command_thread);
965 }
966
967 /*
968 * Audio thread.
969 */
970
971 /* Sends a message from the stream to the client to indicate an error.
972 * If the running stream encounters an error, then it must tell the client
973 * to stop running it.
974 */
send_stream_message(const struct client_stream * stream,unsigned msg_id)975 static int send_stream_message(const struct client_stream *stream,
976 unsigned msg_id)
977 {
978 int res;
979 struct stream_msg msg;
980
981 msg.stream_id = stream->id;
982 msg.msg_id = msg_id;
983 res = write(stream->client->stream_fds[1], &msg, sizeof(msg));
984 if (res != sizeof(msg))
985 return -EPIPE;
986
987 return 0;
988 }
989
990 /* Blocks until there is data to be read from the read_fd or until woken by an
991 * incoming "poke" on wake_fd. Up to "len" bytes are read into "buf". */
read_with_wake_fd(int wake_fd,int read_fd,uint8_t * buf,size_t len)992 static int read_with_wake_fd(int wake_fd, int read_fd, uint8_t *buf, size_t len)
993 {
994 struct pollfd pollfds[2];
995 int nread = 0;
996 int nfds = 1;
997 int rc;
998 char tmp;
999
1000 pollfds[0].fd = wake_fd;
1001 pollfds[0].events = POLLIN;
1002 if (read_fd >= 0) {
1003 nfds++;
1004 pollfds[1].fd = read_fd;
1005 pollfds[1].events = POLLIN;
1006 }
1007
1008 rc = poll(pollfds, nfds, -1);
1009 if (rc < 0)
1010 return rc;
1011 if (read_fd >= 0 && pollfds[1].revents & POLLIN) {
1012 nread = read(read_fd, buf, len);
1013 if (nread != (int)len)
1014 return -EIO;
1015 }
1016 if (pollfds[0].revents & POLLIN) {
1017 rc = read(wake_fd, &tmp, 1);
1018 if (rc < 0)
1019 return rc;
1020 }
1021
1022 return nread;
1023 }
1024 /* Check the availability and configures a capture buffer.
1025 * Args:
1026 * stream - The input stream to configure buffer for.
1027 * captured_frames - To be filled with the pointer to the beginning of
1028 * captured buffer.
1029 * num_frames - Number of captured frames.
1030 * Returns:
1031 * Number of frames available in captured_frames.
1032 */
config_capture_buf(struct client_stream * stream,uint8_t ** captured_frames,unsigned int num_frames)1033 static unsigned int config_capture_buf(struct client_stream *stream,
1034 uint8_t **captured_frames,
1035 unsigned int num_frames)
1036 {
1037 /* Always return the beginning of the read buffer because Chrome expects
1038 * so. */
1039 *captured_frames = cras_shm_get_read_buffer_base(&stream->capture_shm);
1040
1041 /* Don't ask for more frames than the client desires. */
1042 if (stream->flags & BULK_AUDIO_OK)
1043 num_frames = MIN(num_frames, stream->config->buffer_frames);
1044 else
1045 num_frames = MIN(num_frames, stream->config->cb_threshold);
1046
1047 /* If shm readable frames is less than client requests, that means
1048 * overrun has happened in server side. Don't send partial corrupted
1049 * buffer to client. */
1050 if (cras_shm_get_curr_read_frames(&stream->capture_shm) < num_frames)
1051 return 0;
1052
1053 return num_frames;
1054 }
1055
complete_capture_read_current(struct client_stream * stream,unsigned int num_frames)1056 static void complete_capture_read_current(struct client_stream *stream,
1057 unsigned int num_frames)
1058 {
1059 cras_shm_buffer_read_current(&stream->capture_shm, num_frames);
1060 }
1061
send_capture_reply(struct client_stream * stream,unsigned int frames,int err)1062 static int send_capture_reply(struct client_stream *stream,
1063 unsigned int frames,
1064 int err)
1065 {
1066 struct audio_message aud_msg;
1067 int rc;
1068
1069 if (!cras_stream_uses_input_hw(stream->direction))
1070 return 0;
1071
1072 aud_msg.id = AUDIO_MESSAGE_DATA_CAPTURED;
1073 aud_msg.frames = frames;
1074 aud_msg.error = err;
1075
1076 rc = write(stream->aud_fd, &aud_msg, sizeof(aud_msg));
1077 if (rc != sizeof(aud_msg))
1078 return -EPIPE;
1079
1080 return 0;
1081 }
1082
1083 /* For capture streams this handles the message signalling that data is ready to
1084 * be passed to the user of this stream. Calls the audio callback with the new
1085 * samples, and mark them as read.
1086 * Args:
1087 * stream - The stream the message was received for.
1088 * num_frames - The number of captured frames.
1089 * Returns:
1090 * 0, unless there is a fatal error or the client declares enod of file.
1091 */
handle_capture_data_ready(struct client_stream * stream,unsigned int num_frames)1092 static int handle_capture_data_ready(struct client_stream *stream,
1093 unsigned int num_frames)
1094 {
1095 int frames;
1096 struct cras_stream_params *config;
1097 uint8_t *captured_frames;
1098 struct timespec ts;
1099 int rc = 0;
1100
1101 config = stream->config;
1102 /* If this message is for an output stream, log error and drop it. */
1103 if (!cras_stream_has_input(stream->direction)) {
1104 syslog(LOG_ERR, "cras_client: Play data to input\n");
1105 return 0;
1106 }
1107
1108 num_frames = config_capture_buf(stream, &captured_frames, num_frames);
1109 if (num_frames == 0)
1110 return 0;
1111
1112 cras_timespec_to_timespec(&ts, &stream->capture_shm.area->ts);
1113
1114 if (config->unified_cb)
1115 frames = config->unified_cb(stream->client,
1116 stream->id,
1117 captured_frames,
1118 NULL,
1119 num_frames,
1120 &ts,
1121 NULL,
1122 config->user_data);
1123 else
1124 frames = config->aud_cb(stream->client,
1125 stream->id,
1126 captured_frames,
1127 num_frames,
1128 &ts,
1129 config->user_data);
1130 if (frames < 0) {
1131 send_stream_message(stream, CLIENT_STREAM_EOF);
1132 rc = frames;
1133 goto reply_captured;
1134 }
1135 if (frames == 0)
1136 return 0;
1137
1138 complete_capture_read_current(stream, frames);
1139 reply_captured:
1140 return send_capture_reply(stream, frames, rc);
1141 }
1142
1143 /* Notifies the server that "frames" samples have been written. */
send_playback_reply(struct client_stream * stream,unsigned int frames,int error)1144 static int send_playback_reply(struct client_stream *stream,
1145 unsigned int frames,
1146 int error)
1147 {
1148 struct audio_message aud_msg;
1149 int rc;
1150
1151 if (!cras_stream_uses_output_hw(stream->direction))
1152 return 0;
1153
1154 aud_msg.id = AUDIO_MESSAGE_DATA_READY;
1155 aud_msg.frames = frames;
1156 aud_msg.error = error;
1157
1158 rc = write(stream->aud_fd, &aud_msg, sizeof(aud_msg));
1159 if (rc != sizeof(aud_msg))
1160 return -EPIPE;
1161
1162 return 0;
1163 }
1164
1165 /* For playback streams when current buffer is empty, this handles the request
1166 * for more samples by calling the audio callback for the thread, and signaling
1167 * the server that the samples have been written. */
handle_playback_request(struct client_stream * stream,unsigned int num_frames)1168 static int handle_playback_request(struct client_stream *stream,
1169 unsigned int num_frames)
1170 {
1171 uint8_t *buf;
1172 int frames;
1173 int rc = 0;
1174 struct cras_stream_params *config;
1175 struct cras_audio_shm *shm = &stream->play_shm;
1176 struct timespec ts;
1177
1178 config = stream->config;
1179
1180 /* If this message is for an input stream, log error and drop it. */
1181 if (stream->direction != CRAS_STREAM_OUTPUT) {
1182 syslog(LOG_ERR, "cras_client: Record data from output\n");
1183 return 0;
1184 }
1185
1186 buf = cras_shm_get_write_buffer_base(&stream->play_shm);
1187
1188 /* Limit the amount of frames to the configured amount. */
1189 num_frames = MIN(num_frames, config->cb_threshold);
1190
1191 cras_timespec_to_timespec(&ts, &shm->area->ts);
1192
1193 /* Get samples from the user */
1194 if (config->unified_cb)
1195 frames = config->unified_cb(stream->client,
1196 stream->id,
1197 NULL,
1198 buf,
1199 num_frames,
1200 NULL,
1201 &ts,
1202 config->user_data);
1203 else
1204 frames = config->aud_cb(stream->client,
1205 stream->id,
1206 buf,
1207 num_frames,
1208 &ts,
1209 config->user_data);
1210 if (frames < 0) {
1211 send_stream_message(stream, CLIENT_STREAM_EOF);
1212 rc = frames;
1213 goto reply_written;
1214 }
1215
1216 cras_shm_buffer_written_start(shm, frames);
1217
1218 reply_written:
1219 /* Signal server that data is ready, or that an error has occurred. */
1220 rc = send_playback_reply(stream, frames, rc);
1221 return rc;
1222 }
1223
audio_thread_set_priority(struct client_stream * stream)1224 static void audio_thread_set_priority(struct client_stream *stream)
1225 {
1226 /* Use provided callback to set priority if available. */
1227 if (stream->client->thread_priority_cb) {
1228 stream->client->thread_priority_cb(stream->client);
1229 return;
1230 }
1231
1232 /* Try to get RT scheduling, if that fails try to set the nice value. */
1233 if (cras_set_rt_scheduling(CRAS_CLIENT_RT_THREAD_PRIORITY) ||
1234 cras_set_thread_priority(CRAS_CLIENT_RT_THREAD_PRIORITY))
1235 cras_set_nice_level(CRAS_CLIENT_NICENESS_LEVEL);
1236 }
1237
1238 /* Listens to the audio socket for messages from the server indicating that
1239 * the stream needs to be serviced. One of these runs per stream. */
audio_thread(void * arg)1240 static void *audio_thread(void *arg)
1241 {
1242 struct client_stream *stream = (struct client_stream *)arg;
1243 int thread_terminated = 0;
1244 struct audio_message aud_msg;
1245 int aud_fd;
1246 int num_read;
1247
1248 if (arg == NULL)
1249 return (void *)-EIO;
1250
1251 audio_thread_set_priority(stream);
1252
1253 /* Notify the control thread that we've started. */
1254 pthread_mutex_lock(&stream->client->stream_start_lock);
1255 pthread_cond_broadcast(&stream->client->stream_start_cond);
1256 pthread_mutex_unlock(&stream->client->stream_start_lock);
1257
1258 while (thread_is_running(&stream->thread) && !thread_terminated) {
1259 /* While we are warming up, aud_fd may not be valid and some
1260 * shared memory resources may not yet be available. */
1261 aud_fd = (stream->thread.state == CRAS_THREAD_WARMUP) ?
1262 -1 : stream->aud_fd;
1263 num_read = read_with_wake_fd(stream->wake_fds[0],
1264 aud_fd,
1265 (uint8_t *)&aud_msg,
1266 sizeof(aud_msg));
1267 if (num_read < 0)
1268 return (void *)-EIO;
1269 if (num_read == 0)
1270 continue;
1271
1272 switch (aud_msg.id) {
1273 case AUDIO_MESSAGE_DATA_READY:
1274 thread_terminated = handle_capture_data_ready(
1275 stream,
1276 aud_msg.frames);
1277 break;
1278 case AUDIO_MESSAGE_REQUEST_DATA:
1279 thread_terminated = handle_playback_request(
1280 stream,
1281 aud_msg.frames);
1282 break;
1283 default:
1284 break;
1285 }
1286 }
1287
1288 return NULL;
1289 }
1290
1291 /* Pokes the audio thread so that it can notice if it has been terminated. */
wake_aud_thread(struct client_stream * stream)1292 static int wake_aud_thread(struct client_stream *stream)
1293 {
1294 int rc;
1295
1296 rc = write(stream->wake_fds[1], &rc, 1);
1297 if (rc != 1)
1298 return rc;
1299 return 0;
1300 }
1301
1302 /* Stop the audio thread for the given stream.
1303 * Args:
1304 * stream - Stream for which to stop the audio thread.
1305 * join - When non-zero, attempt to join the audio thread (wait for it to
1306 * complete).
1307 */
stop_aud_thread(struct client_stream * stream,int join)1308 static void stop_aud_thread(struct client_stream *stream, int join)
1309 {
1310 if (thread_is_running(&stream->thread)) {
1311 stream->thread.state = CRAS_THREAD_STOP;
1312 wake_aud_thread(stream);
1313 if (join)
1314 pthread_join(stream->thread.tid, NULL);
1315 }
1316
1317 if (stream->wake_fds[0] >= 0) {
1318 close(stream->wake_fds[0]);
1319 close(stream->wake_fds[1]);
1320 stream->wake_fds[0] = -1;
1321 }
1322 }
1323
1324 /* Start the audio thread for this stream.
1325 * Returns when the thread has started and is waiting.
1326 * Args:
1327 * stream - The stream that needs an audio thread.
1328 * Returns:
1329 * 0 for success, or a negative error code.
1330 */
start_aud_thread(struct client_stream * stream)1331 static int start_aud_thread(struct client_stream *stream)
1332 {
1333 int rc;
1334 struct timespec future;
1335
1336 rc = pipe(stream->wake_fds);
1337 if (rc < 0) {
1338 rc = -errno;
1339 syslog(LOG_ERR, "cras_client: pipe: %s", strerror(-rc));
1340 return rc;
1341 }
1342
1343 stream->thread.state = CRAS_THREAD_WARMUP;
1344
1345 pthread_mutex_lock(&stream->client->stream_start_lock);
1346 rc = pthread_create(&stream->thread.tid, NULL, audio_thread, stream);
1347 if (rc) {
1348 pthread_mutex_unlock(&stream->client->stream_start_lock);
1349 syslog(LOG_ERR,
1350 "cras_client: Couldn't create audio stream: %s",
1351 strerror(rc));
1352 stream->thread.state = CRAS_THREAD_STOP;
1353 stop_aud_thread(stream, 0);
1354 return -rc;
1355 }
1356
1357 clock_gettime(CLOCK_REALTIME, &future);
1358 future.tv_sec += 2; /* Wait up to two seconds. */
1359 rc = pthread_cond_timedwait(&stream->client->stream_start_cond,
1360 &stream->client->stream_start_lock, &future);
1361 pthread_mutex_unlock(&stream->client->stream_start_lock);
1362 if (rc != 0) {
1363 /* Something is very wrong: try to cancel the thread and don't
1364 * wait for it. */
1365 syslog(LOG_ERR, "cras_client: Client thread not responding: %s",
1366 strerror(rc));
1367 stop_aud_thread(stream, 0);
1368 return -rc;
1369 }
1370 return 0;
1371 }
1372
1373 /*
1374 * Client thread.
1375 */
1376
1377 /* Gets the update_count of the server state shm region. */
1378 static inline
begin_server_state_read(const struct cras_server_state * state)1379 unsigned begin_server_state_read(const struct cras_server_state *state)
1380 {
1381 unsigned count;
1382
1383 /* Version will be odd when the server is writing. */
1384 while ((count = *(volatile unsigned *)&state->update_count) & 1)
1385 sched_yield();
1386 __sync_synchronize();
1387 return count;
1388 }
1389
1390 /* Checks if the update count of the server state shm region has changed from
1391 * count. Returns 0 if the count still matches.
1392 */
1393 static inline
end_server_state_read(const struct cras_server_state * state,unsigned count)1394 int end_server_state_read(const struct cras_server_state *state, unsigned count)
1395 {
1396 __sync_synchronize();
1397 if (count != *(volatile unsigned *)&state->update_count)
1398 return -EAGAIN;
1399 return 0;
1400
1401 }
1402
1403 /* Gets the shared memory region used to share audio data with the server. */
config_shm(struct cras_audio_shm * shm,int shm_fd,size_t size)1404 static int config_shm(struct cras_audio_shm *shm, int shm_fd, size_t size)
1405 {
1406 shm->area = (struct cras_audio_shm_area *)mmap(
1407 NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
1408 shm_fd, 0);
1409 if (shm->area == (struct cras_audio_shm_area *)-1) {
1410 syslog(LOG_ERR,
1411 "cras_client: mmap failed to map shm for stream.");
1412 return errno;
1413 }
1414 /* Copy server shm config locally. */
1415 cras_shm_copy_shared_config(shm);
1416
1417 return 0;
1418 }
1419
1420 /* Release shm areas if references to them are held. */
free_shm(struct client_stream * stream)1421 static void free_shm(struct client_stream *stream)
1422 {
1423 if (stream->capture_shm.area) {
1424 munmap(stream->capture_shm.area, stream->capture_shm_size);
1425 }
1426 if (stream->play_shm.area) {
1427 munmap(stream->play_shm.area, stream->play_shm_size);
1428 }
1429 stream->capture_shm.area = NULL;
1430 stream->play_shm.area = NULL;
1431 }
1432
1433 /* Handles the stream connected message from the server. Check if we need a
1434 * format converter, configure the shared memory region, and start the audio
1435 * thread that will handle requests from the server. */
stream_connected(struct client_stream * stream,const struct cras_client_stream_connected * msg,const int stream_fds[2],const unsigned int num_fds)1436 static int stream_connected(struct client_stream *stream,
1437 const struct cras_client_stream_connected *msg,
1438 const int stream_fds[2], const unsigned int num_fds)
1439 {
1440 int rc;
1441 struct cras_audio_format mfmt;
1442
1443 if (msg->err || num_fds != 2) {
1444 syslog(LOG_ERR, "cras_client: Error Setting up stream %d\n",
1445 msg->err);
1446 rc = msg->err;
1447 goto err_ret;
1448 }
1449
1450 unpack_cras_audio_format(&mfmt, &msg->format);
1451
1452 if (cras_stream_has_input(stream->direction)) {
1453 rc = config_shm(&stream->capture_shm,
1454 stream_fds[0],
1455 msg->shm_max_size);
1456 if (rc < 0) {
1457 syslog(LOG_ERR,
1458 "cras_client: Error configuring capture shm");
1459 goto err_ret;
1460 }
1461 stream->capture_shm_size = msg->shm_max_size;
1462 }
1463
1464 if (cras_stream_uses_output_hw(stream->direction)) {
1465 rc = config_shm(&stream->play_shm,
1466 stream_fds[1],
1467 msg->shm_max_size);
1468 if (rc < 0) {
1469 syslog(LOG_ERR,
1470 "cras_client: Error configuring playback shm");
1471 goto err_ret;
1472 }
1473 stream->play_shm_size = msg->shm_max_size;
1474
1475 cras_shm_set_volume_scaler(&stream->play_shm,
1476 stream->volume_scaler);
1477 }
1478
1479 stream->thread.state = CRAS_THREAD_RUNNING;
1480 wake_aud_thread(stream);
1481
1482 close(stream_fds[0]);
1483 close(stream_fds[1]);
1484 return 0;
1485 err_ret:
1486 stop_aud_thread(stream, 1);
1487 close(stream_fds[0]);
1488 close(stream_fds[1]);
1489 free_shm(stream);
1490 return rc;
1491 }
1492
send_connect_message(struct cras_client * client,struct client_stream * stream,uint32_t dev_idx)1493 static int send_connect_message(struct cras_client *client,
1494 struct client_stream *stream,
1495 uint32_t dev_idx)
1496 {
1497 int rc;
1498 struct cras_connect_message serv_msg;
1499 int sock[2] = {-1, -1};
1500
1501 /* Create a socket pair for the server to notify of audio events. */
1502 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
1503 if (rc != 0) {
1504 rc = -errno;
1505 syslog(LOG_ERR, "cras_client: socketpair: %s", strerror(-rc));
1506 goto fail;
1507 }
1508
1509 cras_fill_connect_message(&serv_msg,
1510 stream->config->direction,
1511 stream->id,
1512 stream->config->stream_type,
1513 stream->config->buffer_frames,
1514 stream->config->cb_threshold,
1515 stream->flags,
1516 stream->config->effects,
1517 stream->config->format,
1518 dev_idx);
1519 rc = cras_send_with_fds(client->server_fd, &serv_msg, sizeof(serv_msg),
1520 &sock[1], 1);
1521 if (rc != sizeof(serv_msg)) {
1522 rc = EIO;
1523 syslog(LOG_ERR,
1524 "cras_client: add_stream: Send server message failed.");
1525 goto fail;
1526 }
1527
1528 stream->aud_fd = sock[0];
1529 close(sock[1]);
1530 return 0;
1531
1532 fail:
1533 if (sock[0] != -1)
1534 close(sock[0]);
1535 if (sock[1] != -1)
1536 close(sock[1]);
1537 return rc;
1538 }
1539
1540 /* Adds a stream to a running client. Checks to make sure that the client is
1541 * attached, waits if it isn't. The stream is prepared on the main thread and
1542 * passed here. */
client_thread_add_stream(struct cras_client * client,struct client_stream * stream,cras_stream_id_t * stream_id_out,uint32_t dev_idx)1543 static int client_thread_add_stream(struct cras_client *client,
1544 struct client_stream *stream,
1545 cras_stream_id_t *stream_id_out,
1546 uint32_t dev_idx)
1547 {
1548 int rc;
1549 cras_stream_id_t new_id;
1550 struct client_stream *out;
1551
1552 /* Find the hotword device index. */
1553 if ((stream->flags & HOTWORD_STREAM) == HOTWORD_STREAM &&
1554 dev_idx == NO_DEVICE) {
1555 int hotword_idx;
1556 hotword_idx = cras_client_get_first_dev_type_idx(client,
1557 CRAS_NODE_TYPE_HOTWORD, CRAS_STREAM_INPUT);
1558 if (hotword_idx < 0) {
1559 syslog(LOG_ERR,
1560 "cras_client: add_stream: Finding hotword dev");
1561 return hotword_idx;
1562 }
1563 dev_idx = hotword_idx;
1564 }
1565
1566 /* Find an available stream id. */
1567 do {
1568 new_id = cras_get_stream_id(client->id, client->next_stream_id);
1569 client->next_stream_id++;
1570 DL_SEARCH_SCALAR(client->streams, out, id, new_id);
1571 } while (out != NULL);
1572
1573 stream->id = new_id;
1574 *stream_id_out = new_id;
1575 stream->client = client;
1576
1577 /* Start the audio thread. */
1578 rc = start_aud_thread(stream);
1579 if (rc != 0)
1580 return rc;
1581
1582 /* Start the thread associated with this stream. */
1583 /* send a message to the server asking that the stream be started. */
1584 rc = send_connect_message(client, stream, dev_idx);
1585 if (rc != 0) {
1586 stop_aud_thread(stream, 1);
1587 return rc;
1588 }
1589
1590 /* Add the stream to the linked list */
1591 DL_APPEND(client->streams, stream);
1592
1593 return 0;
1594 }
1595
1596 /* Removes a stream from a running client from within the running client's
1597 * context. */
client_thread_rm_stream(struct cras_client * client,cras_stream_id_t stream_id)1598 static int client_thread_rm_stream(struct cras_client *client,
1599 cras_stream_id_t stream_id)
1600 {
1601 struct cras_disconnect_stream_message msg;
1602 struct client_stream *stream =
1603 stream_from_id(client, stream_id);
1604 int rc;
1605
1606 if (stream == NULL)
1607 return 0;
1608
1609 /* Tell server to remove. */
1610 if (client->server_fd_state == CRAS_SOCKET_STATE_CONNECTED) {
1611 cras_fill_disconnect_stream_message(&msg, stream_id);
1612 rc = write(client->server_fd, &msg, sizeof(msg));
1613 if (rc < 0)
1614 syslog(LOG_ERR,
1615 "cras_client: error removing stream from server\n");
1616 }
1617
1618 /* And shut down locally. */
1619 stop_aud_thread(stream, 1);
1620
1621 free_shm(stream);
1622
1623 DL_DELETE(client->streams, stream);
1624 if (stream->aud_fd >= 0)
1625 close(stream->aud_fd);
1626
1627 free(stream->config);
1628 free(stream);
1629
1630 return 0;
1631 }
1632
1633 /* Sets the volume scaling factor for a playing stream. */
client_thread_set_stream_volume(struct cras_client * client,cras_stream_id_t stream_id,float volume_scaler)1634 static int client_thread_set_stream_volume(struct cras_client *client,
1635 cras_stream_id_t stream_id,
1636 float volume_scaler)
1637 {
1638 struct client_stream *stream;
1639
1640 stream = stream_from_id(client, stream_id);
1641 if (stream == NULL || volume_scaler > 1.0 || volume_scaler < 0.0)
1642 return -EINVAL;
1643
1644 stream->volume_scaler = volume_scaler;
1645 if (stream->play_shm.area != NULL)
1646 cras_shm_set_volume_scaler(&stream->play_shm, volume_scaler);
1647
1648 return 0;
1649 }
1650
1651 /* Attach to the shm region containing the server state. */
client_attach_shm(struct cras_client * client,int shm_fd)1652 static int client_attach_shm(struct cras_client *client, int shm_fd)
1653 {
1654 int lock_rc;
1655 int rc;
1656
1657 lock_rc = server_state_wrlock(client);
1658 if (client->server_state) {
1659 rc = -EBUSY;
1660 goto error;
1661 }
1662
1663 client->server_state = (struct cras_server_state *)mmap(
1664 NULL, sizeof(*client->server_state),
1665 PROT_READ, MAP_SHARED, shm_fd, 0);
1666 rc = -errno;
1667 close(shm_fd);
1668 if (client->server_state == (struct cras_server_state *)-1) {
1669 syslog(LOG_ERR,
1670 "cras_client: mmap failed to map shm for client: %s",
1671 strerror(-rc));
1672 goto error;
1673 }
1674
1675 if (client->server_state->state_version != CRAS_SERVER_STATE_VERSION) {
1676 munmap((void *)client->server_state,
1677 sizeof(*client->server_state));
1678 client->server_state = NULL;
1679 rc = -EINVAL;
1680 syslog(LOG_ERR, "cras_client: Unknown server_state version.");
1681 } else {
1682 rc = 0;
1683 }
1684
1685 error:
1686 server_state_unlock(client, lock_rc);
1687 return rc;
1688 }
1689
cras_client_get_hotword_models_ready(struct cras_client * client,const char * hotword_models)1690 static void cras_client_get_hotword_models_ready(
1691 struct cras_client *client,
1692 const char *hotword_models)
1693 {
1694 if (!client->get_hotword_models_cb)
1695 return;
1696 client->get_hotword_models_cb(client, hotword_models);
1697 client->get_hotword_models_cb = NULL;
1698 }
1699
1700 /* Handles messages from the cras server. */
handle_message_from_server(struct cras_client * client)1701 static int handle_message_from_server(struct cras_client *client)
1702 {
1703 uint8_t buf[CRAS_CLIENT_MAX_MSG_SIZE];
1704 struct cras_client_message *msg;
1705 int rc = 0;
1706 int nread;
1707 int server_fds[2];
1708 unsigned int num_fds = 2;
1709
1710 msg = (struct cras_client_message *)buf;
1711 nread = cras_recv_with_fds(client->server_fd, buf, sizeof(buf),
1712 server_fds, &num_fds);
1713 if (nread < (int)sizeof(msg->length) || (int)msg->length != nread)
1714 return -EIO;
1715
1716 switch (msg->id) {
1717 case CRAS_CLIENT_CONNECTED: {
1718 struct cras_client_connected *cmsg =
1719 (struct cras_client_connected *)msg;
1720 if (num_fds != 1)
1721 return -EINVAL;
1722 rc = client_attach_shm(client, server_fds[0]);
1723 if (rc)
1724 return rc;
1725 client->id = cmsg->client_id;
1726
1727 break;
1728 }
1729 case CRAS_CLIENT_STREAM_CONNECTED: {
1730 struct cras_client_stream_connected *cmsg =
1731 (struct cras_client_stream_connected *)msg;
1732 struct client_stream *stream =
1733 stream_from_id(client, cmsg->stream_id);
1734 if (stream == NULL) {
1735 if (num_fds != 2) {
1736 syslog(LOG_ERR, "cras_client: Error receiving "
1737 "stream 0x%x connected message",
1738 cmsg->stream_id);
1739 return -EINVAL;
1740 }
1741
1742 /*
1743 * Usually, the fds should be closed in stream_connected
1744 * callback. However, sometimes a stream is removed
1745 * before it is connected.
1746 */
1747 close(server_fds[0]);
1748 close(server_fds[1]);
1749 break;
1750 }
1751 rc = stream_connected(stream, cmsg, server_fds, num_fds);
1752 if (rc < 0)
1753 stream->config->err_cb(stream->client,
1754 stream->id,
1755 rc,
1756 stream->config->user_data);
1757 break;
1758 }
1759 case CRAS_CLIENT_AUDIO_DEBUG_INFO_READY:
1760 if (client->debug_info_callback)
1761 client->debug_info_callback(client);
1762 client->debug_info_callback = NULL;
1763 break;
1764 case CRAS_CLIENT_GET_HOTWORD_MODELS_READY: {
1765 struct cras_client_get_hotword_models_ready *cmsg =
1766 (struct cras_client_get_hotword_models_ready *)msg;
1767 cras_client_get_hotword_models_ready(client,
1768 (const char *)cmsg->hotword_models);
1769 break;
1770 }
1771 case CRAS_CLIENT_OUTPUT_VOLUME_CHANGED: {
1772 struct cras_client_volume_changed *cmsg =
1773 (struct cras_client_volume_changed *)msg;
1774 if (client->observer_ops.output_volume_changed)
1775 client->observer_ops.output_volume_changed(
1776 client->observer_context,
1777 cmsg->volume);
1778 break;
1779 }
1780 case CRAS_CLIENT_OUTPUT_MUTE_CHANGED: {
1781 struct cras_client_mute_changed *cmsg =
1782 (struct cras_client_mute_changed *)msg;
1783 if (client->observer_ops.output_mute_changed)
1784 client->observer_ops.output_mute_changed(
1785 client->observer_context,
1786 cmsg->muted,
1787 cmsg->user_muted,
1788 cmsg->mute_locked);
1789 break;
1790 }
1791 case CRAS_CLIENT_CAPTURE_GAIN_CHANGED: {
1792 struct cras_client_volume_changed *cmsg =
1793 (struct cras_client_volume_changed *)msg;
1794 if (client->observer_ops.capture_gain_changed)
1795 client->observer_ops.capture_gain_changed(
1796 client->observer_context,
1797 cmsg->volume);
1798 break;
1799 }
1800 case CRAS_CLIENT_CAPTURE_MUTE_CHANGED: {
1801 struct cras_client_mute_changed *cmsg =
1802 (struct cras_client_mute_changed *)msg;
1803 if (client->observer_ops.capture_mute_changed)
1804 client->observer_ops.capture_mute_changed(
1805 client->observer_context,
1806 cmsg->muted,
1807 cmsg->mute_locked);
1808 break;
1809 }
1810 case CRAS_CLIENT_NODES_CHANGED: {
1811 if (client->observer_ops.nodes_changed)
1812 client->observer_ops.nodes_changed(
1813 client->observer_context);
1814 break;
1815 }
1816 case CRAS_CLIENT_ACTIVE_NODE_CHANGED: {
1817 struct cras_client_active_node_changed *cmsg =
1818 (struct cras_client_active_node_changed *)msg;
1819 enum CRAS_STREAM_DIRECTION direction =
1820 (enum CRAS_STREAM_DIRECTION)cmsg->direction;
1821 if (client->observer_ops.active_node_changed)
1822 client->observer_ops.active_node_changed(
1823 client->observer_context,
1824 direction, cmsg->node_id);
1825 break;
1826 }
1827 case CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED: {
1828 struct cras_client_node_value_changed *cmsg =
1829 (struct cras_client_node_value_changed *)msg;
1830 if (client->observer_ops.output_node_volume_changed)
1831 client->observer_ops.output_node_volume_changed(
1832 client->observer_context,
1833 cmsg->node_id,
1834 cmsg->value);
1835 break;
1836 }
1837 case CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED: {
1838 struct cras_client_node_value_changed *cmsg =
1839 (struct cras_client_node_value_changed *)msg;
1840 if (client->observer_ops.node_left_right_swapped_changed)
1841 client->observer_ops.node_left_right_swapped_changed(
1842 client->observer_context,
1843 cmsg->node_id,
1844 cmsg->value);
1845 break;
1846 }
1847 case CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED: {
1848 struct cras_client_node_value_changed *cmsg =
1849 (struct cras_client_node_value_changed *)msg;
1850 if (client->observer_ops.input_node_gain_changed)
1851 client->observer_ops.input_node_gain_changed(
1852 client->observer_context,
1853 cmsg->node_id,
1854 cmsg->value);
1855 break;
1856 }
1857 case CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED: {
1858 struct cras_client_num_active_streams_changed *cmsg =
1859 (struct cras_client_num_active_streams_changed *)msg;
1860 enum CRAS_STREAM_DIRECTION direction =
1861 (enum CRAS_STREAM_DIRECTION)cmsg->direction;
1862 if (client->observer_ops.num_active_streams_changed)
1863 client->observer_ops.num_active_streams_changed(
1864 client->observer_context,
1865 direction, cmsg->num_active_streams);
1866 break;
1867 }
1868 default:
1869 break;
1870 }
1871
1872 return 0;
1873 }
1874
1875 /* Handles messages from streams to this client. */
handle_stream_message(struct cras_client * client,int poll_revents)1876 static int handle_stream_message(struct cras_client *client,
1877 int poll_revents)
1878 {
1879 struct stream_msg msg;
1880 int rc;
1881
1882 if ((poll_revents & POLLIN) == 0)
1883 return 0;
1884
1885 rc = read(client->stream_fds[0], &msg, sizeof(msg));
1886 if (rc < 0)
1887 syslog(LOG_ERR, "cras_client: Stream read failed %d\n", errno);
1888 /* The only reason a stream sends a message is if it needs to be
1889 * removed. An error on read would mean the same thing so regardless of
1890 * what gets us here, just remove the stream */
1891 client_thread_rm_stream(client, msg.stream_id);
1892 return 0;
1893 }
1894
1895 /* Handles messages from users to this client. */
handle_command_message(struct cras_client * client,int poll_revents)1896 static int handle_command_message(struct cras_client *client,
1897 int poll_revents)
1898 {
1899 uint8_t buf[MAX_CMD_MSG_LEN];
1900 struct command_msg *msg = (struct command_msg *)buf;
1901 int rc, to_read;
1902
1903 if ((poll_revents & POLLIN) == 0)
1904 return 0;
1905
1906 rc = read(client->command_fds[0], buf, sizeof(msg->len));
1907 if (rc != sizeof(msg->len) || msg->len > MAX_CMD_MSG_LEN) {
1908 rc = -EIO;
1909 goto cmd_msg_complete;
1910 }
1911 to_read = msg->len - rc;
1912 rc = read(client->command_fds[0], &buf[0] + rc, to_read);
1913 if (rc != to_read) {
1914 rc = -EIO;
1915 goto cmd_msg_complete;
1916 }
1917
1918 switch (msg->msg_id) {
1919 case CLIENT_STOP: {
1920 struct client_stream *s;
1921
1922 /* Stop all playing streams */
1923 DL_FOREACH(client->streams, s)
1924 client_thread_rm_stream(client, s->id);
1925
1926 /* And stop this client */
1927 client->thread.state = CRAS_THREAD_STOP;
1928 rc = 0;
1929 break;
1930 }
1931 case CLIENT_ADD_STREAM: {
1932 struct add_stream_command_message *add_msg =
1933 (struct add_stream_command_message *)msg;
1934 rc = client_thread_add_stream(client,
1935 add_msg->stream,
1936 add_msg->stream_id_out,
1937 add_msg->dev_idx);
1938 break;
1939 }
1940 case CLIENT_REMOVE_STREAM:
1941 rc = client_thread_rm_stream(client, msg->stream_id);
1942 break;
1943 case CLIENT_SET_STREAM_VOLUME_SCALER: {
1944 struct set_stream_volume_command_message *vol_msg =
1945 (struct set_stream_volume_command_message *)msg;
1946 rc = client_thread_set_stream_volume(client,
1947 vol_msg->header.stream_id,
1948 vol_msg->volume_scaler);
1949 break;
1950 }
1951 case CLIENT_SERVER_CONNECT:
1952 rc = connect_to_server_wait(client, false);
1953 break;
1954 case CLIENT_SERVER_CONNECT_ASYNC:
1955 rc = server_connect(client);
1956 break;
1957 default:
1958 assert(0);
1959 break;
1960 }
1961
1962 cmd_msg_complete:
1963 /* Wake the waiting main thread with the result of the command. */
1964 if (write(client->command_reply_fds[1], &rc, sizeof(rc)) != sizeof(rc))
1965 return -EIO;
1966 return rc;
1967 }
1968
1969 /* This thread handles non audio sample communication with the audio server.
1970 * The client program will call fucntions below to send messages to this thread
1971 * to add or remove streams or change parameters.
1972 */
client_thread(void * arg)1973 static void *client_thread(void *arg)
1974 {
1975 struct cras_client *client = (struct cras_client *)arg;
1976 struct pollfd pollfds[4];
1977 int (*cbs[4])(struct cras_client *client, int poll_revents);
1978 unsigned int num_pollfds, i;
1979 int rc;
1980
1981 if (arg == NULL)
1982 return (void *)-EINVAL;
1983
1984 while (thread_is_running(&client->thread)) {
1985 num_pollfds = 0;
1986
1987 rc = cras_file_wait_get_fd(client->sock_file_wait);
1988 if (rc >= 0) {
1989 cbs[num_pollfds] = sock_file_wait_dispatch;
1990 pollfds[num_pollfds].fd = rc;
1991 pollfds[num_pollfds].events = POLLIN;
1992 pollfds[num_pollfds].revents = 0;
1993 num_pollfds++;
1994 }
1995 else
1996 syslog(LOG_ERR, "file wait fd: %d", rc);
1997 if (client->server_fd >= 0) {
1998 cbs[num_pollfds] = server_fd_dispatch;
1999 server_fill_pollfd(client, &(pollfds[num_pollfds]));
2000 num_pollfds++;
2001 }
2002 if (client->command_fds[0] >= 0) {
2003 cbs[num_pollfds] = handle_command_message;
2004 pollfds[num_pollfds].fd = client->command_fds[0];
2005 pollfds[num_pollfds].events = POLLIN;
2006 pollfds[num_pollfds].revents = 0;
2007 num_pollfds++;
2008 }
2009 if (client->stream_fds[0] >= 0) {
2010 cbs[num_pollfds] = handle_stream_message;
2011 pollfds[num_pollfds].fd = client->stream_fds[0];
2012 pollfds[num_pollfds].events = POLLIN;
2013 pollfds[num_pollfds].revents = 0;
2014 num_pollfds++;
2015 }
2016
2017 rc = poll(pollfds, num_pollfds, -1);
2018 if (rc <= 0)
2019 continue;
2020
2021 for (i = 0; i < num_pollfds; i++) {
2022 /* Only do one at a time, since some messages may
2023 * result in change to other fds. */
2024 if (pollfds[i].revents) {
2025 cbs[i](client, pollfds[i].revents);
2026 break;
2027 }
2028 }
2029 }
2030
2031 /* close the command reply pipe. */
2032 close(client->command_reply_fds[1]);
2033 client->command_reply_fds[1] = -1;
2034
2035 return NULL;
2036 }
2037
2038 /* Sends a message to the client thread to complete an action requested by the
2039 * user. Then waits for the action to complete and returns the result. */
send_command_message(struct cras_client * client,struct command_msg * msg)2040 static int send_command_message(struct cras_client *client,
2041 struct command_msg *msg)
2042 {
2043 int rc, cmd_res;
2044 if (client == NULL || !thread_is_running(&client->thread))
2045 return -EINVAL;
2046
2047 rc = write(client->command_fds[1], msg, msg->len);
2048 if (rc != (int)msg->len)
2049 return -EPIPE;
2050
2051 /* Wait for command to complete. */
2052 rc = read(client->command_reply_fds[0], &cmd_res, sizeof(cmd_res));
2053 if (rc != sizeof(cmd_res))
2054 return -EPIPE;
2055 return cmd_res;
2056 }
2057
2058 /* Send a simple message to the client thread that holds no data. */
send_simple_cmd_msg(struct cras_client * client,cras_stream_id_t stream_id,unsigned msg_id)2059 static int send_simple_cmd_msg(struct cras_client *client,
2060 cras_stream_id_t stream_id,
2061 unsigned msg_id)
2062 {
2063 struct command_msg msg;
2064
2065 msg.len = sizeof(msg);
2066 msg.stream_id = stream_id;
2067 msg.msg_id = msg_id;
2068
2069 return send_command_message(client, &msg);
2070 }
2071
2072 /* Sends the set volume message to the client thread. */
send_stream_volume_command_msg(struct cras_client * client,cras_stream_id_t stream_id,float volume_scaler)2073 static int send_stream_volume_command_msg(struct cras_client *client,
2074 cras_stream_id_t stream_id,
2075 float volume_scaler)
2076 {
2077 struct set_stream_volume_command_message msg;
2078
2079 msg.header.len = sizeof(msg);
2080 msg.header.stream_id = stream_id;
2081 msg.header.msg_id = CLIENT_SET_STREAM_VOLUME_SCALER;
2082 msg.volume_scaler = volume_scaler;
2083
2084 return send_command_message(client, &msg.header);
2085 }
2086
2087 /* Sends a message back to the client and returns the error code. */
write_message_to_server(struct cras_client * client,const struct cras_server_message * msg)2088 static int write_message_to_server(struct cras_client *client,
2089 const struct cras_server_message *msg)
2090 {
2091 ssize_t write_rc = -EPIPE;
2092
2093 if (client->server_fd_state == CRAS_SOCKET_STATE_CONNECTED ||
2094 client->server_fd_state == CRAS_SOCKET_STATE_FIRST_MESSAGE) {
2095 write_rc = write(client->server_fd, msg, msg->length);
2096 if (write_rc < 0)
2097 write_rc = -errno;
2098 }
2099
2100 if (write_rc != (ssize_t)msg->length &&
2101 client->server_fd_state != CRAS_SOCKET_STATE_FIRST_MESSAGE)
2102 return -EPIPE;
2103
2104 if (write_rc < 0)
2105 return write_rc;
2106 else if (write_rc != (ssize_t)msg->length)
2107 return -EIO;
2108 else
2109 return 0;
2110 }
2111
2112 /*
2113 * Exported Client Interface
2114 */
2115
cras_client_create(struct cras_client ** client)2116 int cras_client_create(struct cras_client **client)
2117 {
2118 const char *sock_dir;
2119 size_t sock_file_size;
2120 int rc;
2121 struct client_int *client_int;
2122 pthread_condattr_t cond_attr;
2123
2124 /* Ignore SIGPIPE while using this API. */
2125 signal(SIGPIPE, SIG_IGN);
2126
2127 sock_dir = cras_config_get_system_socket_file_dir();
2128 if (!sock_dir)
2129 return -ENOMEM;
2130
2131 client_int = (struct client_int *)calloc(1, sizeof(*client_int));
2132 if (!client_int)
2133 return -ENOMEM;
2134 *client = &client_int->client;
2135 (*client)->server_fd = -1;
2136 (*client)->id = -1;
2137
2138 rc = pthread_rwlock_init(&client_int->server_state_rwlock, NULL);
2139 if (rc != 0) {
2140 syslog(LOG_ERR, "cras_client: Could not init state rwlock.");
2141 rc = -rc;
2142 goto free_client;
2143 }
2144
2145 rc = pthread_mutex_init(&(*client)->stream_start_lock, NULL);
2146 if (rc != 0) {
2147 syslog(LOG_ERR, "cras_client: Could not init start lock.");
2148 rc = -rc;
2149 goto free_rwlock;
2150 }
2151
2152 pthread_condattr_init(&cond_attr);
2153 pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
2154 rc = pthread_cond_init(&(*client)->stream_start_cond, &cond_attr);
2155 pthread_condattr_destroy(&cond_attr);
2156 if (rc != 0) {
2157 syslog(LOG_ERR, "cras_client: Could not init start cond.");
2158 rc = -rc;
2159 goto free_lock;
2160 }
2161
2162 (*client)->server_event_fd = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK);
2163 if ((*client)->server_event_fd < 0) {
2164 syslog(LOG_ERR, "cras_client: Could not setup server eventfd.");
2165 rc = -errno;
2166 goto free_cond;
2167 }
2168
2169 sock_file_size = strlen(sock_dir) + strlen(CRAS_SOCKET_FILE) + 2;
2170 (*client)->sock_file = (const char *)malloc(sock_file_size);
2171 if (!(*client)->sock_file) {
2172 rc = -ENOMEM;
2173 goto free_error;
2174 }
2175 snprintf((char *)(*client)->sock_file, sock_file_size, "%s/%s", sock_dir,
2176 CRAS_SOCKET_FILE);
2177
2178 rc = cras_file_wait_create((*client)->sock_file,
2179 CRAS_FILE_WAIT_FLAG_NONE,
2180 sock_file_wait_callback, *client,
2181 &(*client)->sock_file_wait);
2182 if (rc != 0 && rc != -ENOENT) {
2183 syslog(LOG_ERR, "cras_client: Could not setup watch for '%s'.",
2184 (*client)->sock_file);
2185 goto free_error;
2186 }
2187 (*client)->sock_file_exists = (rc == 0);
2188
2189 /* Pipes used by the main thread and the client thread to send commands
2190 * and replies. */
2191 rc = pipe((*client)->command_fds);
2192 if (rc < 0)
2193 goto free_error;
2194 /* Pipe used to communicate between the client thread and the audio
2195 * thread. */
2196 rc = pipe((*client)->stream_fds);
2197 if (rc < 0) {
2198 close((*client)->command_fds[0]);
2199 close((*client)->command_fds[1]);
2200 goto free_error;
2201 }
2202 (*client)->command_reply_fds[0] = -1;
2203 (*client)->command_reply_fds[1] = -1;
2204
2205 return 0;
2206 free_error:
2207 if ((*client)->server_event_fd >= 0)
2208 close((*client)->server_event_fd);
2209 cras_file_wait_destroy((*client)->sock_file_wait);
2210 free((void *)(*client)->sock_file);
2211 free_cond:
2212 pthread_cond_destroy(&(*client)->stream_start_cond);
2213 free_lock:
2214 pthread_mutex_destroy(&(*client)->stream_start_lock);
2215 free_rwlock:
2216 pthread_rwlock_destroy(&client_int->server_state_rwlock);
2217 free_client:
2218 *client = NULL;
2219 free(client_int);
2220 return rc;
2221 }
2222
cras_client_destroy(struct cras_client * client)2223 void cras_client_destroy(struct cras_client *client)
2224 {
2225 struct client_int *client_int;
2226 if (client == NULL)
2227 return;
2228 client_int = to_client_int(client);
2229 client->server_connection_cb = NULL;
2230 client->server_err_cb = NULL;
2231 cras_client_stop(client);
2232 server_disconnect(client);
2233 close(client->server_event_fd);
2234 close(client->command_fds[0]);
2235 close(client->command_fds[1]);
2236 close(client->stream_fds[0]);
2237 close(client->stream_fds[1]);
2238 cras_file_wait_destroy(client->sock_file_wait);
2239 pthread_rwlock_destroy(&client_int->server_state_rwlock);
2240 free((void *)client->sock_file);
2241 free(client_int);
2242 }
2243
cras_client_connect(struct cras_client * client)2244 int cras_client_connect(struct cras_client *client)
2245 {
2246 return connect_to_server(client, NULL, true);
2247 }
2248
cras_client_connect_timeout(struct cras_client * client,unsigned int timeout_ms)2249 int cras_client_connect_timeout(struct cras_client *client,
2250 unsigned int timeout_ms)
2251 {
2252 return connect_to_server_wait_retry(client, timeout_ms, true);
2253 }
2254
cras_client_connected_wait(struct cras_client * client)2255 int cras_client_connected_wait(struct cras_client *client)
2256 {
2257 return send_simple_cmd_msg(client, 0, CLIENT_SERVER_CONNECT);
2258 }
2259
cras_client_connect_async(struct cras_client * client)2260 int cras_client_connect_async(struct cras_client *client)
2261 {
2262 return send_simple_cmd_msg(client, 0, CLIENT_SERVER_CONNECT_ASYNC);
2263 }
2264
cras_client_stream_params_create(enum CRAS_STREAM_DIRECTION direction,size_t buffer_frames,size_t cb_threshold,size_t unused,enum CRAS_STREAM_TYPE stream_type,uint32_t flags,void * user_data,cras_playback_cb_t aud_cb,cras_error_cb_t err_cb,struct cras_audio_format * format)2265 struct cras_stream_params *cras_client_stream_params_create(
2266 enum CRAS_STREAM_DIRECTION direction,
2267 size_t buffer_frames,
2268 size_t cb_threshold,
2269 size_t unused,
2270 enum CRAS_STREAM_TYPE stream_type,
2271 uint32_t flags,
2272 void *user_data,
2273 cras_playback_cb_t aud_cb,
2274 cras_error_cb_t err_cb,
2275 struct cras_audio_format *format)
2276 {
2277 struct cras_stream_params *params;
2278
2279 params = (struct cras_stream_params *)malloc(sizeof(*params));
2280 if (params == NULL)
2281 return NULL;
2282
2283 params->direction = direction;
2284 params->buffer_frames = buffer_frames;
2285 params->cb_threshold = cb_threshold;
2286 params->effects = 0;
2287 params->stream_type = stream_type;
2288 params->flags = flags;
2289 params->user_data = user_data;
2290 params->aud_cb = aud_cb;
2291 params->unified_cb = 0;
2292 params->err_cb = err_cb;
2293 memcpy(&(params->format), format, sizeof(*format));
2294 return params;
2295 }
2296
cras_client_stream_params_enable_aec(struct cras_stream_params * params)2297 void cras_client_stream_params_enable_aec(struct cras_stream_params *params)
2298 {
2299 params->effects |= APM_ECHO_CANCELLATION;
2300 }
2301
cras_client_stream_params_disable_aec(struct cras_stream_params * params)2302 void cras_client_stream_params_disable_aec(struct cras_stream_params *params)
2303 {
2304 params->effects &= ~APM_ECHO_CANCELLATION;
2305 }
2306
cras_client_stream_params_enable_ns(struct cras_stream_params * params)2307 void cras_client_stream_params_enable_ns(struct cras_stream_params *params)
2308 {
2309 params->effects |= APM_NOISE_SUPRESSION;
2310 }
2311
cras_client_stream_params_disable_ns(struct cras_stream_params * params)2312 void cras_client_stream_params_disable_ns(struct cras_stream_params *params)
2313 {
2314 params->effects &= ~APM_NOISE_SUPRESSION;
2315 }
2316
cras_client_stream_params_enable_agc(struct cras_stream_params * params)2317 void cras_client_stream_params_enable_agc(struct cras_stream_params *params)
2318 {
2319 params->effects |= APM_GAIN_CONTROL;
2320 }
2321
cras_client_stream_params_disable_agc(struct cras_stream_params * params)2322 void cras_client_stream_params_disable_agc(struct cras_stream_params *params)
2323 {
2324 params->effects &= ~APM_GAIN_CONTROL;
2325 }
2326
cras_client_stream_params_enable_vad(struct cras_stream_params * params)2327 void cras_client_stream_params_enable_vad(struct cras_stream_params *params)
2328 {
2329 params->effects |= APM_VOICE_DETECTION;
2330 }
2331
cras_client_stream_params_disable_vad(struct cras_stream_params * params)2332 void cras_client_stream_params_disable_vad(struct cras_stream_params *params)
2333 {
2334 params->effects &= ~APM_VOICE_DETECTION;
2335 }
2336
cras_client_unified_params_create(enum CRAS_STREAM_DIRECTION direction,unsigned int block_size,enum CRAS_STREAM_TYPE stream_type,uint32_t flags,void * user_data,cras_unified_cb_t unified_cb,cras_error_cb_t err_cb,struct cras_audio_format * format)2337 struct cras_stream_params *cras_client_unified_params_create(
2338 enum CRAS_STREAM_DIRECTION direction,
2339 unsigned int block_size,
2340 enum CRAS_STREAM_TYPE stream_type,
2341 uint32_t flags,
2342 void *user_data,
2343 cras_unified_cb_t unified_cb,
2344 cras_error_cb_t err_cb,
2345 struct cras_audio_format *format)
2346 {
2347 struct cras_stream_params *params;
2348
2349 params = (struct cras_stream_params *)malloc(sizeof(*params));
2350 if (params == NULL)
2351 return NULL;
2352
2353 params->direction = direction;
2354 params->buffer_frames = block_size * 2;
2355 params->cb_threshold = block_size;
2356 params->stream_type = stream_type;
2357 params->flags = flags;
2358 params->effects = 0;
2359 params->user_data = user_data;
2360 params->aud_cb = 0;
2361 params->unified_cb = unified_cb;
2362 params->err_cb = err_cb;
2363 memcpy(&(params->format), format, sizeof(*format));
2364
2365 return params;
2366 }
2367
cras_client_stream_params_destroy(struct cras_stream_params * params)2368 void cras_client_stream_params_destroy(struct cras_stream_params *params)
2369 {
2370 free(params);
2371 }
2372
cras_client_send_add_stream_command_message(struct cras_client * client,uint32_t dev_idx,cras_stream_id_t * stream_id_out,struct cras_stream_params * config)2373 static inline int cras_client_send_add_stream_command_message(
2374 struct cras_client *client,
2375 uint32_t dev_idx,
2376 cras_stream_id_t *stream_id_out,
2377 struct cras_stream_params *config)
2378 {
2379 struct add_stream_command_message cmd_msg;
2380 struct client_stream *stream;
2381 int rc = 0;
2382
2383 if (client == NULL || config == NULL || stream_id_out == NULL)
2384 return -EINVAL;
2385
2386 if (config->aud_cb == NULL && config->unified_cb == NULL)
2387 return -EINVAL;
2388
2389 if (config->err_cb == NULL)
2390 return -EINVAL;
2391
2392 stream = (struct client_stream *)calloc(1, sizeof(*stream));
2393 if (stream == NULL) {
2394 rc = -ENOMEM;
2395 goto add_failed;
2396 }
2397 stream->config = (struct cras_stream_params *)
2398 malloc(sizeof(*(stream->config)));
2399 if (stream->config == NULL) {
2400 rc = -ENOMEM;
2401 goto add_failed;
2402 }
2403 memcpy(stream->config, config, sizeof(*config));
2404 stream->aud_fd = -1;
2405 stream->wake_fds[0] = -1;
2406 stream->wake_fds[1] = -1;
2407 stream->direction = config->direction;
2408 stream->volume_scaler = 1.0;
2409 stream->flags = config->flags;
2410
2411 cmd_msg.header.len = sizeof(cmd_msg);
2412 cmd_msg.header.msg_id = CLIENT_ADD_STREAM;
2413 cmd_msg.header.stream_id = stream->id;
2414 cmd_msg.stream = stream;
2415 cmd_msg.stream_id_out = stream_id_out;
2416 cmd_msg.dev_idx = dev_idx;
2417 rc = send_command_message(client, &cmd_msg.header);
2418 if (rc < 0) {
2419 syslog(LOG_ERR,
2420 "cras_client: adding stream failed in thread %d", rc);
2421 goto add_failed;
2422 }
2423
2424 return 0;
2425
2426 add_failed:
2427 if (stream) {
2428 if (stream->config)
2429 free(stream->config);
2430 free(stream);
2431 }
2432 return rc;
2433 }
2434
cras_client_add_stream(struct cras_client * client,cras_stream_id_t * stream_id_out,struct cras_stream_params * config)2435 int cras_client_add_stream(struct cras_client *client,
2436 cras_stream_id_t *stream_id_out,
2437 struct cras_stream_params *config)
2438 {
2439 return cras_client_send_add_stream_command_message(
2440 client,
2441 NO_DEVICE,
2442 stream_id_out,
2443 config);
2444 }
2445
cras_client_add_pinned_stream(struct cras_client * client,uint32_t dev_idx,cras_stream_id_t * stream_id_out,struct cras_stream_params * config)2446 int cras_client_add_pinned_stream(struct cras_client *client,
2447 uint32_t dev_idx,
2448 cras_stream_id_t *stream_id_out,
2449 struct cras_stream_params *config)
2450 {
2451 return cras_client_send_add_stream_command_message(
2452 client,
2453 dev_idx,
2454 stream_id_out,
2455 config);
2456 }
2457
cras_client_rm_stream(struct cras_client * client,cras_stream_id_t stream_id)2458 int cras_client_rm_stream(struct cras_client *client,
2459 cras_stream_id_t stream_id)
2460 {
2461 if (client == NULL)
2462 return -EINVAL;
2463
2464 return send_simple_cmd_msg(client, stream_id, CLIENT_REMOVE_STREAM);
2465 }
2466
cras_client_set_stream_volume(struct cras_client * client,cras_stream_id_t stream_id,float volume_scaler)2467 int cras_client_set_stream_volume(struct cras_client *client,
2468 cras_stream_id_t stream_id,
2469 float volume_scaler)
2470 {
2471 if (client == NULL)
2472 return -EINVAL;
2473
2474 return send_stream_volume_command_msg(client, stream_id, volume_scaler);
2475 }
2476
cras_client_set_system_volume(struct cras_client * client,size_t volume)2477 int cras_client_set_system_volume(struct cras_client *client, size_t volume)
2478 {
2479 struct cras_set_system_volume msg;
2480
2481 if (client == NULL)
2482 return -EINVAL;
2483
2484 cras_fill_set_system_volume(&msg, volume);
2485 return write_message_to_server(client, &msg.header);
2486 }
2487
cras_client_set_system_capture_gain(struct cras_client * client,long gain)2488 int cras_client_set_system_capture_gain(struct cras_client *client, long gain)
2489 {
2490 struct cras_set_system_capture_gain msg;
2491
2492 if (client == NULL)
2493 return -EINVAL;
2494
2495 cras_fill_set_system_capture_gain(&msg, gain);
2496 return write_message_to_server(client, &msg.header);
2497 }
2498
cras_client_set_system_mute(struct cras_client * client,int mute)2499 int cras_client_set_system_mute(struct cras_client *client, int mute)
2500 {
2501 struct cras_set_system_mute msg;
2502
2503 if (client == NULL)
2504 return -EINVAL;
2505
2506 cras_fill_set_system_mute(&msg, mute);
2507 return write_message_to_server(client, &msg.header);
2508 }
2509
cras_client_set_user_mute(struct cras_client * client,int mute)2510 int cras_client_set_user_mute(struct cras_client *client, int mute)
2511 {
2512 struct cras_set_system_mute msg;
2513
2514 if (client == NULL)
2515 return -EINVAL;
2516
2517 cras_fill_set_user_mute(&msg, mute);
2518 return write_message_to_server(client, &msg.header);
2519 }
2520
cras_client_set_system_mute_locked(struct cras_client * client,int locked)2521 int cras_client_set_system_mute_locked(struct cras_client *client, int locked)
2522 {
2523 struct cras_set_system_mute msg;
2524
2525 if (client == NULL)
2526 return -EINVAL;
2527
2528 cras_fill_set_system_mute_locked(&msg, locked);
2529 return write_message_to_server(client, &msg.header);
2530 }
2531
cras_client_set_system_capture_mute(struct cras_client * client,int mute)2532 int cras_client_set_system_capture_mute(struct cras_client *client, int mute)
2533 {
2534 struct cras_set_system_mute msg;
2535
2536 if (client == NULL)
2537 return -EINVAL;
2538
2539 cras_fill_set_system_capture_mute(&msg, mute);
2540 return write_message_to_server(client, &msg.header);
2541 }
2542
cras_client_set_system_capture_mute_locked(struct cras_client * client,int locked)2543 int cras_client_set_system_capture_mute_locked(struct cras_client *client,
2544 int locked)
2545 {
2546 struct cras_set_system_mute msg;
2547
2548 if (client == NULL)
2549 return -EINVAL;
2550
2551 cras_fill_set_system_capture_mute_locked(&msg, locked);
2552 return write_message_to_server(client, &msg.header);
2553 }
2554
cras_client_get_system_volume(const struct cras_client * client)2555 size_t cras_client_get_system_volume(const struct cras_client *client)
2556 {
2557 size_t volume;
2558 int lock_rc;
2559
2560 lock_rc = server_state_rdlock(client);
2561 if (lock_rc)
2562 return 0;
2563
2564 volume = client->server_state->volume;
2565 server_state_unlock(client, lock_rc);
2566 return volume;
2567 }
2568
cras_client_get_system_capture_gain(const struct cras_client * client)2569 long cras_client_get_system_capture_gain(const struct cras_client *client)
2570 {
2571 long gain;
2572 int lock_rc;
2573
2574 lock_rc = server_state_rdlock(client);
2575 if (lock_rc)
2576 return 0;
2577
2578 gain = client->server_state->capture_gain;
2579 server_state_unlock(client, lock_rc);
2580 return gain;
2581 }
2582
cras_client_get_system_muted(const struct cras_client * client)2583 int cras_client_get_system_muted(const struct cras_client *client)
2584 {
2585 int muted;
2586 int lock_rc;
2587
2588 lock_rc = server_state_rdlock(client);
2589 if (lock_rc)
2590 return 0;
2591
2592 muted = client->server_state->mute;
2593 server_state_unlock(client, lock_rc);
2594 return muted;
2595 }
2596
cras_client_get_user_muted(const struct cras_client * client)2597 int cras_client_get_user_muted(const struct cras_client *client)
2598 {
2599 int muted;
2600 int lock_rc;
2601
2602 lock_rc = server_state_rdlock(client);
2603 if (lock_rc)
2604 return 0;
2605
2606 muted = client->server_state->user_mute;
2607 server_state_unlock(client, lock_rc);
2608 return muted;
2609 }
2610
cras_client_get_system_capture_muted(const struct cras_client * client)2611 int cras_client_get_system_capture_muted(const struct cras_client *client)
2612 {
2613 int muted;
2614 int lock_rc;
2615
2616 lock_rc = server_state_rdlock(client);
2617 if (lock_rc)
2618 return 0;
2619
2620 muted = client->server_state->capture_mute;
2621 server_state_unlock(client, lock_rc);
2622 return muted;
2623 }
2624
cras_client_get_system_min_volume(const struct cras_client * client)2625 long cras_client_get_system_min_volume(const struct cras_client *client)
2626 {
2627 long min_volume;
2628 int lock_rc;
2629
2630 lock_rc = server_state_rdlock(client);
2631 if (lock_rc)
2632 return 0;
2633
2634 min_volume = client->server_state->min_volume_dBFS;
2635 server_state_unlock(client, lock_rc);
2636 return min_volume;
2637 }
2638
cras_client_get_system_max_volume(const struct cras_client * client)2639 long cras_client_get_system_max_volume(const struct cras_client *client)
2640 {
2641 long max_volume;
2642 int lock_rc;
2643
2644 lock_rc = server_state_rdlock(client);
2645 if (lock_rc)
2646 return 0;
2647
2648 max_volume = client->server_state->max_volume_dBFS;
2649 server_state_unlock(client, lock_rc);
2650 return max_volume;
2651 }
2652
cras_client_get_system_min_capture_gain(const struct cras_client * client)2653 long cras_client_get_system_min_capture_gain(const struct cras_client *client)
2654 {
2655 long min_gain;
2656 int lock_rc;
2657
2658 lock_rc = server_state_rdlock(client);
2659 if (lock_rc)
2660 return 0;
2661
2662 min_gain = client->server_state->min_capture_gain;
2663 server_state_unlock(client, lock_rc);
2664 return min_gain;
2665 }
2666
cras_client_get_system_max_capture_gain(const struct cras_client * client)2667 long cras_client_get_system_max_capture_gain(const struct cras_client *client)
2668 {
2669 long max_gain;
2670 int lock_rc;
2671
2672 lock_rc = server_state_rdlock(client);
2673 if (lock_rc)
2674 return 0;
2675
2676 max_gain = client->server_state->max_capture_gain;
2677 server_state_unlock(client, lock_rc);
2678 return max_gain;
2679 }
2680
cras_client_get_audio_debug_info(const struct cras_client * client)2681 const struct audio_debug_info *cras_client_get_audio_debug_info(
2682 const struct cras_client *client)
2683 {
2684 const struct audio_debug_info *debug_info;
2685 int lock_rc;
2686
2687 lock_rc = server_state_rdlock(client);
2688 if (lock_rc)
2689 return 0;
2690
2691 debug_info = &client->server_state->audio_debug_info;
2692 server_state_unlock(client, lock_rc);
2693 return debug_info;
2694 }
2695
2696 const struct cras_audio_thread_snapshot_buffer*
cras_client_get_audio_thread_snapshot_buffer(const struct cras_client * client)2697 cras_client_get_audio_thread_snapshot_buffer(
2698 const struct cras_client *client)
2699 {
2700 const struct cras_audio_thread_snapshot_buffer *snapshot_buffer;
2701 int lock_rc;
2702
2703 lock_rc = server_state_rdlock(client);
2704 if (lock_rc)
2705 return 0;
2706
2707 snapshot_buffer = &client->server_state->snapshot_buffer;
2708 server_state_unlock(client, lock_rc);
2709 return snapshot_buffer;
2710 }
2711
cras_client_get_num_active_streams(const struct cras_client * client,struct timespec * ts)2712 unsigned cras_client_get_num_active_streams(const struct cras_client *client,
2713 struct timespec *ts)
2714 {
2715 unsigned num_streams, version, i;
2716 int lock_rc;
2717
2718 lock_rc = server_state_rdlock(client);
2719 if (lock_rc)
2720 return 0;
2721
2722 read_active_streams_again:
2723 version = begin_server_state_read(client->server_state);
2724 num_streams = 0;
2725 for (i = 0; i < CRAS_NUM_DIRECTIONS; i++)
2726 num_streams += client->server_state->num_active_streams[i];
2727 if (ts) {
2728 if (num_streams)
2729 clock_gettime(CLOCK_MONOTONIC_RAW, ts);
2730 else
2731 cras_timespec_to_timespec(ts,
2732 &client->server_state->last_active_stream_time);
2733 }
2734 if (end_server_state_read(client->server_state, version))
2735 goto read_active_streams_again;
2736
2737 server_state_unlock(client, lock_rc);
2738 return num_streams;
2739 }
2740
cras_client_run_thread(struct cras_client * client)2741 int cras_client_run_thread(struct cras_client *client)
2742 {
2743 int rc;
2744
2745 if (client == NULL)
2746 return -EINVAL;
2747 if (thread_is_running(&client->thread))
2748 return 0;
2749
2750 assert(client->command_reply_fds[0] == -1 &&
2751 client->command_reply_fds[1] == -1);
2752
2753 if (pipe(client->command_reply_fds) < 0)
2754 return -EIO;
2755 client->thread.state = CRAS_THREAD_RUNNING;
2756 rc = pthread_create(&client->thread.tid, NULL, client_thread, client);
2757 if (rc) {
2758 client->thread.state = CRAS_THREAD_STOP;
2759 return -rc;
2760 }
2761
2762 return 0;
2763 }
2764
cras_client_stop(struct cras_client * client)2765 int cras_client_stop(struct cras_client *client)
2766 {
2767 if (client == NULL)
2768 return -EINVAL;
2769 if (!thread_is_running(&client->thread))
2770 return 0;
2771
2772 send_simple_cmd_msg(client, 0, CLIENT_STOP);
2773 pthread_join(client->thread.tid, NULL);
2774
2775 /* The other end of the reply pipe is closed by the client thread, just
2776 * clost the read end here. */
2777 close(client->command_reply_fds[0]);
2778 client->command_reply_fds[0] = -1;
2779
2780 return 0;
2781 }
2782
cras_client_set_server_error_cb(struct cras_client * client,cras_server_error_cb_t err_cb,void * user_arg)2783 void cras_client_set_server_error_cb(struct cras_client *client,
2784 cras_server_error_cb_t err_cb,
2785 void *user_arg)
2786 {
2787 client->server_err_cb = err_cb;
2788 client->server_connection_user_arg = user_arg;
2789 }
2790
cras_client_set_connection_status_cb(struct cras_client * client,cras_connection_status_cb_t connection_cb,void * user_arg)2791 void cras_client_set_connection_status_cb(
2792 struct cras_client *client,
2793 cras_connection_status_cb_t connection_cb,
2794 void *user_arg)
2795 {
2796 client->server_connection_cb = connection_cb;
2797 client->server_connection_user_arg = user_arg;
2798 }
2799
cras_client_set_thread_priority_cb(struct cras_client * client,cras_thread_priority_cb_t cb)2800 void cras_client_set_thread_priority_cb(struct cras_client *client,
2801 cras_thread_priority_cb_t cb)
2802 {
2803 client->thread_priority_cb = cb;
2804 }
2805
cras_client_get_output_devices(const struct cras_client * client,struct cras_iodev_info * devs,struct cras_ionode_info * nodes,size_t * num_devs,size_t * num_nodes)2806 int cras_client_get_output_devices(const struct cras_client *client,
2807 struct cras_iodev_info *devs,
2808 struct cras_ionode_info *nodes,
2809 size_t *num_devs, size_t *num_nodes)
2810 {
2811 const struct cras_server_state *state;
2812 unsigned avail_devs, avail_nodes, version;
2813 int lock_rc;
2814
2815 lock_rc = server_state_rdlock(client);
2816 if (lock_rc)
2817 return -EINVAL;
2818 state = client->server_state;
2819
2820 read_outputs_again:
2821 version = begin_server_state_read(state);
2822 avail_devs = MIN(*num_devs, state->num_output_devs);
2823 memcpy(devs, state->output_devs, avail_devs * sizeof(*devs));
2824 avail_nodes = MIN(*num_nodes, state->num_output_nodes);
2825 memcpy(nodes, state->output_nodes, avail_nodes * sizeof(*nodes));
2826 if (end_server_state_read(state, version))
2827 goto read_outputs_again;
2828 server_state_unlock(client, lock_rc);
2829
2830 *num_devs = avail_devs;
2831 *num_nodes = avail_nodes;
2832
2833 return 0;
2834 }
2835
cras_client_get_input_devices(const struct cras_client * client,struct cras_iodev_info * devs,struct cras_ionode_info * nodes,size_t * num_devs,size_t * num_nodes)2836 int cras_client_get_input_devices(const struct cras_client *client,
2837 struct cras_iodev_info *devs,
2838 struct cras_ionode_info *nodes,
2839 size_t *num_devs, size_t *num_nodes)
2840 {
2841 const struct cras_server_state *state;
2842 unsigned avail_devs, avail_nodes, version;
2843 int lock_rc;
2844
2845 lock_rc = server_state_rdlock(client);
2846 if (!client)
2847 return -EINVAL;
2848 state = client->server_state;
2849
2850 read_inputs_again:
2851 version = begin_server_state_read(state);
2852 avail_devs = MIN(*num_devs, state->num_input_devs);
2853 memcpy(devs, state->input_devs, avail_devs * sizeof(*devs));
2854 avail_nodes = MIN(*num_nodes, state->num_input_nodes);
2855 memcpy(nodes, state->input_nodes, avail_nodes * sizeof(*nodes));
2856 if (end_server_state_read(state, version))
2857 goto read_inputs_again;
2858 server_state_unlock(client, lock_rc);
2859
2860 *num_devs = avail_devs;
2861 *num_nodes = avail_nodes;
2862
2863 return 0;
2864 }
2865
cras_client_get_attached_clients(const struct cras_client * client,struct cras_attached_client_info * clients,size_t max_clients)2866 int cras_client_get_attached_clients(const struct cras_client *client,
2867 struct cras_attached_client_info *clients,
2868 size_t max_clients)
2869 {
2870 const struct cras_server_state *state;
2871 unsigned num, version;
2872 int lock_rc;
2873
2874 lock_rc = server_state_rdlock(client);
2875 if (lock_rc)
2876 return -EINVAL;
2877 state = client->server_state;
2878
2879 read_clients_again:
2880 version = begin_server_state_read(state);
2881 num = MIN(max_clients, state->num_attached_clients);
2882 memcpy(clients, state->client_info, num * sizeof(*clients));
2883 if (end_server_state_read(state, version))
2884 goto read_clients_again;
2885 server_state_unlock(client, lock_rc);
2886
2887 return num;
2888 }
2889
2890 /* Find an output ionode on an iodev with the matching name.
2891 *
2892 * Args:
2893 * dev_name - The prefix of the iodev name.
2894 * node_name - The prefix of the ionode name.
2895 * dev_info - The information about the iodev will be returned here.
2896 * node_info - The information about the ionode will be returned here.
2897 * Returns:
2898 * 0 if successful, -1 if the node cannot be found.
2899 */
cras_client_find_output_node(const struct cras_client * client,const char * dev_name,const char * node_name,struct cras_iodev_info * dev_info,struct cras_ionode_info * node_info)2900 static int cras_client_find_output_node(const struct cras_client *client,
2901 const char *dev_name,
2902 const char *node_name,
2903 struct cras_iodev_info *dev_info,
2904 struct cras_ionode_info *node_info)
2905 {
2906 size_t ndevs, nnodes;
2907 struct cras_iodev_info *devs = NULL;
2908 struct cras_ionode_info *nodes = NULL;
2909 int rc = -1;
2910 unsigned i, j;
2911
2912 if (!client || !dev_name || !node_name)
2913 goto quit;
2914
2915 devs = (struct cras_iodev_info *)
2916 malloc(CRAS_MAX_IODEVS * sizeof(*devs));
2917 if (!devs)
2918 goto quit;
2919
2920 nodes = (struct cras_ionode_info *)
2921 malloc(CRAS_MAX_IONODES * sizeof(*nodes));
2922 if (!nodes)
2923 goto quit;
2924
2925 ndevs = CRAS_MAX_IODEVS;
2926 nnodes = CRAS_MAX_IONODES;
2927 rc = cras_client_get_output_devices(client, devs, nodes, &ndevs,
2928 &nnodes);
2929 if (rc < 0)
2930 goto quit;
2931
2932 for (i = 0; i < ndevs; i++)
2933 if (!strncmp(dev_name, devs[i].name, strlen(dev_name)))
2934 goto found_dev;
2935 rc = -1;
2936 goto quit;
2937
2938 found_dev:
2939 for (j = 0; j < nnodes; j++)
2940 if (nodes[j].iodev_idx == devs[i].idx &&
2941 !strncmp(node_name, nodes[j].name, strlen(node_name)))
2942 goto found_node;
2943 rc = -1;
2944 goto quit;
2945
2946 found_node:
2947 *dev_info = devs[i];
2948 *node_info = nodes[j];
2949 rc = 0;
2950
2951 quit:
2952 free(devs);
2953 free(nodes);
2954 return rc;
2955 }
2956
cras_client_get_node_by_id(const struct cras_client * client,int input,const cras_node_id_t node_id,struct cras_ionode_info * node_info)2957 int cras_client_get_node_by_id(const struct cras_client *client,
2958 int input,
2959 const cras_node_id_t node_id,
2960 struct cras_ionode_info* node_info)
2961 {
2962 size_t ndevs, nnodes;
2963 struct cras_iodev_info *devs = NULL;
2964 struct cras_ionode_info *nodes = NULL;
2965 int rc = -EINVAL;
2966 unsigned i;
2967
2968 if (!client || !node_info) {
2969 rc = -EINVAL;
2970 goto quit;
2971 }
2972
2973 devs = (struct cras_iodev_info *)
2974 malloc(CRAS_MAX_IODEVS * sizeof(*devs));
2975 if (!devs) {
2976 rc = -ENOMEM;
2977 goto quit;
2978 }
2979
2980 nodes = (struct cras_ionode_info *)
2981 malloc(CRAS_MAX_IONODES * sizeof(*nodes));
2982 if (!nodes) {
2983 rc = -ENOMEM;
2984 goto quit;
2985 }
2986
2987 ndevs = CRAS_MAX_IODEVS;
2988 nnodes = CRAS_MAX_IONODES;
2989 if (input)
2990 rc = cras_client_get_input_devices(client, devs, nodes,
2991 &ndevs, &nnodes);
2992 else
2993 rc = cras_client_get_output_devices(client, devs, nodes,
2994 &ndevs, &nnodes);
2995 if (rc < 0)
2996 goto quit;
2997
2998 rc = -ENOENT;
2999 for (i = 0; i < nnodes; i++) {
3000 if (node_id == cras_make_node_id(nodes[i].iodev_idx,
3001 nodes[i].ionode_idx)) {
3002 memcpy(node_info, &nodes[i], sizeof(*node_info));
3003 rc = 0;
3004 break;
3005 }
3006 }
3007
3008 quit:
3009 free(devs);
3010 free(nodes);
3011 return rc;
3012 }
3013
cras_client_output_dev_plugged(const struct cras_client * client,const char * name)3014 int cras_client_output_dev_plugged(const struct cras_client *client,
3015 const char *name)
3016 {
3017 struct cras_iodev_info dev_info;
3018 struct cras_ionode_info node_info = { 0 };
3019
3020 if (cras_client_find_output_node(client, name, "Front Headphone Jack",
3021 &dev_info, &node_info) < 0)
3022 return 0;
3023
3024 return node_info.plugged;
3025 }
3026
cras_client_set_node_attr(struct cras_client * client,cras_node_id_t node_id,enum ionode_attr attr,int value)3027 int cras_client_set_node_attr(struct cras_client *client,
3028 cras_node_id_t node_id,
3029 enum ionode_attr attr, int value)
3030 {
3031 struct cras_set_node_attr msg;
3032
3033 if (client == NULL)
3034 return -EINVAL;
3035
3036 cras_fill_set_node_attr(&msg, node_id, attr, value);
3037 return write_message_to_server(client, &msg.header);
3038 }
3039
cras_client_select_node(struct cras_client * client,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)3040 int cras_client_select_node(struct cras_client *client,
3041 enum CRAS_STREAM_DIRECTION direction,
3042 cras_node_id_t node_id)
3043 {
3044 struct cras_select_node msg;
3045
3046 if (client == NULL)
3047 return -EINVAL;
3048
3049 cras_fill_select_node(&msg, direction, node_id);
3050 return write_message_to_server(client, &msg.header);
3051 }
3052
cras_client_add_active_node(struct cras_client * client,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)3053 int cras_client_add_active_node(struct cras_client *client,
3054 enum CRAS_STREAM_DIRECTION direction,
3055 cras_node_id_t node_id)
3056 {
3057 struct cras_add_active_node msg;
3058
3059 if (client == NULL)
3060 return -EINVAL;
3061
3062 cras_fill_add_active_node(&msg, direction, node_id);
3063 return write_message_to_server(client, &msg.header);
3064 }
3065
cras_client_rm_active_node(struct cras_client * client,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)3066 int cras_client_rm_active_node(struct cras_client *client,
3067 enum CRAS_STREAM_DIRECTION direction,
3068 cras_node_id_t node_id)
3069 {
3070 struct cras_rm_active_node msg;
3071
3072 if (client == NULL)
3073 return -EINVAL;
3074
3075 cras_fill_rm_active_node(&msg, direction, node_id);
3076 return write_message_to_server(client, &msg.header);
3077 }
3078
cras_client_format_bytes_per_frame(struct cras_audio_format * fmt)3079 int cras_client_format_bytes_per_frame(struct cras_audio_format *fmt)
3080 {
3081 if (fmt == NULL)
3082 return -EINVAL;
3083
3084 return cras_get_format_bytes(fmt);
3085 }
3086
cras_client_calc_playback_latency(const struct timespec * sample_time,struct timespec * delay)3087 int cras_client_calc_playback_latency(const struct timespec *sample_time,
3088 struct timespec *delay)
3089 {
3090 struct timespec now;
3091
3092 if (delay == NULL)
3093 return -EINVAL;
3094
3095 clock_gettime(CLOCK_MONOTONIC_RAW, &now);
3096
3097 /* for output return time until sample is played (t - now) */
3098 subtract_timespecs(sample_time, &now, delay);
3099 return 0;
3100 }
3101
cras_client_calc_capture_latency(const struct timespec * sample_time,struct timespec * delay)3102 int cras_client_calc_capture_latency(const struct timespec *sample_time,
3103 struct timespec *delay)
3104 {
3105 struct timespec now;
3106
3107 if (delay == NULL)
3108 return -EINVAL;
3109
3110 clock_gettime(CLOCK_MONOTONIC_RAW, &now);
3111
3112 /* For input want time since sample read (now - t) */
3113 subtract_timespecs(&now, sample_time, delay);
3114 return 0;
3115 }
3116
cras_client_reload_dsp(struct cras_client * client)3117 int cras_client_reload_dsp(struct cras_client *client)
3118 {
3119 struct cras_reload_dsp msg;
3120
3121 if (client == NULL)
3122 return -EINVAL;
3123
3124 cras_fill_reload_dsp(&msg);
3125 return write_message_to_server(client, &msg.header);
3126 }
3127
cras_client_dump_dsp_info(struct cras_client * client)3128 int cras_client_dump_dsp_info(struct cras_client *client)
3129 {
3130 struct cras_dump_dsp_info msg;
3131
3132 if (client == NULL)
3133 return -EINVAL;
3134
3135 cras_fill_dump_dsp_info(&msg);
3136 return write_message_to_server(client, &msg.header);
3137 }
3138
cras_client_update_audio_debug_info(struct cras_client * client,void (* debug_info_cb)(struct cras_client *))3139 int cras_client_update_audio_debug_info(
3140 struct cras_client *client,
3141 void (*debug_info_cb)(struct cras_client *))
3142 {
3143 struct cras_dump_audio_thread msg;
3144
3145 if (client == NULL)
3146 return -EINVAL;
3147
3148 if (client->debug_info_callback != NULL)
3149 return -EINVAL;
3150 client->debug_info_callback = debug_info_cb;
3151
3152 cras_fill_dump_audio_thread(&msg);
3153 return write_message_to_server(client, &msg.header);
3154 }
3155
cras_client_update_audio_thread_snapshots(struct cras_client * client,void (* debug_info_cb)(struct cras_client *))3156 int cras_client_update_audio_thread_snapshots(
3157 struct cras_client *client,
3158 void (*debug_info_cb)(struct cras_client *))
3159 {
3160 struct cras_dump_snapshots msg;
3161
3162 if (client == NULL)
3163 return -EINVAL;
3164
3165 if (client->debug_info_callback != NULL)
3166 return -EINVAL;
3167 client->debug_info_callback = debug_info_cb;
3168
3169 cras_fill_dump_snapshots(&msg);
3170 return write_message_to_server(client, &msg.header);
3171 }
3172
cras_client_set_node_volume(struct cras_client * client,cras_node_id_t node_id,uint8_t volume)3173 int cras_client_set_node_volume(struct cras_client *client,
3174 cras_node_id_t node_id,
3175 uint8_t volume)
3176 {
3177 struct cras_set_node_attr msg;
3178
3179 if (client == NULL)
3180 return -EINVAL;
3181
3182 cras_fill_set_node_attr(&msg, node_id, IONODE_ATTR_VOLUME, volume);
3183 return write_message_to_server(client, &msg.header);
3184 }
3185
cras_client_swap_node_left_right(struct cras_client * client,cras_node_id_t node_id,int enable)3186 int cras_client_swap_node_left_right(struct cras_client *client,
3187 cras_node_id_t node_id, int enable)
3188 {
3189 struct cras_set_node_attr msg;
3190
3191 if (client == NULL)
3192 return -EINVAL;
3193
3194 cras_fill_set_node_attr(&msg, node_id, IONODE_ATTR_SWAP_LEFT_RIGHT,
3195 enable);
3196 return write_message_to_server(client, &msg.header);
3197 }
3198
cras_client_set_node_capture_gain(struct cras_client * client,cras_node_id_t node_id,long gain)3199 int cras_client_set_node_capture_gain(struct cras_client *client,
3200 cras_node_id_t node_id,
3201 long gain)
3202 {
3203 struct cras_set_node_attr msg;
3204
3205 if (client == NULL)
3206 return -EINVAL;
3207 if (gain > INT_MAX || gain < INT_MIN)
3208 return -EINVAL;
3209
3210 cras_fill_set_node_attr(&msg, node_id, IONODE_ATTR_CAPTURE_GAIN, gain);
3211 return write_message_to_server(client, &msg.header);
3212 }
3213
cras_client_add_test_iodev(struct cras_client * client,enum TEST_IODEV_TYPE type)3214 int cras_client_add_test_iodev(struct cras_client *client,
3215 enum TEST_IODEV_TYPE type)
3216 {
3217 struct cras_add_test_dev msg;
3218
3219 cras_fill_add_test_dev(&msg, type);
3220 return write_message_to_server(client, &msg.header);
3221 }
3222
cras_client_test_iodev_command(struct cras_client * client,unsigned int iodev_idx,enum CRAS_TEST_IODEV_CMD command,unsigned int data_len,const uint8_t * data)3223 int cras_client_test_iodev_command(struct cras_client *client,
3224 unsigned int iodev_idx,
3225 enum CRAS_TEST_IODEV_CMD command,
3226 unsigned int data_len,
3227 const uint8_t *data)
3228 {
3229 struct cras_test_dev_command *msg;
3230 int rc;
3231
3232 msg = (struct cras_test_dev_command *)malloc(sizeof(*msg) + data_len);
3233 cras_fill_test_dev_command(msg, iodev_idx, command, data_len, data);
3234 rc = write_message_to_server(client, &msg->header);
3235 free(msg);
3236 return rc;
3237 }
3238
cras_client_config_global_remix(struct cras_client * client,unsigned num_channels,float * coefficient)3239 int cras_client_config_global_remix(struct cras_client *client,
3240 unsigned num_channels,
3241 float *coefficient)
3242 {
3243 struct cras_config_global_remix *msg;
3244 int rc;
3245
3246 msg = (struct cras_config_global_remix *)malloc(sizeof(*msg) +
3247 num_channels * num_channels * sizeof(*coefficient));
3248 cras_fill_config_global_remix_command(msg, num_channels,
3249 coefficient,
3250 num_channels * num_channels);
3251 rc = write_message_to_server(client, &msg->header);
3252 free(msg);
3253 return rc;
3254 }
3255
cras_client_get_first_node_type_idx(const struct cras_client * client,enum CRAS_NODE_TYPE type,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t * node_id)3256 int cras_client_get_first_node_type_idx(const struct cras_client *client,
3257 enum CRAS_NODE_TYPE type,
3258 enum CRAS_STREAM_DIRECTION direction,
3259 cras_node_id_t *node_id)
3260 {
3261 const struct cras_server_state *state;
3262 unsigned int version;
3263 unsigned int i;
3264 const struct cras_ionode_info *node_list;
3265 unsigned int num_nodes;
3266 int lock_rc;
3267
3268 lock_rc = server_state_rdlock(client);
3269 if (lock_rc)
3270 return -EINVAL;
3271 state = client->server_state;
3272
3273 read_nodes_again:
3274 version = begin_server_state_read(state);
3275 if (direction == CRAS_STREAM_OUTPUT) {
3276 node_list = state->output_nodes;
3277 num_nodes = state->num_output_nodes;
3278 } else {
3279 node_list = state->input_nodes;
3280 num_nodes = state->num_input_nodes;
3281 }
3282 for (i = 0; i < num_nodes; i++) {
3283 if ((enum CRAS_NODE_TYPE)node_list[i].type_enum == type) {
3284 *node_id = cras_make_node_id(node_list[i].iodev_idx,
3285 node_list[i].ionode_idx);
3286 server_state_unlock(client, lock_rc);
3287 return 0;
3288 }
3289 }
3290 if (end_server_state_read(state, version))
3291 goto read_nodes_again;
3292 server_state_unlock(client, lock_rc);
3293
3294 return -ENODEV;
3295 }
3296
cras_client_get_first_dev_type_idx(const struct cras_client * client,enum CRAS_NODE_TYPE type,enum CRAS_STREAM_DIRECTION direction)3297 int cras_client_get_first_dev_type_idx(const struct cras_client *client,
3298 enum CRAS_NODE_TYPE type,
3299 enum CRAS_STREAM_DIRECTION direction)
3300 {
3301 cras_node_id_t node_id;
3302 int rc;
3303
3304 rc = cras_client_get_first_node_type_idx(client, type, direction,
3305 &node_id);
3306 if (rc)
3307 return rc;
3308
3309 return dev_index_of(node_id);
3310 }
3311
cras_client_set_suspend(struct cras_client * client,int suspend)3312 int cras_client_set_suspend(struct cras_client *client, int suspend)
3313 {
3314 struct cras_server_message msg;
3315
3316 cras_fill_suspend_message(&msg, suspend);
3317 return write_message_to_server(client, &msg);
3318 }
3319
cras_client_get_hotword_models(struct cras_client * client,cras_node_id_t node_id,get_hotword_models_cb_t cb)3320 int cras_client_get_hotword_models(struct cras_client *client,
3321 cras_node_id_t node_id,
3322 get_hotword_models_cb_t cb)
3323 {
3324 struct cras_get_hotword_models msg;
3325
3326 if (!client)
3327 return -EINVAL;
3328 client->get_hotword_models_cb = cb;
3329
3330 cras_fill_get_hotword_models_message(&msg, node_id);
3331 return write_message_to_server(client, &msg.header);
3332 }
3333
cras_client_set_hotword_model(struct cras_client * client,cras_node_id_t node_id,const char * model_name)3334 int cras_client_set_hotword_model(struct cras_client *client,
3335 cras_node_id_t node_id,
3336 const char *model_name)
3337 {
3338 struct cras_set_hotword_model msg;
3339
3340 cras_fill_set_hotword_model_message(&msg, node_id, model_name);
3341 return write_message_to_server(client, &msg.header);
3342 }
3343
cras_client_set_aec_dump(struct cras_client * client,cras_stream_id_t stream_id,int start,int fd)3344 int cras_client_set_aec_dump(struct cras_client *client,
3345 cras_stream_id_t stream_id,
3346 int start,
3347 int fd)
3348 {
3349 struct cras_set_aec_dump msg;
3350
3351 cras_fill_set_aec_dump_message(&msg, stream_id, start);
3352
3353 if (fd != -1)
3354 return cras_send_with_fds(client->server_fd, &msg,
3355 sizeof(msg), &fd, 1);
3356 else
3357 return write_message_to_server(client, &msg.header);
3358 }
3359
cras_client_reload_aec_config(struct cras_client * client)3360 int cras_client_reload_aec_config(struct cras_client *client)
3361 {
3362 struct cras_reload_aec_config msg;
3363
3364 cras_fill_reload_aec_config(&msg);
3365 return write_message_to_server(client, &msg.header);
3366 }
3367
cras_client_get_aec_supported(struct cras_client * client)3368 int cras_client_get_aec_supported(struct cras_client *client)
3369 {
3370 int aec_supported;
3371 int lock_rc;
3372
3373 lock_rc = server_state_rdlock(client);
3374 if (lock_rc)
3375 return 0;
3376
3377 aec_supported = client->server_state->aec_supported;
3378 server_state_unlock(client, lock_rc);
3379 return aec_supported;
3380 }
3381
cras_client_set_state_change_callback_context(struct cras_client * client,void * context)3382 void cras_client_set_state_change_callback_context(
3383 struct cras_client *client, void *context)
3384 {
3385 if (!client)
3386 return;
3387 client->observer_context = context;
3388 }
3389
cras_send_register_notification(struct cras_client * client,enum CRAS_CLIENT_MESSAGE_ID msg_id,int do_register)3390 static int cras_send_register_notification(struct cras_client *client,
3391 enum CRAS_CLIENT_MESSAGE_ID msg_id,
3392 int do_register)
3393 {
3394 struct cras_register_notification msg;
3395 int rc;
3396
3397 /* This library automatically re-registers notifications when
3398 * reconnecting, so we can ignore message send failure due to no
3399 * connection. */
3400 cras_fill_register_notification_message(&msg, msg_id, do_register);
3401 rc = write_message_to_server(client, &msg.header);
3402 if (rc == -EPIPE)
3403 rc = 0;
3404 return rc;
3405 }
3406
cras_client_set_output_volume_changed_callback(struct cras_client * client,cras_client_output_volume_changed_callback cb)3407 int cras_client_set_output_volume_changed_callback(
3408 struct cras_client *client,
3409 cras_client_output_volume_changed_callback cb)
3410 {
3411 if (!client)
3412 return -EINVAL;
3413 client->observer_ops.output_volume_changed = cb;
3414 return cras_send_register_notification(
3415 client, CRAS_CLIENT_OUTPUT_VOLUME_CHANGED, cb != NULL);
3416 }
3417
cras_client_set_output_mute_changed_callback(struct cras_client * client,cras_client_output_mute_changed_callback cb)3418 int cras_client_set_output_mute_changed_callback(
3419 struct cras_client *client,
3420 cras_client_output_mute_changed_callback cb)
3421 {
3422 if (!client)
3423 return -EINVAL;
3424 client->observer_ops.output_mute_changed = cb;
3425 return cras_send_register_notification(
3426 client, CRAS_CLIENT_OUTPUT_MUTE_CHANGED, cb != NULL);
3427 }
3428
cras_client_set_capture_gain_changed_callback(struct cras_client * client,cras_client_capture_gain_changed_callback cb)3429 int cras_client_set_capture_gain_changed_callback(
3430 struct cras_client *client,
3431 cras_client_capture_gain_changed_callback cb)
3432 {
3433 if (!client)
3434 return -EINVAL;
3435 client->observer_ops.capture_gain_changed = cb;
3436 return cras_send_register_notification(
3437 client, CRAS_CLIENT_CAPTURE_GAIN_CHANGED, cb != NULL);
3438 }
3439
cras_client_set_capture_mute_changed_callback(struct cras_client * client,cras_client_capture_mute_changed_callback cb)3440 int cras_client_set_capture_mute_changed_callback(
3441 struct cras_client *client,
3442 cras_client_capture_mute_changed_callback cb)
3443 {
3444 if (!client)
3445 return -EINVAL;
3446 client->observer_ops.capture_mute_changed = cb;
3447 return cras_send_register_notification(
3448 client, CRAS_CLIENT_CAPTURE_MUTE_CHANGED, cb != NULL);
3449 }
3450
cras_client_set_nodes_changed_callback(struct cras_client * client,cras_client_nodes_changed_callback cb)3451 int cras_client_set_nodes_changed_callback(
3452 struct cras_client *client,
3453 cras_client_nodes_changed_callback cb)
3454 {
3455 if (!client)
3456 return -EINVAL;
3457 client->observer_ops.nodes_changed = cb;
3458 return cras_send_register_notification(
3459 client, CRAS_CLIENT_NODES_CHANGED, cb != NULL);
3460 }
3461
cras_client_set_active_node_changed_callback(struct cras_client * client,cras_client_active_node_changed_callback cb)3462 int cras_client_set_active_node_changed_callback(
3463 struct cras_client *client,
3464 cras_client_active_node_changed_callback cb)
3465 {
3466 if (!client)
3467 return -EINVAL;
3468 client->observer_ops.active_node_changed = cb;
3469 return cras_send_register_notification(
3470 client, CRAS_CLIENT_ACTIVE_NODE_CHANGED, cb != NULL);
3471 }
3472
cras_client_set_output_node_volume_changed_callback(struct cras_client * client,cras_client_output_node_volume_changed_callback cb)3473 int cras_client_set_output_node_volume_changed_callback(
3474 struct cras_client *client,
3475 cras_client_output_node_volume_changed_callback cb)
3476 {
3477 if (!client)
3478 return -EINVAL;
3479 client->observer_ops.output_node_volume_changed = cb;
3480 return cras_send_register_notification(
3481 client, CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED, cb != NULL);
3482 }
3483
cras_client_set_node_left_right_swapped_changed_callback(struct cras_client * client,cras_client_node_left_right_swapped_changed_callback cb)3484 int cras_client_set_node_left_right_swapped_changed_callback(
3485 struct cras_client *client,
3486 cras_client_node_left_right_swapped_changed_callback cb)
3487 {
3488 if (!client)
3489 return -EINVAL;
3490 client->observer_ops.node_left_right_swapped_changed = cb;
3491 return cras_send_register_notification(
3492 client, CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED, cb != NULL);
3493 }
3494
cras_client_set_input_node_gain_changed_callback(struct cras_client * client,cras_client_input_node_gain_changed_callback cb)3495 int cras_client_set_input_node_gain_changed_callback(
3496 struct cras_client *client,
3497 cras_client_input_node_gain_changed_callback cb)
3498 {
3499 if (!client)
3500 return -EINVAL;
3501 client->observer_ops.input_node_gain_changed = cb;
3502 return cras_send_register_notification(
3503 client, CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED, cb != NULL);
3504 }
3505
cras_client_set_num_active_streams_changed_callback(struct cras_client * client,cras_client_num_active_streams_changed_callback cb)3506 int cras_client_set_num_active_streams_changed_callback(
3507 struct cras_client *client,
3508 cras_client_num_active_streams_changed_callback cb)
3509 {
3510 if (!client)
3511 return -EINVAL;
3512 client->observer_ops.num_active_streams_changed = cb;
3513 return cras_send_register_notification(
3514 client, CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED, cb != NULL);
3515 }
3516
reregister_notifications(struct cras_client * client)3517 static int reregister_notifications(struct cras_client *client)
3518 {
3519 int rc;
3520
3521 if (client->observer_ops.output_volume_changed) {
3522 rc = cras_client_set_output_volume_changed_callback(
3523 client,
3524 client->observer_ops.output_volume_changed);
3525 if (rc != 0)
3526 return rc;
3527 }
3528 if (client->observer_ops.output_mute_changed) {
3529 rc = cras_client_set_output_mute_changed_callback(
3530 client,
3531 client->observer_ops.output_mute_changed);
3532 if (rc != 0)
3533 return rc;
3534 }
3535 if (client->observer_ops.capture_gain_changed) {
3536 rc = cras_client_set_capture_gain_changed_callback(
3537 client,
3538 client->observer_ops.capture_gain_changed);
3539 if (rc != 0)
3540 return rc;
3541 }
3542 if (client->observer_ops.capture_mute_changed) {
3543 rc = cras_client_set_capture_mute_changed_callback(
3544 client,
3545 client->observer_ops.capture_mute_changed);
3546 if (rc != 0)
3547 return rc;
3548 }
3549 if (client->observer_ops.nodes_changed) {
3550 rc = cras_client_set_nodes_changed_callback(
3551 client, client->observer_ops.nodes_changed);
3552 if (rc != 0)
3553 return rc;
3554 }
3555 if (client->observer_ops.active_node_changed) {
3556 rc = cras_client_set_active_node_changed_callback(
3557 client,
3558 client->observer_ops.active_node_changed);
3559 if (rc != 0)
3560 return rc;
3561 }
3562 if (client->observer_ops.output_node_volume_changed) {
3563 rc = cras_client_set_output_node_volume_changed_callback(
3564 client,
3565 client->observer_ops.output_node_volume_changed);
3566 if (rc != 0)
3567 return rc;
3568 }
3569 if (client->observer_ops.node_left_right_swapped_changed) {
3570 rc = cras_client_set_node_left_right_swapped_changed_callback(
3571 client,
3572 client->observer_ops.node_left_right_swapped_changed);
3573 if (rc != 0)
3574 return rc;
3575 }
3576 if (client->observer_ops.input_node_gain_changed) {
3577 rc = cras_client_set_input_node_gain_changed_callback(
3578 client,
3579 client->observer_ops.input_node_gain_changed);
3580 if (rc != 0)
3581 return rc;
3582 }
3583 if (client->observer_ops.num_active_streams_changed) {
3584 rc = cras_client_set_num_active_streams_changed_callback(
3585 client,
3586 client->observer_ops.num_active_streams_changed);
3587 if (rc != 0)
3588 return rc;
3589 }
3590 return 0;
3591 }
3592
hotword_read_cb(struct cras_client * client,cras_stream_id_t stream_id,uint8_t * captured_samples,uint8_t * playback_samples,unsigned int frames,const struct timespec * captured_time,const struct timespec * playback_time,void * user_arg)3593 static int hotword_read_cb(struct cras_client *client,
3594 cras_stream_id_t stream_id,
3595 uint8_t *captured_samples,
3596 uint8_t *playback_samples,
3597 unsigned int frames,
3598 const struct timespec *captured_time,
3599 const struct timespec *playback_time,
3600 void *user_arg)
3601 {
3602 struct cras_hotword_handle *handle;
3603
3604 handle = (struct cras_hotword_handle *)user_arg;
3605 if (handle->trigger_cb)
3606 handle->trigger_cb(client, handle, handle->user_data);
3607
3608 return 0;
3609 }
3610
hotword_err_cb(struct cras_client * client,cras_stream_id_t stream_id,int error,void * user_arg)3611 static int hotword_err_cb(struct cras_client *client,
3612 cras_stream_id_t stream_id,
3613 int error,
3614 void *user_arg)
3615 {
3616 struct cras_hotword_handle *handle;
3617
3618 handle = (struct cras_hotword_handle *)user_arg;
3619 if (handle->err_cb)
3620 handle->err_cb(client, handle, error, handle->user_data);
3621
3622 return 0;
3623 }
3624
cras_client_enable_hotword_callback(struct cras_client * client,void * user_data,cras_hotword_trigger_cb_t trigger_cb,cras_hotword_error_cb_t err_cb,struct cras_hotword_handle ** handle_out)3625 int cras_client_enable_hotword_callback(struct cras_client *client,
3626 void *user_data,
3627 cras_hotword_trigger_cb_t trigger_cb,
3628 cras_hotword_error_cb_t err_cb,
3629 struct cras_hotword_handle **handle_out)
3630 {
3631 struct cras_hotword_handle *handle;
3632 int ret = 0;
3633
3634 if (!client)
3635 return -EINVAL;
3636
3637 handle = (struct cras_hotword_handle *)calloc(1, sizeof(*handle));
3638 if (!handle)
3639 return -ENOMEM;
3640
3641 handle->format = cras_audio_format_create(SND_PCM_FORMAT_S16_LE,
3642 HOTWORD_FRAME_RATE, 1);
3643 if (!handle->format) {
3644 ret = -ENOMEM;
3645 goto cleanup;
3646 }
3647
3648 handle->params = cras_client_unified_params_create(
3649 CRAS_STREAM_INPUT,
3650 HOTWORD_BLOCK_SIZE,
3651 CRAS_STREAM_TYPE_DEFAULT,
3652 HOTWORD_STREAM | TRIGGER_ONLY,
3653 (void *)handle,
3654 hotword_read_cb,
3655 hotword_err_cb,
3656 handle->format);
3657 if (!handle->params) {
3658 ret = -ENOMEM;
3659 goto cleanup_format;
3660 }
3661
3662 handle->trigger_cb = trigger_cb;
3663 handle->err_cb = err_cb;
3664 handle->user_data = user_data;
3665
3666 ret = cras_client_add_stream(client, &handle->stream_id,
3667 handle->params);
3668 if (ret)
3669 goto cleanup_params;
3670
3671 *handle_out = handle;
3672 return 0;
3673
3674 cleanup_params:
3675 cras_client_stream_params_destroy(handle->params);
3676 cleanup_format:
3677 cras_audio_format_destroy(handle->format);
3678 cleanup:
3679 free(handle);
3680 return ret;
3681 }
3682
cras_client_disable_hotword_callback(struct cras_client * client,struct cras_hotword_handle * handle)3683 int cras_client_disable_hotword_callback(struct cras_client *client,
3684 struct cras_hotword_handle *handle)
3685 {
3686 if (!client || !handle)
3687 return -EINVAL;
3688
3689 cras_client_rm_stream(client, handle->stream_id);
3690 cras_audio_format_destroy(handle->format);
3691 cras_client_stream_params_destroy(handle->params);
3692 free(handle);
3693 return 0;
3694 }
3695