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