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