summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_rclient_util.h
blob: e00f87c9401f9ba91d874891de4ab913a8419f86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* Copyright 2019 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Common utility functions for rclients.
 */
#ifndef CRAS_RCLIENT_UTIL_H_
#define CRAS_RCLIENT_UTIL_H_

#define MSG_LEN_VALID(msg, type) ((msg)->length >= sizeof(type))

struct cras_connect_message;
struct cras_rclient;
struct cras_rclient_message;
struct cras_rstream_config;
struct cras_server_message;

/* Sends a message to the client. */
int rclient_send_message_to_client(const struct cras_rclient *client,
				   const struct cras_client_message *msg,
				   int *fds, unsigned int num_fds);

/* Removes all streams that the client owns and destroys it. */
void rclient_destroy(struct cras_rclient *client);

/* Checks if the number of incoming fds matches the needs of the message from
 * client.
 *
 * Args:
 *   msg - The cras_server_message from client.
 *   fds - The array for incoming fds from client.
 *   num_fds - The number of fds from client.
 *
 * Returns:
 *   0 on success. Or negative value if the number of fds is invalid.
 */
int rclient_validate_message_fds(const struct cras_server_message *msg,
				 int *fds, unsigned int num_fds);

/* Checks if the incoming stream connect message contains
 * - stream_id matches client->id.
 * - direction supported by the client.
 *
 * Args:
 *   client - The cras_rclient which gets the message.
 *   msg - cras_connect_message from client.
 *   audio_fd - Audio fd from client.
 *   client_shm_fd - client shared memory fd from client. It can be -1.
 *
 * Returns:
 *   0 on success, negative error on failure.
 */
int rclient_validate_stream_connect_params(
	const struct cras_rclient *client,
	const struct cras_connect_message *msg, int audio_fd,
	int client_shm_fd);

/* Handles a message from the client to connect a new stream
 *
 * Args:
 *   client - The cras_rclient which gets the message.
 *   msg - The cras_connect_message from client.
 *   aud_fd - The audio fd comes from client. Its ownership will be taken.
 *   client_shm_fd - The client_shm_fd from client. Its ownership will be taken.
 *
 * Returns:
 *   0 on success, negative error on failure.
 */
int rclient_handle_client_stream_connect(struct cras_rclient *client,
					 const struct cras_connect_message *msg,
					 int aud_fd, int client_shm_fd);

/* Handles messages from the client requesting that a stream be removed from the
 * server.
 *
 * Args:
 *   client - The cras_rclient which gets the message.
 *   msg - The cras_disconnect_stream_message from client.
 *
 * Returns:
 *   0 on success, negative error on failure.
 */
int rclient_handle_client_stream_disconnect(
	struct cras_rclient *client,
	const struct cras_disconnect_stream_message *msg);

/* Generic rclient create function for different types of rclients.
 * Creates a client structure and sends a message back informing the client
 * that the connection has succeeded.
 *
 * Args:
 *    fd - The file descriptor used for communication with the client.
 *    id - Unique identifier for this client.
 *    ops - cras_rclient_ops pointer for the client.
 *    supported_directions - supported directions for the this rclient.
 * Returns:
 *    A pointer to the newly created rclient on success, NULL on failure.
 */
struct cras_rclient *rclient_generic_create(int fd, size_t id,
					    const struct cras_rclient_ops *ops,
					    int supported_directions);

/* Generic handle_message_from_client function for different types of rlicnets.
 * Supports only stream connect and stream disconnect messages.
 *
 * If the message from clients has incorrect length (truncated message), return
 * an error up to CRAS server.
 * If the message from clients has invalid content, should return the errors to
 * clients by send_message_to_client and return 0 here.
 *
 * Args:
 *   client - The cras_rclient which gets the message.
 *   msg - The cras_server_message from client.
 *   fds - The array for incoming fds from client.
 *   num_fds - The number of fds from client.
 * Returns:
 *   0 on success, negative error on failure.
 */
int rclient_handle_message_from_client(struct cras_rclient *client,
				       const struct cras_server_message *msg,
				       int *fds, unsigned int num_fds);

/*
 * Converts an old version of connect message to the correct
 * cras_connect_message. Returns zero on success, negative on failure.
 * Note that this is special check only for libcras transition in
 * clients, from CRAS_PROTO_VER 5 to 7.
 * TODO(fletcherw): clean up the function once transition is done.
 */
static inline int
convert_connect_message_old(const struct cras_server_message *msg,
			    struct cras_connect_message *cmsg)
{
	struct cras_connect_message_old *old;

	if (!MSG_LEN_VALID(msg, struct cras_connect_message_old))
		return -EINVAL;

	old = (struct cras_connect_message_old *)msg;
	if (old->proto_version != 5 || CRAS_PROTO_VER != 7)
		return -EINVAL;

	// We want to copy everything except the client_shm_size field, since
	// that overlaps slightly with the now larger client_shm_size.
	memcpy(cmsg, old, sizeof(*old) - sizeof(old->client_shm_size));
	cmsg->client_shm_size = old->client_shm_size;
	cmsg->buffer_offsets[0] = 0;
	cmsg->buffer_offsets[1] = 0;
	return 0;
}

#endif /* CRAS_RCLIENT_UTIL_H_ */