cras_bt_io.c revision dace0e596c97dfa4b0a2b3baa3004376eb2fd2c0
1/* Copyright (c) 2014 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 <syslog.h>
7
8#include "cras_bt_io.h"
9#include "cras_bt_device.h"
10#include "cras_utf8.h"
11#include "cras_iodev.h"
12#include "cras_iodev_list.h"
13#include "utlist.h"
14
15#define DEFAULT_BT_DEVICE_NAME "BLUETOOTH"
16
17/* Extends cras_ionode to hold bluetooth profile information
18 * so that iodevs of different profile(A2DP or HFP/HSP) can be
19 * associated with the same bt_io.
20 * Members:
21 *    base - The base class cras_ionode.
22 *    profile_dev - Pointer to the profile specific iodev.
23 *    profile - The bluetooth profile profile_dev runs on.
24 */
25struct bt_node {
26	struct cras_ionode base;
27	struct cras_iodev *profile_dev;
28	unsigned int profile;
29};
30
31/* The structure represents a virtual input or output device of a
32 * bluetooth audio device, speaker or headset for example. A node
33 * will be added to this virtual iodev for each profile supported
34 * by the bluetooth audio device.
35 * Member:
36 *    base - The base class cras_iodev
37 *    next_node_id - The index will give to the next node
38 */
39struct bt_io {
40	struct cras_iodev base;
41	unsigned int next_node_id;
42	struct cras_bt_device *device;
43};
44
45/* Returns the active profile specific iodev. */
46static struct cras_iodev *active_profile_dev(const struct cras_iodev *iodev)
47{
48	struct bt_node *active = (struct bt_node *)iodev->active_node;
49
50	return active->profile_dev;
51}
52
53/* Adds a profile specific iodev to btio. */
54static struct cras_ionode *add_profile_dev(struct cras_iodev *bt_iodev,
55					   struct cras_iodev *dev,
56					   enum cras_bt_device_profile profile)
57{
58	struct bt_node *n;
59	struct bt_io *btio = (struct bt_io *)bt_iodev;
60
61	n = (struct bt_node *)calloc(1, sizeof(*n));
62	if (!n)
63		return NULL;
64
65	n->base.dev = bt_iodev;
66	n->base.idx = btio->next_node_id++;
67	n->base.type = CRAS_NODE_TYPE_BLUETOOTH;
68	n->base.volume = 100;
69	n->base.stable_id = dev->info.stable_id;
70	n->base.max_software_gain = 0;
71	gettimeofday(&n->base.plugged_time, NULL);
72
73	strcpy(n->base.name, dev->info.name);
74	n->profile_dev = dev;
75	n->profile = profile;
76
77	cras_iodev_add_node(bt_iodev, &n->base);
78	return &n->base;
79}
80
81/* Forces bt device to switch to use the given profile. Note that if
82 * it has already been open for streaming, the new active profile will
83 * take effect after the related btio(s) are reopened.
84 */
85static void bt_switch_to_profile(struct cras_bt_device *device,
86				 enum cras_bt_device_profile profile)
87{
88	switch (profile) {
89	case CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY:
90	case CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY:
91		cras_bt_device_set_active_profile(device,
92				CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY |
93				CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
94		break;
95	case CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE:
96		cras_bt_device_set_active_profile(device,
97				CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
98		break;
99	default:
100		syslog(LOG_ERR, "Unexpect profile %u", profile);
101		break;
102	}
103}
104
105/* Checks if bt device is active for the given profile.
106 */
107static int device_using_profile(struct cras_bt_device *device,
108				unsigned int profile)
109{
110	return cras_bt_device_get_active_profile(device) & profile;
111}
112
113/* Checks if the condition is met to switch to a different profile
114 * when trying to set the format to btio before open it. Base on two
115 * rules:
116 * (1) Prefer to use A2DP for output since the audio quality is better.
117 * (2) Must use HFP/HSP for input since A2DP doesn't support audio input.
118 *
119 * If the profile switch happens, return non-zero error code, otherwise
120 * return zero.
121 */
122static int update_supported_formats(struct cras_iodev *iodev)
123{
124	struct bt_io *btio = (struct bt_io *)iodev;
125	struct cras_iodev *dev = active_profile_dev(iodev);
126	int rc, length, i;
127
128	/* Force to use HFP if opening input dev. */
129	if (device_using_profile(btio->device,
130				 CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE) &&
131	    iodev->direction == CRAS_STREAM_INPUT) {
132		bt_switch_to_profile(btio->device,
133				     CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
134		cras_bt_device_switch_profile_enable_dev(btio->device, iodev);
135		return -EAGAIN;
136	}
137
138	if (dev->format == NULL) {
139		dev->format = (struct cras_audio_format *)
140				malloc(sizeof(*dev->format));
141		*dev->format = *iodev->format;
142	}
143
144	if (dev->update_supported_formats) {
145		rc = dev->update_supported_formats(dev);
146		if (rc)
147			return rc;
148	}
149
150	/* Fill in the supported rates and channel counts. */
151	for (length = 0; dev->supported_rates[length]; length++);
152	free(iodev->supported_rates);
153	iodev->supported_rates = (size_t *)malloc(
154			(length + 1) * sizeof(*iodev->supported_rates));
155	for (i = 0; i < length + 1; i++)
156		iodev->supported_rates[i] = dev->supported_rates[i];
157
158	for (length = 0; dev->supported_channel_counts[length]; length++);
159	iodev->supported_channel_counts = (size_t *)malloc(
160		(length + 1) * sizeof(*iodev->supported_channel_counts));
161	for (i = 0; i < length + 1; i++)
162		iodev->supported_channel_counts[i] =
163			dev->supported_channel_counts[i];
164
165	for (length = 0; dev->supported_formats[length]; length++);
166	iodev->supported_formats = (snd_pcm_format_t *)malloc(
167		(length + 1) * sizeof(*iodev->supported_formats));
168	for (i = 0; i < length + 1; i++)
169		iodev->supported_formats[i] =
170			dev->supported_formats[i];
171	return 0;
172}
173
174static int open_dev(struct cras_iodev *iodev)
175{
176	int rc;
177	struct cras_iodev *dev = active_profile_dev(iodev);
178	if (!dev)
179		return -EINVAL;
180
181	/* Fill back the format iodev is using. */
182	*dev->format = *iodev->format;
183
184	rc = dev->open_dev(dev);
185	if (rc) {
186		/* Free format here to assure the update_supported_format
187		 * callback will be called before any future open_dev call. */
188		cras_iodev_free_format(iodev);
189		return rc;
190	}
191
192	iodev->buffer_size = dev->buffer_size;
193	iodev->min_buffer_level = dev->min_buffer_level;
194	return 0;
195}
196
197static int close_dev(struct cras_iodev *iodev)
198{
199	struct bt_io *btio = (struct bt_io *)iodev;
200	int rc;
201	struct cras_iodev *dev = active_profile_dev(iodev);
202
203	/* Force back to A2DP if closing HFP. */
204	if (device_using_profile(btio->device,
205			CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY |
206			CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY) &&
207	    iodev->direction == CRAS_STREAM_INPUT &&
208	    cras_bt_device_has_a2dp(btio->device)) {
209		cras_bt_device_set_active_profile(btio->device,
210				CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
211		cras_bt_device_switch_profile(btio->device, iodev);
212	}
213
214	rc = dev->close_dev(dev);
215	if (rc < 0)
216		return rc;
217	cras_iodev_free_format(iodev);
218	return 0;
219}
220
221static void set_bt_volume(struct cras_iodev *iodev)
222{
223	struct cras_iodev *dev = active_profile_dev(iodev);
224
225	if (dev->active_node)
226		dev->active_node->volume = iodev->active_node->volume;
227
228	/* The parent bt_iodev could set software_volume_needed flag for cases
229	 * that software volume provides better experience across profiles
230	 * (HFP and A2DP). Otherwise, use the profile specific implementation
231	 * to adjust volume. */
232	if (dev->set_volume && !iodev->software_volume_needed)
233		dev->set_volume(dev);
234}
235
236static int is_open(const struct cras_iodev *iodev)
237{
238	struct cras_iodev *dev = active_profile_dev(iodev);
239	if (!dev)
240		return 0;
241	return dev->is_open(dev);
242}
243
244static int frames_queued(const struct cras_iodev *iodev)
245{
246	struct cras_iodev *dev = active_profile_dev(iodev);
247	if (!dev)
248		return -EINVAL;
249	return dev->frames_queued(dev);
250}
251
252static int start(const struct cras_iodev *iodev)
253{
254	struct cras_iodev *dev = active_profile_dev(iodev);
255	if (!dev)
256		return -EINVAL;
257	return dev->start(dev);
258}
259
260static int dev_running(const struct cras_iodev *iodev)
261{
262	struct cras_iodev *dev = active_profile_dev(iodev);
263	if (!dev)
264		return -EINVAL;
265	return dev->dev_running(dev);
266}
267
268static int delay_frames(const struct cras_iodev *iodev)
269{
270	struct cras_iodev *dev = active_profile_dev(iodev);
271	if (!dev)
272		return -EINVAL;
273	return dev->delay_frames(dev);
274}
275
276static int get_buffer(struct cras_iodev *iodev,
277		      struct cras_audio_area **area,
278		      unsigned *frames)
279{
280	struct cras_iodev *dev = active_profile_dev(iodev);
281	if (!dev)
282		return -EINVAL;
283	return dev->get_buffer(dev, area, frames);
284}
285
286static int put_buffer(struct cras_iodev *iodev, unsigned nwritten)
287{
288	struct cras_iodev *dev = active_profile_dev(iodev);
289	if (!dev)
290		return -EINVAL;
291	return dev->put_buffer(dev, nwritten);
292}
293
294static int flush_buffer(struct cras_iodev *iodev)
295{
296	struct cras_iodev *dev = active_profile_dev(iodev);
297	if (!dev)
298		return -EINVAL;
299	return dev->flush_buffer(dev);
300}
301
302/* If the first private iodev doesn't match the active profile stored on
303 * device, select to the correct private iodev.
304 */
305static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
306			       unsigned dev_enabled)
307{
308	struct bt_io *btio = (struct bt_io *)iodev;
309	struct cras_ionode *node;
310	struct bt_node *active = (struct bt_node *)iodev->active_node;
311
312	if (device_using_profile(btio->device, active->profile))
313		return;
314
315	/* Switch to the correct dev using active_profile. */
316	DL_FOREACH(iodev->nodes, node) {
317		struct bt_node *n = (struct bt_node *)node;
318		if (n == active)
319			continue;
320
321		if (device_using_profile(btio->device, n->profile)) {
322			active->profile = n->profile;
323			active->profile_dev = n->profile_dev;
324
325			/* Set volume for the new profile. */
326			set_bt_volume(iodev);
327		}
328	}
329}
330
331struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
332				     struct cras_iodev *dev,
333				     enum cras_bt_device_profile profile)
334{
335	int err;
336	struct bt_io *btio;
337	struct cras_iodev *iodev;
338	struct cras_ionode *node;
339	struct bt_node *active;
340
341	if (!dev)
342		return NULL;
343
344	btio = (struct bt_io *)calloc(1, sizeof(*btio));
345	if (!btio)
346		goto error;
347	btio->device = device;
348
349	iodev = &btio->base;
350	iodev->direction = dev->direction;
351	strcpy(iodev->info.name, dev->info.name);
352	iodev->info.stable_id = dev->info.stable_id;
353
354	iodev->open_dev = open_dev;
355	iodev->is_open = is_open; /* Needed by thread_add_stream */
356	iodev->frames_queued = frames_queued;
357	iodev->dev_running = dev_running;
358	iodev->start = start;
359	iodev->delay_frames = delay_frames;
360	iodev->get_buffer = get_buffer;
361	iodev->put_buffer = put_buffer;
362	iodev->flush_buffer = flush_buffer;
363	iodev->close_dev = close_dev;
364	iodev->update_supported_formats = update_supported_formats;
365	iodev->update_active_node = update_active_node;
366	iodev->software_volume_needed = 1;
367	iodev->set_volume = set_bt_volume;
368
369	/* Create the dummy node set to plugged so it's the only node exposed
370	 * to UI, and point it to the first profile dev. */
371	active = (struct bt_node *)calloc(1, sizeof(*active));
372	if (!active)
373		return NULL;
374	active->base.dev = iodev;
375	active->base.idx = btio->next_node_id++;
376	active->base.type = CRAS_NODE_TYPE_BLUETOOTH;
377	active->base.volume = 100;
378	active->base.plugged = 1;
379	active->profile = profile;
380	active->profile_dev = dev;
381	gettimeofday(&active->base.plugged_time, NULL);
382	strcpy(active->base.name, dev->info.name);
383	/* The node name exposed to UI should be a valid UTF8 string. */
384	if (!is_utf8_string(active->base.name))
385		strcpy(active->base.name, DEFAULT_BT_DEVICE_NAME);
386	cras_iodev_add_node(iodev, &active->base);
387
388	node = add_profile_dev(&btio->base, dev, profile);
389	if (node == NULL)
390		goto error;
391
392	/* Default active profile to a2dp whenever it's allowed. */
393	if (!cras_bt_device_get_active_profile(device) ||
394	    (profile == CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE &&
395	     cras_bt_device_can_switch_to_a2dp(device)))
396		bt_switch_to_profile(device, profile);
397
398	if (iodev->direction == CRAS_STREAM_OUTPUT)
399		err = cras_iodev_list_add_output(iodev);
400	else
401		err = cras_iodev_list_add_input(iodev);
402	if (err)
403		goto error;
404
405	cras_iodev_set_active_node(iodev, &active->base);
406	return &btio->base;
407
408error:
409	if (btio)
410		free(btio);
411	return NULL;
412}
413
414void cras_bt_io_destroy(struct cras_iodev *bt_iodev)
415{
416	int rc;
417	struct bt_io *btio = (struct bt_io *)bt_iodev;
418	struct cras_ionode *node;
419	struct bt_node *n;
420
421	if (bt_iodev->direction == CRAS_STREAM_OUTPUT)
422		rc = cras_iodev_list_rm_output(bt_iodev);
423	else
424		rc = cras_iodev_list_rm_input(bt_iodev);
425	if (rc == -EBUSY)
426		return;
427
428	DL_FOREACH(bt_iodev->nodes, node) {
429		n = (struct bt_node *)node;
430		cras_iodev_rm_node(bt_iodev, node);
431		free(n);
432	}
433	free(btio);
434}
435
436struct cras_ionode *cras_bt_io_get_profile(struct cras_iodev *bt_iodev,
437					   enum cras_bt_device_profile profile)
438{
439	struct cras_ionode *node;
440	DL_FOREACH(bt_iodev->nodes, node) {
441		struct bt_node *n = (struct bt_node *)node;
442		if (n->profile & profile)
443			return node;
444	}
445	return NULL;
446}
447
448int cras_bt_io_append(struct cras_iodev *bt_iodev,
449		      struct cras_iodev *dev,
450		      enum cras_bt_device_profile profile)
451{
452	struct cras_ionode *node;
453	struct bt_io *btio = (struct bt_io *)bt_iodev;
454
455	if (cras_bt_io_get_profile(bt_iodev, profile))
456		return -EEXIST;
457
458	node = add_profile_dev(bt_iodev, dev, profile);
459	if (!node)
460		return -ENOMEM;
461
462	if (profile == CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE &&
463	    cras_bt_device_can_switch_to_a2dp(btio->device)) {
464		bt_switch_to_profile(btio->device,
465				     CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
466		cras_bt_device_switch_profile(btio->device, bt_iodev);
467		syslog(LOG_ERR, "Switch to A2DP on append");
468	}
469	return 0;
470}
471
472int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
473			  enum cras_bt_device_profile profile)
474{
475	struct bt_node *btnode = (struct bt_node *)bt_iodev->active_node;
476	return !!(profile & btnode->profile);
477}
478
479int cras_bt_io_update_buffer_size(struct cras_iodev *bt_iodev)
480{
481	struct cras_iodev *dev = active_profile_dev(bt_iodev);
482	if (!dev)
483		return -EINVAL;
484
485	bt_iodev->buffer_size = dev->buffer_size;
486	return 0;
487}
488
489unsigned int cras_bt_io_try_remove(struct cras_iodev *bt_iodev,
490				   struct cras_iodev *dev)
491{
492	struct cras_ionode *node;
493	struct bt_node *active, *btnode;
494	unsigned int try_profile = 0;
495
496	active = (struct bt_node *)bt_iodev->active_node;
497
498	if (active->profile_dev == dev) {
499		DL_FOREACH(bt_iodev->nodes, node) {
500			btnode = (struct bt_node *)node;
501			/* Skip the active node and the node we're trying
502			 * to remove. */
503			if (btnode == active || btnode->profile_dev == dev)
504				continue;
505			try_profile = btnode->profile;
506			break;
507		}
508	} else {
509		try_profile = active->profile;
510	}
511	return try_profile;
512}
513
514int cras_bt_io_remove(struct cras_iodev *bt_iodev,
515		      struct cras_iodev *dev)
516{
517	struct cras_ionode *node;
518	struct bt_node *btnode;
519
520	DL_FOREACH(bt_iodev->nodes, node) {
521		btnode = (struct bt_node *)node;
522		if (btnode->profile_dev != dev)
523			continue;
524
525		/* If this is the active node, reset it. Otherwise delete
526		 * this node. */
527		if (node == bt_iodev->active_node) {
528			btnode->profile_dev = NULL;
529			btnode->profile = 0;
530		} else {
531			DL_DELETE(bt_iodev->nodes, node);
532			free(node);
533		}
534	}
535
536	/* The node of active profile could have been removed, update it.
537	 * Return err when fail to locate the active profile dev. */
538	update_active_node(bt_iodev, 0, 1);
539	btnode = (struct bt_node *)bt_iodev->active_node;
540	if ((btnode->profile == 0) || (btnode->profile_dev == NULL))
541		return -EINVAL;
542
543	return 0;
544}
545