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