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