2 This file is part of PulseAudio.
4 Copyright 2008-2009 Joao Paulo Rechi Vita
5 Copyright 2011-2012 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 <linux/sockios.h>
30 #include <arpa/inet.h>
32 #include <pulse/rtclock.h>
33 #include <pulse/sample.h>
34 #include <pulse/timeval.h>
35 #include <pulse/xmalloc.h>
37 #include <pulsecore/i18n.h>
38 #include <pulsecore/module.h>
39 #include <pulsecore/modargs.h>
40 #include <pulsecore/core-rtclock.h>
41 #include <pulsecore/core-util.h>
42 #include <pulsecore/core-error.h>
43 #include <pulsecore/shared.h>
44 #include <pulsecore/socket-util.h>
45 #include <pulsecore/thread.h>
46 #include <pulsecore/thread-mq.h>
47 #include <pulsecore/poll.h>
48 #include <pulsecore/rtpoll.h>
49 #include <pulsecore/time-smoother.h>
50 #include <pulsecore/namereg.h>
51 #include <pulsecore/dbus-shared.h>
55 #include "module-bluetooth-device-symdef.h"
56 #include "a2dp-codecs.h"
58 #include "bluetooth-util.h"
60 #define BITPOOL_DEC_LIMIT 32
61 #define BITPOOL_DEC_STEP 5
62 #define HSP_MAX_GAIN 15
64 PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
65 PA_MODULE_DESCRIPTION("Bluetooth audio sink and source");
66 PA_MODULE_VERSION(PACKAGE_VERSION
);
67 PA_MODULE_LOAD_ONCE(FALSE
);
69 "name=<name for the card/sink/source, to be prefixed> "
70 "card_name=<name for the card> "
71 "card_properties=<properties for the card> "
72 "sink_name=<name for the sink> "
73 "sink_properties=<properties for the sink> "
74 "source_name=<name for the source> "
75 "source_properties=<properties for the source> "
76 "address=<address of the device> "
77 "profile=<a2dp|hsp|hfgw> "
79 "channels=<number of channels> "
80 "path=<device object path> "
81 "auto_connect=<automatically connect?> "
82 "sco_sink=<SCO over PCM sink name> "
83 "sco_source=<SCO over PCM source name>");
85 /* TODO: not close fd when entering suspend mode in a2dp */
87 static const char* const valid_modargs
[] = {
107 sbc_t sbc
; /* Codec data */
108 pa_bool_t sbc_initialized
; /* Keep track if the encoder is initialized */
109 size_t codesize
, frame_length
; /* SBC Codesize, frame_length. We simply cache those values here */
111 void* buffer
; /* Codec transfer buffer */
112 size_t buffer_size
; /* Size of the buffer */
114 uint16_t seq_num
; /* Cumulative packet sequence */
121 void (*sco_sink_set_volume
)(pa_sink
*s
);
122 pa_source
*sco_source
;
123 void (*sco_source_set_volume
)(pa_source
*s
);
124 pa_hook_slot
*sink_state_changed_slot
;
125 pa_hook_slot
*source_state_changed_slot
;
126 pa_hook_slot
*nrec_changed_slot
;
129 struct bluetooth_msg
{
134 typedef struct bluetooth_msg bluetooth_msg
;
135 PA_DEFINE_PRIVATE_CLASS(bluetooth_msg
, pa_msgobject
);
136 #define BLUETOOTH_MSG(o) (bluetooth_msg_cast(o))
142 pa_bluetooth_device
*device
;
145 pa_bluetooth_transport
*transport
;
147 pa_hook_slot
*transport_removed_slot
;
148 pa_hook_slot
*device_removed_slot
;
150 pa_bluetooth_discovery
*discovery
;
151 pa_bool_t auto_connect
;
153 pa_dbus_connection
*connection
;
159 pa_thread_mq thread_mq
;
161 pa_rtpoll_item
*rtpoll_item
;
165 uint64_t read_index
, write_index
;
166 pa_usec_t started_at
;
167 pa_smoother
*read_smoother
;
169 pa_memchunk write_memchunk
;
171 pa_sample_spec sample_spec
, requested_sample_spec
;
175 size_t read_link_mtu
;
176 size_t read_block_size
;
178 size_t write_link_mtu
;
179 size_t write_block_size
;
181 struct a2dp_info a2dp
;
184 enum profile profile
;
188 int stream_write_type
;
190 pa_bool_t filter_added
;
194 BLUETOOTH_MESSAGE_IO_THREAD_FAILED
,
195 BLUETOOTH_MESSAGE_MAX
198 #define FIXED_LATENCY_PLAYBACK_A2DP (25*PA_USEC_PER_MSEC)
199 #define FIXED_LATENCY_RECORD_A2DP (25*PA_USEC_PER_MSEC)
200 #define FIXED_LATENCY_PLAYBACK_HSP (125*PA_USEC_PER_MSEC)
201 #define FIXED_LATENCY_RECORD_HSP (25*PA_USEC_PER_MSEC)
203 #define MAX_PLAYBACK_CATCH_UP_USEC (100*PA_USEC_PER_MSEC)
205 #define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
207 static int init_profile(struct userdata
*u
);
210 static void a2dp_set_bitpool(struct userdata
*u
, uint8_t bitpool
)
212 struct a2dp_info
*a2dp
;
218 if (a2dp
->sbc
.bitpool
== bitpool
)
221 if (bitpool
> a2dp
->max_bitpool
)
222 bitpool
= a2dp
->max_bitpool
;
223 else if (bitpool
< a2dp
->min_bitpool
)
224 bitpool
= a2dp
->min_bitpool
;
226 a2dp
->sbc
.bitpool
= bitpool
;
228 a2dp
->codesize
= sbc_get_codesize(&a2dp
->sbc
);
229 a2dp
->frame_length
= sbc_get_frame_length(&a2dp
->sbc
);
231 pa_log_debug("Bitpool has changed to %u", a2dp
->sbc
.bitpool
);
234 (u
->read_link_mtu
- sizeof(struct rtp_header
) - sizeof(struct rtp_payload
))
235 / a2dp
->frame_length
* a2dp
->codesize
;
237 u
->write_block_size
=
238 (u
->write_link_mtu
- sizeof(struct rtp_header
) - sizeof(struct rtp_payload
))
239 / a2dp
->frame_length
* a2dp
->codesize
;
241 pa_sink_set_max_request_within_thread(u
->sink
, u
->write_block_size
);
242 pa_sink_set_fixed_latency_within_thread(u
->sink
,
243 FIXED_LATENCY_PLAYBACK_A2DP
+ pa_bytes_to_usec(u
->write_block_size
, &u
->sample_spec
));
246 /* from IO thread, except in SCO over PCM */
247 static void bt_transport_config_mtu(struct userdata
*u
) {
248 /* Calculate block sizes */
249 if (u
->profile
== PROFILE_HSP
|| u
->profile
== PROFILE_HFGW
) {
250 u
->read_block_size
= u
->read_link_mtu
;
251 u
->write_block_size
= u
->write_link_mtu
;
254 (u
->read_link_mtu
- sizeof(struct rtp_header
) - sizeof(struct rtp_payload
))
255 / u
->a2dp
.frame_length
* u
->a2dp
.codesize
;
257 u
->write_block_size
=
258 (u
->write_link_mtu
- sizeof(struct rtp_header
) - sizeof(struct rtp_payload
))
259 / u
->a2dp
.frame_length
* u
->a2dp
.codesize
;
262 if (USE_SCO_OVER_PCM(u
))
266 pa_sink_set_max_request_within_thread(u
->sink
, u
->write_block_size
);
267 pa_sink_set_fixed_latency_within_thread(u
->sink
,
268 (u
->profile
== PROFILE_A2DP
?
269 FIXED_LATENCY_PLAYBACK_A2DP
: FIXED_LATENCY_PLAYBACK_HSP
) +
270 pa_bytes_to_usec(u
->write_block_size
, &u
->sample_spec
));
274 pa_source_set_fixed_latency_within_thread(u
->source
,
275 (u
->profile
== PROFILE_A2DP_SOURCE
?
276 FIXED_LATENCY_RECORD_A2DP
: FIXED_LATENCY_RECORD_HSP
) +
277 pa_bytes_to_usec(u
->read_block_size
, &u
->sample_spec
));
280 /* from IO thread, except in SCO over PCM */
282 static void setup_stream(struct userdata
*u
) {
283 struct pollfd
*pollfd
;
286 bt_transport_config_mtu(u
);
288 pa_make_fd_nonblock(u
->stream_fd
);
289 pa_make_socket_low_delay(u
->stream_fd
);
292 if (setsockopt(u
->stream_fd
, SOL_SOCKET
, SO_TIMESTAMP
, &one
, sizeof(one
)) < 0)
293 pa_log_warn("Failed to enable SO_TIMESTAMP: %s", pa_cstrerror(errno
));
295 pa_log_debug("Stream properly set up, we're ready to roll!");
297 if (u
->profile
== PROFILE_A2DP
)
298 a2dp_set_bitpool(u
, u
->a2dp
.max_bitpool
);
300 u
->rtpoll_item
= pa_rtpoll_item_new(u
->rtpoll
, PA_RTPOLL_NEVER
, 1);
301 pollfd
= pa_rtpoll_item_get_pollfd(u
->rtpoll_item
, NULL
);
302 pollfd
->fd
= u
->stream_fd
;
303 pollfd
->events
= pollfd
->revents
= 0;
305 u
->read_index
= u
->write_index
= 0;
309 u
->read_smoother
= pa_smoother_new(
319 static bool bt_transport_is_acquired(struct userdata
*u
) {
320 if (u
->accesstype
== NULL
) {
321 pa_assert(u
->stream_fd
< 0);
324 /* During IO thread HUP stream_fd can be -1 */
329 static void teardown_stream(struct userdata
*u
) {
330 if (u
->rtpoll_item
) {
331 pa_rtpoll_item_free(u
->rtpoll_item
);
332 u
->rtpoll_item
= NULL
;
335 if (u
->stream_fd
>= 0) {
336 pa_close(u
->stream_fd
);
340 if (u
->read_smoother
) {
341 pa_smoother_free(u
->read_smoother
);
342 u
->read_smoother
= NULL
;
345 pa_log_debug("Audio stream torn down");
348 static void bt_transport_release(struct userdata
*u
) {
349 pa_assert(u
->transport
);
351 /* Ignore if already released */
352 if (!bt_transport_is_acquired(u
))
355 pa_log_debug("Releasing transport %s", u
->transport
->path
);
357 pa_bluetooth_transport_release(u
->transport
, u
->accesstype
);
359 pa_xfree(u
->accesstype
);
360 u
->accesstype
= NULL
;
365 static pa_bt_audio_state_t
get_profile_audio_state(const struct userdata
*u
, const pa_bluetooth_device
*d
) {
368 return d
->headset_state
;
370 return d
->audio_sink_state
;
371 case PROFILE_A2DP_SOURCE
:
372 return d
->audio_source_state
;
374 return d
->hfgw_state
;
379 pa_assert_not_reached();
382 static int bt_transport_acquire(struct userdata
*u
, pa_bool_t start
) {
383 const char *accesstype
= "rw";
385 pa_assert(u
->transport
);
387 if (bt_transport_is_acquired(u
)) {
393 pa_log_debug("Acquiring transport %s", u
->transport
->path
);
396 /* FIXME: we are trying to acquire the transport only if the stream is
397 playing, without actually initiating the stream request from our side
398 (which is typically undesireable specially for hfgw use-cases.
399 However this approach is racy, since the stream could have been
400 suspended in the meantime, so we can't really guarantee that the
401 stream will not be requested until BlueZ's API supports this
403 if (get_profile_audio_state(u
, u
->device
) < PA_BT_AUDIO_STATE_PLAYING
) {
404 pa_log_info("Failed optional acquire of transport %s", u
->transport
->path
);
409 u
->stream_fd
= pa_bluetooth_transport_acquire(u
->transport
, accesstype
, &u
->read_link_mtu
, &u
->write_link_mtu
);
410 if (u
->stream_fd
< 0) {
412 pa_log("Failed to acquire transport %s", u
->transport
->path
);
414 pa_log_info("Failed optional acquire of transport %s", u
->transport
->path
);
419 u
->accesstype
= pa_xstrdup(accesstype
);
420 pa_log_info("Transport %s acquired: fd %d", u
->transport
->path
, u
->stream_fd
);
426 pa_log_info("Transport %s resuming", u
->transport
->path
);
432 /* Run from IO thread */
433 static int sink_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
434 struct userdata
*u
= PA_SINK(o
)->userdata
;
435 pa_bool_t failed
= FALSE
;
438 pa_assert(u
->sink
== PA_SINK(o
));
439 pa_assert(u
->transport
);
443 case PA_SINK_MESSAGE_SET_STATE
:
445 switch ((pa_sink_state_t
) PA_PTR_TO_UINT(data
)) {
447 case PA_SINK_SUSPENDED
:
448 /* Ignore if transition is PA_SINK_INIT->PA_SINK_SUSPENDED */
449 if (!PA_SINK_IS_OPENED(u
->sink
->thread_info
.state
))
452 /* Stop the device if the source is suspended as well */
453 if (!u
->source
|| u
->source
->state
== PA_SOURCE_SUSPENDED
)
454 /* We deliberately ignore whether stopping
455 * actually worked. Since the stream_fd is
456 * closed it doesn't really matter */
457 bt_transport_release(u
);
462 case PA_SINK_RUNNING
:
463 if (u
->sink
->thread_info
.state
!= PA_SINK_SUSPENDED
)
466 /* Resume the device if the source was suspended as well */
467 if (!u
->source
|| u
->source
->state
== PA_SOURCE_SUSPENDED
) {
468 if (bt_transport_acquire(u
, TRUE
) < 0)
473 case PA_SINK_UNLINKED
:
475 case PA_SINK_INVALID_STATE
:
480 case PA_SINK_MESSAGE_GET_LATENCY
: {
482 if (u
->read_smoother
) {
485 ri
= pa_smoother_get(u
->read_smoother
, pa_rtclock_now());
486 wi
= pa_bytes_to_usec(u
->write_index
+ u
->write_block_size
, &u
->sample_spec
);
488 *((pa_usec_t
*) data
) = wi
> ri
? wi
- ri
: 0;
492 ri
= pa_rtclock_now() - u
->started_at
;
493 wi
= pa_bytes_to_usec(u
->write_index
, &u
->sample_spec
);
495 *((pa_usec_t
*) data
) = wi
> ri
? wi
- ri
: 0;
498 *((pa_usec_t
*) data
) += u
->sink
->thread_info
.fixed_latency
;
503 r
= pa_sink_process_msg(o
, code
, data
, offset
, chunk
);
505 return (r
< 0 || !failed
) ? r
: -1;
508 /* Run from IO thread */
509 static int source_process_msg(pa_msgobject
*o
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
510 struct userdata
*u
= PA_SOURCE(o
)->userdata
;
511 pa_bool_t failed
= FALSE
;
514 pa_assert(u
->source
== PA_SOURCE(o
));
515 pa_assert(u
->transport
);
519 case PA_SOURCE_MESSAGE_SET_STATE
:
521 switch ((pa_source_state_t
) PA_PTR_TO_UINT(data
)) {
523 case PA_SOURCE_SUSPENDED
:
524 /* Ignore if transition is PA_SOURCE_INIT->PA_SOURCE_SUSPENDED */
525 if (!PA_SOURCE_IS_OPENED(u
->source
->thread_info
.state
))
528 /* Stop the device if the sink is suspended as well */
529 if (!u
->sink
|| u
->sink
->state
== PA_SINK_SUSPENDED
)
530 bt_transport_release(u
);
532 if (u
->read_smoother
)
533 pa_smoother_pause(u
->read_smoother
, pa_rtclock_now());
537 case PA_SOURCE_RUNNING
:
538 if (u
->source
->thread_info
.state
!= PA_SOURCE_SUSPENDED
)
541 /* Resume the device if the sink was suspended as well */
542 if (!u
->sink
|| u
->sink
->thread_info
.state
== PA_SINK_SUSPENDED
) {
543 if (bt_transport_acquire(u
, TRUE
) < 0)
546 /* We don't resume the smoother here. Instead we
547 * wait until the first packet arrives */
550 case PA_SOURCE_UNLINKED
:
552 case PA_SOURCE_INVALID_STATE
:
557 case PA_SOURCE_MESSAGE_GET_LATENCY
: {
560 if (u
->read_smoother
) {
561 wi
= pa_smoother_get(u
->read_smoother
, pa_rtclock_now());
562 ri
= pa_bytes_to_usec(u
->read_index
, &u
->sample_spec
);
564 *((pa_usec_t
*) data
) = (wi
> ri
? wi
- ri
: 0) + u
->source
->thread_info
.fixed_latency
;
566 *((pa_usec_t
*) data
) = 0;
573 r
= pa_source_process_msg(o
, code
, data
, offset
, chunk
);
575 return (r
< 0 || !failed
) ? r
: -1;
578 /* Called from main thread context */
579 static int device_process_msg(pa_msgobject
*obj
, int code
, void *data
, int64_t offset
, pa_memchunk
*chunk
) {
580 struct bluetooth_msg
*u
= BLUETOOTH_MSG(obj
);
583 case BLUETOOTH_MESSAGE_IO_THREAD_FAILED
: {
584 if (u
->card
->module
->unload_requested
)
587 pa_log_debug("Switching the profile to off due to IO thread failure.");
589 pa_assert_se(pa_card_set_profile(u
->card
, "off", false) >= 0);
596 /* Run from IO thread */
597 static int hsp_process_render(struct userdata
*u
) {
601 pa_assert(u
->profile
== PROFILE_HSP
|| u
->profile
== PROFILE_HFGW
);
604 /* First, render some data */
605 if (!u
->write_memchunk
.memblock
)
606 pa_sink_render_full(u
->sink
, u
->write_block_size
, &u
->write_memchunk
);
608 pa_assert(u
->write_memchunk
.length
== u
->write_block_size
);
614 /* Now write that data to the socket. The socket is of type
615 * SEQPACKET, and we generated the data of the MTU size, so this
616 * should just work. */
618 p
= (const uint8_t *) pa_memblock_acquire_chunk(&u
->write_memchunk
);
619 l
= pa_write(u
->stream_fd
, p
, u
->write_memchunk
.length
, &u
->stream_write_type
);
620 pa_memblock_release(u
->write_memchunk
.memblock
);
627 /* Retry right away if we got interrupted */
630 else if (errno
== EAGAIN
)
631 /* Hmm, apparently the socket was not writable, give up for now */
634 pa_log_error("Failed to write data to SCO socket: %s", pa_cstrerror(errno
));
639 pa_assert((size_t) l
<= u
->write_memchunk
.length
);
641 if ((size_t) l
!= u
->write_memchunk
.length
) {
642 pa_log_error("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
643 (unsigned long long) l
,
644 (unsigned long long) u
->write_memchunk
.length
);
649 u
->write_index
+= (uint64_t) u
->write_memchunk
.length
;
650 pa_memblock_unref(u
->write_memchunk
.memblock
);
651 pa_memchunk_reset(&u
->write_memchunk
);
660 /* Run from IO thread */
661 static int hsp_process_push(struct userdata
*u
) {
663 pa_memchunk memchunk
;
666 pa_assert(u
->profile
== PROFILE_HSP
|| u
->profile
== PROFILE_HFGW
);
667 pa_assert(u
->source
);
668 pa_assert(u
->read_smoother
);
670 memchunk
.memblock
= pa_memblock_new(u
->core
->mempool
, u
->read_block_size
);
671 memchunk
.index
= memchunk
.length
= 0;
680 pa_bool_t found_tstamp
= FALSE
;
683 memset(&m
, 0, sizeof(m
));
684 memset(&aux
, 0, sizeof(aux
));
685 memset(&iov
, 0, sizeof(iov
));
690 m
.msg_controllen
= sizeof(aux
);
692 p
= pa_memblock_acquire(memchunk
.memblock
);
694 iov
.iov_len
= pa_memblock_get_length(memchunk
.memblock
);
695 l
= recvmsg(u
->stream_fd
, &m
, 0);
696 pa_memblock_release(memchunk
.memblock
);
700 if (l
< 0 && errno
== EINTR
)
701 /* Retry right away if we got interrupted */
704 else if (l
< 0 && errno
== EAGAIN
)
705 /* Hmm, apparently the socket was not readable, give up for now. */
708 pa_log_error("Failed to read data from SCO socket: %s", l
< 0 ? pa_cstrerror(errno
) : "EOF");
713 pa_assert((size_t) l
<= pa_memblock_get_length(memchunk
.memblock
));
715 memchunk
.length
= (size_t) l
;
716 u
->read_index
+= (uint64_t) l
;
718 for (cm
= CMSG_FIRSTHDR(&m
); cm
; cm
= CMSG_NXTHDR(&m
, cm
))
719 if (cm
->cmsg_level
== SOL_SOCKET
&& cm
->cmsg_type
== SO_TIMESTAMP
) {
720 struct timeval
*tv
= (struct timeval
*) CMSG_DATA(cm
);
721 pa_rtclock_from_wallclock(tv
);
722 tstamp
= pa_timeval_load(tv
);
728 pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
729 tstamp
= pa_rtclock_now();
732 pa_smoother_put(u
->read_smoother
, tstamp
, pa_bytes_to_usec(u
->read_index
, &u
->sample_spec
));
733 pa_smoother_resume(u
->read_smoother
, tstamp
, TRUE
);
735 pa_source_post(u
->source
, &memchunk
);
741 pa_memblock_unref(memchunk
.memblock
);
746 /* Run from IO thread */
747 static void a2dp_prepare_buffer(struct userdata
*u
) {
748 size_t min_buffer_size
= PA_MAX(u
->read_link_mtu
, u
->write_link_mtu
);
752 if (u
->a2dp
.buffer_size
>= min_buffer_size
)
755 u
->a2dp
.buffer_size
= 2 * min_buffer_size
;
756 pa_xfree(u
->a2dp
.buffer
);
757 u
->a2dp
.buffer
= pa_xmalloc(u
->a2dp
.buffer_size
);
760 /* Run from IO thread */
761 static int a2dp_process_render(struct userdata
*u
) {
762 struct a2dp_info
*a2dp
;
763 struct rtp_header
*header
;
764 struct rtp_payload
*payload
;
768 size_t to_write
, to_encode
;
769 unsigned frame_count
;
773 pa_assert(u
->profile
== PROFILE_A2DP
);
776 /* First, render some data */
777 if (!u
->write_memchunk
.memblock
)
778 pa_sink_render_full(u
->sink
, u
->write_block_size
, &u
->write_memchunk
);
780 pa_assert(u
->write_memchunk
.length
== u
->write_block_size
);
782 a2dp_prepare_buffer(u
);
785 header
= a2dp
->buffer
;
786 payload
= (struct rtp_payload
*) ((uint8_t*) a2dp
->buffer
+ sizeof(*header
));
790 /* Try to create a packet of the full MTU */
792 p
= (const uint8_t *) pa_memblock_acquire_chunk(&u
->write_memchunk
);
793 to_encode
= u
->write_memchunk
.length
;
795 d
= (uint8_t*) a2dp
->buffer
+ sizeof(*header
) + sizeof(*payload
);
796 to_write
= a2dp
->buffer_size
- sizeof(*header
) - sizeof(*payload
);
798 while (PA_LIKELY(to_encode
> 0 && to_write
> 0)) {
802 encoded
= sbc_encode(&a2dp
->sbc
,
807 if (PA_UNLIKELY(encoded
<= 0)) {
808 pa_log_error("SBC encoding error (%li)", (long) encoded
);
809 pa_memblock_release(u
->write_memchunk
.memblock
);
813 /* pa_log_debug("SBC: encoded: %lu; written: %lu", (unsigned long) encoded, (unsigned long) written); */
814 /* pa_log_debug("SBC: codesize: %lu; frame_length: %lu", (unsigned long) a2dp->codesize, (unsigned long) a2dp->frame_length); */
816 pa_assert_fp((size_t) encoded
<= to_encode
);
817 pa_assert_fp((size_t) encoded
== a2dp
->codesize
);
819 pa_assert_fp((size_t) written
<= to_write
);
820 pa_assert_fp((size_t) written
== a2dp
->frame_length
);
822 p
= (const uint8_t*) p
+ encoded
;
823 to_encode
-= encoded
;
825 d
= (uint8_t*) d
+ written
;
831 pa_memblock_release(u
->write_memchunk
.memblock
);
833 pa_assert(to_encode
== 0);
836 pa_log_debug("Using SBC encoder implementation: %s", pa_strnull(sbc_get_implementation_info(&a2dp
->sbc
)));
839 /* write it to the fifo */
840 memset(a2dp
->buffer
, 0, sizeof(*header
) + sizeof(*payload
));
843 header
->sequence_number
= htons(a2dp
->seq_num
++);
844 header
->timestamp
= htonl(u
->write_index
/ pa_frame_size(&u
->sample_spec
));
845 header
->ssrc
= htonl(1);
846 payload
->frame_count
= frame_count
;
848 nbytes
= (uint8_t*) d
- (uint8_t*) a2dp
->buffer
;
853 l
= pa_write(u
->stream_fd
, a2dp
->buffer
, nbytes
, &u
->stream_write_type
);
860 /* Retry right away if we got interrupted */
863 else if (errno
== EAGAIN
)
864 /* Hmm, apparently the socket was not writable, give up for now */
867 pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno
));
872 pa_assert((size_t) l
<= nbytes
);
874 if ((size_t) l
!= nbytes
) {
875 pa_log_warn("Wrote memory block to socket only partially! %llu written, wanted to write %llu.",
876 (unsigned long long) l
,
877 (unsigned long long) nbytes
);
882 u
->write_index
+= (uint64_t) u
->write_memchunk
.length
;
883 pa_memblock_unref(u
->write_memchunk
.memblock
);
884 pa_memchunk_reset(&u
->write_memchunk
);
894 static int a2dp_process_push(struct userdata
*u
) {
896 pa_memchunk memchunk
;
899 pa_assert(u
->profile
== PROFILE_A2DP_SOURCE
);
900 pa_assert(u
->source
);
901 pa_assert(u
->read_smoother
);
903 memchunk
.memblock
= pa_memblock_new(u
->core
->mempool
, u
->read_block_size
);
904 memchunk
.index
= memchunk
.length
= 0;
907 pa_bool_t found_tstamp
= FALSE
;
909 struct a2dp_info
*a2dp
;
910 struct rtp_header
*header
;
911 struct rtp_payload
*payload
;
915 size_t to_write
, to_decode
;
917 a2dp_prepare_buffer(u
);
920 header
= a2dp
->buffer
;
921 payload
= (struct rtp_payload
*) ((uint8_t*) a2dp
->buffer
+ sizeof(*header
));
923 l
= pa_read(u
->stream_fd
, a2dp
->buffer
, a2dp
->buffer_size
, &u
->stream_write_type
);
927 if (l
< 0 && errno
== EINTR
)
928 /* Retry right away if we got interrupted */
931 else if (l
< 0 && errno
== EAGAIN
)
932 /* Hmm, apparently the socket was not readable, give up for now. */
935 pa_log_error("Failed to read data from socket: %s", l
< 0 ? pa_cstrerror(errno
) : "EOF");
940 pa_assert((size_t) l
<= a2dp
->buffer_size
);
942 u
->read_index
+= (uint64_t) l
;
944 /* TODO: get timestamp from rtp */
946 /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!"); */
947 tstamp
= pa_rtclock_now();
950 pa_smoother_put(u
->read_smoother
, tstamp
, pa_bytes_to_usec(u
->read_index
, &u
->sample_spec
));
951 pa_smoother_resume(u
->read_smoother
, tstamp
, TRUE
);
953 p
= (uint8_t*) a2dp
->buffer
+ sizeof(*header
) + sizeof(*payload
);
954 to_decode
= l
- sizeof(*header
) - sizeof(*payload
);
956 d
= pa_memblock_acquire(memchunk
.memblock
);
957 to_write
= memchunk
.length
= pa_memblock_get_length(memchunk
.memblock
);
959 while (PA_LIKELY(to_decode
> 0)) {
963 decoded
= sbc_decode(&a2dp
->sbc
,
968 if (PA_UNLIKELY(decoded
<= 0)) {
969 pa_log_error("SBC decoding error (%li)", (long) decoded
);
970 pa_memblock_release(memchunk
.memblock
);
971 pa_memblock_unref(memchunk
.memblock
);
975 /* pa_log_debug("SBC: decoded: %lu; written: %lu", (unsigned long) decoded, (unsigned long) written); */
976 /* pa_log_debug("SBC: frame_length: %lu; codesize: %lu", (unsigned long) a2dp->frame_length, (unsigned long) a2dp->codesize); */
978 /* Reset frame length, it can be changed due to bitpool change */
979 a2dp
->frame_length
= sbc_get_frame_length(&a2dp
->sbc
);
981 pa_assert_fp((size_t) decoded
<= to_decode
);
982 pa_assert_fp((size_t) decoded
== a2dp
->frame_length
);
984 pa_assert_fp((size_t) written
== a2dp
->codesize
);
986 p
= (const uint8_t*) p
+ decoded
;
987 to_decode
-= decoded
;
989 d
= (uint8_t*) d
+ written
;
993 memchunk
.length
-= to_write
;
995 pa_memblock_release(memchunk
.memblock
);
997 pa_source_post(u
->source
, &memchunk
);
1003 pa_memblock_unref(memchunk
.memblock
);
1008 static void a2dp_reduce_bitpool(struct userdata
*u
)
1010 struct a2dp_info
*a2dp
;
1017 /* Check if bitpool is already at its limit */
1018 if (a2dp
->sbc
.bitpool
<= BITPOOL_DEC_LIMIT
)
1021 bitpool
= a2dp
->sbc
.bitpool
- BITPOOL_DEC_STEP
;
1023 if (bitpool
< BITPOOL_DEC_LIMIT
)
1024 bitpool
= BITPOOL_DEC_LIMIT
;
1026 a2dp_set_bitpool(u
, bitpool
);
1029 static void thread_func(void *userdata
) {
1030 struct userdata
*u
= userdata
;
1031 unsigned do_write
= 0;
1032 unsigned pending_read_bytes
= 0;
1033 pa_bool_t writable
= FALSE
;
1036 pa_assert(u
->transport
);
1038 pa_log_debug("IO Thread starting up");
1040 if (u
->core
->realtime_scheduling
)
1041 pa_make_realtime(u
->core
->realtime_priority
);
1043 pa_thread_mq_install(&u
->thread_mq
);
1045 /* Setup the stream only if the transport was already acquired */
1046 if (bt_transport_is_acquired(u
))
1047 bt_transport_acquire(u
, TRUE
);
1050 struct pollfd
*pollfd
;
1052 pa_bool_t disable_timer
= TRUE
;
1054 pollfd
= u
->rtpoll_item
? pa_rtpoll_item_get_pollfd(u
->rtpoll_item
, NULL
) : NULL
;
1056 if (u
->source
&& PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
)) {
1058 /* We should send two blocks to the device before we expect
1061 if (u
->write_index
== 0 && u
->read_index
<= 0)
1064 if (pollfd
&& (pollfd
->revents
& POLLIN
)) {
1067 if (u
->profile
== PROFILE_HSP
|| u
->profile
== PROFILE_HFGW
)
1068 n_read
= hsp_process_push(u
);
1070 n_read
= a2dp_process_push(u
);
1075 /* We just read something, so we are supposed to write something, too */
1076 pending_read_bytes
+= n_read
;
1077 do_write
+= pending_read_bytes
/ u
->write_block_size
;
1078 pending_read_bytes
= pending_read_bytes
% u
->write_block_size
;
1082 if (u
->sink
&& PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
)) {
1084 if (PA_UNLIKELY(u
->sink
->thread_info
.rewind_requested
))
1085 pa_sink_process_rewind(u
->sink
, 0);
1088 if (pollfd
->revents
& POLLOUT
)
1091 if ((!u
->source
|| !PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
)) && do_write
<= 0 && writable
) {
1092 pa_usec_t time_passed
;
1093 pa_usec_t audio_sent
;
1095 /* Hmm, there is no input stream we could synchronize
1096 * to. So let's do things by time */
1098 time_passed
= pa_rtclock_now() - u
->started_at
;
1099 audio_sent
= pa_bytes_to_usec(u
->write_index
, &u
->sample_spec
);
1101 if (audio_sent
<= time_passed
) {
1102 pa_usec_t audio_to_send
= time_passed
- audio_sent
;
1104 /* Never try to catch up for more than 100ms */
1105 if (u
->write_index
> 0 && audio_to_send
> MAX_PLAYBACK_CATCH_UP_USEC
) {
1106 pa_usec_t skip_usec
;
1107 uint64_t skip_bytes
;
1109 skip_usec
= audio_to_send
- MAX_PLAYBACK_CATCH_UP_USEC
;
1110 skip_bytes
= pa_usec_to_bytes(skip_usec
, &u
->sample_spec
);
1112 if (skip_bytes
> 0) {
1115 pa_log_warn("Skipping %llu us (= %llu bytes) in audio stream",
1116 (unsigned long long) skip_usec
,
1117 (unsigned long long) skip_bytes
);
1119 pa_sink_render_full(u
->sink
, skip_bytes
, &tmp
);
1120 pa_memblock_unref(tmp
.memblock
);
1121 u
->write_index
+= skip_bytes
;
1123 if (u
->profile
== PROFILE_A2DP
)
1124 a2dp_reduce_bitpool(u
);
1129 pending_read_bytes
= 0;
1133 if (writable
&& do_write
> 0) {
1136 if (u
->write_index
<= 0)
1137 u
->started_at
= pa_rtclock_now();
1139 if (u
->profile
== PROFILE_A2DP
) {
1140 if ((n_written
= a2dp_process_render(u
)) < 0)
1143 if ((n_written
= hsp_process_render(u
)) < 0)
1148 pa_log("Broken kernel: we got EAGAIN on write() after POLLOUT!");
1150 do_write
-= n_written
;
1154 if ((!u
->source
|| !PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
)) && do_write
<= 0) {
1155 pa_usec_t sleep_for
;
1156 pa_usec_t time_passed
, next_write_at
;
1159 /* Hmm, there is no input stream we could synchronize
1160 * to. So let's estimate when we need to wake up the latest */
1161 time_passed
= pa_rtclock_now() - u
->started_at
;
1162 next_write_at
= pa_bytes_to_usec(u
->write_index
, &u
->sample_spec
);
1163 sleep_for
= time_passed
< next_write_at
? next_write_at
- time_passed
: 0;
1164 /* pa_log("Sleeping for %lu; time passed %lu, next write at %lu", (unsigned long) sleep_for, (unsigned long) time_passed, (unsigned long)next_write_at); */
1166 /* drop stream every 500 ms */
1167 sleep_for
= PA_USEC_PER_MSEC
* 500;
1169 pa_rtpoll_set_timer_relative(u
->rtpoll
, sleep_for
);
1170 disable_timer
= FALSE
;
1176 pa_rtpoll_set_timer_disabled(u
->rtpoll
);
1178 /* Hmm, nothing to do. Let's sleep */
1180 pollfd
->events
= (short) (((u
->sink
&& PA_SINK_IS_LINKED(u
->sink
->thread_info
.state
) && !writable
) ? POLLOUT
: 0) |
1181 (u
->source
&& PA_SOURCE_IS_LINKED(u
->source
->thread_info
.state
) ? POLLIN
: 0));
1183 if ((ret
= pa_rtpoll_run(u
->rtpoll
, TRUE
)) < 0) {
1184 pa_log_debug("pa_rtpoll_run failed with: %d", ret
);
1188 pa_log_debug("IO thread shutdown requested, stopping cleanly");
1189 bt_transport_release(u
);
1193 pollfd
= u
->rtpoll_item
? pa_rtpoll_item_get_pollfd(u
->rtpoll_item
, NULL
) : NULL
;
1195 if (pollfd
&& (pollfd
->revents
& ~(POLLOUT
|POLLIN
))) {
1196 pa_log_info("FD error: %s%s%s%s",
1197 pollfd
->revents
& POLLERR
? "POLLERR " :"",
1198 pollfd
->revents
& POLLHUP
? "POLLHUP " :"",
1199 pollfd
->revents
& POLLPRI
? "POLLPRI " :"",
1200 pollfd
->revents
& POLLNVAL
? "POLLNVAL " :"");
1207 /* In case of HUP, just tear down the streams */
1208 if (!pollfd
|| (pollfd
->revents
& POLLHUP
) == 0)
1212 pending_read_bytes
= 0;
1219 /* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */
1220 pa_log_debug("IO thread failed");
1221 pa_asyncmsgq_post(pa_thread_mq_get()->outq
, PA_MSGOBJECT(u
->msg
), BLUETOOTH_MESSAGE_IO_THREAD_FAILED
, NULL
, 0, NULL
, NULL
);
1222 pa_asyncmsgq_wait_for(u
->thread_mq
.inq
, PA_MESSAGE_SHUTDOWN
);
1225 pa_log_debug("IO thread shutting down");
1228 static pa_bt_audio_state_t
parse_state_property_change(DBusMessage
*m
) {
1229 DBusMessageIter iter
;
1230 DBusMessageIter variant
;
1233 pa_bt_audio_state_t state
;
1235 if (!dbus_message_iter_init(m
, &iter
)) {
1236 pa_log("Failed to parse PropertyChanged");
1237 return PA_BT_AUDIO_STATE_INVALID
;
1240 if (dbus_message_iter_get_arg_type(&iter
) != DBUS_TYPE_STRING
) {
1241 pa_log("Property name not a string");
1242 return PA_BT_AUDIO_STATE_INVALID
;
1245 dbus_message_iter_get_basic(&iter
, &key
);
1247 if (!pa_streq(key
, "State"))
1248 return PA_BT_AUDIO_STATE_INVALID
;
1250 if (!dbus_message_iter_next(&iter
)) {
1251 pa_log("Property value missing");
1252 return PA_BT_AUDIO_STATE_INVALID
;
1255 dbus_message_iter_recurse(&iter
, &variant
);
1257 if (dbus_message_iter_get_arg_type(&variant
) != DBUS_TYPE_STRING
) {
1258 pa_log("Property value not a string");
1259 return PA_BT_AUDIO_STATE_INVALID
;
1262 dbus_message_iter_get_basic(&variant
, &value
);
1264 pa_log_debug("dbus: %s property 'State' changed to value '%s'", dbus_message_get_interface(m
), value
);
1266 state
= pa_bt_audio_state_from_string(value
);
1268 if (state
== PA_BT_AUDIO_STATE_INVALID
)
1269 pa_log("Unexpected value for property 'State': '%s'", value
);
1274 static pa_port_available_t
audio_state_to_availability(pa_bt_audio_state_t state
) {
1275 if (state
< PA_BT_AUDIO_STATE_CONNECTED
)
1276 return PA_PORT_AVAILABLE_NO
;
1277 else if (state
>= PA_BT_AUDIO_STATE_PLAYING
)
1278 return PA_PORT_AVAILABLE_YES
;
1280 return PA_PORT_AVAILABLE_UNKNOWN
;
1283 /* Run from main thread */
1284 static DBusHandlerResult
filter_cb(DBusConnection
*bus
, DBusMessage
*m
, void *userdata
) {
1287 bool acquire
= FALSE
;
1288 bool release
= FALSE
;
1292 pa_assert_se(u
= userdata
);
1294 dbus_error_init(&err
);
1296 pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
1297 dbus_message_get_interface(m
),
1298 dbus_message_get_path(m
),
1299 dbus_message_get_member(m
));
1301 if (!dbus_message_has_path(m
, u
->path
) && (!u
->transport
|| !dbus_message_has_path(m
, u
->transport
->path
)))
1304 if (dbus_message_is_signal(m
, "org.bluez.Headset", "SpeakerGainChanged") ||
1305 dbus_message_is_signal(m
, "org.bluez.Headset", "MicrophoneGainChanged")) {
1310 if (!dbus_message_get_args(m
, &err
, DBUS_TYPE_UINT16
, &gain
, DBUS_TYPE_INVALID
) || gain
> HSP_MAX_GAIN
) {
1311 pa_log("Failed to parse org.bluez.Headset.{Speaker|Microphone}GainChanged: %s", err
.message
);
1315 if (u
->profile
== PROFILE_HSP
) {
1316 if (u
->sink
&& dbus_message_is_signal(m
, "org.bluez.Headset", "SpeakerGainChanged")) {
1317 pa_volume_t volume
= (pa_volume_t
) (gain
* PA_VOLUME_NORM
/ HSP_MAX_GAIN
);
1319 /* increment volume by one to correct rounding errors */
1320 if (volume
< PA_VOLUME_NORM
)
1323 pa_cvolume_set(&v
, u
->sample_spec
.channels
, volume
);
1324 pa_sink_volume_changed(u
->sink
, &v
);
1326 } else if (u
->source
&& dbus_message_is_signal(m
, "org.bluez.Headset", "MicrophoneGainChanged")) {
1327 pa_volume_t volume
= (pa_volume_t
) (gain
* PA_VOLUME_NORM
/ HSP_MAX_GAIN
);
1329 /* increment volume by one to correct rounding errors */
1330 if (volume
< PA_VOLUME_NORM
)
1333 pa_cvolume_set(&v
, u
->sample_spec
.channels
, volume
);
1334 pa_source_volume_changed(u
->source
, &v
);
1337 } else if (dbus_message_is_signal(m
, "org.bluez.HandsfreeGateway", "PropertyChanged")) {
1338 pa_bt_audio_state_t state
= parse_state_property_change(m
);
1340 if (state
!= PA_BT_AUDIO_STATE_INVALID
&& pa_hashmap_get(u
->card
->profiles
, "hfgw")) {
1341 pa_device_port
*port
;
1342 pa_port_available_t available
= audio_state_to_availability(state
);
1344 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hfgw-output"));
1345 pa_device_port_set_available(port
, available
);
1347 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hfgw-input"));
1348 pa_device_port_set_available(port
, available
);
1350 acquire
= (available
== PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_HFGW
);
1351 release
= (available
!= PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_HFGW
);
1353 } else if (dbus_message_is_signal(m
, "org.bluez.Headset", "PropertyChanged")) {
1354 pa_bt_audio_state_t state
= parse_state_property_change(m
);
1356 if (state
!= PA_BT_AUDIO_STATE_INVALID
&& pa_hashmap_get(u
->card
->profiles
, "hsp")) {
1357 pa_device_port
*port
;
1358 pa_port_available_t available
= audio_state_to_availability(state
);
1360 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hsp-output"));
1361 pa_device_port_set_available(port
, available
);
1363 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hsp-input"));
1364 pa_device_port_set_available(port
, available
);
1366 acquire
= (available
== PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_HSP
);
1367 release
= (available
!= PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_HSP
);
1369 } else if (dbus_message_is_signal(m
, "org.bluez.AudioSource", "PropertyChanged")) {
1370 pa_bt_audio_state_t state
= parse_state_property_change(m
);
1372 if (state
!= PA_BT_AUDIO_STATE_INVALID
&& pa_hashmap_get(u
->card
->profiles
, "a2dp_source")) {
1373 pa_device_port
*port
;
1374 pa_port_available_t available
= audio_state_to_availability(state
);
1376 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "a2dp-input"));
1377 pa_device_port_set_available(port
, available
);
1379 acquire
= (available
== PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_A2DP_SOURCE
);
1380 release
= (available
!= PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_A2DP_SOURCE
);
1382 } else if (dbus_message_is_signal(m
, "org.bluez.AudioSink", "PropertyChanged")) {
1383 pa_bt_audio_state_t state
= parse_state_property_change(m
);
1385 if (state
!= PA_BT_AUDIO_STATE_INVALID
&& pa_hashmap_get(u
->card
->profiles
, "a2dp")) {
1386 pa_device_port
*port
;
1387 pa_port_available_t available
= audio_state_to_availability(state
);
1389 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "a2dp-output"));
1390 pa_device_port_set_available(port
, available
);
1392 acquire
= (available
== PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_A2DP
);
1393 release
= (available
!= PA_PORT_AVAILABLE_YES
&& u
->profile
== PROFILE_A2DP
);
1398 if (bt_transport_acquire(u
, FALSE
) >= 0) {
1400 pa_source_suspend(u
->source
, FALSE
, PA_SUSPEND_IDLE
|PA_SUSPEND_USER
);
1403 pa_sink_suspend(u
->sink
, FALSE
, PA_SUSPEND_IDLE
|PA_SUSPEND_USER
);
1406 if (release
&& bt_transport_is_acquired(u
)) {
1407 /* FIXME: this release is racy, since the audio stream might have
1408 been set up again in the meantime (but not processed yet by PA).
1409 BlueZ should probably release the transport automatically, and
1410 in that case we would just mark the transport as released */
1412 /* Remote side closed the stream so we consider it PA_SUSPEND_USER */
1414 pa_source_suspend(u
->source
, TRUE
, PA_SUSPEND_USER
);
1417 pa_sink_suspend(u
->sink
, TRUE
, PA_SUSPEND_USER
);
1421 dbus_error_free(&err
);
1423 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1426 /* Run from main thread */
1427 static void sink_set_volume_cb(pa_sink
*s
) {
1437 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) s
);
1438 u
= pa_shared_get(s
->core
, k
);
1442 pa_assert(u
->sink
== s
);
1443 pa_assert(u
->profile
== PROFILE_HSP
);
1445 gain
= (pa_cvolume_max(&s
->real_volume
) * HSP_MAX_GAIN
) / PA_VOLUME_NORM
;
1447 if (gain
> HSP_MAX_GAIN
)
1448 gain
= HSP_MAX_GAIN
;
1450 volume
= (pa_volume_t
) (gain
* PA_VOLUME_NORM
/ HSP_MAX_GAIN
);
1452 /* increment volume by one to correct rounding errors */
1453 if (volume
< PA_VOLUME_NORM
)
1456 pa_cvolume_set(&s
->real_volume
, u
->sample_spec
.channels
, volume
);
1458 pa_assert_se(m
= dbus_message_new_method_call("org.bluez", u
->path
, "org.bluez.Headset", "SetSpeakerGain"));
1459 pa_assert_se(dbus_message_append_args(m
, DBUS_TYPE_UINT16
, &gain
, DBUS_TYPE_INVALID
));
1460 pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u
->connection
), m
, NULL
));
1461 dbus_message_unref(m
);
1464 /* Run from main thread */
1465 static void source_set_volume_cb(pa_source
*s
) {
1475 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) s
);
1476 u
= pa_shared_get(s
->core
, k
);
1480 pa_assert(u
->source
== s
);
1481 pa_assert(u
->profile
== PROFILE_HSP
);
1483 gain
= (pa_cvolume_max(&s
->real_volume
) * HSP_MAX_GAIN
) / PA_VOLUME_NORM
;
1485 if (gain
> HSP_MAX_GAIN
)
1486 gain
= HSP_MAX_GAIN
;
1488 volume
= (pa_volume_t
) (gain
* PA_VOLUME_NORM
/ HSP_MAX_GAIN
);
1490 /* increment volume by one to correct rounding errors */
1491 if (volume
< PA_VOLUME_NORM
)
1494 pa_cvolume_set(&s
->real_volume
, u
->sample_spec
.channels
, volume
);
1496 pa_assert_se(m
= dbus_message_new_method_call("org.bluez", u
->path
, "org.bluez.Headset", "SetMicrophoneGain"));
1497 pa_assert_se(dbus_message_append_args(m
, DBUS_TYPE_UINT16
, &gain
, DBUS_TYPE_INVALID
));
1498 pa_assert_se(dbus_connection_send(pa_dbus_connection_get(u
->connection
), m
, NULL
));
1499 dbus_message_unref(m
);
1502 /* Run from main thread */
1503 static char *get_name(const char *type
, pa_modargs
*ma
, const char *device_id
, pa_bool_t
*namereg_fail
) {
1509 pa_assert(device_id
);
1510 pa_assert(namereg_fail
);
1512 t
= pa_sprintf_malloc("%s_name", type
);
1513 n
= pa_modargs_get_value(ma
, t
, NULL
);
1517 *namereg_fail
= TRUE
;
1518 return pa_xstrdup(n
);
1521 if ((n
= pa_modargs_get_value(ma
, "name", NULL
)))
1522 *namereg_fail
= TRUE
;
1525 *namereg_fail
= FALSE
;
1528 return pa_sprintf_malloc("bluez_%s.%s", type
, n
);
1531 static int sco_over_pcm_state_update(struct userdata
*u
, pa_bool_t changed
) {
1533 pa_assert(USE_SCO_OVER_PCM(u
));
1535 if (PA_SINK_IS_OPENED(pa_sink_get_state(u
->hsp
.sco_sink
)) ||
1536 PA_SOURCE_IS_OPENED(pa_source_get_state(u
->hsp
.sco_source
))) {
1538 if (u
->stream_fd
>= 0)
1541 pa_log_debug("Resuming SCO over PCM");
1542 if (init_profile(u
) < 0) {
1543 pa_log("Can't resume SCO over PCM");
1547 return bt_transport_acquire(u
, TRUE
);
1551 if (u
->stream_fd
< 0)
1554 pa_log_debug("Closing SCO over PCM");
1556 bt_transport_release(u
);
1562 static pa_hook_result_t
sink_state_changed_cb(pa_core
*c
, pa_sink
*s
, struct userdata
*u
) {
1564 pa_sink_assert_ref(s
);
1567 if (s
!= u
->hsp
.sco_sink
)
1570 sco_over_pcm_state_update(u
, TRUE
);
1575 static pa_hook_result_t
source_state_changed_cb(pa_core
*c
, pa_source
*s
, struct userdata
*u
) {
1577 pa_source_assert_ref(s
);
1580 if (s
!= u
->hsp
.sco_source
)
1583 sco_over_pcm_state_update(u
, TRUE
);
1588 static pa_hook_result_t
nrec_changed_cb(pa_bluetooth_transport
*t
, void *call_data
, struct userdata
*u
) {
1594 p
= pa_proplist_new();
1595 pa_proplist_sets(p
, "bluetooth.nrec", t
->nrec
? "1" : "0");
1596 pa_source_update_proplist(u
->source
, PA_UPDATE_REPLACE
, p
);
1597 pa_proplist_free(p
);
1602 static void connect_ports(struct userdata
*u
, void *sink_or_source_new_data
, pa_direction_t direction
) {
1604 pa_sink_new_data
*sink_new_data
;
1605 pa_source_new_data
*source_new_data
;
1607 pa_device_port
*port
;
1609 if (direction
== PA_DIRECTION_OUTPUT
)
1610 data
.sink_new_data
= sink_or_source_new_data
;
1612 data
.source_new_data
= sink_or_source_new_data
;
1614 switch (u
->profile
) {
1616 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "a2dp-output"));
1617 pa_assert_se(pa_hashmap_put(data
.sink_new_data
->ports
, port
->name
, port
) >= 0);
1618 pa_device_port_ref(port
);
1621 case PROFILE_A2DP_SOURCE
:
1622 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "a2dp-input"));
1623 pa_assert_se(pa_hashmap_put(data
.source_new_data
->ports
, port
->name
, port
) >= 0);
1624 pa_device_port_ref(port
);
1628 if (direction
== PA_DIRECTION_OUTPUT
) {
1629 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hsp-output"));
1630 pa_assert_se(pa_hashmap_put(data
.sink_new_data
->ports
, port
->name
, port
) >= 0);
1632 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hsp-input"));
1633 pa_assert_se(pa_hashmap_put(data
.source_new_data
->ports
, port
->name
, port
) >= 0);
1635 pa_device_port_ref(port
);
1639 if (direction
== PA_DIRECTION_OUTPUT
) {
1640 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hfgw-output"));
1641 pa_assert_se(pa_hashmap_put(data
.sink_new_data
->ports
, port
->name
, port
) >= 0);
1643 pa_assert_se(port
= pa_hashmap_get(u
->card
->ports
, "hfgw-input"));
1644 pa_assert_se(pa_hashmap_put(data
.source_new_data
->ports
, port
->name
, port
) >= 0);
1646 pa_device_port_ref(port
);
1650 pa_assert_not_reached();
1654 static const char *profile_to_string(enum profile profile
) {
1658 case PROFILE_A2DP_SOURCE
:
1659 return "a2dp_source";
1665 pa_assert_not_reached();
1669 static int sink_set_port_cb(pa_sink
*s
, pa_device_port
*p
) {
1673 static int source_set_port_cb(pa_source
*s
, pa_device_port
*p
) {
1677 /* Run from main thread */
1678 static int add_sink(struct userdata
*u
) {
1681 pa_assert(u
->transport
);
1683 if (USE_SCO_OVER_PCM(u
)) {
1686 u
->sink
= u
->hsp
.sco_sink
;
1687 p
= pa_proplist_new();
1688 pa_proplist_sets(p
, "bluetooth.protocol", profile_to_string(u
->profile
));
1689 pa_proplist_update(u
->sink
->proplist
, PA_UPDATE_MERGE
, p
);
1690 pa_proplist_free(p
);
1692 if (!u
->hsp
.sink_state_changed_slot
)
1693 u
->hsp
.sink_state_changed_slot
= pa_hook_connect(&u
->core
->hooks
[PA_CORE_HOOK_SINK_STATE_CHANGED
], PA_HOOK_NORMAL
, (pa_hook_cb_t
) sink_state_changed_cb
, u
);
1696 pa_sink_new_data data
;
1699 pa_sink_new_data_init(&data
);
1700 data
.driver
= __FILE__
;
1701 data
.module
= u
->module
;
1702 pa_sink_new_data_set_sample_spec(&data
, &u
->sample_spec
);
1703 pa_proplist_sets(data
.proplist
, "bluetooth.protocol", profile_to_string(u
->profile
));
1704 if (u
->profile
== PROFILE_HSP
)
1705 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_INTENDED_ROLES
, "phone");
1706 data
.card
= u
->card
;
1707 data
.name
= get_name("sink", u
->modargs
, u
->address
, &b
);
1708 data
.namereg_fail
= b
;
1710 if (pa_modargs_get_proplist(u
->modargs
, "sink_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1711 pa_log("Invalid properties");
1712 pa_sink_new_data_done(&data
);
1715 connect_ports(u
, &data
, PA_DIRECTION_OUTPUT
);
1717 if (!bt_transport_is_acquired(u
))
1718 switch (u
->profile
) {
1721 data
.suspend_cause
= PA_SUSPEND_IDLE
;
1724 data
.suspend_cause
= PA_SUSPEND_USER
;
1726 case PROFILE_A2DP_SOURCE
:
1728 pa_assert_not_reached();
1731 u
->sink
= pa_sink_new(u
->core
, &data
, PA_SINK_HARDWARE
|PA_SINK_LATENCY
);
1732 pa_sink_new_data_done(&data
);
1735 pa_log_error("Failed to create sink");
1739 u
->sink
->userdata
= u
;
1740 u
->sink
->parent
.process_msg
= sink_process_msg
;
1741 u
->sink
->set_port
= sink_set_port_cb
;
1744 if (u
->profile
== PROFILE_HSP
) {
1745 pa_sink_set_set_volume_callback(u
->sink
, sink_set_volume_cb
);
1746 u
->sink
->n_volume_steps
= 16;
1748 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->sink
);
1749 pa_shared_set(u
->core
, k
, u
);
1756 /* Run from main thread */
1757 static int add_source(struct userdata
*u
) {
1760 pa_assert(u
->transport
);
1762 if (USE_SCO_OVER_PCM(u
)) {
1763 u
->source
= u
->hsp
.sco_source
;
1764 pa_proplist_sets(u
->source
->proplist
, "bluetooth.protocol", profile_to_string(u
->profile
));
1766 if (!u
->hsp
.source_state_changed_slot
)
1767 u
->hsp
.source_state_changed_slot
= pa_hook_connect(&u
->core
->hooks
[PA_CORE_HOOK_SOURCE_STATE_CHANGED
], PA_HOOK_NORMAL
, (pa_hook_cb_t
) source_state_changed_cb
, u
);
1770 pa_source_new_data data
;
1773 pa_source_new_data_init(&data
);
1774 data
.driver
= __FILE__
;
1775 data
.module
= u
->module
;
1776 pa_source_new_data_set_sample_spec(&data
, &u
->sample_spec
);
1777 pa_proplist_sets(data
.proplist
, "bluetooth.protocol", profile_to_string(u
->profile
));
1778 if (u
->profile
== PROFILE_HSP
)
1779 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_INTENDED_ROLES
, "phone");
1781 data
.card
= u
->card
;
1782 data
.name
= get_name("source", u
->modargs
, u
->address
, &b
);
1783 data
.namereg_fail
= b
;
1785 if (pa_modargs_get_proplist(u
->modargs
, "source_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
1786 pa_log("Invalid properties");
1787 pa_source_new_data_done(&data
);
1791 connect_ports(u
, &data
, PA_DIRECTION_INPUT
);
1793 if (!bt_transport_is_acquired(u
))
1794 switch (u
->profile
) {
1796 data
.suspend_cause
= PA_SUSPEND_IDLE
;
1798 case PROFILE_A2DP_SOURCE
:
1800 data
.suspend_cause
= PA_SUSPEND_USER
;
1804 pa_assert_not_reached();
1807 u
->source
= pa_source_new(u
->core
, &data
, PA_SOURCE_HARDWARE
|PA_SOURCE_LATENCY
);
1808 pa_source_new_data_done(&data
);
1811 pa_log_error("Failed to create source");
1815 u
->source
->userdata
= u
;
1816 u
->source
->parent
.process_msg
= source_process_msg
;
1817 u
->source
->set_port
= source_set_port_cb
;
1820 if ((u
->profile
== PROFILE_HSP
) || (u
->profile
== PROFILE_HFGW
)) {
1821 pa_bluetooth_transport
*t
= u
->transport
;
1822 pa_proplist_sets(u
->source
->proplist
, "bluetooth.nrec", t
->nrec
? "1" : "0");
1824 if (!u
->hsp
.nrec_changed_slot
)
1825 u
->hsp
.nrec_changed_slot
= pa_hook_connect(&t
->hooks
[PA_BLUETOOTH_TRANSPORT_HOOK_NREC_CHANGED
], PA_HOOK_NORMAL
, (pa_hook_cb_t
) nrec_changed_cb
, u
);
1828 if (u
->profile
== PROFILE_HSP
) {
1829 pa_source_set_set_volume_callback(u
->source
, source_set_volume_cb
);
1830 u
->source
->n_volume_steps
= 16;
1832 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->source
);
1833 pa_shared_set(u
->core
, k
, u
);
1840 static void bt_transport_config_a2dp(struct userdata
*u
) {
1841 const pa_bluetooth_transport
*t
;
1842 struct a2dp_info
*a2dp
= &u
->a2dp
;
1848 config
= (a2dp_sbc_t
*) t
->config
;
1850 u
->sample_spec
.format
= PA_SAMPLE_S16LE
;
1852 if (a2dp
->sbc_initialized
)
1853 sbc_reinit(&a2dp
->sbc
, 0);
1855 sbc_init(&a2dp
->sbc
, 0);
1856 a2dp
->sbc_initialized
= TRUE
;
1858 switch (config
->frequency
) {
1859 case SBC_SAMPLING_FREQ_16000
:
1860 a2dp
->sbc
.frequency
= SBC_FREQ_16000
;
1861 u
->sample_spec
.rate
= 16000U;
1863 case SBC_SAMPLING_FREQ_32000
:
1864 a2dp
->sbc
.frequency
= SBC_FREQ_32000
;
1865 u
->sample_spec
.rate
= 32000U;
1867 case SBC_SAMPLING_FREQ_44100
:
1868 a2dp
->sbc
.frequency
= SBC_FREQ_44100
;
1869 u
->sample_spec
.rate
= 44100U;
1871 case SBC_SAMPLING_FREQ_48000
:
1872 a2dp
->sbc
.frequency
= SBC_FREQ_48000
;
1873 u
->sample_spec
.rate
= 48000U;
1876 pa_assert_not_reached();
1879 switch (config
->channel_mode
) {
1880 case SBC_CHANNEL_MODE_MONO
:
1881 a2dp
->sbc
.mode
= SBC_MODE_MONO
;
1882 u
->sample_spec
.channels
= 1;
1884 case SBC_CHANNEL_MODE_DUAL_CHANNEL
:
1885 a2dp
->sbc
.mode
= SBC_MODE_DUAL_CHANNEL
;
1886 u
->sample_spec
.channels
= 2;
1888 case SBC_CHANNEL_MODE_STEREO
:
1889 a2dp
->sbc
.mode
= SBC_MODE_STEREO
;
1890 u
->sample_spec
.channels
= 2;
1892 case SBC_CHANNEL_MODE_JOINT_STEREO
:
1893 a2dp
->sbc
.mode
= SBC_MODE_JOINT_STEREO
;
1894 u
->sample_spec
.channels
= 2;
1897 pa_assert_not_reached();
1900 switch (config
->allocation_method
) {
1901 case SBC_ALLOCATION_SNR
:
1902 a2dp
->sbc
.allocation
= SBC_AM_SNR
;
1904 case SBC_ALLOCATION_LOUDNESS
:
1905 a2dp
->sbc
.allocation
= SBC_AM_LOUDNESS
;
1908 pa_assert_not_reached();
1911 switch (config
->subbands
) {
1912 case SBC_SUBBANDS_4
:
1913 a2dp
->sbc
.subbands
= SBC_SB_4
;
1915 case SBC_SUBBANDS_8
:
1916 a2dp
->sbc
.subbands
= SBC_SB_8
;
1919 pa_assert_not_reached();
1922 switch (config
->block_length
) {
1923 case SBC_BLOCK_LENGTH_4
:
1924 a2dp
->sbc
.blocks
= SBC_BLK_4
;
1926 case SBC_BLOCK_LENGTH_8
:
1927 a2dp
->sbc
.blocks
= SBC_BLK_8
;
1929 case SBC_BLOCK_LENGTH_12
:
1930 a2dp
->sbc
.blocks
= SBC_BLK_12
;
1932 case SBC_BLOCK_LENGTH_16
:
1933 a2dp
->sbc
.blocks
= SBC_BLK_16
;
1936 pa_assert_not_reached();
1939 a2dp
->min_bitpool
= config
->min_bitpool
;
1940 a2dp
->max_bitpool
= config
->max_bitpool
;
1942 /* Set minimum bitpool for source to get the maximum possible block_size */
1943 a2dp
->sbc
.bitpool
= u
->profile
== PROFILE_A2DP
? a2dp
->max_bitpool
: a2dp
->min_bitpool
;
1944 a2dp
->codesize
= sbc_get_codesize(&a2dp
->sbc
);
1945 a2dp
->frame_length
= sbc_get_frame_length(&a2dp
->sbc
);
1947 pa_log_info("SBC parameters:\n\tallocation=%u\n\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n",
1948 a2dp
->sbc
.allocation
, a2dp
->sbc
.subbands
, a2dp
->sbc
.blocks
, a2dp
->sbc
.bitpool
);
1951 static void bt_transport_config(struct userdata
*u
) {
1952 if (u
->profile
== PROFILE_HSP
|| u
->profile
== PROFILE_HFGW
) {
1953 u
->sample_spec
.format
= PA_SAMPLE_S16LE
;
1954 u
->sample_spec
.channels
= 1;
1955 u
->sample_spec
.rate
= 8000;
1957 bt_transport_config_a2dp(u
);
1960 /* Run from main thread */
1961 static pa_hook_result_t
transport_removed_cb(pa_bluetooth_transport
*t
, void *call_data
, struct userdata
*u
) {
1965 pa_assert_se(pa_card_set_profile(u
->card
, "off", false) >= 0);
1970 /* Run from main thread */
1971 static int setup_transport(struct userdata
*u
) {
1972 pa_bluetooth_transport
*t
;
1975 pa_assert(!u
->transport
);
1977 /* check if profile has a transport */
1978 t
= pa_bluetooth_device_get_transport(u
->device
, u
->profile
);
1980 pa_log_warn("Profile has no transport");
1986 u
->transport_removed_slot
= pa_hook_connect(&t
->hooks
[PA_BLUETOOTH_TRANSPORT_HOOK_REMOVED
], PA_HOOK_NORMAL
,
1987 (pa_hook_cb_t
) transport_removed_cb
, u
);
1989 bt_transport_acquire(u
, FALSE
);
1991 bt_transport_config(u
);
1996 /* Run from main thread */
1997 static int init_profile(struct userdata
*u
) {
2000 pa_assert(u
->profile
!= PROFILE_OFF
);
2002 if (setup_transport(u
) < 0)
2005 pa_assert(u
->transport
);
2007 if (u
->profile
== PROFILE_A2DP
||
2008 u
->profile
== PROFILE_HSP
||
2009 u
->profile
== PROFILE_HFGW
)
2010 if (add_sink(u
) < 0)
2013 if (u
->profile
== PROFILE_HSP
||
2014 u
->profile
== PROFILE_A2DP_SOURCE
||
2015 u
->profile
== PROFILE_HFGW
)
2016 if (add_source(u
) < 0)
2022 /* Run from main thread */
2023 static void stop_thread(struct userdata
*u
) {
2028 if (u
->sink
&& !USE_SCO_OVER_PCM(u
))
2029 pa_sink_unlink(u
->sink
);
2031 if (u
->source
&& !USE_SCO_OVER_PCM(u
))
2032 pa_source_unlink(u
->source
);
2035 pa_asyncmsgq_send(u
->thread_mq
.inq
, NULL
, PA_MESSAGE_SHUTDOWN
, NULL
, 0, NULL
);
2036 pa_thread_free(u
->thread
);
2040 if (u
->rtpoll_item
) {
2041 pa_rtpoll_item_free(u
->rtpoll_item
);
2042 u
->rtpoll_item
= NULL
;
2045 if (u
->hsp
.sink_state_changed_slot
) {
2046 pa_hook_slot_free(u
->hsp
.sink_state_changed_slot
);
2047 u
->hsp
.sink_state_changed_slot
= NULL
;
2050 if (u
->hsp
.source_state_changed_slot
) {
2051 pa_hook_slot_free(u
->hsp
.source_state_changed_slot
);
2052 u
->hsp
.source_state_changed_slot
= NULL
;
2055 if (u
->hsp
.nrec_changed_slot
) {
2056 pa_hook_slot_free(u
->hsp
.nrec_changed_slot
);
2057 u
->hsp
.nrec_changed_slot
= NULL
;
2060 if (u
->transport_removed_slot
) {
2061 pa_hook_slot_free(u
->transport_removed_slot
);
2062 u
->transport_removed_slot
= NULL
;
2066 bt_transport_release(u
);
2067 u
->transport
= NULL
;
2071 if (u
->profile
== PROFILE_HSP
) {
2072 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->sink
);
2073 pa_shared_remove(u
->core
, k
);
2077 pa_sink_unref(u
->sink
);
2082 if (u
->profile
== PROFILE_HSP
) {
2083 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->source
);
2084 pa_shared_remove(u
->core
, k
);
2088 pa_source_unref(u
->source
);
2093 pa_thread_mq_done(&u
->thread_mq
);
2095 pa_rtpoll_free(u
->rtpoll
);
2099 if (u
->read_smoother
) {
2100 pa_smoother_free(u
->read_smoother
);
2101 u
->read_smoother
= NULL
;
2105 /* Run from main thread */
2106 static int start_thread(struct userdata
*u
) {
2108 pa_assert(!u
->thread
);
2109 pa_assert(!u
->rtpoll
);
2110 pa_assert(!u
->rtpoll_item
);
2112 u
->rtpoll
= pa_rtpoll_new();
2113 pa_thread_mq_init(&u
->thread_mq
, u
->core
->mainloop
, u
->rtpoll
);
2115 if (USE_SCO_OVER_PCM(u
)) {
2116 if (sco_over_pcm_state_update(u
, FALSE
) < 0) {
2120 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->sink
);
2121 pa_shared_remove(u
->core
, k
);
2126 k
= pa_sprintf_malloc("bluetooth-device@%p", (void*) u
->source
);
2127 pa_shared_remove(u
->core
, k
);
2134 pa_sink_ref(u
->sink
);
2135 pa_source_ref(u
->source
);
2136 /* FIXME: monitor stream_fd error */
2140 if (!(u
->thread
= pa_thread_new("bluetooth", thread_func
, u
))) {
2141 pa_log_error("Failed to create IO thread");
2146 pa_sink_set_asyncmsgq(u
->sink
, u
->thread_mq
.inq
);
2147 pa_sink_set_rtpoll(u
->sink
, u
->rtpoll
);
2148 pa_sink_put(u
->sink
);
2150 if (u
->sink
->set_volume
)
2151 u
->sink
->set_volume(u
->sink
);
2155 pa_source_set_asyncmsgq(u
->source
, u
->thread_mq
.inq
);
2156 pa_source_set_rtpoll(u
->source
, u
->rtpoll
);
2157 pa_source_put(u
->source
);
2159 if (u
->source
->set_volume
)
2160 u
->source
->set_volume(u
->source
);
2166 static void save_sco_volume_callbacks(struct userdata
*u
) {
2168 pa_assert(USE_SCO_OVER_PCM(u
));
2170 u
->hsp
.sco_sink_set_volume
= u
->hsp
.sco_sink
->set_volume
;
2171 u
->hsp
.sco_source_set_volume
= u
->hsp
.sco_source
->set_volume
;
2174 static void restore_sco_volume_callbacks(struct userdata
*u
) {
2176 pa_assert(USE_SCO_OVER_PCM(u
));
2178 pa_sink_set_set_volume_callback(u
->hsp
.sco_sink
, u
->hsp
.sco_sink_set_volume
);
2179 pa_source_set_set_volume_callback(u
->hsp
.sco_source
, u
->hsp
.sco_source_set_volume
);
2182 /* Run from main thread */
2183 static int card_set_profile(pa_card
*c
, pa_card_profile
*new_profile
) {
2188 pa_assert(new_profile
);
2189 pa_assert_se(u
= c
->userdata
);
2191 d
= PA_CARD_PROFILE_DATA(new_profile
);
2193 if (*d
!= PROFILE_OFF
) {
2194 const pa_bluetooth_device
*device
= u
->device
;
2196 if (device
->headset_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_HSP
) {
2197 pa_log_warn("HSP is not connected, refused to switch profile");
2199 } else if (device
->audio_sink_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_A2DP
) {
2200 pa_log_warn("A2DP Sink is not connected, refused to switch profile");
2202 } else if (device
->audio_source_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_A2DP_SOURCE
) {
2203 pa_log_warn("A2DP Source is not connected, refused to switch profile");
2205 } else if (device
->hfgw_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_HFGW
) {
2206 pa_log_warn("HandsfreeGateway is not connected, refused to switch profile");
2213 if (USE_SCO_OVER_PCM(u
))
2214 restore_sco_volume_callbacks(u
);
2217 u
->sample_spec
= u
->requested_sample_spec
;
2219 if (USE_SCO_OVER_PCM(u
))
2220 save_sco_volume_callbacks(u
);
2222 if (u
->profile
!= PROFILE_OFF
)
2223 if (init_profile(u
) < 0)
2226 if (u
->sink
|| u
->source
)
2227 if (start_thread(u
) < 0)
2235 pa_assert_se(pa_card_set_profile(u
->card
, "off", false) >= 0);
2240 static void create_ports_for_profile(struct userdata
*u
, pa_hashmap
*ports
, pa_card_profile
*profile
) {
2241 pa_bluetooth_device
*device
= u
->device
;
2242 pa_device_port
*port
;
2245 d
= PA_CARD_PROFILE_DATA(profile
);
2249 pa_assert_se(port
= pa_device_port_new(u
->core
, "a2dp-output", _("Bluetooth High Quality (A2DP)"), 0));
2250 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2251 port
->is_output
= 1;
2253 port
->priority
= profile
->priority
* 100;
2254 port
->available
= audio_state_to_availability(device
->audio_sink_state
);
2255 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2258 case PROFILE_A2DP_SOURCE
:
2259 pa_assert_se(port
= pa_device_port_new(u
->core
, "a2dp-input", _("Bluetooth High Quality (A2DP)"), 0));
2260 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2261 port
->is_output
= 0;
2263 port
->priority
= profile
->priority
* 100;
2264 port
->available
= audio_state_to_availability(device
->audio_source_state
);
2265 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2269 pa_assert_se(port
= pa_device_port_new(u
->core
, "hsp-output", _("Bluetooth Telephony (HSP/HFP)"), 0));
2270 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2271 port
->is_output
= 1;
2273 port
->priority
= profile
->priority
* 100;
2274 port
->available
= audio_state_to_availability(device
->headset_state
);
2275 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2277 pa_assert_se(port
= pa_device_port_new(u
->core
, "hsp-input", _("Bluetooth Telephony (HSP/HFP)"), 0));
2278 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2279 port
->is_output
= 0;
2281 port
->priority
= profile
->priority
* 100;
2282 port
->available
= audio_state_to_availability(device
->headset_state
);
2283 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2287 pa_assert_se(port
= pa_device_port_new(u
->core
, "hfgw-output", _("Bluetooth Handsfree Gateway"), 0));
2288 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2289 port
->is_output
= 1;
2291 port
->priority
= profile
->priority
* 100;
2292 port
->available
= audio_state_to_availability(device
->hfgw_state
);
2293 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2295 pa_assert_se(port
= pa_device_port_new(u
->core
, "hfgw-input", _("Bluetooth Handsfree Gateway"), 0));
2296 pa_assert_se(pa_hashmap_put(ports
, port
->name
, port
) >= 0);
2297 port
->is_output
= 0;
2299 port
->priority
= profile
->priority
* 100;
2300 port
->available
= audio_state_to_availability(device
->hfgw_state
);
2301 pa_hashmap_put(port
->profiles
, profile
->name
, profile
);
2305 pa_assert_not_reached();
2310 /* Run from main thread */
2311 static pa_card_profile
*create_card_profile(struct userdata
*u
, const char *uuid
) {
2312 pa_card_profile
*p
= NULL
;
2315 if (pa_streq(uuid
, A2DP_SINK_UUID
)) {
2316 p
= pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP)"), sizeof(enum profile
));
2320 p
->max_sink_channels
= 2;
2321 p
->max_source_channels
= 0;
2323 d
= PA_CARD_PROFILE_DATA(p
);
2325 } else if (pa_streq(uuid
, A2DP_SOURCE_UUID
)) {
2326 p
= pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP)"), sizeof(enum profile
));
2330 p
->max_sink_channels
= 0;
2331 p
->max_source_channels
= 2;
2333 d
= PA_CARD_PROFILE_DATA(p
);
2334 *d
= PROFILE_A2DP_SOURCE
;
2335 } else if (pa_streq(uuid
, HSP_HS_UUID
) || pa_streq(uuid
, HFP_HS_UUID
)) {
2336 p
= pa_card_profile_new("hsp", _("Telephony Duplex (HSP/HFP)"), sizeof(enum profile
));
2340 p
->max_sink_channels
= 1;
2341 p
->max_source_channels
= 1;
2343 d
= PA_CARD_PROFILE_DATA(p
);
2345 } else if (pa_streq(uuid
, HFP_AG_UUID
)) {
2346 p
= pa_card_profile_new("hfgw", _("Handsfree Gateway"), sizeof(enum profile
));
2350 p
->max_sink_channels
= 1;
2351 p
->max_source_channels
= 1;
2353 d
= PA_CARD_PROFILE_DATA(p
);
2360 /* Run from main thread */
2361 static int add_card(struct userdata
*u
) {
2362 pa_card_new_data data
;
2368 const char *default_profile
;
2369 const pa_bluetooth_device
*device
= u
->device
;
2370 const pa_bluetooth_uuid
*uuid
;
2375 pa_card_new_data_init(&data
);
2376 data
.driver
= __FILE__
;
2377 data
.module
= u
->module
;
2379 n
= pa_bluetooth_cleanup_name(device
->name
);
2380 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_DESCRIPTION
, n
);
2382 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_STRING
, device
->address
);
2383 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_API
, "bluez");
2384 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_CLASS
, "sound");
2385 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_BUS
, "bluetooth");
2386 if ((ff
= pa_bluetooth_get_form_factor(device
->class)))
2387 pa_proplist_sets(data
.proplist
, PA_PROP_DEVICE_FORM_FACTOR
, ff
);
2388 pa_proplist_sets(data
.proplist
, "bluez.path", device
->path
);
2389 pa_proplist_setf(data
.proplist
, "bluez.class", "0x%06x", (unsigned) device
->class);
2390 pa_proplist_sets(data
.proplist
, "bluez.name", device
->name
);
2391 data
.name
= get_name("card", u
->modargs
, device
->address
, &b
);
2392 data
.namereg_fail
= b
;
2394 if (pa_modargs_get_proplist(u
->modargs
, "card_properties", data
.proplist
, PA_UPDATE_REPLACE
) < 0) {
2395 pa_log("Invalid properties");
2396 pa_card_new_data_done(&data
);
2400 PA_LLIST_FOREACH(uuid
, device
->uuids
) {
2401 p
= create_card_profile(u
, uuid
->uuid
);
2406 if (pa_hashmap_get(data
.profiles
, p
->name
)) {
2407 pa_card_profile_free(p
);
2411 pa_hashmap_put(data
.profiles
, p
->name
, p
);
2412 create_ports_for_profile(u
, data
.ports
, p
);
2415 pa_assert(!pa_hashmap_isempty(data
.profiles
));
2417 p
= pa_card_profile_new("off", _("Off"), sizeof(enum profile
));
2418 d
= PA_CARD_PROFILE_DATA(p
);
2420 pa_hashmap_put(data
.profiles
, p
->name
, p
);
2422 if ((default_profile
= pa_modargs_get_value(u
->modargs
, "profile", NULL
))) {
2423 if (pa_hashmap_get(data
.profiles
, default_profile
))
2424 pa_card_new_data_set_profile(&data
, default_profile
);
2426 pa_log_warn("Profile '%s' not valid or not supported by device.", default_profile
);
2429 u
->card
= pa_card_new(u
->core
, &data
);
2430 pa_card_new_data_done(&data
);
2433 pa_log("Failed to allocate card.");
2437 u
->card
->userdata
= u
;
2438 u
->card
->set_profile
= card_set_profile
;
2440 d
= PA_CARD_PROFILE_DATA(u
->card
->active_profile
);
2442 if ((device
->headset_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_HSP
) ||
2443 (device
->audio_sink_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_A2DP
) ||
2444 (device
->audio_source_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_A2DP_SOURCE
) ||
2445 (device
->hfgw_state
< PA_BT_AUDIO_STATE_CONNECTED
&& *d
== PROFILE_HFGW
)) {
2446 pa_log_warn("Default profile not connected, selecting off profile");
2447 u
->card
->active_profile
= pa_hashmap_get(u
->card
->profiles
, "off");
2448 u
->card
->save_profile
= FALSE
;
2451 d
= PA_CARD_PROFILE_DATA(u
->card
->active_profile
);
2454 if (USE_SCO_OVER_PCM(u
))
2455 save_sco_volume_callbacks(u
);
2460 /* Run from main thread */
2461 static pa_bluetooth_device
* find_device(struct userdata
*u
, const char *address
, const char *path
) {
2462 pa_bluetooth_device
*d
= NULL
;
2466 if (!address
&& !path
) {
2467 pa_log_error("Failed to get device address/path from module arguments.");
2472 if (!(d
= pa_bluetooth_discovery_get_by_path(u
->discovery
, path
))) {
2473 pa_log_error("%s is not a valid BlueZ audio device.", path
);
2477 if (address
&& !(pa_streq(d
->address
, address
))) {
2478 pa_log_error("Passed path %s address %s != %s don't match.", path
, d
->address
, address
);
2483 if (!(d
= pa_bluetooth_discovery_get_by_address(u
->discovery
, address
))) {
2484 pa_log_error("%s is not known.", address
);
2490 u
->address
= pa_xstrdup(d
->address
);
2491 u
->path
= pa_xstrdup(d
->path
);
2497 /* Run from main thread */
2498 static int setup_dbus(struct userdata
*u
) {
2501 dbus_error_init(&err
);
2503 u
->connection
= pa_dbus_bus_get(u
->core
, DBUS_BUS_SYSTEM
, &err
);
2505 if (dbus_error_is_set(&err
) || !u
->connection
) {
2506 pa_log("Failed to get D-Bus connection: %s", err
.message
);
2507 dbus_error_free(&err
);
2514 /* Run from main thread */
2515 static pa_hook_result_t
device_removed_cb(pa_bluetooth_device
*d
, void *call_data
, struct userdata
*u
) {
2519 pa_log_debug("Device %s removed: unloading module", d
->path
);
2520 pa_module_unload(u
->core
, u
->module
, TRUE
);
2525 int pa__init(pa_module
* m
) {
2529 const char *address
, *path
;
2531 char *mike
, *speaker
;
2532 pa_bluetooth_device
*device
;
2536 dbus_error_init(&err
);
2538 if (!(ma
= pa_modargs_new(m
->argument
, valid_modargs
))) {
2539 pa_log_error("Failed to parse module arguments");
2543 m
->userdata
= u
= pa_xnew0(struct userdata
, 1);
2547 u
->sample_spec
= m
->core
->default_sample_spec
;
2550 if (pa_modargs_get_value(ma
, "sco_sink", NULL
) &&
2551 !(u
->hsp
.sco_sink
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "sco_sink", NULL
), PA_NAMEREG_SINK
))) {
2552 pa_log("SCO sink not found");
2556 if (pa_modargs_get_value(ma
, "sco_source", NULL
) &&
2557 !(u
->hsp
.sco_source
= pa_namereg_get(m
->core
, pa_modargs_get_value(ma
, "sco_source", NULL
), PA_NAMEREG_SOURCE
))) {
2558 pa_log("SCO source not found");
2562 if (pa_modargs_get_value_u32(ma
, "rate", &u
->sample_spec
.rate
) < 0 ||
2563 u
->sample_spec
.rate
<= 0 || u
->sample_spec
.rate
> PA_RATE_MAX
) {
2564 pa_log_error("Failed to get rate from module arguments");
2568 u
->auto_connect
= TRUE
;
2569 if (pa_modargs_get_value_boolean(ma
, "auto_connect", &u
->auto_connect
)) {
2570 pa_log("Failed to parse auto_connect= argument");
2574 channels
= u
->sample_spec
.channels
;
2575 if (pa_modargs_get_value_u32(ma
, "channels", &channels
) < 0 ||
2576 channels
<= 0 || channels
> PA_CHANNELS_MAX
) {
2577 pa_log_error("Failed to get channels from module arguments");
2580 u
->sample_spec
.channels
= (uint8_t) channels
;
2581 u
->requested_sample_spec
= u
->sample_spec
;
2583 address
= pa_modargs_get_value(ma
, "address", NULL
);
2584 path
= pa_modargs_get_value(ma
, "path", NULL
);
2586 if (setup_dbus(u
) < 0)
2589 if (!(u
->discovery
= pa_bluetooth_discovery_get(m
->core
)))
2592 if (!(device
= find_device(u
, address
, path
)))
2595 u
->device_removed_slot
= pa_hook_connect(&device
->hooks
[PA_BLUETOOTH_DEVICE_HOOK_REMOVED
], PA_HOOK_NORMAL
,
2596 (pa_hook_cb_t
) device_removed_cb
, u
);
2600 /* Add the card structure. This will also initialize the default profile */
2601 if (add_card(u
) < 0)
2604 if (!(u
->msg
= pa_msgobject_new(bluetooth_msg
)))
2607 u
->msg
->parent
.process_msg
= device_process_msg
;
2608 u
->msg
->card
= u
->card
;
2610 if (!dbus_connection_add_filter(pa_dbus_connection_get(u
->connection
), filter_cb
, u
, NULL
)) {
2611 pa_log_error("Failed to add filter function");
2614 u
->filter_added
= TRUE
;
2616 speaker
= pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='SpeakerGainChanged',path='%s'", u
->path
);
2617 mike
= pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='MicrophoneGainChanged',path='%s'", u
->path
);
2619 if (pa_dbus_add_matches(
2620 pa_dbus_connection_get(u
->connection
), &err
,
2623 "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
2624 "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
2625 "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'",
2626 "type='signal',sender='org.bluez',interface='org.bluez.AudioSource',member='PropertyChanged'",
2627 "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'",
2633 pa_log("Failed to add D-Bus matches: %s", err
.message
);
2640 if (u
->profile
!= PROFILE_OFF
)
2641 if (init_profile(u
) < 0)
2644 if (u
->sink
|| u
->source
)
2645 if (start_thread(u
) < 0)
2653 pa_assert_se(pa_card_set_profile(u
->card
, "off", false) >= 0);
2661 dbus_error_free(&err
);
2666 int pa__get_n_used(pa_module
*m
) {
2670 pa_assert_se(u
= m
->userdata
);
2673 (u
->sink
? pa_sink_linked_by(u
->sink
) : 0) +
2674 (u
->source
? pa_source_linked_by(u
->source
) : 0);
2677 void pa__done(pa_module
*m
) {
2682 if (!(u
= m
->userdata
))
2687 if (u
->device_removed_slot
) {
2688 pa_hook_slot_free(u
->device_removed_slot
);
2689 u
->device_removed_slot
= NULL
;
2692 if (USE_SCO_OVER_PCM(u
))
2693 restore_sco_volume_callbacks(u
);
2695 if (u
->connection
) {
2698 char *speaker
, *mike
;
2699 speaker
= pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='SpeakerGainChanged',path='%s'", u
->path
);
2700 mike
= pa_sprintf_malloc("type='signal',sender='org.bluez',interface='org.bluez.Headset',member='MicrophoneGainChanged',path='%s'", u
->path
);
2702 pa_dbus_remove_matches(pa_dbus_connection_get(u
->connection
), speaker
, mike
,
2703 "type='signal',sender='org.bluez',interface='org.bluez.MediaTransport',member='PropertyChanged'",
2704 "type='signal',sender='org.bluez',interface='org.bluez.HandsfreeGateway',member='PropertyChanged'",
2711 if (u
->filter_added
)
2712 dbus_connection_remove_filter(pa_dbus_connection_get(u
->connection
), filter_cb
, u
);
2714 pa_dbus_connection_unref(u
->connection
);
2721 pa_card_free(u
->card
);
2723 if (u
->read_smoother
)
2724 pa_smoother_free(u
->read_smoother
);
2727 pa_xfree(u
->a2dp
.buffer
);
2729 sbc_finish(&u
->a2dp
.sbc
);
2732 pa_modargs_free(u
->modargs
);
2734 pa_xfree(u
->address
);
2738 pa_bluetooth_discovery_unref(u
->discovery
);