• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 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 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <syslog.h>
9 
10 #include "cras_audio_area.h"
11 #include "cras_hfp_slc.h"
12 #include "cras_iodev.h"
13 #include "cras_system_state.h"
14 #include "cras_util.h"
15 #include "sfh.h"
16 #include "utlist.h"
17 #include "cras_bt_device.h"
18 
19 #include "cras_hfp_alsa_iodev.h"
20 
21 /* Object to represent a special HFP iodev which would be managed by bt_io but
22  * playback/capture via an inner ALSA iodev.
23  * Members:
24  *    base - The base class cras_iodev.
25  *    device - The corresponding remote BT device.
26  *    slc - The service level connection.
27  *    aio - The effective iodev for playback/capture.
28  */
29 struct hfp_alsa_io {
30 	struct cras_iodev base;
31 	struct cras_bt_device *device;
32 	struct hfp_slc_handle *slc;
33 	struct cras_iodev *aio;
34 };
35 
hfp_alsa_open_dev(struct cras_iodev * iodev)36 static int hfp_alsa_open_dev(struct cras_iodev *iodev)
37 {
38 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
39 	struct cras_iodev *aio = hfp_alsa_io->aio;
40 
41 	return aio->open_dev(aio);
42 }
43 
hfp_alsa_update_supported_formats(struct cras_iodev * iodev)44 static int hfp_alsa_update_supported_formats(struct cras_iodev *iodev)
45 {
46 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
47 	struct cras_iodev *aio = hfp_alsa_io->aio;
48 	int rc, i;
49 
50 	/* 16 bit, mono, 8kHz (narrow band speech); */
51 	rc = aio->update_supported_formats(aio);
52 	if (rc)
53 		return rc;
54 
55 	for (i = 0; aio->supported_rates[i]; ++i)
56 		if (aio->supported_rates[i] == 8000)
57 			break;
58 	if (aio->supported_rates[i] != 8000)
59 		return -EINVAL;
60 
61 	for (i = 0; aio->supported_channel_counts[i]; ++i)
62 		if (aio->supported_channel_counts[i] == 1)
63 			break;
64 	if (aio->supported_channel_counts[i] != 1)
65 		return -EINVAL;
66 
67 	for (i = 0; aio->supported_formats[i]; ++i)
68 		if (aio->supported_formats[i] == SND_PCM_FORMAT_S16_LE)
69 			break;
70 	if (aio->supported_formats[i] != SND_PCM_FORMAT_S16_LE)
71 		return -EINVAL;
72 
73 	free(aio->format);
74 	aio->format = malloc(sizeof(struct cras_audio_format));
75 	if (!aio->format)
76 		return -ENOMEM;
77 	aio->format->format = SND_PCM_FORMAT_S16_LE;
78 	aio->format->frame_rate = 8000;
79 	aio->format->num_channels = 1;
80 
81 	free(iodev->supported_rates);
82 	iodev->supported_rates = malloc(2 * sizeof(*iodev->supported_rates));
83 	if (!iodev->supported_rates)
84 		return -ENOMEM;
85 	iodev->supported_rates[0] = 8000;
86 	iodev->supported_rates[1] = 0;
87 
88 	free(iodev->supported_channel_counts);
89 	iodev->supported_channel_counts =
90 		malloc(2 * sizeof(*iodev->supported_channel_counts));
91 	if (!iodev->supported_channel_counts)
92 		return -ENOMEM;
93 	iodev->supported_channel_counts[0] = 1;
94 	iodev->supported_channel_counts[1] = 0;
95 
96 	free(iodev->supported_formats);
97 	iodev->supported_formats =
98 		malloc(2 * sizeof(*iodev->supported_formats));
99 	if (!iodev->supported_formats)
100 		return -ENOMEM;
101 	iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
102 	iodev->supported_formats[1] = 0;
103 
104 	return 0;
105 }
106 
hfp_alsa_configure_dev(struct cras_iodev * iodev)107 static int hfp_alsa_configure_dev(struct cras_iodev *iodev)
108 {
109 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
110 	struct cras_iodev *aio = hfp_alsa_io->aio;
111 	int rc;
112 
113 	rc = aio->configure_dev(aio);
114 	if (rc) {
115 		syslog(LOG_ERR, "Failed to configure aio: %d\n", rc);
116 		return rc;
117 	}
118 
119 	rc = cras_bt_device_get_sco(
120 		hfp_alsa_io->device,
121 		hfp_slc_get_selected_codec(hfp_alsa_io->slc));
122 	if (rc < 0) {
123 		syslog(LOG_ERR, "Failed to get sco: %d\n", rc);
124 		return rc;
125 	}
126 
127 	hfp_set_call_status(hfp_alsa_io->slc, 1);
128 	iodev->buffer_size = aio->buffer_size;
129 
130 	return 0;
131 }
132 
hfp_alsa_close_dev(struct cras_iodev * iodev)133 static int hfp_alsa_close_dev(struct cras_iodev *iodev)
134 {
135 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
136 	struct cras_iodev *aio = hfp_alsa_io->aio;
137 
138 	cras_bt_device_put_sco(hfp_alsa_io->device);
139 	cras_iodev_free_format(iodev);
140 	return aio->close_dev(aio);
141 }
142 
hfp_alsa_frames_queued(const struct cras_iodev * iodev,struct timespec * tstamp)143 static int hfp_alsa_frames_queued(const struct cras_iodev *iodev,
144 				  struct timespec *tstamp)
145 {
146 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
147 	struct cras_iodev *aio = hfp_alsa_io->aio;
148 
149 	return aio->frames_queued(aio, tstamp);
150 }
151 
hfp_alsa_delay_frames(const struct cras_iodev * iodev)152 static int hfp_alsa_delay_frames(const struct cras_iodev *iodev)
153 {
154 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
155 	struct cras_iodev *aio = hfp_alsa_io->aio;
156 
157 	return aio->delay_frames(aio);
158 }
159 
hfp_alsa_get_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)160 static int hfp_alsa_get_buffer(struct cras_iodev *iodev,
161 			       struct cras_audio_area **area, unsigned *frames)
162 {
163 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
164 	struct cras_iodev *aio = hfp_alsa_io->aio;
165 
166 	return aio->get_buffer(aio, area, frames);
167 }
168 
hfp_alsa_put_buffer(struct cras_iodev * iodev,unsigned nwritten)169 static int hfp_alsa_put_buffer(struct cras_iodev *iodev, unsigned nwritten)
170 {
171 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
172 	struct cras_iodev *aio = hfp_alsa_io->aio;
173 
174 	return aio->put_buffer(aio, nwritten);
175 }
176 
hfp_alsa_flush_buffer(struct cras_iodev * iodev)177 static int hfp_alsa_flush_buffer(struct cras_iodev *iodev)
178 {
179 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
180 	struct cras_iodev *aio = hfp_alsa_io->aio;
181 
182 	return aio->flush_buffer(aio);
183 }
184 
hfp_alsa_update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)185 static void hfp_alsa_update_active_node(struct cras_iodev *iodev,
186 					unsigned node_idx, unsigned dev_enabled)
187 {
188 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
189 	struct cras_iodev *aio = hfp_alsa_io->aio;
190 
191 	aio->update_active_node(aio, node_idx, dev_enabled);
192 }
193 
hfp_alsa_start(const struct cras_iodev * iodev)194 static int hfp_alsa_start(const struct cras_iodev *iodev)
195 {
196 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
197 	struct cras_iodev *aio = hfp_alsa_io->aio;
198 
199 	return aio->start(aio);
200 }
201 
hfp_alsa_set_volume(struct cras_iodev * iodev)202 static void hfp_alsa_set_volume(struct cras_iodev *iodev)
203 {
204 	size_t volume;
205 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
206 
207 	volume = cras_system_get_volume();
208 	if (iodev->active_node)
209 		volume = cras_iodev_adjust_node_volume(iodev->active_node,
210 						       volume);
211 
212 	hfp_event_speaker_gain(hfp_alsa_io->slc, volume);
213 }
214 
hfp_alsa_no_stream(struct cras_iodev * iodev,int enable)215 static int hfp_alsa_no_stream(struct cras_iodev *iodev, int enable)
216 {
217 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
218 	struct cras_iodev *aio = hfp_alsa_io->aio;
219 
220 	/*
221 	 * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
222 	 * (i.e. hfp_alsa_iodev).  no_stream() of alsa_io will use them.
223 	 */
224 	aio->min_cb_level = iodev->min_cb_level;
225 	aio->max_cb_level = iodev->max_cb_level;
226 	return aio->no_stream(aio, enable);
227 }
228 
hfp_alsa_is_free_running(const struct cras_iodev * iodev)229 static int hfp_alsa_is_free_running(const struct cras_iodev *iodev)
230 {
231 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
232 	struct cras_iodev *aio = hfp_alsa_io->aio;
233 
234 	return aio->is_free_running(aio);
235 }
236 
hfp_alsa_iodev_create(struct cras_iodev * aio,struct cras_bt_device * device,struct hfp_slc_handle * slc,enum cras_bt_device_profile profile)237 struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
238 					 struct cras_bt_device *device,
239 					 struct hfp_slc_handle *slc,
240 					 enum cras_bt_device_profile profile)
241 {
242 	struct hfp_alsa_io *hfp_alsa_io;
243 	struct cras_iodev *iodev;
244 	struct cras_ionode *node;
245 	const char *name;
246 
247 	hfp_alsa_io = calloc(1, sizeof(*hfp_alsa_io));
248 	if (!hfp_alsa_io)
249 		return NULL;
250 
251 	iodev = &hfp_alsa_io->base;
252 	iodev->direction = aio->direction;
253 
254 	hfp_alsa_io->device = device;
255 	hfp_alsa_io->slc = slc;
256 	hfp_alsa_io->aio = aio;
257 
258 	/* Set iodev's name to device readable name or the address. */
259 	name = cras_bt_device_name(device);
260 	if (!name)
261 		name = cras_bt_device_object_path(device);
262 	snprintf(iodev->info.name, sizeof(iodev->info.name), "%s.HFP_PCM",
263 		 name);
264 	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
265 	iodev->info.stable_id =
266 		SuperFastHash(cras_bt_device_object_path(device),
267 			      strlen(cras_bt_device_object_path(device)),
268 			      strlen(cras_bt_device_object_path(device)));
269 
270 	iodev->open_dev = hfp_alsa_open_dev;
271 	iodev->update_supported_formats = hfp_alsa_update_supported_formats;
272 	iodev->configure_dev = hfp_alsa_configure_dev;
273 	iodev->close_dev = hfp_alsa_close_dev;
274 
275 	iodev->frames_queued = hfp_alsa_frames_queued;
276 	iodev->delay_frames = hfp_alsa_delay_frames;
277 	iodev->get_buffer = hfp_alsa_get_buffer;
278 	iodev->put_buffer = hfp_alsa_put_buffer;
279 	iodev->flush_buffer = hfp_alsa_flush_buffer;
280 
281 	iodev->update_active_node = hfp_alsa_update_active_node;
282 	iodev->start = hfp_alsa_start;
283 	iodev->set_volume = hfp_alsa_set_volume;
284 	iodev->no_stream = hfp_alsa_no_stream;
285 	iodev->is_free_running = hfp_alsa_is_free_running;
286 
287 	iodev->min_buffer_level = aio->min_buffer_level;
288 
289 	node = calloc(1, sizeof(*node));
290 	node->dev = iodev;
291 	strcpy(node->name, iodev->info.name);
292 
293 	node->plugged = 1;
294 	node->type = CRAS_NODE_TYPE_BLUETOOTH;
295 	node->volume = 100;
296 	gettimeofday(&node->plugged_time, NULL);
297 
298 	cras_bt_device_append_iodev(device, iodev, profile);
299 	cras_iodev_add_node(iodev, node);
300 	cras_iodev_set_active_node(iodev, node);
301 
302 	return iodev;
303 }
304 
hfp_alsa_iodev_destroy(struct cras_iodev * iodev)305 void hfp_alsa_iodev_destroy(struct cras_iodev *iodev)
306 {
307 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
308 	struct cras_ionode *node;
309 
310 	cras_bt_device_rm_iodev(hfp_alsa_io->device, iodev);
311 
312 	node = iodev->active_node;
313 	if (node) {
314 		cras_iodev_rm_node(iodev, node);
315 		free(node);
316 	}
317 
318 	free(iodev->supported_channel_counts);
319 	free(iodev->supported_rates);
320 	free(iodev->supported_formats);
321 	cras_iodev_free_resources(iodev);
322 
323 	free(hfp_alsa_io);
324 }
325