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