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