]> code.delx.au - pulseaudio/blob - src/modules/bluetooth/module-bluez5-device.c
bluetooth: Create source for BlueZ 5 cards
[pulseaudio] / src / modules / bluetooth / module-bluez5-device.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2008-2013 João Paulo Rechi Vita
5 Copyright 2011-2013 BMW Car IT GmbH.
6
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.
11
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.
16
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
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <sbc/sbc.h>
28
29 #include <pulsecore/core-util.h>
30 #include <pulsecore/i18n.h>
31 #include <pulsecore/module.h>
32 #include <pulsecore/modargs.h>
33
34 #include "a2dp-codecs.h"
35 #include "bluez5-util.h"
36
37 #include "module-bluez5-device-symdef.h"
38
39 PA_MODULE_AUTHOR("João Paulo Rechi Vita");
40 PA_MODULE_DESCRIPTION("BlueZ 5 Bluetooth audio sink and source");
41 PA_MODULE_VERSION(PACKAGE_VERSION);
42 PA_MODULE_LOAD_ONCE(false);
43 PA_MODULE_USAGE("path=<device object path>");
44
45 static const char* const valid_modargs[] = {
46 "path",
47 NULL
48 };
49
50 typedef struct sbc_info {
51 sbc_t sbc; /* Codec data */
52 bool sbc_initialized; /* Keep track if the encoder is initialized */
53 size_t codesize, frame_length; /* SBC Codesize, frame_length. We simply cache those values here */
54 uint16_t seq_num; /* Cumulative packet sequence */
55 uint8_t min_bitpool;
56 uint8_t max_bitpool;
57
58 void* buffer; /* Codec transfer buffer */
59 size_t buffer_size; /* Size of the buffer */
60 } sbc_info_t;
61
62 struct userdata {
63 pa_module *module;
64 pa_core *core;
65
66 pa_hook_slot *device_connection_changed_slot;
67
68 pa_bluetooth_discovery *discovery;
69 pa_bluetooth_device *device;
70 pa_bluetooth_transport *transport;
71 bool transport_acquired;
72
73 pa_card *card;
74 pa_sink *sink;
75 pa_source *source;
76 pa_bluetooth_profile_t profile;
77 char *output_port_name;
78 char *input_port_name;
79
80 int stream_fd;
81 size_t read_link_mtu;
82 size_t write_link_mtu;
83 size_t read_block_size;
84 size_t write_block_size;
85 pa_sample_spec sample_spec;
86 struct sbc_info sbc_info;
87 };
88
89 typedef enum pa_bluetooth_form_factor {
90 PA_BLUETOOTH_FORM_FACTOR_UNKNOWN,
91 PA_BLUETOOTH_FORM_FACTOR_HEADSET,
92 PA_BLUETOOTH_FORM_FACTOR_HANDSFREE,
93 PA_BLUETOOTH_FORM_FACTOR_MICROPHONE,
94 PA_BLUETOOTH_FORM_FACTOR_SPEAKER,
95 PA_BLUETOOTH_FORM_FACTOR_HEADPHONE,
96 PA_BLUETOOTH_FORM_FACTOR_PORTABLE,
97 PA_BLUETOOTH_FORM_FACTOR_CAR,
98 PA_BLUETOOTH_FORM_FACTOR_HIFI,
99 PA_BLUETOOTH_FORM_FACTOR_PHONE,
100 } pa_bluetooth_form_factor_t;
101
102 /* Run from main thread */
103 static pa_bluetooth_form_factor_t form_factor_from_class(uint32_t class_of_device) {
104 unsigned major, minor;
105 pa_bluetooth_form_factor_t r;
106
107 static const pa_bluetooth_form_factor_t table[] = {
108 [1] = PA_BLUETOOTH_FORM_FACTOR_HEADSET,
109 [2] = PA_BLUETOOTH_FORM_FACTOR_HANDSFREE,
110 [4] = PA_BLUETOOTH_FORM_FACTOR_MICROPHONE,
111 [5] = PA_BLUETOOTH_FORM_FACTOR_SPEAKER,
112 [6] = PA_BLUETOOTH_FORM_FACTOR_HEADPHONE,
113 [7] = PA_BLUETOOTH_FORM_FACTOR_PORTABLE,
114 [8] = PA_BLUETOOTH_FORM_FACTOR_CAR,
115 [10] = PA_BLUETOOTH_FORM_FACTOR_HIFI
116 };
117
118 /*
119 * See Bluetooth Assigned Numbers:
120 * https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
121 */
122 major = (class_of_device >> 8) & 0x1F;
123 minor = (class_of_device >> 2) & 0x3F;
124
125 switch (major) {
126 case 2:
127 return PA_BLUETOOTH_FORM_FACTOR_PHONE;
128 case 4:
129 break;
130 default:
131 pa_log_debug("Unknown Bluetooth major device class %u", major);
132 return PA_BLUETOOTH_FORM_FACTOR_UNKNOWN;
133 }
134
135 r = minor < PA_ELEMENTSOF(table) ? table[minor] : PA_BLUETOOTH_FORM_FACTOR_UNKNOWN;
136
137 if (!r)
138 pa_log_debug("Unknown Bluetooth minor device class %u", minor);
139
140 return r;
141 }
142
143 /* Run from main thread */
144 static const char *form_factor_to_string(pa_bluetooth_form_factor_t ff) {
145 switch (ff) {
146 case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN:
147 return "unknown";
148 case PA_BLUETOOTH_FORM_FACTOR_HEADSET:
149 return "headset";
150 case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE:
151 return "hands-free";
152 case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE:
153 return "microphone";
154 case PA_BLUETOOTH_FORM_FACTOR_SPEAKER:
155 return "speaker";
156 case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE:
157 return "headphone";
158 case PA_BLUETOOTH_FORM_FACTOR_PORTABLE:
159 return "portable";
160 case PA_BLUETOOTH_FORM_FACTOR_CAR:
161 return "car";
162 case PA_BLUETOOTH_FORM_FACTOR_HIFI:
163 return "hifi";
164 case PA_BLUETOOTH_FORM_FACTOR_PHONE:
165 return "phone";
166 }
167
168 pa_assert_not_reached();
169 }
170
171 /* Run from main thread */
172 static void connect_ports(struct userdata *u, void *new_data, pa_direction_t direction) {
173 pa_device_port *port;
174
175 if (direction == PA_DIRECTION_OUTPUT) {
176 pa_sink_new_data *sink_new_data = new_data;
177
178 pa_assert_se(port = pa_hashmap_get(u->card->ports, u->output_port_name));
179 pa_assert_se(pa_hashmap_put(sink_new_data->ports, port->name, port) >= 0);
180 pa_device_port_ref(port);
181 } else {
182 pa_source_new_data *source_new_data = new_data;
183
184 pa_assert_se(port = pa_hashmap_get(u->card->ports, u->input_port_name));
185 pa_assert_se(pa_hashmap_put(source_new_data->ports, port->name, port) >= 0);
186 pa_device_port_ref(port);
187 }
188 }
189
190 static int transport_acquire(struct userdata *u, bool optional) {
191 pa_assert(u->transport);
192
193 if (u->transport_acquired)
194 return 0;
195
196 pa_log_debug("Acquiring transport %s", u->transport->path);
197
198 u->stream_fd = u->transport->acquire(u->transport, optional, &u->read_link_mtu, &u->write_link_mtu);
199 if (u->stream_fd < 0)
200 return -1;
201
202 u->transport_acquired = true;
203 pa_log_info("Transport %s acquired: fd %d", u->transport->path, u->stream_fd);
204
205 return 0;
206 }
207
208 /* Run from main thread */
209 static int add_source(struct userdata *u) {
210 pa_source_new_data data;
211
212 pa_assert(u->transport);
213
214 pa_source_new_data_init(&data);
215 data.module = u->module;
216 data.card = u->card;
217 data.driver = __FILE__;
218 data.name = pa_sprintf_malloc("bluez_source.%s", u->device->address);
219 data.namereg_fail = false;
220 pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
221 pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
222
223 connect_ports(u, &data, PA_DIRECTION_INPUT);
224
225 if (!u->transport_acquired)
226 switch (u->profile) {
227 case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
228 data.suspend_cause = PA_SUSPEND_USER;
229 break;
230 case PA_BLUETOOTH_PROFILE_A2DP_SINK:
231 case PA_BLUETOOTH_PROFILE_OFF:
232 pa_assert_not_reached();
233 break;
234 }
235
236 u->source = pa_source_new(u->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
237 pa_source_new_data_done(&data);
238 if (!u->source) {
239 pa_log_error("Failed to create source");
240 return -1;
241 }
242
243 u->source->userdata = u;
244
245 return 0;
246 }
247
248 /* Run from main thread */
249 static int add_sink(struct userdata *u) {
250 pa_sink_new_data data;
251
252 pa_assert(u->transport);
253
254 pa_sink_new_data_init(&data);
255 data.module = u->module;
256 data.card = u->card;
257 data.driver = __FILE__;
258 data.name = pa_sprintf_malloc("bluez_sink.%s", u->device->address);
259 data.namereg_fail = false;
260 pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
261 pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
262
263 connect_ports(u, &data, PA_DIRECTION_OUTPUT);
264
265 if (!u->transport_acquired)
266 switch (u->profile) {
267 case PA_BLUETOOTH_PROFILE_A2DP_SINK:
268 /* Profile switch should have failed */
269 case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
270 case PA_BLUETOOTH_PROFILE_OFF:
271 pa_assert_not_reached();
272 break;
273 }
274
275 u->sink = pa_sink_new(u->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
276 pa_sink_new_data_done(&data);
277 if (!u->sink) {
278 pa_log_error("Failed to create sink");
279 return -1;
280 }
281
282 u->sink->userdata = u;
283
284 return 0;
285 }
286
287 /* Run from main thread */
288 static void transport_config(struct userdata *u) {
289 sbc_info_t *sbc_info = &u->sbc_info;
290 a2dp_sbc_t *config;
291
292 pa_assert(u->transport);
293
294 u->sample_spec.format = PA_SAMPLE_S16LE;
295 config = (a2dp_sbc_t *) u->transport->config;
296
297 if (sbc_info->sbc_initialized)
298 sbc_reinit(&sbc_info->sbc, 0);
299 else
300 sbc_init(&sbc_info->sbc, 0);
301 sbc_info->sbc_initialized = true;
302
303 switch (config->frequency) {
304 case SBC_SAMPLING_FREQ_16000:
305 sbc_info->sbc.frequency = SBC_FREQ_16000;
306 u->sample_spec.rate = 16000U;
307 break;
308 case SBC_SAMPLING_FREQ_32000:
309 sbc_info->sbc.frequency = SBC_FREQ_32000;
310 u->sample_spec.rate = 32000U;
311 break;
312 case SBC_SAMPLING_FREQ_44100:
313 sbc_info->sbc.frequency = SBC_FREQ_44100;
314 u->sample_spec.rate = 44100U;
315 break;
316 case SBC_SAMPLING_FREQ_48000:
317 sbc_info->sbc.frequency = SBC_FREQ_48000;
318 u->sample_spec.rate = 48000U;
319 break;
320 default:
321 pa_assert_not_reached();
322 }
323
324 switch (config->channel_mode) {
325 case SBC_CHANNEL_MODE_MONO:
326 sbc_info->sbc.mode = SBC_MODE_MONO;
327 u->sample_spec.channels = 1;
328 break;
329 case SBC_CHANNEL_MODE_DUAL_CHANNEL:
330 sbc_info->sbc.mode = SBC_MODE_DUAL_CHANNEL;
331 u->sample_spec.channels = 2;
332 break;
333 case SBC_CHANNEL_MODE_STEREO:
334 sbc_info->sbc.mode = SBC_MODE_STEREO;
335 u->sample_spec.channels = 2;
336 break;
337 case SBC_CHANNEL_MODE_JOINT_STEREO:
338 sbc_info->sbc.mode = SBC_MODE_JOINT_STEREO;
339 u->sample_spec.channels = 2;
340 break;
341 default:
342 pa_assert_not_reached();
343 }
344
345 switch (config->allocation_method) {
346 case SBC_ALLOCATION_SNR:
347 sbc_info->sbc.allocation = SBC_AM_SNR;
348 break;
349 case SBC_ALLOCATION_LOUDNESS:
350 sbc_info->sbc.allocation = SBC_AM_LOUDNESS;
351 break;
352 default:
353 pa_assert_not_reached();
354 }
355
356 switch (config->subbands) {
357 case SBC_SUBBANDS_4:
358 sbc_info->sbc.subbands = SBC_SB_4;
359 break;
360 case SBC_SUBBANDS_8:
361 sbc_info->sbc.subbands = SBC_SB_8;
362 break;
363 default:
364 pa_assert_not_reached();
365 }
366
367 switch (config->block_length) {
368 case SBC_BLOCK_LENGTH_4:
369 sbc_info->sbc.blocks = SBC_BLK_4;
370 break;
371 case SBC_BLOCK_LENGTH_8:
372 sbc_info->sbc.blocks = SBC_BLK_8;
373 break;
374 case SBC_BLOCK_LENGTH_12:
375 sbc_info->sbc.blocks = SBC_BLK_12;
376 break;
377 case SBC_BLOCK_LENGTH_16:
378 sbc_info->sbc.blocks = SBC_BLK_16;
379 break;
380 default:
381 pa_assert_not_reached();
382 }
383
384 sbc_info->min_bitpool = config->min_bitpool;
385 sbc_info->max_bitpool = config->max_bitpool;
386
387 /* Set minimum bitpool for source to get the maximum possible block_size */
388 sbc_info->sbc.bitpool = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK ? sbc_info->max_bitpool : sbc_info->min_bitpool;
389 sbc_info->codesize = sbc_get_codesize(&sbc_info->sbc);
390 sbc_info->frame_length = sbc_get_frame_length(&sbc_info->sbc);
391
392 pa_log_info("SBC parameters: allocation=%u, subbands=%u, blocks=%u, bitpool=%u",
393 sbc_info->sbc.allocation, sbc_info->sbc.subbands, sbc_info->sbc.blocks, sbc_info->sbc.bitpool);
394 }
395
396 /* Run from main thread */
397 static int setup_transport(struct userdata *u) {
398 pa_bluetooth_transport *t;
399
400 pa_assert(u);
401 pa_assert(!u->transport);
402 pa_assert(u->profile != PA_BLUETOOTH_PROFILE_OFF);
403
404 /* check if profile has a transport */
405 t = u->device->transports[u->profile];
406 if (!t || t->state <= PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED) {
407 pa_log_warn("Profile has no transport");
408 return -1;
409 }
410
411 u->transport = t;
412
413 if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
414 transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
415 else if (transport_acquire(u, false) < 0)
416 return -1; /* We need to fail here until the interactions with module-suspend-on-idle and alike get improved */
417
418 transport_config(u);
419
420 return 0;
421 }
422
423 /* Run from main thread */
424 static int init_profile(struct userdata *u) {
425 int r = 0;
426 pa_assert(u);
427 pa_assert(u->profile != PA_BLUETOOTH_PROFILE_OFF);
428
429 if (setup_transport(u) < 0)
430 return -1;
431
432 pa_assert(u->transport);
433
434 if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK)
435 if (add_sink(u) < 0)
436 r = -1;
437
438 if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
439 if (add_source(u) < 0)
440 r = -1;
441
442 return r;
443 }
444
445 /* Run from main thread */
446 static char *cleanup_name(const char *name) {
447 char *t, *s, *d;
448 bool space = false;
449
450 pa_assert(name);
451
452 while ((*name >= 1 && *name <= 32) || *name >= 127)
453 name++;
454
455 t = pa_xstrdup(name);
456
457 for (s = d = t; *s; s++) {
458
459 if (*s <= 32 || *s >= 127 || *s == '_') {
460 space = true;
461 continue;
462 }
463
464 if (space) {
465 *(d++) = ' ';
466 space = false;
467 }
468
469 *(d++) = *s;
470 }
471
472 *d = 0;
473
474 return t;
475 }
476
477 /* Run from main thread */
478 static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
479 static const pa_direction_t profile_direction[] = {
480 [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
481 [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
482 [PA_BLUETOOTH_PROFILE_OFF] = 0
483 };
484
485 return profile_direction[p];
486 }
487
488 /* Run from main thread */
489 static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
490 pa_available_t result = PA_AVAILABLE_NO;
491 unsigned i;
492
493 pa_assert(u);
494 pa_assert(u->device);
495
496 for (i = 0; i < PA_BLUETOOTH_PROFILE_COUNT; i++) {
497 pa_bluetooth_transport *transport;
498
499 if (!(get_profile_direction(i) & direction))
500 continue;
501
502 if (!(transport = u->device->transports[i]))
503 continue;
504
505 switch(transport->state) {
506 case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
507 continue;
508
509 case PA_BLUETOOTH_TRANSPORT_STATE_IDLE:
510 if (result == PA_AVAILABLE_NO)
511 result = PA_AVAILABLE_UNKNOWN;
512
513 break;
514
515 case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
516 return PA_AVAILABLE_YES;
517 }
518 }
519
520 return result;
521 }
522
523 /* Run from main thread */
524 static pa_available_t transport_state_to_availability(pa_bluetooth_transport_state_t state) {
525 switch (state) {
526 case PA_BLUETOOTH_TRANSPORT_STATE_DISCONNECTED:
527 return PA_AVAILABLE_NO;
528 case PA_BLUETOOTH_TRANSPORT_STATE_PLAYING:
529 return PA_AVAILABLE_YES;
530 default:
531 return PA_AVAILABLE_UNKNOWN;
532 }
533 }
534
535 /* Run from main thread */
536 static void create_card_ports(struct userdata *u, pa_hashmap *ports) {
537 pa_device_port *port;
538 pa_device_port_new_data port_data;
539 const char *name_prefix, *input_description, *output_description;
540
541 pa_assert(u);
542 pa_assert(ports);
543 pa_assert(u->device);
544
545 name_prefix = "unknown";
546 input_description = _("Bluetooth Input");
547 output_description = _("Bluetooth Output");
548
549 switch (form_factor_from_class(u->device->class_of_device)) {
550 case PA_BLUETOOTH_FORM_FACTOR_HEADSET:
551 name_prefix = "headset";
552 input_description = output_description = _("Headset");
553 break;
554
555 case PA_BLUETOOTH_FORM_FACTOR_HANDSFREE:
556 name_prefix = "handsfree";
557 input_description = output_description = _("Handsfree");
558 break;
559
560 case PA_BLUETOOTH_FORM_FACTOR_MICROPHONE:
561 name_prefix = "microphone";
562 input_description = _("Microphone");
563 output_description = _("Bluetooth Output");
564 break;
565
566 case PA_BLUETOOTH_FORM_FACTOR_SPEAKER:
567 name_prefix = "speaker";
568 input_description = _("Bluetooth Input");
569 output_description = _("Speaker");
570 break;
571
572 case PA_BLUETOOTH_FORM_FACTOR_HEADPHONE:
573 name_prefix = "headphone";
574 input_description = _("Bluetooth Input");
575 output_description = _("Headphone");
576 break;
577
578 case PA_BLUETOOTH_FORM_FACTOR_PORTABLE:
579 name_prefix = "portable";
580 input_description = output_description = _("Portable");
581 break;
582
583 case PA_BLUETOOTH_FORM_FACTOR_CAR:
584 name_prefix = "car";
585 input_description = output_description = _("Car");
586 break;
587
588 case PA_BLUETOOTH_FORM_FACTOR_HIFI:
589 name_prefix = "hifi";
590 input_description = output_description = _("HiFi");
591 break;
592
593 case PA_BLUETOOTH_FORM_FACTOR_PHONE:
594 name_prefix = "phone";
595 input_description = output_description = _("Phone");
596 break;
597
598 case PA_BLUETOOTH_FORM_FACTOR_UNKNOWN:
599 name_prefix = "unknown";
600 input_description = _("Bluetooth Input");
601 output_description = _("Bluetooth Output");
602 break;
603 }
604
605 u->output_port_name = pa_sprintf_malloc("%s-output", name_prefix);
606 pa_device_port_new_data_init(&port_data);
607 pa_device_port_new_data_set_name(&port_data, u->output_port_name);
608 pa_device_port_new_data_set_description(&port_data, output_description);
609 pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_OUTPUT);
610 pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_OUTPUT));
611 pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
612 pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
613 pa_device_port_new_data_done(&port_data);
614
615 u->input_port_name = pa_sprintf_malloc("%s-input", name_prefix);
616 pa_device_port_new_data_init(&port_data);
617 pa_device_port_new_data_set_name(&port_data, u->input_port_name);
618 pa_device_port_new_data_set_description(&port_data, input_description);
619 pa_device_port_new_data_set_direction(&port_data, PA_DIRECTION_INPUT);
620 pa_device_port_new_data_set_available(&port_data, get_port_availability(u, PA_DIRECTION_INPUT));
621 pa_assert_se(port = pa_device_port_new(u->core, &port_data, 0));
622 pa_assert_se(pa_hashmap_put(ports, port->name, port) >= 0);
623 pa_device_port_new_data_done(&port_data);
624 }
625
626 /* Run from main thread */
627 static pa_card_profile *create_card_profile(struct userdata *u, const char *uuid, pa_hashmap *ports) {
628 pa_device_port *input_port, *output_port;
629 pa_card_profile *cp = NULL;
630 pa_bluetooth_profile_t *p;
631
632 pa_assert(u->input_port_name);
633 pa_assert(u->output_port_name);
634 pa_assert_se(input_port = pa_hashmap_get(ports, u->input_port_name));
635 pa_assert_se(output_port = pa_hashmap_get(ports, u->output_port_name));
636
637 if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK)) {
638 /* TODO: Change this profile's name to a2dp_sink, to reflect the remote
639 * device's role and be consistent with the a2dp source profile */
640 cp = pa_card_profile_new("a2dp", _("High Fidelity Playback (A2DP Sink)"), sizeof(pa_bluetooth_profile_t));
641 cp->priority = 10;
642 cp->n_sinks = 1;
643 cp->n_sources = 0;
644 cp->max_sink_channels = 2;
645 cp->max_source_channels = 0;
646 pa_hashmap_put(output_port->profiles, cp->name, cp);
647
648 p = PA_CARD_PROFILE_DATA(cp);
649 *p = PA_BLUETOOTH_PROFILE_A2DP_SINK;
650 } else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE)) {
651 cp = pa_card_profile_new("a2dp_source", _("High Fidelity Capture (A2DP Source)"), sizeof(pa_bluetooth_profile_t));
652 cp->priority = 10;
653 cp->n_sinks = 0;
654 cp->n_sources = 1;
655 cp->max_sink_channels = 0;
656 cp->max_source_channels = 2;
657 pa_hashmap_put(input_port->profiles, cp->name, cp);
658
659 p = PA_CARD_PROFILE_DATA(cp);
660 *p = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
661 }
662
663 if (cp && u->device->transports[*p])
664 cp->available = transport_state_to_availability(u->device->transports[*p]->state);
665
666 return cp;
667 }
668
669 /* Run from main thread */
670 static int add_card(struct userdata *u) {
671 const pa_bluetooth_device *d;
672 pa_card_new_data data;
673 char *alias;
674 pa_bluetooth_form_factor_t ff;
675 pa_card_profile *cp;
676 pa_bluetooth_profile_t *p;
677 const char *uuid;
678 void *state;
679
680 pa_assert(u);
681 pa_assert(u->device);
682
683 d = u->device;
684
685 pa_card_new_data_init(&data);
686 data.driver = __FILE__;
687 data.module = u->module;
688
689 alias = cleanup_name(d->alias);
690 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, alias);
691 pa_xfree(alias);
692
693 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, d->address);
694 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
695 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
696 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
697
698 if ((ff = form_factor_from_class(d->class_of_device)) != PA_BLUETOOTH_FORM_FACTOR_UNKNOWN)
699 pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, form_factor_to_string(ff));
700
701 pa_proplist_sets(data.proplist, "bluez.path", d->path);
702 pa_proplist_setf(data.proplist, "bluez.class", "0x%06x", d->class_of_device);
703 pa_proplist_sets(data.proplist, "bluez.alias", d->alias);
704 data.name = pa_sprintf_malloc("bluez_card.%s", d->address);
705 data.namereg_fail = false;
706
707 create_card_ports(u, data.ports);
708
709 PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
710 cp = create_card_profile(u, uuid, data.ports);
711
712 if (!cp)
713 continue;
714
715 if (pa_hashmap_get(data.profiles, cp->name)) {
716 pa_card_profile_free(cp);
717 continue;
718 }
719
720 pa_hashmap_put(data.profiles, cp->name, cp);
721 }
722
723 pa_assert(!pa_hashmap_isempty(data.profiles));
724
725 cp = pa_card_profile_new("off", _("Off"), sizeof(pa_bluetooth_profile_t));
726 cp->available = PA_AVAILABLE_YES;
727 p = PA_CARD_PROFILE_DATA(cp);
728 *p = PA_BLUETOOTH_PROFILE_OFF;
729 pa_hashmap_put(data.profiles, cp->name, cp);
730
731 u->card = pa_card_new(u->core, &data);
732 pa_card_new_data_done(&data);
733 if (!u->card) {
734 pa_log("Failed to allocate card.");
735 return -1;
736 }
737
738 u->card->userdata = u;
739
740 p = PA_CARD_PROFILE_DATA(u->card->active_profile);
741 u->profile = *p;
742
743 return 0;
744 }
745
746 /* Run from main thread */
747 static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
748 pa_assert(d);
749 pa_assert(u);
750
751 if (d != u->device || pa_bluetooth_device_any_transport_connected(d))
752 return PA_HOOK_OK;
753
754 pa_log_debug("Unloading module for device %s", d->path);
755 pa_module_unload(u->core, u->module, true);
756
757 return PA_HOOK_OK;
758 }
759
760 int pa__init(pa_module* m) {
761 struct userdata *u;
762 const char *path;
763 pa_modargs *ma;
764
765 pa_assert(m);
766
767 m->userdata = u = pa_xnew0(struct userdata, 1);
768 u->module = m;
769 u->core = m->core;
770
771 if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
772 pa_log_error("Failed to parse module arguments");
773 goto fail;
774 }
775
776 if (!(path = pa_modargs_get_value(ma, "path", NULL))) {
777 pa_log_error("Failed to get device path from module arguments");
778 goto fail;
779 }
780
781 if (!(u->discovery = pa_bluetooth_discovery_get(m->core)))
782 goto fail;
783
784 if (!(u->device = pa_bluetooth_discovery_get_device_by_path(u->discovery, path))) {
785 pa_log_error("%s is unknown", path);
786 goto fail;
787 }
788
789 pa_modargs_free(ma);
790
791 u->device_connection_changed_slot =
792 pa_hook_connect(pa_bluetooth_discovery_hook(u->discovery, PA_BLUETOOTH_HOOK_DEVICE_CONNECTION_CHANGED),
793 PA_HOOK_NORMAL, (pa_hook_cb_t) device_connection_changed_cb, u);
794
795 if (add_card(u) < 0)
796 goto fail;
797
798 if (u->profile != PA_BLUETOOTH_PROFILE_OFF)
799 if (init_profile(u) < 0)
800 goto off;
801
802 return 0;
803
804 off:
805
806 pa_assert_se(pa_card_set_profile(u->card, "off", false) >= 0);
807
808 return 0;
809
810 fail:
811
812 if (ma)
813 pa_modargs_free(ma);
814
815 pa__done(m);
816
817 return -1;
818 }
819
820 void pa__done(pa_module *m) {
821 struct userdata *u;
822
823 pa_assert(m);
824
825 if (!(u = m->userdata))
826 return;
827
828 if (u->device_connection_changed_slot)
829 pa_hook_slot_free(u->device_connection_changed_slot);
830
831 if (u->sbc_info.sbc_initialized)
832 sbc_finish(&u->sbc_info.sbc);
833
834 if (u->card)
835 pa_card_free(u->card);
836
837 if (u->discovery)
838 pa_bluetooth_discovery_unref(u->discovery);
839
840 pa_xfree(u->output_port_name);
841 pa_xfree(u->input_port_name);
842
843 pa_xfree(u);
844 }