1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2006-2010 Nokia Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdlib.h>
30 #include <errno.h>
31
32 #include <dbus/dbus.h>
33 #include <glib.h>
34
35 #include <bluetooth/bluetooth.h>
36 #include <bluetooth/sdp.h>
37 #include <bluetooth/sdp_lib.h>
38
39 #include "log.h"
40 #include "device.h"
41 #include "manager.h"
42 #include "avdtp.h"
43 #include "sink.h"
44 #include "source.h"
45 #include "unix.h"
46 #include "a2dp.h"
47 #include "sdpd.h"
48
49 /* The duration that streams without users are allowed to stay in
50 * STREAMING state. */
51 #define SUSPEND_TIMEOUT 5
52 #define RECONFIGURE_TIMEOUT 500
53
54 #ifndef MIN
55 # define MIN(x, y) ((x) < (y) ? (x) : (y))
56 #endif
57
58 #ifndef MAX
59 # define MAX(x, y) ((x) > (y) ? (x) : (y))
60 #endif
61
62 struct a2dp_sep {
63 uint8_t type;
64 uint8_t codec;
65 struct avdtp_local_sep *sep;
66 struct avdtp *session;
67 struct avdtp_stream *stream;
68 guint suspend_timer;
69 gboolean delay_reporting;
70 gboolean locked;
71 gboolean suspending;
72 gboolean starting;
73 };
74
75 struct a2dp_setup_cb {
76 a2dp_config_cb_t config_cb;
77 a2dp_stream_cb_t resume_cb;
78 a2dp_stream_cb_t suspend_cb;
79 void *user_data;
80 unsigned int id;
81 };
82
83 struct a2dp_setup {
84 struct audio_device *dev;
85 struct avdtp *session;
86 struct a2dp_sep *sep;
87 struct avdtp_stream *stream;
88 struct avdtp_error *err;
89 GSList *client_caps;
90 gboolean reconfigure;
91 gboolean start;
92 GSList *cb;
93 int ref;
94 };
95
96 static DBusConnection *connection = NULL;
97
98 struct a2dp_server {
99 bdaddr_t src;
100 GSList *sinks;
101 GSList *sources;
102 uint32_t source_record_id;
103 uint32_t sink_record_id;
104 uint16_t version;
105 };
106
107 static GSList *servers = NULL;
108 static GSList *setups = NULL;
109 static unsigned int cb_id = 0;
110
setup_ref(struct a2dp_setup * setup)111 static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
112 {
113 setup->ref++;
114
115 DBG("%p: ref=%d", setup, setup->ref);
116
117 return setup;
118 }
119
setup_free(struct a2dp_setup * s)120 static void setup_free(struct a2dp_setup *s)
121 {
122 DBG("%p", s);
123 setups = g_slist_remove(setups, s);
124 if (s->session)
125 avdtp_unref(s->session);
126 g_slist_foreach(s->cb, (GFunc) g_free, NULL);
127 g_slist_free(s->cb);
128 g_free(s);
129 }
130
setup_unref(struct a2dp_setup * setup)131 static void setup_unref(struct a2dp_setup *setup)
132 {
133 setup->ref--;
134
135 DBG("%p: ref=%d", setup, setup->ref);
136
137 if (setup->ref <= 0)
138 setup_free(setup);
139 }
140
a2dp_get_dev(struct avdtp * session)141 static struct audio_device *a2dp_get_dev(struct avdtp *session)
142 {
143 bdaddr_t src, dst;
144
145 avdtp_get_peers(session, &src, &dst);
146
147 return manager_find_device(NULL, &src, &dst, NULL, FALSE);
148 }
149
finalize_config(struct a2dp_setup * s)150 static gboolean finalize_config(struct a2dp_setup *s)
151 {
152 GSList *l;
153
154 setup_ref(s);
155 for (l = s->cb; l != NULL; l = l->next) {
156 struct a2dp_setup_cb *cb = l->data;
157 struct avdtp_stream *stream = s->err ? NULL : s->stream;
158
159 if (!cb->config_cb)
160 continue;
161
162 cb->config_cb(s->session, s->sep, stream, s->err,
163 cb->user_data);
164 cb->config_cb = NULL;
165 setup_unref(s);
166 }
167
168 setup_unref(s);
169 return FALSE;
170 }
171
finalize_config_errno(struct a2dp_setup * s,int err)172 static gboolean finalize_config_errno(struct a2dp_setup *s, int err)
173 {
174 struct avdtp_error avdtp_err;
175
176 avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
177 s->err = err ? &avdtp_err : NULL;
178
179 return finalize_config(s);
180 }
181
finalize_resume(struct a2dp_setup * s)182 static gboolean finalize_resume(struct a2dp_setup *s)
183 {
184 GSList *l;
185
186 setup_ref(s);
187 for (l = s->cb; l != NULL; l = l->next) {
188 struct a2dp_setup_cb *cb = l->data;
189
190 if (cb && cb->resume_cb) {
191 cb->resume_cb(s->session, s->err, cb->user_data);
192 cb->resume_cb = NULL;
193 setup_unref(s);
194 }
195 }
196
197 setup_unref(s);
198 return FALSE;
199 }
200
finalize_suspend(struct a2dp_setup * s)201 static gboolean finalize_suspend(struct a2dp_setup *s)
202 {
203 GSList *l;
204
205 setup_ref(s);
206 for (l = s->cb; l != NULL; l = l->next) {
207 struct a2dp_setup_cb *cb = l->data;
208
209 if (cb->suspend_cb) {
210 cb->suspend_cb(s->session, s->err, cb->user_data);
211 cb->suspend_cb = NULL;
212 setup_unref(s);
213 }
214 }
215
216 setup_unref(s);
217 return FALSE;
218 }
219
finalize_suspend_errno(struct a2dp_setup * s,int err)220 static gboolean finalize_suspend_errno(struct a2dp_setup *s, int err)
221 {
222 struct avdtp_error avdtp_err;
223
224 avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
225 s->err = err ? &avdtp_err : NULL;
226
227 return finalize_suspend(s);
228 }
229
find_setup_by_session(struct avdtp * session)230 static struct a2dp_setup *find_setup_by_session(struct avdtp *session)
231 {
232 GSList *l;
233
234 for (l = setups; l != NULL; l = l->next) {
235 struct a2dp_setup *setup = l->data;
236
237 if (setup->session == session)
238 return setup;
239 }
240
241 return NULL;
242 }
243
find_setup_by_dev(struct audio_device * dev)244 static struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
245 {
246 GSList *l;
247
248 for (l = setups; l != NULL; l = l->next) {
249 struct a2dp_setup *setup = l->data;
250
251 if (setup->dev == dev)
252 return setup;
253 }
254
255 return NULL;
256 }
257
stream_state_changed(struct avdtp_stream * stream,avdtp_state_t old_state,avdtp_state_t new_state,struct avdtp_error * err,void * user_data)258 static void stream_state_changed(struct avdtp_stream *stream,
259 avdtp_state_t old_state,
260 avdtp_state_t new_state,
261 struct avdtp_error *err,
262 void *user_data)
263 {
264 struct a2dp_sep *sep = user_data;
265
266 if (new_state != AVDTP_STATE_IDLE)
267 return;
268
269 if (sep->suspend_timer) {
270 g_source_remove(sep->suspend_timer);
271 sep->suspend_timer = 0;
272 }
273
274 if (sep->session) {
275 avdtp_unref(sep->session);
276 sep->session = NULL;
277 }
278
279 sep->stream = NULL;
280
281 }
282
sbc_setconf_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,GSList * caps,uint8_t * err,uint8_t * category,void * user_data)283 static gboolean sbc_setconf_ind(struct avdtp *session,
284 struct avdtp_local_sep *sep,
285 struct avdtp_stream *stream,
286 GSList *caps, uint8_t *err,
287 uint8_t *category, void *user_data)
288 {
289 struct a2dp_sep *a2dp_sep = user_data;
290 struct audio_device *dev;
291
292 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
293 DBG("Sink %p: Set_Configuration_Ind", sep);
294 else
295 DBG("Source %p: Set_Configuration_Ind", sep);
296
297 dev = a2dp_get_dev(session);
298 if (!dev) {
299 *err = AVDTP_UNSUPPORTED_CONFIGURATION;
300 *category = 0x00;
301 return FALSE;
302 }
303
304 /* Check valid settings */
305 for (; caps != NULL; caps = g_slist_next(caps)) {
306 struct avdtp_service_capability *cap = caps->data;
307 struct avdtp_media_codec_capability *codec_cap;
308 struct sbc_codec_cap *sbc_cap;
309
310 if (cap->category == AVDTP_DELAY_REPORTING &&
311 !a2dp_sep->delay_reporting) {
312 *err = AVDTP_UNSUPPORTED_CONFIGURATION;
313 *category = AVDTP_DELAY_REPORTING;
314 return FALSE;
315 }
316
317 if (cap->category != AVDTP_MEDIA_CODEC)
318 continue;
319
320 if (cap->length < sizeof(struct sbc_codec_cap))
321 continue;
322
323 codec_cap = (void *) cap->data;
324
325 if (codec_cap->media_codec_type != A2DP_CODEC_SBC)
326 continue;
327
328 sbc_cap = (void *) codec_cap;
329
330 if (sbc_cap->min_bitpool < MIN_BITPOOL ||
331 sbc_cap->max_bitpool > MAX_BITPOOL) {
332 *err = AVDTP_UNSUPPORTED_CONFIGURATION;
333 *category = AVDTP_MEDIA_CODEC;
334 return FALSE;
335 }
336 }
337
338 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
339 a2dp_sep->stream = stream;
340
341 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
342 sink_new_stream(dev, session, stream);
343
344 return TRUE;
345 }
346
sbc_getcap_ind(struct avdtp * session,struct avdtp_local_sep * sep,gboolean get_all,GSList ** caps,uint8_t * err,void * user_data)347 static gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
348 gboolean get_all, GSList **caps, uint8_t *err,
349 void *user_data)
350 {
351 struct a2dp_sep *a2dp_sep = user_data;
352 struct avdtp_service_capability *media_transport, *media_codec;
353 struct sbc_codec_cap sbc_cap;
354
355 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
356 DBG("Sink %p: Get_Capability_Ind", sep);
357 else
358 DBG("Source %p: Get_Capability_Ind", sep);
359
360 *caps = NULL;
361
362 media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
363 NULL, 0);
364
365 *caps = g_slist_append(*caps, media_transport);
366
367 memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
368
369 sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
370 sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
371
372 #ifdef ANDROID
373 sbc_cap.frequency = SBC_SAMPLING_FREQ_44100;
374 #else
375 sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
376 SBC_SAMPLING_FREQ_44100 |
377 SBC_SAMPLING_FREQ_32000 |
378 SBC_SAMPLING_FREQ_16000 );
379 #endif
380
381 sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
382 SBC_CHANNEL_MODE_STEREO |
383 SBC_CHANNEL_MODE_DUAL_CHANNEL |
384 SBC_CHANNEL_MODE_MONO );
385
386 sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
387 SBC_BLOCK_LENGTH_12 |
388 SBC_BLOCK_LENGTH_8 |
389 SBC_BLOCK_LENGTH_4 );
390
391 sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
392
393 sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
394 SBC_ALLOCATION_SNR );
395
396 sbc_cap.min_bitpool = MIN_BITPOOL;
397 sbc_cap.max_bitpool = MAX_BITPOOL;
398
399 media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
400 sizeof(sbc_cap));
401
402 *caps = g_slist_append(*caps, media_codec);
403
404 if (get_all) {
405 struct avdtp_service_capability *delay_reporting;
406 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
407 NULL, 0);
408 *caps = g_slist_append(*caps, delay_reporting);
409 }
410
411 return TRUE;
412 }
413
mpeg_setconf_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,GSList * caps,uint8_t * err,uint8_t * category,void * user_data)414 static gboolean mpeg_setconf_ind(struct avdtp *session,
415 struct avdtp_local_sep *sep,
416 struct avdtp_stream *stream,
417 GSList *caps, uint8_t *err,
418 uint8_t *category, void *user_data)
419 {
420 struct a2dp_sep *a2dp_sep = user_data;
421 struct audio_device *dev;
422
423 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
424 DBG("Sink %p: Set_Configuration_Ind", sep);
425 else
426 DBG("Source %p: Set_Configuration_Ind", sep);
427
428 dev = a2dp_get_dev(session);
429 if (!dev) {
430 *err = AVDTP_UNSUPPORTED_CONFIGURATION;
431 *category = 0x00;
432 return FALSE;
433 }
434
435 for (; caps != NULL; caps = g_slist_next(caps)) {
436 struct avdtp_service_capability *cap = caps->data;
437
438 if (cap->category == AVDTP_DELAY_REPORTING &&
439 !a2dp_sep->delay_reporting) {
440 *err = AVDTP_UNSUPPORTED_CONFIGURATION;
441 *category = AVDTP_DELAY_REPORTING;
442 return FALSE;
443 }
444 }
445
446 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
447 a2dp_sep->stream = stream;
448
449 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
450 sink_new_stream(dev, session, stream);
451
452 return TRUE;
453 }
454
mpeg_getcap_ind(struct avdtp * session,struct avdtp_local_sep * sep,gboolean get_all,GSList ** caps,uint8_t * err,void * user_data)455 static gboolean mpeg_getcap_ind(struct avdtp *session,
456 struct avdtp_local_sep *sep,
457 gboolean get_all,
458 GSList **caps, uint8_t *err, void *user_data)
459 {
460 struct a2dp_sep *a2dp_sep = user_data;
461 struct avdtp_service_capability *media_transport, *media_codec;
462 struct mpeg_codec_cap mpeg_cap;
463
464 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
465 DBG("Sink %p: Get_Capability_Ind", sep);
466 else
467 DBG("Source %p: Get_Capability_Ind", sep);
468
469 *caps = NULL;
470
471 media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
472 NULL, 0);
473
474 *caps = g_slist_append(*caps, media_transport);
475
476 memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
477
478 mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
479 mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
480
481 mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
482 MPEG_SAMPLING_FREQ_44100 |
483 MPEG_SAMPLING_FREQ_32000 |
484 MPEG_SAMPLING_FREQ_24000 |
485 MPEG_SAMPLING_FREQ_22050 |
486 MPEG_SAMPLING_FREQ_16000 );
487
488 mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
489 MPEG_CHANNEL_MODE_STEREO |
490 MPEG_CHANNEL_MODE_DUAL_CHANNEL |
491 MPEG_CHANNEL_MODE_MONO );
492
493 mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
494
495 mpeg_cap.bitrate = 0xFFFF;
496
497 media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
498 sizeof(mpeg_cap));
499
500 *caps = g_slist_append(*caps, media_codec);
501
502 if (get_all) {
503 struct avdtp_service_capability *delay_reporting;
504 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
505 NULL, 0);
506 *caps = g_slist_append(*caps, delay_reporting);
507 }
508
509 return TRUE;
510 }
511
setconf_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)512 static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
513 struct avdtp_stream *stream,
514 struct avdtp_error *err, void *user_data)
515 {
516 struct a2dp_sep *a2dp_sep = user_data;
517 struct a2dp_setup *setup;
518 struct audio_device *dev;
519 int ret;
520
521 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
522 DBG("Sink %p: Set_Configuration_Cfm", sep);
523 else
524 DBG("Source %p: Set_Configuration_Cfm", sep);
525
526 setup = find_setup_by_session(session);
527
528 if (err) {
529 if (setup) {
530 setup->err = err;
531 finalize_config(setup);
532 }
533 return;
534 }
535
536 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
537 a2dp_sep->stream = stream;
538
539 if (!setup)
540 return;
541
542 dev = a2dp_get_dev(session);
543
544 /* Notify D-Bus interface of the new stream */
545 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
546 sink_new_stream(dev, session, setup->stream);
547 else
548 source_new_stream(dev, session, setup->stream);
549
550 ret = avdtp_open(session, stream);
551 if (ret < 0) {
552 error("Error on avdtp_open %s (%d)", strerror(-ret), -ret);
553 setup->stream = NULL;
554 finalize_config_errno(setup, ret);
555 }
556 }
557
getconf_ind(struct avdtp * session,struct avdtp_local_sep * sep,uint8_t * err,void * user_data)558 static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
559 uint8_t *err, void *user_data)
560 {
561 struct a2dp_sep *a2dp_sep = user_data;
562
563 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
564 DBG("Sink %p: Get_Configuration_Ind", sep);
565 else
566 DBG("Source %p: Get_Configuration_Ind", sep);
567 return TRUE;
568 }
569
getconf_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)570 static void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
571 struct avdtp_stream *stream, struct avdtp_error *err,
572 void *user_data)
573 {
574 struct a2dp_sep *a2dp_sep = user_data;
575
576 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
577 DBG("Sink %p: Set_Configuration_Cfm", sep);
578 else
579 DBG("Source %p: Set_Configuration_Cfm", sep);
580 }
581
open_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,uint8_t * err,void * user_data)582 static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
583 struct avdtp_stream *stream, uint8_t *err,
584 void *user_data)
585 {
586 struct a2dp_sep *a2dp_sep = user_data;
587
588 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
589 DBG("Sink %p: Open_Ind", sep);
590 else
591 DBG("Source %p: Open_Ind", sep);
592 return TRUE;
593 }
594
open_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)595 static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
596 struct avdtp_stream *stream, struct avdtp_error *err,
597 void *user_data)
598 {
599 struct a2dp_sep *a2dp_sep = user_data;
600 struct a2dp_setup *setup;
601
602 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
603 DBG("Sink %p: Open_Cfm", sep);
604 else
605 DBG("Source %p: Open_Cfm", sep);
606
607 setup = find_setup_by_session(session);
608 if (!setup)
609 return;
610
611 if (setup->reconfigure)
612 setup->reconfigure = FALSE;
613
614 if (err) {
615 setup->stream = NULL;
616 setup->err = err;
617 }
618
619 finalize_config(setup);
620 }
621
suspend_timeout(struct a2dp_sep * sep)622 static gboolean suspend_timeout(struct a2dp_sep *sep)
623 {
624 if (avdtp_suspend(sep->session, sep->stream) == 0)
625 sep->suspending = TRUE;
626
627 sep->suspend_timer = 0;
628
629 avdtp_unref(sep->session);
630 sep->session = NULL;
631
632 return FALSE;
633 }
634
start_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,uint8_t * err,void * user_data)635 static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
636 struct avdtp_stream *stream, uint8_t *err,
637 void *user_data)
638 {
639 struct a2dp_sep *a2dp_sep = user_data;
640 struct a2dp_setup *setup;
641
642 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
643 DBG("Sink %p: Start_Ind", sep);
644 else
645 DBG("Source %p: Start_Ind", sep);
646
647 setup = find_setup_by_session(session);
648 if (setup)
649 finalize_resume(setup);
650
651 if (!a2dp_sep->locked) {
652 a2dp_sep->session = avdtp_ref(session);
653 a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
654 (GSourceFunc) suspend_timeout,
655 a2dp_sep);
656 }
657
658 return TRUE;
659 }
660
start_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)661 static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
662 struct avdtp_stream *stream, struct avdtp_error *err,
663 void *user_data)
664 {
665 struct a2dp_sep *a2dp_sep = user_data;
666 struct a2dp_setup *setup;
667
668 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
669 DBG("Sink %p: Start_Cfm", sep);
670 else
671 DBG("Source %p: Start_Cfm", sep);
672
673 setup = find_setup_by_session(session);
674 if (!setup)
675 return;
676
677 if (err) {
678 setup->stream = NULL;
679 setup->err = err;
680 }
681
682 finalize_resume(setup);
683 }
684
suspend_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,uint8_t * err,void * user_data)685 static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
686 struct avdtp_stream *stream, uint8_t *err,
687 void *user_data)
688 {
689 struct a2dp_sep *a2dp_sep = user_data;
690
691 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
692 DBG("Sink %p: Suspend_Ind", sep);
693 else
694 DBG("Source %p: Suspend_Ind", sep);
695
696 if (a2dp_sep->suspend_timer) {
697 g_source_remove(a2dp_sep->suspend_timer);
698 a2dp_sep->suspend_timer = 0;
699 avdtp_unref(a2dp_sep->session);
700 a2dp_sep->session = NULL;
701 }
702
703 return TRUE;
704 }
705
suspend_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)706 static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
707 struct avdtp_stream *stream, struct avdtp_error *err,
708 void *user_data)
709 {
710 struct a2dp_sep *a2dp_sep = user_data;
711 struct a2dp_setup *setup;
712 gboolean start;
713
714 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
715 DBG("Sink %p: Suspend_Cfm", sep);
716 else
717 DBG("Source %p: Suspend_Cfm", sep);
718
719 a2dp_sep->suspending = FALSE;
720
721 setup = find_setup_by_session(session);
722 if (!setup)
723 return;
724
725 start = setup->start;
726 setup->start = FALSE;
727
728 if (err) {
729 setup->stream = NULL;
730 setup->err = err;
731 finalize_suspend(setup);
732 }
733 else
734 finalize_suspend_errno(setup, 0);
735
736 if (!start)
737 return;
738
739 if (err) {
740 setup->err = err;
741 finalize_suspend(setup);
742 } else if (avdtp_start(session, a2dp_sep->stream) < 0) {
743 struct avdtp_error start_err;
744 error("avdtp_start failed");
745 avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO);
746 setup->err = err;
747 finalize_suspend(setup);
748 }
749 }
750
close_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,uint8_t * err,void * user_data)751 static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
752 struct avdtp_stream *stream, uint8_t *err,
753 void *user_data)
754 {
755 struct a2dp_sep *a2dp_sep = user_data;
756
757 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
758 DBG("Sink %p: Close_Ind", sep);
759 else
760 DBG("Source %p: Close_Ind", sep);
761
762 return TRUE;
763 }
764
a2dp_reconfigure(gpointer data)765 static gboolean a2dp_reconfigure(gpointer data)
766 {
767 struct a2dp_setup *setup = data;
768 struct avdtp_local_sep *lsep;
769 struct avdtp_remote_sep *rsep;
770 struct avdtp_service_capability *cap;
771 struct avdtp_media_codec_capability *codec_cap = NULL;
772 GSList *l;
773 int posix_err;
774
775 for (l = setup->client_caps; l != NULL; l = l->next) {
776 cap = l->data;
777
778 if (cap->category != AVDTP_MEDIA_CODEC)
779 continue;
780
781 codec_cap = (void *) cap->data;
782 break;
783 }
784
785 if (!codec_cap) {
786 error("Cannot find capabilities to reconfigure");
787 posix_err = -EINVAL;
788 goto failed;
789 }
790
791 posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK,
792 codec_cap->media_type,
793 codec_cap->media_codec_type,
794 &lsep, &rsep);
795 if (posix_err < 0) {
796 error("No matching ACP and INT SEPs found");
797 goto failed;
798 }
799
800 posix_err = avdtp_set_configuration(setup->session, rsep, lsep,
801 setup->client_caps,
802 &setup->stream);
803 if (posix_err < 0) {
804 error("avdtp_set_configuration: %s", strerror(-posix_err));
805 goto failed;
806 }
807
808 return FALSE;
809
810 failed:
811 finalize_config_errno(setup, posix_err);
812 return FALSE;
813 }
814
close_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)815 static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
816 struct avdtp_stream *stream, struct avdtp_error *err,
817 void *user_data)
818 {
819 struct a2dp_sep *a2dp_sep = user_data;
820 struct a2dp_setup *setup;
821
822 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
823 DBG("Sink %p: Close_Cfm", sep);
824 else
825 DBG("Source %p: Close_Cfm", sep);
826
827 setup = find_setup_by_session(session);
828 if (!setup)
829 return;
830
831 if (err) {
832 setup->stream = NULL;
833 setup->err = err;
834 finalize_config(setup);
835 return;
836 }
837
838 if (setup->reconfigure)
839 g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
840 }
841
abort_ind(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,uint8_t * err,void * user_data)842 static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
843 struct avdtp_stream *stream, uint8_t *err,
844 void *user_data)
845 {
846 struct a2dp_sep *a2dp_sep = user_data;
847
848 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
849 DBG("Sink %p: Abort_Ind", sep);
850 else
851 DBG("Source %p: Abort_Ind", sep);
852
853 a2dp_sep->stream = NULL;
854
855 return TRUE;
856 }
857
abort_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)858 static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
859 struct avdtp_stream *stream, struct avdtp_error *err,
860 void *user_data)
861 {
862 struct a2dp_sep *a2dp_sep = user_data;
863 struct a2dp_setup *setup;
864
865 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
866 DBG("Sink %p: Abort_Cfm", sep);
867 else
868 DBG("Source %p: Abort_Cfm", sep);
869
870 setup = find_setup_by_session(session);
871 if (!setup)
872 return;
873
874 setup_unref(setup);
875 }
876
reconf_ind(struct avdtp * session,struct avdtp_local_sep * sep,uint8_t * err,void * user_data)877 static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
878 uint8_t *err, void *user_data)
879 {
880 struct a2dp_sep *a2dp_sep = user_data;
881
882 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
883 DBG("Sink %p: ReConfigure_Ind", sep);
884 else
885 DBG("Source %p: ReConfigure_Ind", sep);
886
887 return TRUE;
888 }
889
delayreport_ind(struct avdtp * session,struct avdtp_local_sep * sep,uint8_t rseid,uint16_t delay,uint8_t * err,void * user_data)890 static gboolean delayreport_ind(struct avdtp *session,
891 struct avdtp_local_sep *sep,
892 uint8_t rseid, uint16_t delay,
893 uint8_t *err, void *user_data)
894 {
895 struct a2dp_sep *a2dp_sep = user_data;
896 struct audio_device *dev = a2dp_get_dev(session);
897
898 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
899 DBG("Sink %p: DelayReport_Ind", sep);
900 else
901 DBG("Source %p: DelayReport_Ind", sep);
902
903 unix_delay_report(dev, rseid, delay);
904
905 return TRUE;
906 }
907
reconf_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)908 static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
909 struct avdtp_stream *stream, struct avdtp_error *err,
910 void *user_data)
911 {
912 struct a2dp_sep *a2dp_sep = user_data;
913 struct a2dp_setup *setup;
914
915 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
916 DBG("Sink %p: ReConfigure_Cfm", sep);
917 else
918 DBG("Source %p: ReConfigure_Cfm", sep);
919
920 setup = find_setup_by_session(session);
921 if (!setup)
922 return;
923
924 if (err) {
925 setup->stream = NULL;
926 setup->err = err;
927 }
928
929 finalize_config(setup);
930 }
931
delay_report_cfm(struct avdtp * session,struct avdtp_local_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)932 static void delay_report_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
933 struct avdtp_stream *stream,
934 struct avdtp_error *err, void *user_data)
935 {
936 struct a2dp_sep *a2dp_sep = user_data;
937
938 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
939 DBG("Sink %p: DelayReport_Cfm", sep);
940 else
941 DBG("Source %p: DelayReport_Cfm", sep);
942 }
943
944 static struct avdtp_sep_cfm cfm = {
945 .set_configuration = setconf_cfm,
946 .get_configuration = getconf_cfm,
947 .open = open_cfm,
948 .start = start_cfm,
949 .suspend = suspend_cfm,
950 .close = close_cfm,
951 .abort = abort_cfm,
952 .reconfigure = reconf_cfm,
953 .delay_report = delay_report_cfm,
954 };
955
956 static struct avdtp_sep_ind sbc_ind = {
957 .get_capability = sbc_getcap_ind,
958 .set_configuration = sbc_setconf_ind,
959 .get_configuration = getconf_ind,
960 .open = open_ind,
961 .start = start_ind,
962 .suspend = suspend_ind,
963 .close = close_ind,
964 .abort = abort_ind,
965 .reconfigure = reconf_ind,
966 .delayreport = delayreport_ind,
967 };
968
969 static struct avdtp_sep_ind mpeg_ind = {
970 .get_capability = mpeg_getcap_ind,
971 .set_configuration = mpeg_setconf_ind,
972 .get_configuration = getconf_ind,
973 .open = open_ind,
974 .start = start_ind,
975 .suspend = suspend_ind,
976 .close = close_ind,
977 .abort = abort_ind,
978 .reconfigure = reconf_ind,
979 .delayreport = delayreport_ind,
980 };
981
a2dp_record(uint8_t type,uint16_t avdtp_ver)982 static sdp_record_t *a2dp_record(uint8_t type, uint16_t avdtp_ver)
983 {
984 sdp_list_t *svclass_id, *pfseq, *apseq, *root;
985 uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
986 sdp_profile_desc_t profile[1];
987 sdp_list_t *aproto, *proto[2];
988 sdp_record_t *record;
989 sdp_data_t *psm, *version, *features;
990 uint16_t lp = AVDTP_UUID;
991 uint16_t a2dp_ver = 0x0102, feat = 0x000f;
992
993 #ifdef ANDROID
994 feat = 0x0001;
995 #endif
996 record = sdp_record_alloc();
997 if (!record)
998 return NULL;
999
1000 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
1001 root = sdp_list_append(0, &root_uuid);
1002 sdp_set_browse_groups(record, root);
1003
1004 if (type == AVDTP_SEP_TYPE_SOURCE)
1005 sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
1006 else
1007 sdp_uuid16_create(&a2dp_uuid, AUDIO_SINK_SVCLASS_ID);
1008 svclass_id = sdp_list_append(0, &a2dp_uuid);
1009 sdp_set_service_classes(record, svclass_id);
1010
1011 sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
1012 profile[0].version = a2dp_ver;
1013 pfseq = sdp_list_append(0, &profile[0]);
1014 sdp_set_profile_descs(record, pfseq);
1015
1016 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
1017 proto[0] = sdp_list_append(0, &l2cap_uuid);
1018 psm = sdp_data_alloc(SDP_UINT16, &lp);
1019 proto[0] = sdp_list_append(proto[0], psm);
1020 apseq = sdp_list_append(0, proto[0]);
1021
1022 sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
1023 proto[1] = sdp_list_append(0, &avdtp_uuid);
1024 version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
1025 proto[1] = sdp_list_append(proto[1], version);
1026 apseq = sdp_list_append(apseq, proto[1]);
1027
1028 aproto = sdp_list_append(0, apseq);
1029 sdp_set_access_protos(record, aproto);
1030
1031 features = sdp_data_alloc(SDP_UINT16, &feat);
1032 sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
1033
1034 if (type == AVDTP_SEP_TYPE_SOURCE)
1035 sdp_set_info_attr(record, "Audio Source", 0, 0);
1036 else
1037 sdp_set_info_attr(record, "Audio Sink", 0, 0);
1038
1039 free(psm);
1040 free(version);
1041 sdp_list_free(proto[0], 0);
1042 sdp_list_free(proto[1], 0);
1043 sdp_list_free(apseq, 0);
1044 sdp_list_free(pfseq, 0);
1045 sdp_list_free(aproto, 0);
1046 sdp_list_free(root, 0);
1047 sdp_list_free(svclass_id, 0);
1048
1049 return record;
1050 }
1051
a2dp_add_sep(struct a2dp_server * server,uint8_t type,uint8_t codec,gboolean delay_reporting)1052 static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type,
1053 uint8_t codec, gboolean delay_reporting)
1054 {
1055 struct a2dp_sep *sep;
1056 GSList **l;
1057 uint32_t *record_id;
1058 sdp_record_t *record;
1059 struct avdtp_sep_ind *ind;
1060
1061 sep = g_new0(struct a2dp_sep, 1);
1062
1063 ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
1064 sep->sep = avdtp_register_sep(&server->src, type,
1065 AVDTP_MEDIA_TYPE_AUDIO, codec,
1066 delay_reporting, ind, &cfm, sep);
1067 if (sep->sep == NULL) {
1068 g_free(sep);
1069 return NULL;
1070 }
1071
1072 sep->codec = codec;
1073 sep->type = type;
1074 sep->delay_reporting = delay_reporting;
1075
1076 if (type == AVDTP_SEP_TYPE_SOURCE) {
1077 l = &server->sources;
1078 record_id = &server->source_record_id;
1079 } else {
1080 l = &server->sinks;
1081 record_id = &server->sink_record_id;
1082 }
1083
1084 if (*record_id != 0)
1085 goto add;
1086
1087 record = a2dp_record(type, server->version);
1088 if (!record) {
1089 error("Unable to allocate new service record");
1090 avdtp_unregister_sep(sep->sep);
1091 g_free(sep);
1092 return NULL;
1093 }
1094
1095 if (add_record_to_server(&server->src, record) < 0) {
1096 error("Unable to register A2DP service record");\
1097 sdp_record_free(record);
1098 avdtp_unregister_sep(sep->sep);
1099 g_free(sep);
1100 return NULL;
1101 }
1102 *record_id = record->handle;
1103
1104 add:
1105 *l = g_slist_append(*l, sep);
1106
1107 return sep;
1108 }
1109
find_server(GSList * list,const bdaddr_t * src)1110 static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
1111 {
1112 GSList *l;
1113
1114 for (l = list; l; l = l->next) {
1115 struct a2dp_server *server = l->data;
1116
1117 if (bacmp(&server->src, src) == 0)
1118 return server;
1119 }
1120
1121 return NULL;
1122 }
1123
a2dp_register(DBusConnection * conn,const bdaddr_t * src,GKeyFile * config)1124 int a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
1125 {
1126 int sbc_srcs = 1, sbc_sinks = 1;
1127 int mpeg12_srcs = 0, mpeg12_sinks = 0;
1128 gboolean source = TRUE, sink = FALSE, delay_reporting;
1129 char *str;
1130 GError *err = NULL;
1131 int i;
1132 struct a2dp_server *server;
1133
1134 if (!config)
1135 goto proceed;
1136
1137 str = g_key_file_get_string(config, "General", "Enable", &err);
1138
1139 if (err) {
1140 DBG("audio.conf: %s", err->message);
1141 g_clear_error(&err);
1142 } else {
1143 if (strstr(str, "Sink"))
1144 source = TRUE;
1145 if (strstr(str, "Source"))
1146 sink = TRUE;
1147 g_free(str);
1148 }
1149
1150 str = g_key_file_get_string(config, "General", "Disable", &err);
1151
1152 if (err) {
1153 DBG("audio.conf: %s", err->message);
1154 g_clear_error(&err);
1155 } else {
1156 if (strstr(str, "Sink"))
1157 source = FALSE;
1158 if (strstr(str, "Source"))
1159 sink = FALSE;
1160 g_free(str);
1161 }
1162
1163 str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
1164 if (err) {
1165 DBG("audio.conf: %s", err->message);
1166 g_clear_error(&err);
1167 } else {
1168 sbc_srcs = atoi(str);
1169 g_free(str);
1170 }
1171
1172 str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
1173 if (err) {
1174 DBG("audio.conf: %s", err->message);
1175 g_clear_error(&err);
1176 } else {
1177 mpeg12_srcs = atoi(str);
1178 g_free(str);
1179 }
1180
1181 str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
1182 if (err) {
1183 DBG("audio.conf: %s", err->message);
1184 g_clear_error(&err);
1185 } else {
1186 sbc_sinks = atoi(str);
1187 g_free(str);
1188 }
1189
1190 str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
1191 if (err) {
1192 DBG("audio.conf: %s", err->message);
1193 g_clear_error(&err);
1194 } else {
1195 mpeg12_sinks = atoi(str);
1196 g_free(str);
1197 }
1198
1199 proceed:
1200 if (!connection)
1201 connection = dbus_connection_ref(conn);
1202
1203 server = find_server(servers, src);
1204 if (!server) {
1205 int av_err;
1206
1207 server = g_new0(struct a2dp_server, 1);
1208 if (!server)
1209 return -ENOMEM;
1210
1211 av_err = avdtp_init(src, config, &server->version);
1212 if (av_err < 0) {
1213 g_free(server);
1214 return av_err;
1215 }
1216
1217 bacpy(&server->src, src);
1218 servers = g_slist_append(servers, server);
1219 }
1220
1221 delay_reporting = g_key_file_get_boolean(config, "A2DP",
1222 "DelayReporting", NULL);
1223 if (delay_reporting)
1224 server->version = 0x0103;
1225 else
1226 server->version = 0x0102;
1227
1228 if (source) {
1229 for (i = 0; i < sbc_srcs; i++)
1230 a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
1231 A2DP_CODEC_SBC, delay_reporting);
1232
1233 for (i = 0; i < mpeg12_srcs; i++)
1234 a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
1235 A2DP_CODEC_MPEG12, delay_reporting);
1236 }
1237
1238 if (sink) {
1239 for (i = 0; i < sbc_sinks; i++)
1240 a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
1241 A2DP_CODEC_SBC, delay_reporting);
1242
1243 for (i = 0; i < mpeg12_sinks; i++)
1244 a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
1245 A2DP_CODEC_MPEG12, delay_reporting);
1246 }
1247
1248 return 0;
1249 }
1250
a2dp_unregister_sep(struct a2dp_sep * sep)1251 static void a2dp_unregister_sep(struct a2dp_sep *sep)
1252 {
1253 avdtp_unregister_sep(sep->sep);
1254 g_free(sep);
1255 }
1256
a2dp_unregister(const bdaddr_t * src)1257 void a2dp_unregister(const bdaddr_t *src)
1258 {
1259 struct a2dp_server *server;
1260
1261 server = find_server(servers, src);
1262 if (!server)
1263 return;
1264
1265 g_slist_foreach(server->sinks, (GFunc) a2dp_unregister_sep, NULL);
1266 g_slist_free(server->sinks);
1267
1268 g_slist_foreach(server->sources, (GFunc) a2dp_unregister_sep, NULL);
1269 g_slist_free(server->sources);
1270
1271 avdtp_exit(src);
1272
1273 if (server->source_record_id)
1274 remove_record_from_server(server->source_record_id);
1275
1276 if (server->sink_record_id)
1277 remove_record_from_server(server->sink_record_id);
1278
1279 servers = g_slist_remove(servers, server);
1280 g_free(server);
1281
1282 if (servers)
1283 return;
1284
1285 dbus_connection_unref(connection);
1286 connection = NULL;
1287 }
1288
a2dp_get(struct avdtp * session,struct avdtp_remote_sep * rsep)1289 struct a2dp_sep *a2dp_get(struct avdtp *session,
1290 struct avdtp_remote_sep *rsep)
1291 {
1292 GSList *l;
1293 struct a2dp_server *server;
1294 struct avdtp_service_capability *cap;
1295 struct avdtp_media_codec_capability *codec_cap = NULL;
1296 bdaddr_t src;
1297
1298 avdtp_get_peers(session, &src, NULL);
1299 server = find_server(servers, &src);
1300 if (!server)
1301 return NULL;
1302
1303 cap = avdtp_get_codec(rsep);
1304 codec_cap = (void *) cap->data;
1305
1306 if (avdtp_get_type(rsep) == AVDTP_SEP_TYPE_SINK)
1307 l = server->sources;
1308 else
1309 l = server->sinks;
1310
1311 for (; l != NULL; l = l->next) {
1312 struct a2dp_sep *sep = l->data;
1313
1314 if (sep->locked)
1315 continue;
1316
1317 if (sep->codec != codec_cap->media_codec_type)
1318 continue;
1319
1320 if (!sep->stream || avdtp_has_stream(session, sep->stream))
1321 return sep;
1322 }
1323
1324 return NULL;
1325 }
1326
a2dp_config(struct avdtp * session,struct a2dp_sep * sep,a2dp_config_cb_t cb,GSList * caps,void * user_data)1327 unsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
1328 a2dp_config_cb_t cb, GSList *caps,
1329 void *user_data)
1330 {
1331 struct a2dp_setup_cb *cb_data;
1332 GSList *l;
1333 struct a2dp_server *server;
1334 struct a2dp_setup *setup;
1335 struct a2dp_sep *tmp;
1336 struct avdtp_local_sep *lsep;
1337 struct avdtp_remote_sep *rsep;
1338 struct avdtp_service_capability *cap;
1339 struct avdtp_media_codec_capability *codec_cap = NULL;
1340 int posix_err;
1341 bdaddr_t src;
1342 uint8_t remote_type;
1343
1344 avdtp_get_peers(session, &src, NULL);
1345 server = find_server(servers, &src);
1346 if (!server)
1347 return 0;
1348
1349 for (l = caps; l != NULL; l = l->next) {
1350 cap = l->data;
1351
1352 if (cap->category != AVDTP_MEDIA_CODEC)
1353 continue;
1354
1355 codec_cap = (void *) cap->data;
1356 break;
1357 }
1358
1359 if (!codec_cap)
1360 return 0;
1361
1362 if (sep->codec != codec_cap->media_codec_type)
1363 return 0;
1364
1365 DBG("a2dp_config: selected SEP %p", sep->sep);
1366
1367 cb_data = g_new0(struct a2dp_setup_cb, 1);
1368 cb_data->config_cb = cb;
1369 cb_data->user_data = user_data;
1370 cb_data->id = ++cb_id;
1371
1372 setup = find_setup_by_session(session);
1373 if (!setup) {
1374 setup = g_new0(struct a2dp_setup, 1);
1375 setup->session = avdtp_ref(session);
1376 setup->dev = a2dp_get_dev(session);
1377 setups = g_slist_append(setups, setup);
1378 }
1379
1380 setup_ref(setup);
1381 setup->cb = g_slist_append(setup->cb, cb_data);
1382 setup->sep = sep;
1383 setup->stream = sep->stream;
1384 setup->client_caps = caps;
1385
1386 switch (avdtp_sep_get_state(sep->sep)) {
1387 case AVDTP_STATE_IDLE:
1388 if (sep->type == AVDTP_SEP_TYPE_SOURCE) {
1389 l = server->sources;
1390 remote_type = AVDTP_SEP_TYPE_SINK;
1391 } else {
1392 remote_type = AVDTP_SEP_TYPE_SOURCE;
1393 l = server->sinks;
1394 }
1395
1396 for (; l != NULL; l = l->next) {
1397 tmp = l->data;
1398 if (avdtp_has_stream(session, tmp->stream))
1399 break;
1400 }
1401
1402 if (l != NULL) {
1403 setup->reconfigure = TRUE;
1404 if (avdtp_close(session, tmp->stream, FALSE) < 0) {
1405 error("avdtp_close failed");
1406 goto failed;
1407 }
1408 break;
1409 }
1410
1411 if (avdtp_get_seps(session, remote_type,
1412 codec_cap->media_type,
1413 codec_cap->media_codec_type,
1414 &lsep, &rsep) < 0) {
1415 error("No matching ACP and INT SEPs found");
1416 goto failed;
1417 }
1418
1419 posix_err = avdtp_set_configuration(session, rsep, lsep,
1420 caps, &setup->stream);
1421 if (posix_err < 0) {
1422 error("avdtp_set_configuration: %s",
1423 strerror(-posix_err));
1424 goto failed;
1425 }
1426 break;
1427 case AVDTP_STATE_OPEN:
1428 case AVDTP_STATE_STREAMING:
1429 if (avdtp_stream_has_capabilities(setup->stream, caps)) {
1430 DBG("Configuration match: resuming");
1431 g_idle_add((GSourceFunc) finalize_config, setup);
1432 } else if (!setup->reconfigure) {
1433 setup->reconfigure = TRUE;
1434 if (avdtp_close(session, sep->stream, FALSE) < 0) {
1435 error("avdtp_close failed");
1436 goto failed;
1437 }
1438 }
1439 break;
1440 default:
1441 error("SEP in bad state for requesting a new stream");
1442 goto failed;
1443 }
1444
1445 return cb_data->id;
1446
1447 failed:
1448 setup_unref(setup);
1449 cb_id--;
1450 return 0;
1451 }
1452
a2dp_resume(struct avdtp * session,struct a2dp_sep * sep,a2dp_stream_cb_t cb,void * user_data)1453 unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
1454 a2dp_stream_cb_t cb, void *user_data)
1455 {
1456 struct a2dp_setup_cb *cb_data;
1457 struct a2dp_setup *setup;
1458
1459 cb_data = g_new0(struct a2dp_setup_cb, 1);
1460 cb_data->resume_cb = cb;
1461 cb_data->user_data = user_data;
1462 cb_data->id = ++cb_id;
1463
1464 setup = find_setup_by_session(session);
1465 if (!setup) {
1466 setup = g_new0(struct a2dp_setup, 1);
1467 setup->session = avdtp_ref(session);
1468 setup->dev = a2dp_get_dev(session);
1469 setups = g_slist_append(setups, setup);
1470 }
1471
1472 setup_ref(setup);
1473 setup->cb = g_slist_append(setup->cb, cb_data);
1474 setup->sep = sep;
1475 setup->stream = sep->stream;
1476
1477 switch (avdtp_sep_get_state(sep->sep)) {
1478 case AVDTP_STATE_IDLE:
1479 goto failed;
1480 break;
1481 case AVDTP_STATE_OPEN:
1482 if (avdtp_start(session, sep->stream) < 0) {
1483 error("avdtp_start failed");
1484 goto failed;
1485 }
1486 break;
1487 case AVDTP_STATE_STREAMING:
1488 if (!sep->suspending && sep->suspend_timer) {
1489 g_source_remove(sep->suspend_timer);
1490 sep->suspend_timer = 0;
1491 avdtp_unref(sep->session);
1492 sep->session = NULL;
1493 }
1494 if (sep->suspending)
1495 setup->start = TRUE;
1496 else
1497 g_idle_add((GSourceFunc) finalize_resume, setup);
1498 break;
1499 default:
1500 error("SEP in bad state for resume");
1501 goto failed;
1502 }
1503
1504 return cb_data->id;
1505
1506 failed:
1507 setup_unref(setup);
1508 cb_id--;
1509 return 0;
1510 }
1511
a2dp_suspend(struct avdtp * session,struct a2dp_sep * sep,a2dp_stream_cb_t cb,void * user_data)1512 unsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
1513 a2dp_stream_cb_t cb, void *user_data)
1514 {
1515 struct a2dp_setup_cb *cb_data;
1516 struct a2dp_setup *setup;
1517
1518 cb_data = g_new0(struct a2dp_setup_cb, 1);
1519 cb_data->suspend_cb = cb;
1520 cb_data->user_data = user_data;
1521 cb_data->id = ++cb_id;
1522
1523 setup = find_setup_by_session(session);
1524 if (!setup) {
1525 setup = g_new0(struct a2dp_setup, 1);
1526 setup->session = avdtp_ref(session);
1527 setup->dev = a2dp_get_dev(session);
1528 setups = g_slist_append(setups, setup);
1529 }
1530
1531 setup_ref(setup);
1532 setup->cb = g_slist_append(setup->cb, cb_data);
1533 setup->sep = sep;
1534 setup->stream = sep->stream;
1535
1536 switch (avdtp_sep_get_state(sep->sep)) {
1537 case AVDTP_STATE_IDLE:
1538 error("a2dp_suspend: no stream to suspend");
1539 goto failed;
1540 break;
1541 case AVDTP_STATE_OPEN:
1542 g_idle_add((GSourceFunc) finalize_suspend, setup);
1543 break;
1544 case AVDTP_STATE_STREAMING:
1545 if (avdtp_suspend(session, sep->stream) < 0) {
1546 error("avdtp_suspend failed");
1547 goto failed;
1548 }
1549 break;
1550 default:
1551 error("SEP in bad state for suspend");
1552 goto failed;
1553 }
1554
1555 return cb_data->id;
1556
1557 failed:
1558 setup_unref(setup);
1559 cb_id--;
1560 return 0;
1561 }
1562
a2dp_cancel(struct audio_device * dev,unsigned int id)1563 gboolean a2dp_cancel(struct audio_device *dev, unsigned int id)
1564 {
1565 struct a2dp_setup_cb *cb_data;
1566 struct a2dp_setup *setup;
1567 GSList *l;
1568
1569 DBG("a2dp_cancel()");
1570
1571 setup = find_setup_by_dev(dev);
1572 if (!setup)
1573 return FALSE;
1574
1575 for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) {
1576 struct a2dp_setup_cb *cb = l->data;
1577
1578 if (cb->id == id) {
1579 cb_data = cb;
1580 break;
1581 }
1582 }
1583
1584 if (!cb_data)
1585 error("a2dp_cancel: no matching callback with id %u", id);
1586
1587 setup->cb = g_slist_remove(setup->cb, cb_data);
1588 g_free(cb_data);
1589
1590 if (setup->cb)
1591 return TRUE;
1592
1593 avdtp_abort(setup->session, setup->stream);
1594
1595 return TRUE;
1596 }
1597
a2dp_sep_lock(struct a2dp_sep * sep,struct avdtp * session)1598 gboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
1599 {
1600 if (sep->locked)
1601 return FALSE;
1602
1603 DBG("SEP %p locked", sep->sep);
1604 sep->locked = TRUE;
1605
1606 return TRUE;
1607 }
1608
a2dp_sep_unlock(struct a2dp_sep * sep,struct avdtp * session)1609 gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
1610 {
1611 avdtp_state_t state;
1612
1613 state = avdtp_sep_get_state(sep->sep);
1614
1615 sep->locked = FALSE;
1616
1617 DBG("SEP %p unlocked", sep->sep);
1618
1619 if (!sep->stream || state == AVDTP_STATE_IDLE)
1620 return TRUE;
1621
1622 switch (state) {
1623 case AVDTP_STATE_OPEN:
1624 /* Set timer here */
1625 break;
1626 case AVDTP_STATE_STREAMING:
1627 if (avdtp_suspend(session, sep->stream) == 0)
1628 sep->suspending = TRUE;
1629 break;
1630 default:
1631 break;
1632 }
1633
1634 return TRUE;
1635 }
1636
a2dp_sep_get_lock(struct a2dp_sep * sep)1637 gboolean a2dp_sep_get_lock(struct a2dp_sep *sep)
1638 {
1639 return sep->locked;
1640 }
1641
stream_cmp(gconstpointer data,gconstpointer user_data)1642 static int stream_cmp(gconstpointer data, gconstpointer user_data)
1643 {
1644 const struct a2dp_sep *sep = data;
1645 const struct avdtp_stream *stream = user_data;
1646
1647 return (sep->stream != stream);
1648 }
1649
a2dp_get_sep(struct avdtp * session,struct avdtp_stream * stream)1650 struct a2dp_sep *a2dp_get_sep(struct avdtp *session,
1651 struct avdtp_stream *stream)
1652 {
1653 struct a2dp_server *server;
1654 bdaddr_t src, dst;
1655 GSList *l;
1656
1657 avdtp_get_peers(session, &src, &dst);
1658
1659 for (l = servers; l; l = l->next) {
1660 server = l->data;
1661
1662 if (bacmp(&src, &server->src) == 0)
1663 break;
1664 }
1665
1666 if (!l)
1667 return NULL;
1668
1669 l = g_slist_find_custom(server->sources, stream, stream_cmp);
1670 if (l)
1671 return l->data;
1672
1673 l = g_slist_find_custom(server->sinks, stream, stream_cmp);
1674 if (l)
1675 return l->data;
1676
1677 return NULL;
1678 }
1679