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  * Messages sent between the server and clients.
8  */
9 #ifndef CRAS_MESSAGES_H_
10 #define CRAS_MESSAGES_H_
11 
12 #include <stdint.h>
13 
14 #include "cras_iodev_info.h"
15 #include "cras_types.h"
16 
17 /* Rev when message format changes. If new messages are added, or message ID
18  * values change. */
19 #define CRAS_PROTO_VER 7
20 #define CRAS_SERV_MAX_MSG_SIZE 256
21 #define CRAS_CLIENT_MAX_MSG_SIZE 256
22 #define CRAS_MAX_HOTWORD_MODELS 243
23 #define CRAS_MAX_REMIX_CHANNELS 8
24 #define CRAS_MAX_TEST_DATA_LEN 224
25 #define CRAS_AEC_DUMP_FILE_NAME_LEN 128
26 
27 /* Message IDs. */
28 enum CRAS_SERVER_MESSAGE_ID {
29 	/* Client -> Server*/
30 	CRAS_SERVER_CONNECT_STREAM,
31 	CRAS_SERVER_DISCONNECT_STREAM,
32 	CRAS_SERVER_SWITCH_STREAM_TYPE_IODEV, /* Unused */
33 	CRAS_SERVER_SET_SYSTEM_VOLUME,
34 	CRAS_SERVER_SET_SYSTEM_MUTE,
35 	CRAS_SERVER_SET_USER_MUTE,
36 	CRAS_SERVER_SET_SYSTEM_MUTE_LOCKED,
37 	CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN, /* Deprecated */
38 	CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE,
39 	CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE_LOCKED,
40 	CRAS_SERVER_SET_NODE_ATTR,
41 	CRAS_SERVER_SELECT_NODE,
42 	CRAS_SERVER_RELOAD_DSP,
43 	CRAS_SERVER_DUMP_DSP_INFO,
44 	CRAS_SERVER_DUMP_AUDIO_THREAD,
45 	CRAS_SERVER_DUMP_SNAPSHOTS,
46 	CRAS_SERVER_ADD_ACTIVE_NODE,
47 	CRAS_SERVER_RM_ACTIVE_NODE,
48 	CRAS_SERVER_ADD_TEST_DEV,
49 	CRAS_SERVER_TEST_DEV_COMMAND,
50 	CRAS_SERVER_SUSPEND,
51 	CRAS_SERVER_RESUME,
52 	CRAS_CONFIG_GLOBAL_REMIX,
53 	CRAS_SERVER_GET_HOTWORD_MODELS,
54 	CRAS_SERVER_SET_HOTWORD_MODEL,
55 	CRAS_SERVER_REGISTER_NOTIFICATION,
56 	CRAS_SERVER_SET_AEC_DUMP,
57 	CRAS_SERVER_RELOAD_AEC_CONFIG,
58 	CRAS_SERVER_DUMP_BT,
59 	CRAS_SERVER_SET_BT_WBS_ENABLED,
60 	CRAS_SERVER_GET_ATLOG_FD,
61 	CRAS_SERVER_DUMP_MAIN,
62 };
63 
64 enum CRAS_CLIENT_MESSAGE_ID {
65 	/* Server -> Client */
66 	CRAS_CLIENT_CONNECTED,
67 	CRAS_CLIENT_STREAM_CONNECTED,
68 	CRAS_CLIENT_AUDIO_DEBUG_INFO_READY,
69 	CRAS_CLIENT_GET_HOTWORD_MODELS_READY,
70 	/* System status messages */
71 	CRAS_CLIENT_OUTPUT_VOLUME_CHANGED,
72 	CRAS_CLIENT_OUTPUT_MUTE_CHANGED,
73 	CRAS_CLIENT_CAPTURE_GAIN_CHANGED,
74 	CRAS_CLIENT_CAPTURE_MUTE_CHANGED,
75 	CRAS_CLIENT_NODES_CHANGED,
76 	CRAS_CLIENT_ACTIVE_NODE_CHANGED,
77 	CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED,
78 	CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED,
79 	CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED,
80 	CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED,
81 	/* Server -> Client */
82 	CRAS_CLIENT_ATLOG_FD_READY,
83 };
84 
85 /* Messages that control the server. These are sent from the client to affect
86  * and action on the server. */
87 struct __attribute__((__packed__)) cras_server_message {
88 	uint32_t length;
89 	enum CRAS_SERVER_MESSAGE_ID id;
90 };
91 
92 /* Messages that control the client. These are sent from the server to affect
93  * and action on the client. */
94 struct __attribute__((__packed__)) cras_client_message {
95 	uint32_t length;
96 	enum CRAS_CLIENT_MESSAGE_ID id;
97 };
98 
99 /*
100  * Messages from client to server.
101  */
102 
103 /* Sent by a client to connect a stream to the server. */
104 struct __attribute__((__packed__)) cras_connect_message {
105 	struct cras_server_message header;
106 	uint32_t proto_version;
107 	enum CRAS_STREAM_DIRECTION direction; /* input/output/loopback */
108 	cras_stream_id_t stream_id; /* unique id for this stream */
109 	enum CRAS_STREAM_TYPE stream_type; /* media, or call, etc. */
110 	uint32_t buffer_frames; /* Buffer size in frames. */
111 	uint32_t cb_threshold; /* callback client when this much is left */
112 	uint32_t flags;
113 	struct cras_audio_format_packed format; /* rate, channel, sample size */
114 	uint32_t dev_idx; /* device to attach stream, 0 if none */
115 	uint64_t effects; /* Bit map of requested effects. */
116 	enum CRAS_CLIENT_TYPE client_type; /* chrome, or arc, etc. */
117 	uint64_t client_shm_size; /* Size of client-provided samples shm, if any */
118 	/* Initial values for shm samples buffer offsets. These will be 0 for
119 	 * streams that do not use client-provided shm */
120 	uint64_t buffer_offsets[2];
121 };
122 
cras_fill_connect_message(struct cras_connect_message * m,enum CRAS_STREAM_DIRECTION direction,cras_stream_id_t stream_id,enum CRAS_STREAM_TYPE stream_type,enum CRAS_CLIENT_TYPE client_type,size_t buffer_frames,size_t cb_threshold,uint32_t flags,uint64_t effects,struct cras_audio_format format,uint32_t dev_idx)123 static inline void cras_fill_connect_message(
124 	struct cras_connect_message *m, enum CRAS_STREAM_DIRECTION direction,
125 	cras_stream_id_t stream_id, enum CRAS_STREAM_TYPE stream_type,
126 	enum CRAS_CLIENT_TYPE client_type, size_t buffer_frames,
127 	size_t cb_threshold, uint32_t flags, uint64_t effects,
128 	struct cras_audio_format format, uint32_t dev_idx)
129 {
130 	m->proto_version = CRAS_PROTO_VER;
131 	m->direction = direction;
132 	m->stream_id = stream_id;
133 	m->stream_type = stream_type;
134 	m->buffer_frames = buffer_frames;
135 	m->cb_threshold = cb_threshold;
136 	m->flags = flags;
137 	m->effects = effects;
138 	pack_cras_audio_format(&m->format, &format);
139 	m->dev_idx = dev_idx;
140 	m->client_type = client_type;
141 	m->client_shm_size = 0;
142 	m->buffer_offsets[0] = 0;
143 	m->buffer_offsets[1] = 0;
144 	m->header.id = CRAS_SERVER_CONNECT_STREAM;
145 	m->header.length = sizeof(struct cras_connect_message);
146 }
147 
148 /* Sent by a client to remove a stream from the server. */
149 struct __attribute__((__packed__)) cras_disconnect_stream_message {
150 	struct cras_server_message header;
151 	cras_stream_id_t stream_id;
152 };
153 static inline void
cras_fill_disconnect_stream_message(struct cras_disconnect_stream_message * m,cras_stream_id_t stream_id)154 cras_fill_disconnect_stream_message(struct cras_disconnect_stream_message *m,
155 				    cras_stream_id_t stream_id)
156 {
157 	m->stream_id = stream_id;
158 	m->header.id = CRAS_SERVER_DISCONNECT_STREAM;
159 	m->header.length = sizeof(struct cras_disconnect_stream_message);
160 }
161 
162 /* Move streams of "type" to the iodev at "iodev_idx". */
163 struct __attribute__((__packed__)) cras_switch_stream_type_iodev {
164 	struct cras_server_message header;
165 	enum CRAS_STREAM_TYPE stream_type;
166 	uint32_t iodev_idx;
167 };
168 
169 /* Set the system volume. */
170 struct __attribute__((__packed__)) cras_set_system_volume {
171 	struct cras_server_message header;
172 	uint32_t volume;
173 };
cras_fill_set_system_volume(struct cras_set_system_volume * m,size_t volume)174 static inline void cras_fill_set_system_volume(struct cras_set_system_volume *m,
175 					       size_t volume)
176 {
177 	m->volume = volume;
178 	m->header.id = CRAS_SERVER_SET_SYSTEM_VOLUME;
179 	m->header.length = sizeof(*m);
180 }
181 
182 /* Set the system mute state. */
183 struct __attribute__((__packed__)) cras_set_system_mute {
184 	struct cras_server_message header;
185 	int32_t mute; /* 0 = un-mute, 1 = mute. */
186 };
cras_fill_set_system_mute(struct cras_set_system_mute * m,int mute)187 static inline void cras_fill_set_system_mute(struct cras_set_system_mute *m,
188 					     int mute)
189 {
190 	m->mute = mute;
191 	m->header.id = CRAS_SERVER_SET_SYSTEM_MUTE;
192 	m->header.length = sizeof(*m);
193 }
cras_fill_set_user_mute(struct cras_set_system_mute * m,int mute)194 static inline void cras_fill_set_user_mute(struct cras_set_system_mute *m,
195 					   int mute)
196 {
197 	m->mute = mute;
198 	m->header.id = CRAS_SERVER_SET_USER_MUTE;
199 	m->header.length = sizeof(*m);
200 }
201 static inline void
cras_fill_set_system_mute_locked(struct cras_set_system_mute * m,int locked)202 cras_fill_set_system_mute_locked(struct cras_set_system_mute *m, int locked)
203 {
204 	m->mute = locked;
205 	m->header.id = CRAS_SERVER_SET_SYSTEM_MUTE_LOCKED;
206 	m->header.length = sizeof(*m);
207 }
208 static inline void
cras_fill_set_system_capture_mute(struct cras_set_system_mute * m,int mute)209 cras_fill_set_system_capture_mute(struct cras_set_system_mute *m, int mute)
210 {
211 	m->mute = mute;
212 	m->header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE;
213 	m->header.length = sizeof(*m);
214 }
215 static inline void
cras_fill_set_system_capture_mute_locked(struct cras_set_system_mute * m,int locked)216 cras_fill_set_system_capture_mute_locked(struct cras_set_system_mute *m,
217 					 int locked)
218 {
219 	m->mute = locked;
220 	m->header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE_LOCKED;
221 	m->header.length = sizeof(*m);
222 }
223 
224 /* Set an attribute of an ionode. */
225 struct __attribute__((__packed__)) cras_set_node_attr {
226 	struct cras_server_message header;
227 	cras_node_id_t node_id;
228 	enum ionode_attr attr;
229 	int32_t value;
230 };
cras_fill_set_node_attr(struct cras_set_node_attr * m,cras_node_id_t node_id,enum ionode_attr attr,int value)231 static inline void cras_fill_set_node_attr(struct cras_set_node_attr *m,
232 					   cras_node_id_t node_id,
233 					   enum ionode_attr attr, int value)
234 {
235 	m->header.id = CRAS_SERVER_SET_NODE_ATTR;
236 	m->node_id = node_id;
237 	m->attr = attr;
238 	m->value = value;
239 	m->header.length = sizeof(*m);
240 }
241 
242 /* Set an attribute of an ionode. */
243 struct __attribute__((__packed__)) cras_select_node {
244 	struct cras_server_message header;
245 	enum CRAS_STREAM_DIRECTION direction;
246 	cras_node_id_t node_id;
247 };
cras_fill_select_node(struct cras_select_node * m,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)248 static inline void cras_fill_select_node(struct cras_select_node *m,
249 					 enum CRAS_STREAM_DIRECTION direction,
250 					 cras_node_id_t node_id)
251 {
252 	m->header.id = CRAS_SERVER_SELECT_NODE;
253 	m->direction = direction;
254 	m->node_id = node_id;
255 	m->header.length = sizeof(*m);
256 }
257 
258 /* Add an active ionode. */
259 struct __attribute__((__packed__)) cras_add_active_node {
260 	struct cras_server_message header;
261 	enum CRAS_STREAM_DIRECTION direction;
262 	cras_node_id_t node_id;
263 };
264 static inline void
cras_fill_add_active_node(struct cras_add_active_node * m,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)265 cras_fill_add_active_node(struct cras_add_active_node *m,
266 			  enum CRAS_STREAM_DIRECTION direction,
267 			  cras_node_id_t node_id)
268 {
269 	m->header.id = CRAS_SERVER_ADD_ACTIVE_NODE;
270 	m->direction = direction;
271 	m->node_id = node_id;
272 	m->header.length = sizeof(*m);
273 }
274 
275 /* Remove an active ionode. */
276 struct __attribute__((__packed__)) cras_rm_active_node {
277 	struct cras_server_message header;
278 	enum CRAS_STREAM_DIRECTION direction;
279 	cras_node_id_t node_id;
280 };
281 static inline void
cras_fill_rm_active_node(struct cras_rm_active_node * m,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)282 cras_fill_rm_active_node(struct cras_rm_active_node *m,
283 			 enum CRAS_STREAM_DIRECTION direction,
284 			 cras_node_id_t node_id)
285 {
286 	m->header.id = CRAS_SERVER_RM_ACTIVE_NODE;
287 	m->direction = direction;
288 	m->node_id = node_id;
289 	m->header.length = sizeof(*m);
290 }
291 
292 /* Reload the dsp configuration. */
293 struct __attribute__((__packed__)) cras_reload_dsp {
294 	struct cras_server_message header;
295 };
cras_fill_reload_dsp(struct cras_reload_dsp * m)296 static inline void cras_fill_reload_dsp(struct cras_reload_dsp *m)
297 {
298 	m->header.id = CRAS_SERVER_RELOAD_DSP;
299 	m->header.length = sizeof(*m);
300 }
301 
302 /* Dump current dsp information to syslog. */
303 struct __attribute__((__packed__)) cras_dump_dsp_info {
304 	struct cras_server_message header;
305 };
306 
cras_fill_dump_dsp_info(struct cras_dump_dsp_info * m)307 static inline void cras_fill_dump_dsp_info(struct cras_dump_dsp_info *m)
308 {
309 	m->header.id = CRAS_SERVER_DUMP_DSP_INFO;
310 	m->header.length = sizeof(*m);
311 }
312 
313 /* Dump current audio thread information to syslog. */
314 struct __attribute__((__packed__)) cras_dump_audio_thread {
315 	struct cras_server_message header;
316 };
317 
cras_fill_dump_audio_thread(struct cras_dump_audio_thread * m)318 static inline void cras_fill_dump_audio_thread(struct cras_dump_audio_thread *m)
319 {
320 	m->header.id = CRAS_SERVER_DUMP_AUDIO_THREAD;
321 	m->header.length = sizeof(*m);
322 }
323 
324 struct __attribute__((__packed__)) cras_get_atlog_fd {
325 	struct cras_server_message header;
326 };
327 
cras_fill_get_atlog_fd(struct cras_get_atlog_fd * m)328 static inline void cras_fill_get_atlog_fd(struct cras_get_atlog_fd *m)
329 {
330 	m->header.id = CRAS_SERVER_GET_ATLOG_FD;
331 	m->header.length = sizeof(*m);
332 }
333 
334 /* Dump events in CRAS main thread. */
335 struct __attribute__((__packed__)) cras_dump_main {
336 	struct cras_server_message header;
337 };
338 
cras_fill_dump_main(struct cras_dump_main * m)339 static inline void cras_fill_dump_main(struct cras_dump_main *m)
340 {
341 	m->header.id = CRAS_SERVER_DUMP_MAIN;
342 	m->header.length = sizeof(*m);
343 }
344 
345 /* Dump bluetooth events and state changes. */
346 struct __attribute__((__packed__)) cras_dump_bt {
347 	struct cras_server_message header;
348 };
349 
cras_fill_dump_bt(struct cras_dump_bt * m)350 static inline void cras_fill_dump_bt(struct cras_dump_bt *m)
351 {
352 	m->header.id = CRAS_SERVER_DUMP_BT;
353 	m->header.length = sizeof(*m);
354 }
355 
356 /* Dump current audio thread snapshots to shard memory with the client. */
357 struct __attribute__((__packed__)) cras_dump_snapshots {
358 	struct cras_server_message header;
359 };
360 
cras_fill_dump_snapshots(struct cras_dump_snapshots * m)361 static inline void cras_fill_dump_snapshots(struct cras_dump_snapshots *m)
362 {
363 	m->header.id = CRAS_SERVER_DUMP_SNAPSHOTS;
364 	m->header.length = sizeof(*m);
365 }
366 
367 /* Add a test device. */
368 struct __attribute__((__packed__)) cras_add_test_dev {
369 	struct cras_server_message header;
370 	enum TEST_IODEV_TYPE type;
371 };
372 
cras_fill_add_test_dev(struct cras_add_test_dev * m,enum TEST_IODEV_TYPE type)373 static inline void cras_fill_add_test_dev(struct cras_add_test_dev *m,
374 					  enum TEST_IODEV_TYPE type)
375 {
376 	m->header.id = CRAS_SERVER_ADD_TEST_DEV;
377 	m->header.length = sizeof(*m);
378 	m->type = type;
379 }
380 
381 /* Command a test device. */
382 struct __attribute__((__packed__)) cras_test_dev_command {
383 	struct cras_server_message header;
384 	unsigned int command;
385 	unsigned int iodev_idx;
386 	unsigned int data_len;
387 	uint8_t data[CRAS_MAX_TEST_DATA_LEN];
388 };
389 
cras_fill_test_dev_command(struct cras_test_dev_command * m,unsigned int iodev_idx,enum CRAS_TEST_IODEV_CMD command,unsigned int data_len,const uint8_t * data)390 static inline void cras_fill_test_dev_command(struct cras_test_dev_command *m,
391 					      unsigned int iodev_idx,
392 					      enum CRAS_TEST_IODEV_CMD command,
393 					      unsigned int data_len,
394 					      const uint8_t *data)
395 {
396 	m->header.id = CRAS_SERVER_TEST_DEV_COMMAND;
397 	m->header.length = sizeof(*m) + data_len;
398 	m->iodev_idx = iodev_idx;
399 	m->command = command;
400 	m->data_len = data_len;
401 	memcpy(m->data, data, data_len);
402 }
403 
cras_fill_suspend_message(struct cras_server_message * m,int is_suspend)404 static inline void cras_fill_suspend_message(struct cras_server_message *m,
405 					     int is_suspend)
406 {
407 	m->id = is_suspend ? CRAS_SERVER_SUSPEND : CRAS_SERVER_RESUME;
408 	m->length = sizeof(*m);
409 }
410 
411 /*
412  * Configures the global remix converter.
413  * `num_channels` must be less than `CRAS_MAX_REMIX_CHANNELS`.
414  */
415 struct __attribute__((__packed__)) cras_config_global_remix {
416 	struct cras_server_message header;
417 	unsigned int num_channels;
418 	float coefficient[CRAS_MAX_REMIX_CHANNELS * CRAS_MAX_REMIX_CHANNELS];
419 };
420 
421 static inline void
cras_fill_config_global_remix_command(struct cras_config_global_remix * m,unsigned int num_channels,float * coeff,unsigned int count)422 cras_fill_config_global_remix_command(struct cras_config_global_remix *m,
423 				      unsigned int num_channels, float *coeff,
424 				      unsigned int count)
425 {
426 	m->header.id = CRAS_CONFIG_GLOBAL_REMIX;
427 	m->header.length = sizeof(*m) + count * sizeof(*coeff);
428 	m->num_channels = num_channels;
429 	memcpy(m->coefficient, coeff, count * sizeof(*coeff));
430 }
431 
432 /* Get supported hotword models. */
433 struct __attribute__((__packed__)) cras_get_hotword_models {
434 	struct cras_server_message header;
435 	cras_node_id_t node_id;
436 };
437 
438 static inline void
cras_fill_get_hotword_models_message(struct cras_get_hotword_models * m,cras_node_id_t node_id)439 cras_fill_get_hotword_models_message(struct cras_get_hotword_models *m,
440 				     cras_node_id_t node_id)
441 {
442 	m->header.id = CRAS_SERVER_GET_HOTWORD_MODELS;
443 	m->header.length = sizeof(*m);
444 	m->node_id = node_id;
445 }
446 
447 /* Set desired hotword model. */
448 struct __attribute__((__packed__)) cras_set_hotword_model {
449 	struct cras_server_message header;
450 	cras_node_id_t node_id;
451 	char model_name[CRAS_MAX_HOTWORD_MODEL_NAME_SIZE];
452 };
453 
454 static inline void
cras_fill_set_hotword_model_message(struct cras_set_hotword_model * m,cras_node_id_t node_id,const char * model_name)455 cras_fill_set_hotword_model_message(struct cras_set_hotword_model *m,
456 				    cras_node_id_t node_id,
457 				    const char *model_name)
458 {
459 	m->header.id = CRAS_SERVER_SET_HOTWORD_MODEL;
460 	m->header.length = sizeof(*m);
461 	m->node_id = node_id;
462 	memcpy(m->model_name, model_name, CRAS_MAX_HOTWORD_MODEL_NAME_SIZE);
463 }
464 
465 /* Set aec dump to start or stop. */
466 struct __attribute__((__packed__)) cras_set_aec_dump {
467 	struct cras_server_message header;
468 	cras_stream_id_t stream_id;
469 	unsigned int start;
470 };
471 
cras_fill_set_aec_dump_message(struct cras_set_aec_dump * m,cras_stream_id_t stream_id,unsigned int start)472 static inline void cras_fill_set_aec_dump_message(struct cras_set_aec_dump *m,
473 						  cras_stream_id_t stream_id,
474 						  unsigned int start)
475 {
476 	m->header.id = CRAS_SERVER_SET_AEC_DUMP;
477 	m->header.length = sizeof(*m);
478 	m->stream_id = stream_id;
479 	m->start = start;
480 }
481 
482 /* Reload the aec configuration. */
483 struct __attribute__((__packed__)) cras_reload_aec_config {
484 	struct cras_server_message header;
485 };
cras_fill_reload_aec_config(struct cras_reload_aec_config * m)486 static inline void cras_fill_reload_aec_config(struct cras_reload_aec_config *m)
487 {
488 	m->header.id = CRAS_SERVER_RELOAD_AEC_CONFIG;
489 	m->header.length = sizeof(*m);
490 }
491 
492 /* Sets the flag to enable or disable bluetooth wideband speech feature. */
493 struct __attribute__((__packed__)) cras_set_bt_wbs_enabled {
494 	struct cras_server_message header;
495 	unsigned int enabled;
496 };
497 static inline void
cras_fill_set_bt_wbs_enabled(struct cras_set_bt_wbs_enabled * m,unsigned int enabled)498 cras_fill_set_bt_wbs_enabled(struct cras_set_bt_wbs_enabled *m,
499 			     unsigned int enabled)
500 {
501 	m->header.id = CRAS_SERVER_SET_BT_WBS_ENABLED;
502 	m->header.length = sizeof(*m);
503 	m->enabled = enabled;
504 }
505 
506 struct __attribute__((__packed__)) cras_register_notification {
507 	struct cras_server_message header;
508 	uint32_t msg_id;
509 	int do_register;
510 };
511 static inline void
cras_fill_register_notification_message(struct cras_register_notification * m,enum CRAS_CLIENT_MESSAGE_ID msg_id,int do_register)512 cras_fill_register_notification_message(struct cras_register_notification *m,
513 					enum CRAS_CLIENT_MESSAGE_ID msg_id,
514 					int do_register)
515 {
516 	m->header.id = CRAS_SERVER_REGISTER_NOTIFICATION;
517 	m->header.length = sizeof(*m);
518 	m->msg_id = msg_id;
519 	m->do_register = do_register;
520 }
521 
522 /*
523  * Messages sent from server to client.
524  */
525 
526 /* Reply from the server indicating that the client has connected. */
527 struct __attribute__((__packed__)) cras_client_connected {
528 	struct cras_client_message header;
529 	uint32_t client_id;
530 };
cras_fill_client_connected(struct cras_client_connected * m,size_t client_id)531 static inline void cras_fill_client_connected(struct cras_client_connected *m,
532 					      size_t client_id)
533 {
534 	m->client_id = client_id;
535 	m->header.id = CRAS_CLIENT_CONNECTED;
536 	m->header.length = sizeof(struct cras_client_connected);
537 }
538 
539 /*
540  * Reply from server that a stream has been successfully added.
541  * Two file descriptors are added, input shm followed by out shm.
542  *
543  * |samples_shm_size| is valid for normal streams, not client-provided
544  * shm streams.
545  */
546 struct __attribute__((__packed__)) cras_client_stream_connected {
547 	struct cras_client_message header;
548 	int32_t err;
549 	cras_stream_id_t stream_id;
550 	struct cras_audio_format_packed format;
551 	uint32_t samples_shm_size;
552 	uint64_t effects;
553 };
554 
555 static inline void
cras_fill_client_stream_connected(struct cras_client_stream_connected * m,int err,cras_stream_id_t stream_id,struct cras_audio_format * format,size_t samples_shm_size,uint64_t effects)556 cras_fill_client_stream_connected(struct cras_client_stream_connected *m,
557 				  int err, cras_stream_id_t stream_id,
558 				  struct cras_audio_format *format,
559 				  size_t samples_shm_size, uint64_t effects)
560 {
561 	m->err = err;
562 	m->stream_id = stream_id;
563 	pack_cras_audio_format(&m->format, format);
564 	if (samples_shm_size > UINT32_MAX) {
565 		samples_shm_size = UINT32_MAX;
566 	}
567 	m->samples_shm_size = samples_shm_size;
568 	m->effects = effects;
569 	m->header.id = CRAS_CLIENT_STREAM_CONNECTED;
570 	m->header.length = sizeof(struct cras_client_stream_connected);
571 }
572 
573 /* Sent from server to client when audio debug information is requested. */
574 struct __attribute__((__packed__)) cras_client_audio_debug_info_ready {
575 	struct cras_client_message header;
576 };
cras_fill_client_audio_debug_info_ready(struct cras_client_audio_debug_info_ready * m)577 static inline void cras_fill_client_audio_debug_info_ready(
578 	struct cras_client_audio_debug_info_ready *m)
579 {
580 	m->header.id = CRAS_CLIENT_AUDIO_DEBUG_INFO_READY;
581 	m->header.length = sizeof(*m);
582 }
583 
584 struct __attribute__((__packed__)) cras_client_atlog_fd_ready {
585 	struct cras_client_message header;
586 };
587 
588 static inline void
cras_fill_client_atlog_fd_ready(struct cras_client_atlog_fd_ready * m)589 cras_fill_client_atlog_fd_ready(struct cras_client_atlog_fd_ready *m)
590 {
591 	m->header.id = CRAS_CLIENT_ATLOG_FD_READY;
592 	m->header.length = sizeof(*m);
593 }
594 
595 /* Sent from server to client when hotword models info is ready. */
596 struct __attribute__((__packed__)) cras_client_get_hotword_models_ready {
597 	struct cras_client_message header;
598 	int32_t hotword_models_size;
599 	uint8_t hotword_models[CRAS_MAX_HOTWORD_MODELS + 1];
600 };
cras_fill_client_get_hotword_models_ready(struct cras_client_get_hotword_models_ready * m,const char * hotword_models,size_t hotword_models_size)601 static inline void cras_fill_client_get_hotword_models_ready(
602 	struct cras_client_get_hotword_models_ready *m,
603 	const char *hotword_models, size_t hotword_models_size)
604 {
605 	m->header.id = CRAS_CLIENT_GET_HOTWORD_MODELS_READY;
606 	m->header.length = sizeof(*m);
607 	m->hotword_models_size = hotword_models_size;
608 	/* Copy string data with terminator. */
609 	if (hotword_models) {
610 		strncpy((char *)m->hotword_models, hotword_models,
611 			CRAS_MAX_HOTWORD_MODELS);
612 		m->hotword_models[CRAS_MAX_HOTWORD_MODELS] = '\0';
613 	}
614 }
615 
616 /* System status messages sent from server to client when state changes. */
617 struct __attribute__((__packed__)) cras_client_volume_changed {
618 	struct cras_client_message header;
619 	int32_t volume;
620 };
621 static inline void
cras_fill_client_output_volume_changed(struct cras_client_volume_changed * m,int32_t volume)622 cras_fill_client_output_volume_changed(struct cras_client_volume_changed *m,
623 				       int32_t volume)
624 {
625 	m->header.id = CRAS_CLIENT_OUTPUT_VOLUME_CHANGED;
626 	m->header.length = sizeof(*m);
627 	m->volume = volume;
628 }
629 static inline void
cras_fill_client_capture_gain_changed(struct cras_client_volume_changed * m,int32_t gain)630 cras_fill_client_capture_gain_changed(struct cras_client_volume_changed *m,
631 				      int32_t gain)
632 {
633 	m->header.id = CRAS_CLIENT_CAPTURE_GAIN_CHANGED;
634 	m->header.length = sizeof(*m);
635 	m->volume = gain;
636 }
637 
638 struct __attribute__((__packed__)) cras_client_mute_changed {
639 	struct cras_client_message header;
640 	int32_t muted;
641 	int32_t user_muted;
642 	int32_t mute_locked;
643 };
644 static inline void
cras_fill_client_output_mute_changed(struct cras_client_mute_changed * m,int32_t muted,int32_t user_muted,int32_t mute_locked)645 cras_fill_client_output_mute_changed(struct cras_client_mute_changed *m,
646 				     int32_t muted, int32_t user_muted,
647 				     int32_t mute_locked)
648 {
649 	m->header.id = CRAS_CLIENT_OUTPUT_MUTE_CHANGED;
650 	m->header.length = sizeof(*m);
651 	m->muted = muted;
652 	m->user_muted = user_muted;
653 	m->mute_locked = mute_locked;
654 }
655 static inline void
cras_fill_client_capture_mute_changed(struct cras_client_mute_changed * m,int32_t muted,int32_t mute_locked)656 cras_fill_client_capture_mute_changed(struct cras_client_mute_changed *m,
657 				      int32_t muted, int32_t mute_locked)
658 {
659 	m->header.id = CRAS_CLIENT_CAPTURE_MUTE_CHANGED;
660 	m->header.length = sizeof(*m);
661 	m->muted = muted;
662 	m->user_muted = 0;
663 	m->mute_locked = mute_locked;
664 }
665 
666 struct __attribute__((__packed__)) cras_client_nodes_changed {
667 	struct cras_client_message header;
668 };
669 static inline void
cras_fill_client_nodes_changed(struct cras_client_nodes_changed * m)670 cras_fill_client_nodes_changed(struct cras_client_nodes_changed *m)
671 {
672 	m->header.id = CRAS_CLIENT_NODES_CHANGED;
673 	m->header.length = sizeof(*m);
674 }
675 
676 struct __attribute__((__packed__)) cras_client_active_node_changed {
677 	struct cras_client_message header;
678 	uint32_t direction;
679 	cras_node_id_t node_id;
680 };
681 static inline void
cras_fill_client_active_node_changed(struct cras_client_active_node_changed * m,enum CRAS_STREAM_DIRECTION direction,cras_node_id_t node_id)682 cras_fill_client_active_node_changed(struct cras_client_active_node_changed *m,
683 				     enum CRAS_STREAM_DIRECTION direction,
684 				     cras_node_id_t node_id)
685 {
686 	m->header.id = CRAS_CLIENT_ACTIVE_NODE_CHANGED;
687 	m->header.length = sizeof(*m);
688 	m->direction = direction;
689 	m->node_id = node_id;
690 };
691 
692 struct __attribute__((__packed__)) cras_client_node_value_changed {
693 	struct cras_client_message header;
694 	cras_node_id_t node_id;
695 	int32_t value;
696 };
cras_fill_client_output_node_volume_changed(struct cras_client_node_value_changed * m,cras_node_id_t node_id,int32_t volume)697 static inline void cras_fill_client_output_node_volume_changed(
698 	struct cras_client_node_value_changed *m, cras_node_id_t node_id,
699 	int32_t volume)
700 {
701 	m->header.id = CRAS_CLIENT_OUTPUT_NODE_VOLUME_CHANGED;
702 	m->header.length = sizeof(*m);
703 	m->node_id = node_id;
704 	m->value = volume;
705 };
cras_fill_client_node_left_right_swapped_changed(struct cras_client_node_value_changed * m,cras_node_id_t node_id,int swapped)706 static inline void cras_fill_client_node_left_right_swapped_changed(
707 	struct cras_client_node_value_changed *m, cras_node_id_t node_id,
708 	int swapped)
709 {
710 	m->header.id = CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED;
711 	m->header.length = sizeof(*m);
712 	m->node_id = node_id;
713 	m->value = swapped;
714 };
cras_fill_client_input_node_gain_changed(struct cras_client_node_value_changed * m,cras_node_id_t node_id,int32_t gain)715 static inline void cras_fill_client_input_node_gain_changed(
716 	struct cras_client_node_value_changed *m, cras_node_id_t node_id,
717 	int32_t gain)
718 {
719 	m->header.id = CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED;
720 	m->header.length = sizeof(*m);
721 	m->node_id = node_id;
722 	m->value = gain;
723 };
724 
725 struct __attribute__((__packed__)) cras_client_num_active_streams_changed {
726 	struct cras_client_message header;
727 	uint32_t direction;
728 	uint32_t num_active_streams;
729 };
cras_fill_client_num_active_streams_changed(struct cras_client_num_active_streams_changed * m,enum CRAS_STREAM_DIRECTION direction,uint32_t num_active_streams)730 static inline void cras_fill_client_num_active_streams_changed(
731 	struct cras_client_num_active_streams_changed *m,
732 	enum CRAS_STREAM_DIRECTION direction, uint32_t num_active_streams)
733 {
734 	m->header.id = CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED;
735 	m->header.length = sizeof(*m);
736 	m->direction = direction;
737 	m->num_active_streams = num_active_streams;
738 };
739 
740 /*
741  * Messages specific to passing audio between client and server
742  */
743 enum CRAS_AUDIO_MESSAGE_ID {
744 	AUDIO_MESSAGE_REQUEST_DATA,
745 	AUDIO_MESSAGE_DATA_READY,
746 	AUDIO_MESSAGE_DATA_CAPTURED,
747 	NUM_AUDIO_MESSAGES
748 };
749 
750 struct __attribute__((__packed__)) audio_message {
751 	enum CRAS_AUDIO_MESSAGE_ID id;
752 	int32_t error;
753 	uint32_t frames; /* number of samples per channel */
754 };
755 
756 #endif /* CRAS_MESSAGES_H_ */
757