2 This file is part of PulseAudio.
4 Copyright 2008-2013 João Paulo Rechi Vita
5 Copyright 2011-2013 BMW Car IT GmbH.
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29 #include <pulsecore/core-util.h>
30 #include <pulsecore/i18n.h>
31 #include <pulsecore/module.h>
32 #include <pulsecore/modargs.h>
33 #include <pulsecore/poll.h>
34 #include <pulsecore/rtpoll.h>
35 #include <pulsecore/thread.h>
36 #include <pulsecore/thread-mq.h>
38 #include "a2dp-codecs.h"
39 #include "bluez5-util.h"
41 #include "module-bluez5-device-symdef.h"
43 PA_MODULE_AUTHOR("João Paulo Rechi Vita");
44 PA_MODULE_DESCRIPTION("BlueZ 5 Bluetooth audio sink and source");
45 PA_MODULE_VERSION(PACKAGE_VERSION
);
46 PA_MODULE_LOAD_ONCE(false);
47 PA_MODULE_USAGE("path=<device object path>");
49 static const char* const valid_modargs
[] = {
54 typedef struct sbc_info
{
55 sbc_t sbc
; /* Codec data */
56 bool sbc_initialized
; /* Keep track if the encoder is initialized */
57 size_t codesize
, frame_length
; /* SBC Codesize, frame_length. We simply cache those values here */
58 uint16_t seq_num
; /* Cumulative packet sequence */
62 void* buffer
; /* Codec transfer buffer */
63 size_t buffer_size
; /* Size of the buffer */
70 pa_hook_slot
*device_connection_changed_slot
;
72 pa_bluetooth_discovery
*discovery
;
73 pa_bluetooth_device
*device
;
74 pa_bluetooth_transport
*transport
;
75 bool transport_acquired
;
80 pa_bluetooth_profile_t profile
;
81 char *output_port_name
;
82 char *input_port_name
;
85 pa_thread_mq thread_mq
;
87 pa_rtpoll_item
*rtpoll_item
;
91 size_t write_link_mtu
;
92 size_t read_block_size
;
93 size_t write_block_size
;
94 pa_sample_spec sample_spec
;
95 struct sbc_info sbc_info
;
98 typedef enum pa_bluetooth_form_factor
{
99 PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
,
100 PA_BLUETOOTH_FORM_FACTOR_HEADSET
,
101 PA_BLUETOOTH_FORM_FACTOR_HANDSFREE
,
102 PA_BLUETOOTH_FORM_FACTOR_MICROPHONE
,
103 PA_BLUETOOTH_FORM_FACTOR_SPEAKER
,
104 PA_BLUETOOTH_FORM_FACTOR_HEADPHONE
,
105 PA_BLUETOOTH_FORM_FACTOR_PORTABLE
,
106 PA_BLUETOOTH_FORM_FACTOR_CAR
,
107 PA_BLUETOOTH_FORM_FACTOR_HIFI
,
108 PA_BLUETOOTH_FORM_FACTOR_PHONE
,
109 } pa_bluetooth_form_factor_t
;
111 /* Run from main thread */
112 static pa_bluetooth_form_factor_t
form_factor_from_class(uint32_t class_of_device
) {
113 unsigned major
, minor
;
114 pa_bluetooth_form_factor_t r
;
116 static const pa_bluetooth_form_factor_t table
[] = {
117 [1] = PA_BLUETOOTH_FORM_FACTOR_HEADSET
,
118 [2] = PA_BLUETOOTH_FORM_FACTOR_HANDSFREE
,
119 [4] = PA_BLUETOOTH_FORM_FACTOR_MICROPHONE
,
120 [5] = PA_BLUETOOTH_FORM_FACTOR_SPEAKER
,
121 [6] = PA_BLUETOOTH_FORM_FACTOR_HEADPHONE
,
122 [7] = PA_BLUETOOTH_FORM_FACTOR_PORTABLE
,
123 [8] = PA_BLUETOOTH_FORM_FACTOR_CAR
,
124 [10] = PA_BLUETOOTH_FORM_FACTOR_HIFI
128 * See Bluetooth Assigned Numbers:
129 * https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
131 major
= (class_of_device
>> 8) & 0x1F;
132 minor
= (class_of_device
>> 2) & 0x3F;
136 return PA_BLUETOOTH_FORM_FACTOR_PHONE
;
140 pa_log_debug("Unknown Bluetooth major device class %u", major
);
141 return PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
;
144 r
= minor
< PA_ELEMENTSOF(table
) ? table
[minor
] : PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
;
147 pa_log_debug("Unknown Bluetooth minor device class %u", minor
);
152 /* Run from main thread */
153 static const char *form_factor_to_string(pa_bluetooth_form_factor_t ff
) {
155 case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
:
157 case PA_BLUETOOTH_FORM_FACTOR_HEADSET
:
159 case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE
:
161 case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE
:
163 case PA_BLUETOOTH_FORM_FACTOR_SPEAKER
:
165 case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE
:
167 case PA_BLUETOOTH_FORM_FACTOR_PORTABLE
:
169 case PA_BLUETOOTH_FORM_FACTOR_CAR
:
171 case PA_BLUETOOTH_FORM_FACTOR_HIFI
:
173 case PA_BLUETOOTH_FORM_FACTOR_PHONE
:
177 pa_assert_not_reached();
180 /* Run from main thread */
181 static void connect_ports(struct userdata
*u
, void *new_data
, pa_direction_t direction
) {
182 pa_device_port
*port
;
184 if (direction
== PA_DIRECTION_OUTPUT
) {
185 pa_sink_new_data
*sink_new_data
= new_data
;
187 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, u
->output_port_name
));
188 pa_assert_se(pa_hashmap_put(sink_new_data
->ports
, port
->name
, port
) >= 0);
189 pa_device_port_ref(port
);
191 pa_source_new_data
*source_new_data
= new_data
;
193 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, u
->input_port_name
));
194 pa_assert_se(pa_hashmap_put(source_new_data
->ports
, port
->name
, port
) >= 0);
195 pa_device_port_ref(port
);
199 static void teardown_stream(struct userdata
*u
) {
200 if (u
->rtpoll_item
) {
201 pa_rtpoll_item_free(u
->rtpoll_item
);
202 u
->rtpoll_item
= NULL
;
205 if (u
->stream_fd
>= 0) {
206 pa_close(u
->stream_fd
);
210 pa_log_debug("Audio stream torn down");
213 static int transport_acquire(struct userdata
*u
, bool optional
) {
214 pa_assert(u
->transport
);
216 if (u
->transport_acquired
)
219 pa_log_debug("Acquiring transport %s", u
->transport
->path
);
221 u
->stream_fd
= u
->transport
->acquire(u
->transport
, optional
, &u
->read_link_mtu
, &u
->write_link_mtu
);
222 if (u
->stream_fd
< 0)
225 u
->transport_acquired
= true;
226 pa_log_info("Transport %s acquired: fd %d", u
->transport
->path
, u
->stream_fd
);
231 static void transport_release(struct userdata
*u
) {
232 pa_assert(u
->transport
);
234 /* Ignore if already released */
235 if (!u
->transport_acquired
)
238 pa_log_debug("Releasing transport %s", u
->transport
->path
);
240 u
->transport
->release(u
->transport
);
242 u
->transport_acquired
= false;
247 /* Run from main thread */
248 static int add_source(struct userdata
*u
) {
249 pa_source_new_data data
;
251 pa_assert(u
->transport
);
253 pa_source_new_data_init(&data
);
254 data
.module
= u
->module
;
256 data
.driver
= __FILE__
;
257 data
.name
= pa_sprintf_malloc("bluez_source.%s", u
->device
->address
);
258 data
.namereg_fail
= false;
259 pa_proplist_sets(data
.proplist
, "bluetooth.protocol", pa_bluetooth_profile_to_string(u
->profile
));
260 pa_source_new_data_set_sample_spec(&data
, &u
->sample_spec
);
262 connect_ports(u
, &data
, PA_DIRECTION_INPUT
);
264 if (!u
->transport_acquired
)
265 switch (u
->profile
) {
266 case PA_BLUETOOTH_PROFILE_A2DP_SOURCE
:
267 data
.suspend_cause
= PA_SUSPEND_USER
;
269 case PA_BLUETOOTH_PROFILE_A2DP_SINK
:
270 case PA_BLUETOOTH_PROFILE_OFF
:
271 pa_assert_not_reached();
275 u
->source
= pa_source_new(u
->core
, &data
, PA_SOURCE_HARDWARE
|PA_SOURCE_LATENCY
);
276 pa_source_new_data_done(&data
);
278 pa_log_error("Failed to create source");
282 u
->source
->userdata
= u
;
287 /* Run from main thread */
288 static int add_sink(struct userdata
*u
) {
289 pa_sink_new_data data
;
291 pa_assert(u
->transport
);
293 pa_sink_new_data_init(&data
);
294 data
.module
= u
->module
;
296 data
.driver
= __FILE__
;
297 data
.name
= pa_sprintf_malloc("bluez_sink.%s", u
->device
->address
);
298 data
.namereg_fail
= false;
299 pa_proplist_sets(data
.proplist
, "bluetooth.protocol", pa_bluetooth_profile_to_string(u
->profile
));
300 pa_sink_new_data_set_sample_spec(&data
, &u
->sample_spec
);
302 connect_ports(u
, &data
, PA_DIRECTION_OUTPUT
);
304 if (!u
->transport_acquired
)
305 switch (u
->profile
) {
306 case PA_BLUETOOTH_PROFILE_A2DP_SINK
:
307 /* Profile switch should have failed */
308 case PA_BLUETOOTH_PROFILE_A2DP_SOURCE
:
309 case PA_BLUETOOTH_PROFILE_OFF
:
310 pa_assert_not_reached();
314 u
->sink
= pa_sink_new(u
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
);
315 pa_sink_new_data_done(&data
);
317 pa_log_error("Failed to create sink");
321 u
->sink
->userdata
= u
;
326 /* Run from main thread */
327 static void transport_config(struct userdata
*u
) {
328 sbc_info_t
*sbc_info
= &u
->sbc_info
;
331 pa_assert(u
->transport
);
333 u
->sample_spec
.format
= PA_SAMPLE_S16LE
;
334 config
= (a2dp_sbc_t
*) u
->transport
->config
;
336 if (sbc_info
->sbc_initialized
)
337 sbc_reinit(&sbc_info
->sbc
, 0);
339 sbc_init(&sbc_info
->sbc
, 0);
340 sbc_info
->sbc_initialized
= true;
342 switch (config
->frequency
) {
343 case SBC_SAMPLING_FREQ_16000
:
344 sbc_info
->sbc
.frequency
= SBC_FREQ_16000
;
345 u
->sample_spec
.rate
= 16000U;
347 case SBC_SAMPLING_FREQ_32000
:
348 sbc_info
->sbc
.frequency
= SBC_FREQ_32000
;
349 u
->sample_spec
.rate
= 32000U;
351 case SBC_SAMPLING_FREQ_44100
:
352 sbc_info
->sbc
.frequency
= SBC_FREQ_44100
;
353 u
->sample_spec
.rate
= 44100U;
355 case SBC_SAMPLING_FREQ_48000
:
356 sbc_info
->sbc
.frequency
= SBC_FREQ_48000
;
357 u
->sample_spec
.rate
= 48000U;
360 pa_assert_not_reached();
363 switch (config
->channel_mode
) {
364 case SBC_CHANNEL_MODE_MONO
:
365 sbc_info
->sbc
.mode
= SBC_MODE_MONO
;
366 u
->sample_spec
.channels
= 1;
368 case SBC_CHANNEL_MODE_DUAL_CHANNEL
:
369 sbc_info
->sbc
.mode
= SBC_MODE_DUAL_CHANNEL
;
370 u
->sample_spec
.channels
= 2;
372 case SBC_CHANNEL_MODE_STEREO
:
373 sbc_info
->sbc
.mode
= SBC_MODE_STEREO
;
374 u
->sample_spec
.channels
= 2;
376 case SBC_CHANNEL_MODE_JOINT_STEREO
:
377 sbc_info
->sbc
.mode
= SBC_MODE_JOINT_STEREO
;
378 u
->sample_spec
.channels
= 2;
381 pa_assert_not_reached();
384 switch (config
->allocation_method
) {
385 case SBC_ALLOCATION_SNR
:
386 sbc_info
->sbc
.allocation
= SBC_AM_SNR
;
388 case SBC_ALLOCATION_LOUDNESS
:
389 sbc_info
->sbc
.allocation
= SBC_AM_LOUDNESS
;
392 pa_assert_not_reached();
395 switch (config
->subbands
) {
397 sbc_info
->sbc
.subbands
= SBC_SB_4
;
400 sbc_info
->sbc
.subbands
= SBC_SB_8
;
403 pa_assert_not_reached();
406 switch (config
->block_length
) {
407 case SBC_BLOCK_LENGTH_4
:
408 sbc_info
->sbc
.blocks
= SBC_BLK_4
;
410 case SBC_BLOCK_LENGTH_8
:
411 sbc_info
->sbc
.blocks
= SBC_BLK_8
;
413 case SBC_BLOCK_LENGTH_12
:
414 sbc_info
->sbc
.blocks
= SBC_BLK_12
;
416 case SBC_BLOCK_LENGTH_16
:
417 sbc_info
->sbc
.blocks
= SBC_BLK_16
;
420 pa_assert_not_reached();
423 sbc_info
->min_bitpool
= config
->min_bitpool
;
424 sbc_info
->max_bitpool
= config
->max_bitpool
;
426 /* Set minimum bitpool for source to get the maximum possible block_size */
427 sbc_info
->sbc
.bitpool
= u
->profile
== PA_BLUETOOTH_PROFILE_A2DP_SINK
? sbc_info
->max_bitpool
: sbc_info
->min_bitpool
;
428 sbc_info
->codesize
= sbc_get_codesize(&sbc_info
->sbc
);
429 sbc_info
->frame_length
= sbc_get_frame_length(&sbc_info
->sbc
);
431 pa_log_info("SBC parameters: allocation=%u, subbands=%u, blocks=%u, bitpool=%u",
432 sbc_info
->sbc
.allocation
, sbc_info
->sbc
.subbands
, sbc_info
->sbc
.blocks
, sbc_info
->sbc
.bitpool
);
435 /* Run from main thread */
436 static int setup_transport(struct userdata
*u
) {
437 pa_bluetooth_transport
*t
;
440 pa_assert(!u
->transport
);
441 pa_assert(u
->profile
!= PA_BLUETOOTH_PROFILE_OFF
);
443 /* check if profile has a transport */
444 t
= u
->device
->transports
[u
->profile
];
445 if (!t
|| t
->state
<= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED
) {
446 pa_log_warn("Profile has no transport");
452 if (u
->profile
== PA_BLUETOOTH_PROFILE_A2DP_SOURCE
)
453 transport_acquire(u
, true); /* In case of error, the sink/sources will be created suspended */
454 else if (transport_acquire(u
, false) < 0)
455 return -1; /* We need to fail here until the interactions with module-suspend-on-idle and alike get improved */
462 /* Run from main thread */
463 static int init_profile(struct userdata
*u
) {
466 pa_assert(u
->profile
!= PA_BLUETOOTH_PROFILE_OFF
);
468 if (setup_transport(u
) < 0)
471 pa_assert(u
->transport
);
473 if (u
->profile
== PA_BLUETOOTH_PROFILE_A2DP_SINK
)
477 if (u
->profile
== PA_BLUETOOTH_PROFILE_A2DP_SOURCE
)
478 if (add_source(u
) < 0)
484 /* I/O thread function */
485 static void thread_func(void *userdata
) {
488 /* Run from main thread */
489 static int start_thread(struct userdata
*u
) {
491 pa_assert(!u
->thread
);
492 pa_assert(!u
->rtpoll
);
493 pa_assert(!u
->rtpoll_item
);
495 u
->rtpoll
= pa_rtpoll_new();
496 pa_thread_mq_init(&u
->thread_mq
, u
->core
->mainloop
, u
->rtpoll
);
498 if (!(u
->thread
= pa_thread_new("bluetooth", thread_func
, u
))) {
499 pa_log_error("Failed to create IO thread");
504 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
505 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
506 pa_sink_put(u
->sink
);
508 if (u
->sink
->set_volume
)
509 u
->sink
->set_volume(u
->sink
);
513 pa_source_set_asyncmsgq(u
->source
, u
->thread_mq
.inq
);
514 pa_source_set_rtpoll(u
->source
, u
->rtpoll
);
515 pa_source_put(u
->source
);
517 if (u
->source
->set_volume
)
518 u
->source
->set_volume(u
->source
);
524 /* Run from main thread */
525 static void stop_thread(struct userdata
*u
) {
529 pa_sink_unlink(u
->sink
);
532 pa_source_unlink(u
->source
);
535 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
536 pa_thread_free(u
->thread
);
540 if (u
->rtpoll_item
) {
541 pa_rtpoll_item_free(u
->rtpoll_item
);
542 u
->rtpoll_item
= NULL
;
546 pa_thread_mq_done(&u
->thread_mq
);
547 pa_rtpoll_free(u
->rtpoll
);
552 transport_release(u
);
557 pa_sink_unref(u
->sink
);
562 pa_source_unref(u
->source
);
567 /* Run from main thread */
568 static char *cleanup_name(const char *name
) {
574 while ((*name
>= 1 && *name
<= 32) || *name
>= 127)
577 t
= pa_xstrdup(name
);
579 for (s
= d
= t
; *s
; s
++) {
581 if (*s
<= 32 || *s
>= 127 || *s
== '_') {
599 /* Run from main thread */
600 static pa_direction_t
get_profile_direction(pa_bluetooth_profile_t p
) {
601 static const pa_direction_t profile_direction
[] = {
602 [PA_BLUETOOTH_PROFILE_A2DP_SINK
] = PA_DIRECTION_OUTPUT
,
603 [PA_BLUETOOTH_PROFILE_A2DP_SOURCE
] = PA_DIRECTION_INPUT
,
604 [PA_BLUETOOTH_PROFILE_OFF
] = 0
607 return profile_direction
[p
];
610 /* Run from main thread */
611 static pa_available_t
get_port_availability(struct userdata
*u
, pa_direction_t direction
) {
612 pa_available_t result
= PA_AVAILABLE_NO
;
616 pa_assert(u
->device
);
618 for (i
= 0; i
< PA_BLUETOOTH_PROFILE_COUNT
; i
++) {
619 pa_bluetooth_transport
*transport
;
621 if (!(get_profile_direction(i
) & direction
))
624 if (!(transport
= u
->device
->transports
[i
]))
627 switch(transport
->state
) {
628 case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED
:
631 case PA_BLUETOOTH_TRANSPORT_STATE_IDLE
:
632 if (result
== PA_AVAILABLE_NO
)
633 result
= PA_AVAILABLE_UNKNOWN
;
637 case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
:
638 return PA_AVAILABLE_YES
;
645 /* Run from main thread */
646 static pa_available_t
transport_state_to_availability(pa_bluetooth_transport_state_t state
) {
648 case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED
:
649 return PA_AVAILABLE_NO
;
650 case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING
:
651 return PA_AVAILABLE_YES
;
653 return PA_AVAILABLE_UNKNOWN
;
657 /* Run from main thread */
658 static void create_card_ports(struct userdata
*u
, pa_hashmap
*ports
) {
659 pa_device_port
*port
;
660 pa_device_port_new_data port_data
;
661 const char *name_prefix
, *input_description
, *output_description
;
665 pa_assert(u
->device
);
667 name_prefix
= "unknown";
668 input_description
= _("Bluetooth Input");
669 output_description
= _("Bluetooth Output");
671 switch (form_factor_from_class(u
->device
->class_of_device
)) {
672 case PA_BLUETOOTH_FORM_FACTOR_HEADSET
:
673 name_prefix
= "headset";
674 input_description
= output_description
= _("Headset");
677 case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE
:
678 name_prefix
= "handsfree";
679 input_description
= output_description
= _("Handsfree");
682 case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE
:
683 name_prefix
= "microphone";
684 input_description
= _("Microphone");
685 output_description
= _("Bluetooth Output");
688 case PA_BLUETOOTH_FORM_FACTOR_SPEAKER
:
689 name_prefix
= "speaker";
690 input_description
= _("Bluetooth Input");
691 output_description
= _("Speaker");
694 case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE
:
695 name_prefix
= "headphone";
696 input_description
= _("Bluetooth Input");
697 output_description
= _("Headphone");
700 case PA_BLUETOOTH_FORM_FACTOR_PORTABLE
:
701 name_prefix
= "portable";
702 input_description
= output_description
= _("Portable");
705 case PA_BLUETOOTH_FORM_FACTOR_CAR
:
707 input_description
= output_description
= _("Car");
710 case PA_BLUETOOTH_FORM_FACTOR_HIFI
:
711 name_prefix
= "hifi";
712 input_description
= output_description
= _("HiFi");
715 case PA_BLUETOOTH_FORM_FACTOR_PHONE
:
716 name_prefix
= "phone";
717 input_description
= output_description
= _("Phone");
720 case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
:
721 name_prefix
= "unknown";
722 input_description
= _("Bluetooth Input");
723 output_description
= _("Bluetooth Output");
727 u
->output_port_name
= pa_sprintf_malloc("%s-output", name_prefix
);
728 pa_device_port_new_data_init(&port_data
);
729 pa_device_port_new_data_set_name(&port_data
, u
->output_port_name
);
730 pa_device_port_new_data_set_description(&port_data
, output_description
);
731 pa_device_port_new_data_set_direction(&port_data
, PA_DIRECTION_OUTPUT
);
732 pa_device_port_new_data_set_available(&port_data
, get_port_availability(u
, PA_DIRECTION_OUTPUT
));
733 pa_assert_se(port
= pa_device_port_new(u
->core
, &port_data
, 0));
734 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
735 pa_device_port_new_data_done(&port_data
);
737 u
->input_port_name
= pa_sprintf_malloc("%s-input", name_prefix
);
738 pa_device_port_new_data_init(&port_data
);
739 pa_device_port_new_data_set_name(&port_data
, u
->input_port_name
);
740 pa_device_port_new_data_set_description(&port_data
, input_description
);
741 pa_device_port_new_data_set_direction(&port_data
, PA_DIRECTION_INPUT
);
742 pa_device_port_new_data_set_available(&port_data
, get_port_availability(u
, PA_DIRECTION_INPUT
));
743 pa_assert_se(port
= pa_device_port_new(u
->core
, &port_data
, 0));
744 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
745 pa_device_port_new_data_done(&port_data
);
748 /* Run from main thread */
749 static pa_card_profile
*create_card_profile(struct userdata
*u
, const char *uuid
, pa_hashmap
*ports
) {
750 pa_device_port
*input_port
, *output_port
;
751 pa_card_profile
*cp
= NULL
;
752 pa_bluetooth_profile_t
*p
;
754 pa_assert(u
->input_port_name
);
755 pa_assert(u
->output_port_name
);
756 pa_assert_se(input_port
= pa_hashmap_get(ports
, u
->input_port_name
));
757 pa_assert_se(output_port
= pa_hashmap_get(ports
, u
->output_port_name
));
759 if (pa_streq(uuid
, PA_BLUETOOTH_UUID_A2DP_SINK
)) {
760 /* TODO: Change this profile's name to a2dp_sink, to reflect the remote
761 * device's role and be consistent with the a2dp source profile */
762 cp
= pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP Sink)"), sizeof(pa_bluetooth_profile_t
));
766 cp
->max_sink_channels
= 2;
767 cp
->max_source_channels
= 0;
768 pa_hashmap_put(output_port
->profiles
, cp
->name
, cp
);
770 p
= PA_CARD_PROFILE_DATA(cp
);
771 *p
= PA_BLUETOOTH_PROFILE_A2DP_SINK
;
772 } else if (pa_streq(uuid
, PA_BLUETOOTH_UUID_A2DP_SOURCE
)) {
773 cp
= pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP Source)"), sizeof(pa_bluetooth_profile_t
));
777 cp
->max_sink_channels
= 0;
778 cp
->max_source_channels
= 2;
779 pa_hashmap_put(input_port
->profiles
, cp
->name
, cp
);
781 p
= PA_CARD_PROFILE_DATA(cp
);
782 *p
= PA_BLUETOOTH_PROFILE_A2DP_SOURCE
;
785 if (cp
&& u
->device
->transports
[*p
])
786 cp
->available
= transport_state_to_availability(u
->device
->transports
[*p
]->state
);
791 /* Run from main thread */
792 static int add_card(struct userdata
*u
) {
793 const pa_bluetooth_device
*d
;
794 pa_card_new_data data
;
796 pa_bluetooth_form_factor_t ff
;
798 pa_bluetooth_profile_t
*p
;
803 pa_assert(u
->device
);
807 pa_card_new_data_init(&data
);
808 data
.driver
= __FILE__
;
809 data
.module
= u
->module
;
811 alias
= cleanup_name(d
->alias
);
812 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, alias
);
815 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, d
->address
);
816 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_API
, "bluez");
817 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_CLASS
, "sound");
818 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_BUS
, "bluetooth");
820 if ((ff
= form_factor_from_class(d
->class_of_device
)) != PA_BLUETOOTH_FORM_FACTOR_UNKNOWN
)
821 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_FORM_FACTOR
, form_factor_to_string(ff
));
823 pa_proplist_sets(data
.proplist
, "bluez.path", d
->path
);
824 pa_proplist_setf(data
.proplist
, "bluez.class", "0x%06x", d
->class_of_device
);
825 pa_proplist_sets(data
.proplist
, "bluez.alias", d
->alias
);
826 data
.name
= pa_sprintf_malloc("bluez_card.%s", d
->address
);
827 data
.namereg_fail
= false;
829 create_card_ports(u
, data
.ports
);
831 PA_HASHMAP_FOREACH(uuid
, d
->uuids
, state
) {
832 cp
= create_card_profile(u
, uuid
, data
.ports
);
837 if (pa_hashmap_get(data
.profiles
, cp
->name
)) {
838 pa_card_profile_free(cp
);
842 pa_hashmap_put(data
.profiles
, cp
->name
, cp
);
845 pa_assert(!pa_hashmap_isempty(data
.profiles
));
847 cp
= pa_card_profile_new("off", _("Off"), sizeof(pa_bluetooth_profile_t
));
848 cp
->available
= PA_AVAILABLE_YES
;
849 p
= PA_CARD_PROFILE_DATA(cp
);
850 *p
= PA_BLUETOOTH_PROFILE_OFF
;
851 pa_hashmap_put(data
.profiles
, cp
->name
, cp
);
853 u
->card
= pa_card_new(u
->core
, &data
);
854 pa_card_new_data_done(&data
);
856 pa_log("Failed to allocate card.");
860 u
->card
->userdata
= u
;
862 p
= PA_CARD_PROFILE_DATA(u
->card
->active_profile
);
868 /* Run from main thread */
869 static pa_hook_result_t
device_connection_changed_cb(pa_bluetooth_discovery
*y
, const pa_bluetooth_device
*d
, struct userdata
*u
) {
873 if (d
!= u
->device
|| pa_bluetooth_device_any_transport_connected(d
))
876 pa_log_debug("Unloading module for device %s", d
->path
);
877 pa_module_unload(u
->core
, u
->module
, true);
882 int pa__init(pa_module
* m
) {
889 m
->userdata
= u
= pa_xnew0(struct userdata
, 1);
893 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
894 pa_log_error("Failed to parse module arguments");
898 if (!(path
= pa_modargs_get_value(ma
, "path", NULL
))) {
899 pa_log_error("Failed to get device path from module arguments");
903 if (!(u
->discovery
= pa_bluetooth_discovery_get(m
->core
)))
906 if (!(u
->device
= pa_bluetooth_discovery_get_device_by_path(u
->discovery
, path
))) {
907 pa_log_error("%s is unknown", path
);
913 u
->device_connection_changed_slot
=
914 pa_hook_connect(pa_bluetooth_discovery_hook(u
->discovery
, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED
),
915 PA_HOOK_NORMAL
, (pa_hook_cb_t
) device_connection_changed_cb
, u
);
920 if (u
->profile
!= PA_BLUETOOTH_PROFILE_OFF
)
921 if (init_profile(u
) < 0)
924 if (u
->sink
|| u
->source
)
925 if (start_thread(u
) < 0)
933 pa_assert_se(pa_card_set_profile(u
->card
, "off", false) >= 0);
947 void pa__done(pa_module
*m
) {
952 if (!(u
= m
->userdata
))
957 if (u
->device_connection_changed_slot
)
958 pa_hook_slot_free(u
->device_connection_changed_slot
);
960 if (u
->sbc_info
.sbc_initialized
)
961 sbc_finish(&u
->sbc_info
.sbc
);
964 pa_card_free(u
->card
);
967 pa_bluetooth_discovery_unref(u
->discovery
);
969 pa_xfree(u
->output_port_name
);
970 pa_xfree(u
->input_port_name
);