1 /* Copyright (c) 2013 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 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE /* for ppoll */
8 #endif
9
10 #include <dbus/dbus.h>
11
12 #include <errno.h>
13 #include <poll.h>
14 #include <stdbool.h>
15 #include <stdint.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/socket.h>
19 #include <syslog.h>
20
21 #include "bluetooth.h"
22 #include "cras_a2dp_endpoint.h"
23 #include "cras_bt_adapter.h"
24 #include "cras_bt_device.h"
25 #include "cras_bt_constants.h"
26 #include "cras_bt_log.h"
27 #include "cras_bt_io.h"
28 #include "cras_bt_profile.h"
29 #include "cras_hfp_ag_profile.h"
30 #include "cras_hfp_slc.h"
31 #include "cras_iodev.h"
32 #include "cras_iodev_list.h"
33 #include "cras_main_message.h"
34 #include "cras_system_state.h"
35 #include "cras_tm.h"
36 #include "utlist.h"
37
38 /*
39 * Bluetooth Core 5.0 spec, vol 4, part B, section 2 describes
40 * the recommended HCI packet size in one USB transfer for CVSD
41 * and MSBC codec.
42 */
43 #define USB_MSBC_PKT_SIZE 60
44 #define USB_CVSD_PKT_SIZE 48
45 #define DEFAULT_SCO_PKT_SIZE USB_CVSD_PKT_SIZE
46
47 static const unsigned int PROFILE_SWITCH_DELAY_MS = 500;
48 static const unsigned int PROFILE_DROP_SUSPEND_DELAY_MS = 5000;
49
50 /* Check profile connections every 2 seconds and rerty 30 times maximum.
51 * Attemp to connect profiles which haven't been ready every 3 retries.
52 */
53 static const unsigned int CONN_WATCH_PERIOD_MS = 2000;
54 static const unsigned int CONN_WATCH_MAX_RETRIES = 30;
55 static const unsigned int PROFILE_CONN_RETRIES = 3;
56
57 static const unsigned int CRAS_SUPPORTED_PROFILES =
58 CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
59 CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE |
60 CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
61
62 /* Object to represent a general bluetooth device, and used to
63 * associate with some CRAS modules if it supports audio.
64 * Members:
65 * conn - The dbus connection object used to send message to bluetoothd.
66 * object_path - Object path of the bluetooth device.
67 * adapter - The object path of the adapter associates with this device.
68 * address - The BT address of this device.
69 * name - The readable name of this device.
70 * bluetooth_class - The bluetooth class of this device.
71 * paired - If this device is paired.
72 * trusted - If this device is trusted.
73 * connected - If this devices is connected.
74 * connected_profiles - OR'ed all connected audio profiles.
75 * profiles - OR'ed by all audio profiles this device supports.
76 * bt_iodevs - The pointer to the cras_iodevs of this device.
77 * active_profile - The flag to indicate the active audio profile this
78 * device is currently using.
79 * conn_watch_retries - The retry count for conn_watch_timer.
80 * conn_watch_timer - The timer used to watch connected profiles and start
81 * BT audio input/ouput when all profiles are ready.
82 * suspend_timer - The timer used to suspend device.
83 * switch_profile_timer - The timer used to delay enabling iodev after
84 * profile switch.
85 * sco_fd - The file descriptor of the SCO connection.
86 * sco_ref_count - The reference counts of the SCO connection.
87 */
88 struct cras_bt_device {
89 DBusConnection *conn;
90 char *object_path;
91 char *adapter_obj_path;
92 char *address;
93 char *name;
94 uint32_t bluetooth_class;
95 int paired;
96 int trusted;
97 int connected;
98 enum cras_bt_device_profile connected_profiles;
99 enum cras_bt_device_profile profiles;
100 struct cras_iodev *bt_iodevs[CRAS_NUM_DIRECTIONS];
101 unsigned int active_profile;
102 int use_hardware_volume;
103 int conn_watch_retries;
104 struct cras_timer *conn_watch_timer;
105 struct cras_timer *suspend_timer;
106 struct cras_timer *switch_profile_timer;
107 int sco_fd;
108 size_t sco_ref_count;
109
110 struct cras_bt_device *prev, *next;
111 };
112
113 enum BT_DEVICE_COMMAND {
114 BT_DEVICE_CANCEL_SUSPEND,
115 BT_DEVICE_SCHEDULE_SUSPEND,
116 BT_DEVICE_SWITCH_PROFILE,
117 BT_DEVICE_SWITCH_PROFILE_ENABLE_DEV,
118 };
119
120 struct bt_device_msg {
121 struct cras_main_message header;
122 enum BT_DEVICE_COMMAND cmd;
123 struct cras_bt_device *device;
124 struct cras_iodev *dev;
125 unsigned int arg;
126 };
127
128 static struct cras_bt_device *devices;
129
cras_bt_device_profile_from_uuid(const char * uuid)130 enum cras_bt_device_profile cras_bt_device_profile_from_uuid(const char *uuid)
131 {
132 if (strcmp(uuid, HSP_HS_UUID) == 0)
133 return CRAS_BT_DEVICE_PROFILE_HSP_HEADSET;
134 else if (strcmp(uuid, HSP_AG_UUID) == 0)
135 return CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
136 else if (strcmp(uuid, HFP_HF_UUID) == 0)
137 return CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE;
138 else if (strcmp(uuid, HFP_AG_UUID) == 0)
139 return CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
140 else if (strcmp(uuid, A2DP_SOURCE_UUID) == 0)
141 return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
142 else if (strcmp(uuid, A2DP_SINK_UUID) == 0)
143 return CRAS_BT_DEVICE_PROFILE_A2DP_SINK;
144 else if (strcmp(uuid, AVRCP_REMOTE_UUID) == 0)
145 return CRAS_BT_DEVICE_PROFILE_AVRCP_REMOTE;
146 else if (strcmp(uuid, AVRCP_TARGET_UUID) == 0)
147 return CRAS_BT_DEVICE_PROFILE_AVRCP_TARGET;
148 else
149 return 0;
150 }
151
cras_bt_device_create(DBusConnection * conn,const char * object_path)152 struct cras_bt_device *cras_bt_device_create(DBusConnection *conn,
153 const char *object_path)
154 {
155 struct cras_bt_device *device;
156
157 device = calloc(1, sizeof(*device));
158 if (device == NULL)
159 return NULL;
160
161 device->conn = conn;
162 device->object_path = strdup(object_path);
163 if (device->object_path == NULL) {
164 free(device);
165 return NULL;
166 }
167
168 DL_APPEND(devices, device);
169
170 return device;
171 }
172
on_connect_profile_reply(DBusPendingCall * pending_call,void * data)173 static void on_connect_profile_reply(DBusPendingCall *pending_call, void *data)
174 {
175 DBusMessage *reply;
176
177 reply = dbus_pending_call_steal_reply(pending_call);
178 dbus_pending_call_unref(pending_call);
179
180 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
181 syslog(LOG_ERR, "Connect profile message replied error: %s",
182 dbus_message_get_error_name(reply));
183
184 dbus_message_unref(reply);
185 }
186
on_disconnect_reply(DBusPendingCall * pending_call,void * data)187 static void on_disconnect_reply(DBusPendingCall *pending_call, void *data)
188 {
189 DBusMessage *reply;
190
191 reply = dbus_pending_call_steal_reply(pending_call);
192 dbus_pending_call_unref(pending_call);
193
194 if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
195 syslog(LOG_ERR, "Disconnect message replied error");
196
197 dbus_message_unref(reply);
198 }
199
cras_bt_device_connect_profile(DBusConnection * conn,struct cras_bt_device * device,const char * uuid)200 int cras_bt_device_connect_profile(DBusConnection *conn,
201 struct cras_bt_device *device,
202 const char *uuid)
203 {
204 DBusMessage *method_call;
205 DBusError dbus_error;
206 DBusPendingCall *pending_call;
207
208 method_call =
209 dbus_message_new_method_call(BLUEZ_SERVICE, device->object_path,
210 BLUEZ_INTERFACE_DEVICE,
211 "ConnectProfile");
212 if (!method_call)
213 return -ENOMEM;
214
215 if (!dbus_message_append_args(method_call, DBUS_TYPE_STRING, &uuid,
216 DBUS_TYPE_INVALID))
217 return -ENOMEM;
218
219 dbus_error_init(&dbus_error);
220
221 pending_call = NULL;
222 if (!dbus_connection_send_with_reply(conn, method_call, &pending_call,
223 DBUS_TIMEOUT_USE_DEFAULT)) {
224 dbus_message_unref(method_call);
225 syslog(LOG_ERR, "Failed to send Disconnect message");
226 return -EIO;
227 }
228
229 dbus_message_unref(method_call);
230 if (!dbus_pending_call_set_notify(
231 pending_call, on_connect_profile_reply, conn, NULL)) {
232 dbus_pending_call_cancel(pending_call);
233 dbus_pending_call_unref(pending_call);
234 return -EIO;
235 }
236 return 0;
237 }
238
cras_bt_device_disconnect(DBusConnection * conn,struct cras_bt_device * device)239 int cras_bt_device_disconnect(DBusConnection *conn,
240 struct cras_bt_device *device)
241 {
242 DBusMessage *method_call;
243 DBusError dbus_error;
244 DBusPendingCall *pending_call;
245
246 method_call =
247 dbus_message_new_method_call(BLUEZ_SERVICE, device->object_path,
248 BLUEZ_INTERFACE_DEVICE,
249 "Disconnect");
250 if (!method_call)
251 return -ENOMEM;
252
253 dbus_error_init(&dbus_error);
254
255 pending_call = NULL;
256 if (!dbus_connection_send_with_reply(conn, method_call, &pending_call,
257 DBUS_TIMEOUT_USE_DEFAULT)) {
258 dbus_message_unref(method_call);
259 syslog(LOG_ERR, "Failed to send Disconnect message");
260 return -EIO;
261 }
262
263 dbus_message_unref(method_call);
264 if (!dbus_pending_call_set_notify(pending_call, on_disconnect_reply,
265 conn, NULL)) {
266 dbus_pending_call_cancel(pending_call);
267 dbus_pending_call_unref(pending_call);
268 return -EIO;
269 }
270 return 0;
271 }
272
cras_bt_device_destroy(struct cras_bt_device * device)273 static void cras_bt_device_destroy(struct cras_bt_device *device)
274 {
275 struct cras_tm *tm = cras_system_state_get_tm();
276 DL_DELETE(devices, device);
277
278 if (device->conn_watch_timer)
279 cras_tm_cancel_timer(tm, device->conn_watch_timer);
280 if (device->switch_profile_timer)
281 cras_tm_cancel_timer(tm, device->switch_profile_timer);
282 if (device->suspend_timer)
283 cras_tm_cancel_timer(tm, device->suspend_timer);
284 free(device->adapter_obj_path);
285 free(device->object_path);
286 free(device->address);
287 free(device->name);
288 free(device);
289 }
290
cras_bt_device_remove(struct cras_bt_device * device)291 void cras_bt_device_remove(struct cras_bt_device *device)
292 {
293 /*
294 * We expect BT stack to disconnect this device before removing it,
295 * but it may not the case if there's issue at BT side. Print error
296 * log whenever this happens.
297 */
298 if (device->connected)
299 syslog(LOG_ERR, "Removing dev with connected profiles %u",
300 device->connected_profiles);
301 /*
302 * Possibly clean up the associated A2DP and HFP AG iodevs that are
303 * still accessing this device.
304 */
305 cras_a2dp_suspend_connected_device(device);
306 cras_hfp_ag_suspend_connected_device(device);
307 cras_bt_device_destroy(device);
308 }
309
cras_bt_device_reset()310 void cras_bt_device_reset()
311 {
312 while (devices) {
313 syslog(LOG_INFO, "Bluetooth Device: %s removed",
314 devices->address);
315 cras_bt_device_destroy(devices);
316 }
317 }
318
cras_bt_device_get(const char * object_path)319 struct cras_bt_device *cras_bt_device_get(const char *object_path)
320 {
321 struct cras_bt_device *device;
322
323 DL_FOREACH (devices, device) {
324 if (strcmp(device->object_path, object_path) == 0)
325 return device;
326 }
327
328 return NULL;
329 }
330
cras_bt_device_object_path(const struct cras_bt_device * device)331 const char *cras_bt_device_object_path(const struct cras_bt_device *device)
332 {
333 return device->object_path;
334 }
335
336 struct cras_bt_adapter *
cras_bt_device_adapter(const struct cras_bt_device * device)337 cras_bt_device_adapter(const struct cras_bt_device *device)
338 {
339 return cras_bt_adapter_get(device->adapter_obj_path);
340 }
341
cras_bt_device_address(const struct cras_bt_device * device)342 const char *cras_bt_device_address(const struct cras_bt_device *device)
343 {
344 return device->address;
345 }
346
cras_bt_device_name(const struct cras_bt_device * device)347 const char *cras_bt_device_name(const struct cras_bt_device *device)
348 {
349 return device->name;
350 }
351
cras_bt_device_paired(const struct cras_bt_device * device)352 int cras_bt_device_paired(const struct cras_bt_device *device)
353 {
354 return device->paired;
355 }
356
cras_bt_device_trusted(const struct cras_bt_device * device)357 int cras_bt_device_trusted(const struct cras_bt_device *device)
358 {
359 return device->trusted;
360 }
361
cras_bt_device_connected(const struct cras_bt_device * device)362 int cras_bt_device_connected(const struct cras_bt_device *device)
363 {
364 return device->connected;
365 }
366
cras_bt_device_supports_profile(const struct cras_bt_device * device,enum cras_bt_device_profile profile)367 int cras_bt_device_supports_profile(const struct cras_bt_device *device,
368 enum cras_bt_device_profile profile)
369 {
370 return !!(device->profiles & profile);
371 }
372
cras_bt_device_append_iodev(struct cras_bt_device * device,struct cras_iodev * iodev,enum cras_bt_device_profile profile)373 void cras_bt_device_append_iodev(struct cras_bt_device *device,
374 struct cras_iodev *iodev,
375 enum cras_bt_device_profile profile)
376 {
377 struct cras_iodev *bt_iodev;
378
379 bt_iodev = device->bt_iodevs[iodev->direction];
380
381 if (bt_iodev) {
382 cras_bt_io_append(bt_iodev, iodev, profile);
383 } else {
384 device->bt_iodevs[iodev->direction] =
385 cras_bt_io_create(device, iodev, profile);
386 }
387 }
388
389 static void bt_device_switch_profile(struct cras_bt_device *device,
390 struct cras_iodev *bt_iodev,
391 int enable_dev);
392
cras_bt_device_rm_iodev(struct cras_bt_device * device,struct cras_iodev * iodev)393 void cras_bt_device_rm_iodev(struct cras_bt_device *device,
394 struct cras_iodev *iodev)
395 {
396 struct cras_iodev *bt_iodev;
397 int rc;
398
399 bt_iodev = device->bt_iodevs[iodev->direction];
400 if (bt_iodev) {
401 unsigned try_profile;
402
403 /* Check what will the preffered profile be if we remove dev. */
404 try_profile = cras_bt_io_try_remove(bt_iodev, iodev);
405 if (!try_profile)
406 goto destroy_bt_io;
407
408 /* If the check result doesn't match with the active
409 * profile we are currently using, switch to the
410 * preffered profile before actually remove the iodev.
411 */
412 if (!cras_bt_io_on_profile(bt_iodev, try_profile)) {
413 device->active_profile = try_profile;
414 bt_device_switch_profile(device, bt_iodev, 0);
415 }
416 rc = cras_bt_io_remove(bt_iodev, iodev);
417 if (rc) {
418 syslog(LOG_ERR, "Fail to fallback to profile %u",
419 try_profile);
420 goto destroy_bt_io;
421 }
422 }
423 return;
424
425 destroy_bt_io:
426 device->bt_iodevs[iodev->direction] = NULL;
427 cras_bt_io_destroy(bt_iodev);
428
429 if (!device->bt_iodevs[CRAS_STREAM_INPUT] &&
430 !device->bt_iodevs[CRAS_STREAM_OUTPUT])
431 cras_bt_device_set_active_profile(device, 0);
432 }
433
cras_bt_device_a2dp_configured(struct cras_bt_device * device)434 void cras_bt_device_a2dp_configured(struct cras_bt_device *device)
435 {
436 BTLOG(btlog, BT_A2DP_CONFIGURED, device->connected_profiles, 0);
437 device->connected_profiles |= CRAS_BT_DEVICE_PROFILE_A2DP_SINK;
438 }
439
cras_bt_device_has_a2dp(struct cras_bt_device * device)440 int cras_bt_device_has_a2dp(struct cras_bt_device *device)
441 {
442 struct cras_iodev *odev = device->bt_iodevs[CRAS_STREAM_OUTPUT];
443
444 /* Check if there is an output iodev with A2DP node attached. */
445 return odev &&
446 cras_bt_io_get_profile(odev, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
447 }
448
cras_bt_device_can_switch_to_a2dp(struct cras_bt_device * device)449 int cras_bt_device_can_switch_to_a2dp(struct cras_bt_device *device)
450 {
451 struct cras_iodev *idev = device->bt_iodevs[CRAS_STREAM_INPUT];
452
453 return cras_bt_device_has_a2dp(device) &&
454 (!idev || !cras_iodev_is_open(idev));
455 }
456
bt_device_remove_conflict(struct cras_bt_device * device)457 static void bt_device_remove_conflict(struct cras_bt_device *device)
458 {
459 struct cras_bt_device *connected;
460
461 /* Suspend other HFP audio gateways that conflict with device. */
462 cras_hfp_ag_remove_conflict(device);
463
464 /* Check if there's conflict A2DP headset and suspend it. */
465 connected = cras_a2dp_connected_device();
466 if (connected && (connected != device))
467 cras_a2dp_suspend_connected_device(connected);
468 }
469
cras_bt_device_audio_gateway_initialized(struct cras_bt_device * device)470 int cras_bt_device_audio_gateway_initialized(struct cras_bt_device *device)
471 {
472 BTLOG(btlog, BT_AUDIO_GATEWAY_INIT, device->profiles, 0);
473 /* Marks HFP/HSP as connected. This is what connection watcher
474 * checks. */
475 device->connected_profiles |= (CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE |
476 CRAS_BT_DEVICE_PROFILE_HSP_HEADSET);
477
478 return 0;
479 }
480
cras_bt_device_get_active_profile(const struct cras_bt_device * device)481 int cras_bt_device_get_active_profile(const struct cras_bt_device *device)
482 {
483 return device->active_profile;
484 }
485
cras_bt_device_set_active_profile(struct cras_bt_device * device,unsigned int profile)486 void cras_bt_device_set_active_profile(struct cras_bt_device *device,
487 unsigned int profile)
488 {
489 device->active_profile = profile;
490 }
491
cras_bt_device_log_profile(const struct cras_bt_device * device,enum cras_bt_device_profile profile)492 static void cras_bt_device_log_profile(const struct cras_bt_device *device,
493 enum cras_bt_device_profile profile)
494 {
495 switch (profile) {
496 case CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE:
497 syslog(LOG_DEBUG, "Bluetooth Device: %s is HFP handsfree",
498 device->address);
499 break;
500 case CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY:
501 syslog(LOG_DEBUG, "Bluetooth Device: %s is HFP audio gateway",
502 device->address);
503 break;
504 case CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE:
505 syslog(LOG_DEBUG, "Bluetooth Device: %s is A2DP source",
506 device->address);
507 break;
508 case CRAS_BT_DEVICE_PROFILE_A2DP_SINK:
509 syslog(LOG_DEBUG, "Bluetooth Device: %s is A2DP sink",
510 device->address);
511 break;
512 case CRAS_BT_DEVICE_PROFILE_AVRCP_REMOTE:
513 syslog(LOG_DEBUG, "Bluetooth Device: %s is AVRCP remote",
514 device->address);
515 break;
516 case CRAS_BT_DEVICE_PROFILE_AVRCP_TARGET:
517 syslog(LOG_DEBUG, "Bluetooth Device: %s is AVRCP target",
518 device->address);
519 break;
520 case CRAS_BT_DEVICE_PROFILE_HSP_HEADSET:
521 syslog(LOG_DEBUG, "Bluetooth Device: %s is HSP headset",
522 device->address);
523 break;
524 case CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY:
525 syslog(LOG_DEBUG, "Bluetooth Device: %s is HSP audio gateway",
526 device->address);
527 break;
528 }
529 }
530
531 static int
cras_bt_device_is_profile_connected(const struct cras_bt_device * device,enum cras_bt_device_profile profile)532 cras_bt_device_is_profile_connected(const struct cras_bt_device *device,
533 enum cras_bt_device_profile profile)
534 {
535 return !!(device->connected_profiles & profile);
536 }
537
538 static void bt_device_schedule_suspend(struct cras_bt_device *device,
539 unsigned int msec);
540
541 /* Callback used to periodically check if supported profiles are connected. */
bt_device_conn_watch_cb(struct cras_timer * timer,void * arg)542 static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg)
543 {
544 struct cras_tm *tm;
545 struct cras_bt_device *device = (struct cras_bt_device *)arg;
546 int rc;
547
548 BTLOG(btlog, BT_DEV_CONN_WATCH_CB, device->conn_watch_retries,
549 device->profiles);
550 device->conn_watch_timer = NULL;
551
552 /* Skip the callback if it is not an audio device. */
553 if (!device->profiles)
554 return;
555
556 /* If A2DP is not ready, try connect it after a while. */
557 if (cras_bt_device_supports_profile(device,
558 CRAS_BT_DEVICE_PROFILE_A2DP_SINK) &&
559 !cras_bt_device_is_profile_connected(
560 device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK)) {
561 if (0 == device->conn_watch_retries % PROFILE_CONN_RETRIES)
562 cras_bt_device_connect_profile(device->conn, device,
563 A2DP_SINK_UUID);
564 goto arm_retry_timer;
565 }
566
567 /* If HFP is not ready, try connect it after a while. */
568 if (cras_bt_device_supports_profile(
569 device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE) &&
570 !cras_bt_device_is_profile_connected(
571 device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE)) {
572 if (0 == device->conn_watch_retries % PROFILE_CONN_RETRIES)
573 cras_bt_device_connect_profile(device->conn, device,
574 HFP_HF_UUID);
575 goto arm_retry_timer;
576 }
577
578 /* Expected profiles are all connected, no more connection watch
579 * callback will be scheduled.
580 * Base on the decision that we expose only the latest connected
581 * BT audio device to user, treat all other connected devices as
582 * conflict and remove them before we start A2DP/HFP of this device.
583 */
584 bt_device_remove_conflict(device);
585
586 if (cras_bt_device_is_profile_connected(
587 device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK))
588 cras_a2dp_start(device);
589
590 if (cras_bt_device_is_profile_connected(
591 device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE)) {
592 rc = cras_hfp_ag_start(device);
593 if (rc) {
594 syslog(LOG_ERR, "Start audio gateway failed, rc %d",
595 rc);
596 bt_device_schedule_suspend(device, 0);
597 }
598 }
599 return;
600
601 arm_retry_timer:
602
603 syslog(LOG_DEBUG, "conn_watch_retries: %d", device->conn_watch_retries);
604
605 if (--device->conn_watch_retries) {
606 tm = cras_system_state_get_tm();
607 device->conn_watch_timer =
608 cras_tm_create_timer(tm, CONN_WATCH_PERIOD_MS,
609 bt_device_conn_watch_cb, device);
610 } else {
611 syslog(LOG_ERR, "Connection watch timeout.");
612 bt_device_schedule_suspend(device, 0);
613 }
614 }
615
616 static void
cras_bt_device_start_new_conn_watch_timer(struct cras_bt_device * device)617 cras_bt_device_start_new_conn_watch_timer(struct cras_bt_device *device)
618 {
619 struct cras_tm *tm = cras_system_state_get_tm();
620
621 if (device->conn_watch_timer) {
622 cras_tm_cancel_timer(tm, device->conn_watch_timer);
623 }
624 device->conn_watch_retries = CONN_WATCH_MAX_RETRIES;
625 device->conn_watch_timer = cras_tm_create_timer(
626 tm, CONN_WATCH_PERIOD_MS, bt_device_conn_watch_cb, device);
627 }
628
cras_bt_device_set_connected(struct cras_bt_device * device,int value)629 void cras_bt_device_set_connected(struct cras_bt_device *device, int value)
630 {
631 struct cras_tm *tm = cras_system_state_get_tm();
632 if (device->connected || value)
633 BTLOG(btlog, BT_DEV_CONNECTED_CHANGE, device->profiles, value);
634
635 if (device->connected && !value) {
636 cras_bt_profile_on_device_disconnected(device);
637 /* Device is disconnected, resets connected profiles. */
638 device->connected_profiles = 0;
639 }
640
641 device->connected = value;
642
643 if (!device->connected && device->conn_watch_timer) {
644 cras_tm_cancel_timer(tm, device->conn_watch_timer);
645 device->conn_watch_timer = NULL;
646 }
647 }
648
cras_bt_device_notify_profile_dropped(struct cras_bt_device * device,enum cras_bt_device_profile profile)649 void cras_bt_device_notify_profile_dropped(struct cras_bt_device *device,
650 enum cras_bt_device_profile profile)
651 {
652 device->connected_profiles &= !profile;
653
654 /* If any profile, a2dp or hfp/hsp, has dropped for some reason,
655 * we shall make sure this device is fully disconnected within
656 * given time so that user does not see a headset stay connected
657 * but works with partial function.
658 */
659 bt_device_schedule_suspend(device, PROFILE_DROP_SUSPEND_DELAY_MS);
660 }
661
662 /*
663 * Check if the uuid is of a new audio profile that isn't listed
664 * as supported by device.
665 * Args:
666 * device - The BT device holding supported profiles bitmap.
667 * uuid - UUID string from the device properties notified by BlueZ.
668 * Returns:
669 * True if uuid is a new audio profiles not already supported by device.
670 */
cras_bt_device_add_supported_profiles(struct cras_bt_device * device,const char * uuid)671 int cras_bt_device_add_supported_profiles(struct cras_bt_device *device,
672 const char *uuid)
673 {
674 enum cras_bt_device_profile profile =
675 cras_bt_device_profile_from_uuid(uuid);
676
677 if (profile == 0)
678 return 0;
679
680 /* Do nothing if this profile is not new. */
681 if (device->profiles & profile)
682 return 0;
683
684 /* Log this event as we might need to re-intialize the BT audio nodes
685 * if new audio profile is reported for already connected device. */
686 if (device->connected && (profile & CRAS_SUPPORTED_PROFILES))
687 BTLOG(btlog, BT_NEW_AUDIO_PROFILE_AFTER_CONNECT,
688 device->profiles, profile);
689 device->profiles |= profile;
690 cras_bt_device_log_profile(device, profile);
691
692 return (profile & CRAS_SUPPORTED_PROFILES);
693 }
694
cras_bt_device_update_properties(struct cras_bt_device * device,DBusMessageIter * properties_array_iter,DBusMessageIter * invalidated_array_iter)695 void cras_bt_device_update_properties(struct cras_bt_device *device,
696 DBusMessageIter *properties_array_iter,
697 DBusMessageIter *invalidated_array_iter)
698 {
699 int watch_needed = 0;
700 while (dbus_message_iter_get_arg_type(properties_array_iter) !=
701 DBUS_TYPE_INVALID) {
702 DBusMessageIter properties_dict_iter, variant_iter;
703 const char *key;
704 int type;
705
706 dbus_message_iter_recurse(properties_array_iter,
707 &properties_dict_iter);
708
709 dbus_message_iter_get_basic(&properties_dict_iter, &key);
710 dbus_message_iter_next(&properties_dict_iter);
711
712 dbus_message_iter_recurse(&properties_dict_iter, &variant_iter);
713 type = dbus_message_iter_get_arg_type(&variant_iter);
714
715 if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) {
716 const char *value;
717
718 dbus_message_iter_get_basic(&variant_iter, &value);
719
720 if (strcmp(key, "Adapter") == 0) {
721 free(device->adapter_obj_path);
722 device->adapter_obj_path = strdup(value);
723 } else if (strcmp(key, "Address") == 0) {
724 free(device->address);
725 device->address = strdup(value);
726 } else if (strcmp(key, "Alias") == 0) {
727 free(device->name);
728 device->name = strdup(value);
729 }
730
731 } else if (type == DBUS_TYPE_UINT32) {
732 uint32_t value;
733
734 dbus_message_iter_get_basic(&variant_iter, &value);
735
736 if (strcmp(key, "Class") == 0)
737 device->bluetooth_class = value;
738
739 } else if (type == DBUS_TYPE_BOOLEAN) {
740 int value;
741
742 dbus_message_iter_get_basic(&variant_iter, &value);
743
744 if (strcmp(key, "Paired") == 0) {
745 device->paired = value;
746 } else if (strcmp(key, "Trusted") == 0) {
747 device->trusted = value;
748 } else if (strcmp(key, "Connected") == 0) {
749 cras_bt_device_set_connected(device, value);
750 watch_needed = device->connected &&
751 cras_bt_device_supports_profile(
752 device,
753 CRAS_SUPPORTED_PROFILES);
754 }
755
756 } else if (strcmp(dbus_message_iter_get_signature(&variant_iter),
757 "as") == 0 &&
758 strcmp(key, "UUIDs") == 0) {
759 DBusMessageIter uuid_array_iter;
760
761 dbus_message_iter_recurse(&variant_iter,
762 &uuid_array_iter);
763 while (dbus_message_iter_get_arg_type(
764 &uuid_array_iter) != DBUS_TYPE_INVALID) {
765 const char *uuid;
766
767 dbus_message_iter_get_basic(&uuid_array_iter,
768 &uuid);
769
770 /*
771 * If updated properties includes new audio
772 * profile, and device is connected, we need
773 * to start connection watcher. This is needed
774 * because on some bluetooth device, supported
775 * profiles do not present when device
776 * interface is added and they are updated
777 * later.
778 */
779 if (cras_bt_device_add_supported_profiles(
780 device, uuid))
781 watch_needed = device->connected;
782
783 dbus_message_iter_next(&uuid_array_iter);
784 }
785 }
786
787 dbus_message_iter_next(properties_array_iter);
788 }
789
790 while (invalidated_array_iter &&
791 dbus_message_iter_get_arg_type(invalidated_array_iter) !=
792 DBUS_TYPE_INVALID) {
793 const char *key;
794
795 dbus_message_iter_get_basic(invalidated_array_iter, &key);
796
797 if (strcmp(key, "Adapter") == 0) {
798 free(device->adapter_obj_path);
799 device->adapter_obj_path = NULL;
800 } else if (strcmp(key, "Address") == 0) {
801 free(device->address);
802 device->address = NULL;
803 } else if (strcmp(key, "Alias") == 0) {
804 free(device->name);
805 device->name = NULL;
806 } else if (strcmp(key, "Class") == 0) {
807 device->bluetooth_class = 0;
808 } else if (strcmp(key, "Paired") == 0) {
809 device->paired = 0;
810 } else if (strcmp(key, "Trusted") == 0) {
811 device->trusted = 0;
812 } else if (strcmp(key, "Connected") == 0) {
813 device->connected = 0;
814 } else if (strcmp(key, "UUIDs") == 0) {
815 device->profiles = 0;
816 }
817
818 dbus_message_iter_next(invalidated_array_iter);
819 }
820
821 if (watch_needed)
822 cras_bt_device_start_new_conn_watch_timer(device);
823 }
824
825 /* Converts bluetooth address string into sockaddr structure. The address
826 * string is expected of the form 1A:2B:3C:4D:5E:6F, and each of the six
827 * hex values will be parsed into sockaddr in inverse order.
828 * Args:
829 * str - The string version of bluetooth address
830 * addr - The struct to be filled with converted address
831 */
bt_address(const char * str,struct sockaddr * addr)832 static int bt_address(const char *str, struct sockaddr *addr)
833 {
834 int i;
835
836 if (strlen(str) != 17) {
837 syslog(LOG_ERR, "Invalid bluetooth address %s", str);
838 return -1;
839 }
840
841 memset(addr, 0, sizeof(*addr));
842 addr->sa_family = AF_BLUETOOTH;
843 for (i = 5; i >= 0; i--) {
844 addr->sa_data[i] = (unsigned char)strtol(str, NULL, 16);
845 str += 3;
846 }
847
848 return 0;
849 }
850
851 /* Apply codec specific settings to the socket fd. */
apply_codec_settings(int fd,uint8_t codec)852 static int apply_codec_settings(int fd, uint8_t codec)
853 {
854 struct bt_voice voice;
855
856 memset(&voice, 0, sizeof(voice));
857 if (codec == HFP_CODEC_ID_CVSD)
858 return 0;
859
860 if (codec != HFP_CODEC_ID_MSBC) {
861 syslog(LOG_ERR, "Unsupported codec %d", codec);
862 return -1;
863 }
864
865 voice.setting = BT_VOICE_TRANSPARENT;
866
867 if (setsockopt(fd, SOL_BLUETOOTH, BT_VOICE, &voice, sizeof(voice)) <
868 0) {
869 syslog(LOG_ERR, "Failed to apply voice setting");
870 return -1;
871 }
872 return 0;
873 }
874
cras_bt_device_sco_connect(struct cras_bt_device * device,int codec)875 int cras_bt_device_sco_connect(struct cras_bt_device *device, int codec)
876 {
877 int sk = 0, err;
878 struct sockaddr addr;
879 struct cras_bt_adapter *adapter;
880 struct timespec timeout = { 1, 0 };
881 struct pollfd *pollfds;
882
883 adapter = cras_bt_device_adapter(device);
884 if (!adapter) {
885 syslog(LOG_ERR, "No adapter found for device %s at SCO connect",
886 cras_bt_device_object_path(device));
887 goto error;
888 }
889
890 sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET | O_NONBLOCK | SOCK_CLOEXEC,
891 BTPROTO_SCO);
892 if (sk < 0) {
893 syslog(LOG_ERR, "Failed to create socket: %s (%d)",
894 strerror(errno), errno);
895 return -errno;
896 }
897
898 /* Bind to local address */
899 if (bt_address(cras_bt_adapter_address(adapter), &addr))
900 goto error;
901 if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
902 syslog(LOG_ERR, "Failed to bind socket: %s (%d)",
903 strerror(errno), errno);
904 goto error;
905 }
906
907 /* Connect to remote in nonblocking mode */
908 fcntl(sk, F_SETFL, O_NONBLOCK);
909 pollfds = (struct pollfd *)malloc(sizeof(*pollfds));
910 pollfds[0].fd = sk;
911 pollfds[0].events = POLLOUT;
912
913 if (bt_address(cras_bt_device_address(device), &addr))
914 goto error;
915
916 err = apply_codec_settings(sk, codec);
917 if (err)
918 goto error;
919
920 err = connect(sk, (struct sockaddr *)&addr, sizeof(addr));
921 if (err && errno != EINPROGRESS) {
922 syslog(LOG_ERR, "Failed to connect: %s (%d)", strerror(errno),
923 errno);
924 goto error;
925 }
926
927 err = ppoll(pollfds, 1, &timeout, NULL);
928 if (err <= 0) {
929 syslog(LOG_ERR, "Connect SCO: poll for writable timeout");
930 goto error;
931 }
932
933 if (pollfds[0].revents & (POLLERR | POLLHUP)) {
934 syslog(LOG_ERR, "SCO socket error, revents: %u",
935 pollfds[0].revents);
936 bt_device_schedule_suspend(device, 0);
937 goto error;
938 }
939
940 BTLOG(btlog, BT_SCO_CONNECT, 1, sk);
941 return sk;
942
943 error:
944 BTLOG(btlog, BT_SCO_CONNECT, 0, sk);
945 if (sk)
946 close(sk);
947 return -1;
948 }
949
cras_bt_device_sco_packet_size(struct cras_bt_device * device,int sco_socket,int codec)950 int cras_bt_device_sco_packet_size(struct cras_bt_device *device,
951 int sco_socket, int codec)
952 {
953 struct sco_options so;
954 socklen_t len = sizeof(so);
955 struct cras_bt_adapter *adapter;
956
957 adapter = cras_bt_adapter_get(device->adapter_obj_path);
958
959 if (cras_bt_adapter_on_usb(adapter)) {
960 return (codec == HFP_CODEC_ID_MSBC) ? USB_MSBC_PKT_SIZE :
961 USB_CVSD_PKT_SIZE;
962 }
963
964 /* For non-USB cases, query the SCO MTU from driver. */
965 if (getsockopt(sco_socket, SOL_SCO, SCO_OPTIONS, &so, &len) < 0) {
966 syslog(LOG_ERR, "Get SCO options error: %s", strerror(errno));
967 return DEFAULT_SCO_PKT_SIZE;
968 }
969 return so.mtu;
970 }
971
cras_bt_device_set_use_hardware_volume(struct cras_bt_device * device,int use_hardware_volume)972 void cras_bt_device_set_use_hardware_volume(struct cras_bt_device *device,
973 int use_hardware_volume)
974 {
975 struct cras_iodev *iodev;
976
977 device->use_hardware_volume = use_hardware_volume;
978 iodev = device->bt_iodevs[CRAS_STREAM_OUTPUT];
979 if (iodev)
980 iodev->software_volume_needed = !use_hardware_volume;
981 }
982
cras_bt_device_get_use_hardware_volume(struct cras_bt_device * device)983 int cras_bt_device_get_use_hardware_volume(struct cras_bt_device *device)
984 {
985 return device->use_hardware_volume;
986 }
987
init_bt_device_msg(struct bt_device_msg * msg,enum BT_DEVICE_COMMAND cmd,struct cras_bt_device * device,struct cras_iodev * dev,unsigned int arg)988 static void init_bt_device_msg(struct bt_device_msg *msg,
989 enum BT_DEVICE_COMMAND cmd,
990 struct cras_bt_device *device,
991 struct cras_iodev *dev, unsigned int arg)
992 {
993 memset(msg, 0, sizeof(*msg));
994 msg->header.type = CRAS_MAIN_BT;
995 msg->header.length = sizeof(*msg);
996 msg->cmd = cmd;
997 msg->device = device;
998 msg->dev = dev;
999 msg->arg = arg;
1000 }
1001
cras_bt_device_cancel_suspend(struct cras_bt_device * device)1002 int cras_bt_device_cancel_suspend(struct cras_bt_device *device)
1003 {
1004 struct bt_device_msg msg;
1005 int rc;
1006
1007 init_bt_device_msg(&msg, BT_DEVICE_CANCEL_SUSPEND, device, NULL, 0);
1008 rc = cras_main_message_send((struct cras_main_message *)&msg);
1009 return rc;
1010 }
1011
cras_bt_device_schedule_suspend(struct cras_bt_device * device,unsigned int msec)1012 int cras_bt_device_schedule_suspend(struct cras_bt_device *device,
1013 unsigned int msec)
1014 {
1015 struct bt_device_msg msg;
1016 int rc;
1017
1018 init_bt_device_msg(&msg, BT_DEVICE_SCHEDULE_SUSPEND, device, NULL,
1019 msec);
1020 rc = cras_main_message_send((struct cras_main_message *)&msg);
1021 return rc;
1022 }
1023
1024 /* This diagram describes how the profile switching happens. When
1025 * certain conditions met, bt iodev will call the APIs below to interact
1026 * with main thread to switch to another active profile.
1027 *
1028 * Audio thread:
1029 * +--------------------------------------------------------------+
1030 * | bt iodev |
1031 * | +------------------+ +-----------------+ |
1032 * | | condition met to | | open, close, or | |
1033 * | +--| change profile |<---| append profile |<--+ |
1034 * | | +------------------+ +-----------------+ | |
1035 * +-----------|------------------------------------------------|-+
1036 * | |
1037 * Main thread: |
1038 * +-----------|------------------------------------------------|-+
1039 * | | | |
1040 * | | +------------+ +----------------+ | |
1041 * | +----->| set active |---->| switch profile |-----+ |
1042 * | | profile | +----------------+ |
1043 * | bt device +------------+ |
1044 * +--------------------------------------------------------------+
1045 */
cras_bt_device_switch_profile_enable_dev(struct cras_bt_device * device,struct cras_iodev * bt_iodev)1046 int cras_bt_device_switch_profile_enable_dev(struct cras_bt_device *device,
1047 struct cras_iodev *bt_iodev)
1048 {
1049 struct bt_device_msg msg;
1050 int rc;
1051
1052 init_bt_device_msg(&msg, BT_DEVICE_SWITCH_PROFILE_ENABLE_DEV, device,
1053 bt_iodev, 0);
1054 rc = cras_main_message_send((struct cras_main_message *)&msg);
1055 return rc;
1056 }
1057
cras_bt_device_switch_profile(struct cras_bt_device * device,struct cras_iodev * bt_iodev)1058 int cras_bt_device_switch_profile(struct cras_bt_device *device,
1059 struct cras_iodev *bt_iodev)
1060 {
1061 struct bt_device_msg msg;
1062 int rc;
1063
1064 init_bt_device_msg(&msg, BT_DEVICE_SWITCH_PROFILE, device, bt_iodev, 0);
1065 rc = cras_main_message_send((struct cras_main_message *)&msg);
1066 return rc;
1067 }
1068
profile_switch_delay_cb(struct cras_timer * timer,void * arg)1069 static void profile_switch_delay_cb(struct cras_timer *timer, void *arg)
1070 {
1071 struct cras_bt_device *device = (struct cras_bt_device *)arg;
1072 struct cras_iodev *iodev;
1073
1074 device->switch_profile_timer = NULL;
1075 iodev = device->bt_iodevs[CRAS_STREAM_OUTPUT];
1076 if (!iodev)
1077 return;
1078
1079 /*
1080 * During the |PROFILE_SWITCH_DELAY_MS| time interval, BT iodev could
1081 * have been enabled by others, and its active profile may have changed.
1082 * If iodev has been enabled, that means it has already picked up a
1083 * reasonable profile to use and audio thread is accessing iodev now.
1084 * We should NOT call into update_active_node from main thread
1085 * because that may mess up the active node content.
1086 */
1087 iodev->update_active_node(iodev, 0, 1);
1088 cras_iodev_list_resume_dev(iodev->info.idx);
1089 }
1090
bt_device_switch_profile_with_delay(struct cras_bt_device * device,unsigned int delay_ms)1091 static void bt_device_switch_profile_with_delay(struct cras_bt_device *device,
1092 unsigned int delay_ms)
1093 {
1094 struct cras_tm *tm = cras_system_state_get_tm();
1095
1096 if (device->switch_profile_timer) {
1097 cras_tm_cancel_timer(tm, device->switch_profile_timer);
1098 device->switch_profile_timer = NULL;
1099 }
1100 device->switch_profile_timer = cras_tm_create_timer(
1101 tm, delay_ms, profile_switch_delay_cb, device);
1102 }
1103
1104 /* Switches associated bt iodevs to use the active profile. This is
1105 * achieved by close the iodevs, update their active nodes, and then
1106 * finally reopen them. */
bt_device_switch_profile(struct cras_bt_device * device,struct cras_iodev * bt_iodev,int enable_dev)1107 static void bt_device_switch_profile(struct cras_bt_device *device,
1108 struct cras_iodev *bt_iodev,
1109 int enable_dev)
1110 {
1111 struct cras_iodev *iodev;
1112 int dir;
1113
1114 /* If a bt iodev is active, temporarily force close it.
1115 * Note that we need to check all bt_iodevs for the situation that both
1116 * input and output are active while switches from HFP/HSP to A2DP.
1117 */
1118 for (dir = 0; dir < CRAS_NUM_DIRECTIONS; dir++) {
1119 iodev = device->bt_iodevs[dir];
1120 if (!iodev)
1121 continue;
1122 cras_iodev_list_suspend_dev(iodev->info.idx);
1123 }
1124
1125 for (dir = 0; dir < CRAS_NUM_DIRECTIONS; dir++) {
1126 iodev = device->bt_iodevs[dir];
1127 if (!iodev)
1128 continue;
1129
1130 /* If the iodev was active or this profile switching is
1131 * triggered at opening iodev, add it to active dev list.
1132 * However for the output iodev, adding it back to active dev
1133 * list could cause immediate switching from HFP to A2DP if
1134 * there exists an output stream. Certain headset/speaker
1135 * would fail to playback afterwards when the switching happens
1136 * too soon, so put this task in a delayed callback.
1137 */
1138 if (dir == CRAS_STREAM_INPUT) {
1139 iodev->update_active_node(iodev, 0, 1);
1140 cras_iodev_list_resume_dev(iodev->info.idx);
1141 } else {
1142 bt_device_switch_profile_with_delay(
1143 device, PROFILE_SWITCH_DELAY_MS);
1144 }
1145 }
1146 }
1147
bt_device_suspend_cb(struct cras_timer * timer,void * arg)1148 static void bt_device_suspend_cb(struct cras_timer *timer, void *arg)
1149 {
1150 struct cras_bt_device *device = (struct cras_bt_device *)arg;
1151
1152 BTLOG(btlog, BT_DEV_SUSPEND_CB, device->profiles,
1153 device->connected_profiles);
1154 device->suspend_timer = NULL;
1155
1156 cras_a2dp_suspend_connected_device(device);
1157 cras_hfp_ag_suspend_connected_device(device);
1158 cras_bt_device_disconnect(device->conn, device);
1159 }
1160
bt_device_schedule_suspend(struct cras_bt_device * device,unsigned int msec)1161 static void bt_device_schedule_suspend(struct cras_bt_device *device,
1162 unsigned int msec)
1163 {
1164 struct cras_tm *tm = cras_system_state_get_tm();
1165
1166 if (device->suspend_timer)
1167 return;
1168 device->suspend_timer =
1169 cras_tm_create_timer(tm, msec, bt_device_suspend_cb, device);
1170 }
1171
bt_device_cancel_suspend(struct cras_bt_device * device)1172 static void bt_device_cancel_suspend(struct cras_bt_device *device)
1173 {
1174 struct cras_tm *tm = cras_system_state_get_tm();
1175 if (device->suspend_timer == NULL)
1176 return;
1177 cras_tm_cancel_timer(tm, device->suspend_timer);
1178 device->suspend_timer = NULL;
1179 }
1180
bt_device_process_msg(struct cras_main_message * msg,void * arg)1181 static void bt_device_process_msg(struct cras_main_message *msg, void *arg)
1182 {
1183 struct bt_device_msg *bt_msg = (struct bt_device_msg *)msg;
1184 struct cras_bt_device *device = NULL;
1185
1186 DL_FOREACH (devices, device) {
1187 if (device == bt_msg->device)
1188 break;
1189 }
1190
1191 /* Do nothing if target device no longer exists. */
1192 if (device == NULL)
1193 return;
1194
1195 switch (bt_msg->cmd) {
1196 case BT_DEVICE_SWITCH_PROFILE:
1197 bt_device_switch_profile(bt_msg->device, bt_msg->dev, 0);
1198 break;
1199 case BT_DEVICE_SWITCH_PROFILE_ENABLE_DEV:
1200 bt_device_switch_profile(bt_msg->device, bt_msg->dev, 1);
1201 break;
1202 case BT_DEVICE_SCHEDULE_SUSPEND:
1203 bt_device_schedule_suspend(bt_msg->device, bt_msg->arg);
1204 break;
1205 case BT_DEVICE_CANCEL_SUSPEND:
1206 bt_device_cancel_suspend(bt_msg->device);
1207 break;
1208 default:
1209 break;
1210 }
1211 }
1212
cras_bt_device_start_monitor()1213 void cras_bt_device_start_monitor()
1214 {
1215 cras_main_message_add_handler(CRAS_MAIN_BT, bt_device_process_msg,
1216 NULL);
1217 }
1218
cras_bt_device_update_hardware_volume(struct cras_bt_device * device,int volume)1219 void cras_bt_device_update_hardware_volume(struct cras_bt_device *device,
1220 int volume)
1221 {
1222 struct cras_iodev *iodev;
1223
1224 iodev = device->bt_iodevs[CRAS_STREAM_OUTPUT];
1225 if (iodev == NULL)
1226 return;
1227
1228 /* Check if this BT device is okay to use hardware volume. If not
1229 * then ignore the reported volume change event.
1230 */
1231 if (!cras_bt_device_get_use_hardware_volume(device))
1232 return;
1233
1234 iodev->active_node->volume = volume;
1235 cras_iodev_list_notify_node_volume(iodev->active_node);
1236 }
1237
cras_bt_device_get_sco(struct cras_bt_device * device,int codec)1238 int cras_bt_device_get_sco(struct cras_bt_device *device, int codec)
1239 {
1240 if (device->sco_ref_count == 0) {
1241 device->sco_fd = cras_bt_device_sco_connect(device, codec);
1242 if (device->sco_fd < 0)
1243 return device->sco_fd;
1244 }
1245
1246 ++device->sco_ref_count;
1247 return 0;
1248 }
1249
cras_bt_device_put_sco(struct cras_bt_device * device)1250 void cras_bt_device_put_sco(struct cras_bt_device *device)
1251 {
1252 if (device->sco_ref_count == 0)
1253 return;
1254
1255 if (--device->sco_ref_count == 0)
1256 close(device->sco_fd);
1257 }
1258