~bluetooth/bluez/import-mer-patches

« back to all changes in this revision

Viewing changes to audio/a2dp.c

  • Committer: Simon Fels
  • Date: 2015-09-11 09:01:46 UTC
  • Revision ID: morphis@gravedo.de-20150911090146-4c0ln9s7ec3xf0nx
Import package bluez_4.101-0ubuntu25.1~overlay4 from stable phone overlay PPA

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 *  Copyright (C) 2011  BMW Car IT GmbH. All rights reserved.
 
8
 *
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 2 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, write to the Free Software
 
22
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
23
 *
 
24
 */
 
25
 
 
26
#ifdef HAVE_CONFIG_H
 
27
#include <config.h>
 
28
#endif
 
29
 
 
30
#include <stdlib.h>
 
31
#include <errno.h>
 
32
 
 
33
#include <dbus/dbus.h>
 
34
#include <glib.h>
 
35
 
 
36
#include <bluetooth/bluetooth.h>
 
37
#include <bluetooth/sdp.h>
 
38
#include <bluetooth/sdp_lib.h>
 
39
 
 
40
#include "log.h"
 
41
#include "device.h"
 
42
#include "manager.h"
 
43
#include "avdtp.h"
 
44
#include "sink.h"
 
45
#include "source.h"
 
46
#include "unix.h"
 
47
#include "a2dp.h"
 
48
#include "sdpd.h"
 
49
 
 
50
/* The duration that streams without users are allowed to stay in
 
51
 * STREAMING state. */
 
52
#define SUSPEND_TIMEOUT 5
 
53
#define RECONFIGURE_TIMEOUT 500
 
54
 
 
55
#ifndef MIN
 
56
# define MIN(x, y) ((x) < (y) ? (x) : (y))
 
57
#endif
 
58
 
 
59
#ifndef MAX
 
60
# define MAX(x, y) ((x) > (y) ? (x) : (y))
 
61
#endif
 
62
 
 
63
struct a2dp_sep {
 
64
        struct a2dp_server *server;
 
65
        struct a2dp_endpoint *endpoint;
 
66
        uint8_t type;
 
67
        uint8_t codec;
 
68
        struct avdtp_local_sep *lsep;
 
69
        struct avdtp *session;
 
70
        struct avdtp_stream *stream;
 
71
        guint suspend_timer;
 
72
        gboolean delay_reporting;
 
73
        gboolean locked;
 
74
        gboolean suspending;
 
75
        gboolean starting;
 
76
        void *user_data;
 
77
        GDestroyNotify destroy;
 
78
};
 
79
 
 
80
struct a2dp_setup_cb {
 
81
        struct a2dp_setup *setup;
 
82
        a2dp_select_cb_t select_cb;
 
83
        a2dp_config_cb_t config_cb;
 
84
        a2dp_stream_cb_t resume_cb;
 
85
        a2dp_stream_cb_t suspend_cb;
 
86
        guint source_id;
 
87
        void *user_data;
 
88
        unsigned int id;
 
89
};
 
90
 
 
91
struct a2dp_setup {
 
92
        struct audio_device *dev;
 
93
        struct avdtp *session;
 
94
        struct a2dp_sep *sep;
 
95
        struct avdtp_remote_sep *rsep;
 
96
        struct avdtp_stream *stream;
 
97
        struct avdtp_error *err;
 
98
        avdtp_set_configuration_cb setconf_cb;
 
99
        GSList *caps;
 
100
        gboolean reconfigure;
 
101
        gboolean start;
 
102
        GSList *cb;
 
103
        int ref;
 
104
};
 
105
 
 
106
static DBusConnection *connection = NULL;
 
107
 
 
108
struct a2dp_server {
 
109
        bdaddr_t src;
 
110
        GSList *sinks;
 
111
        GSList *sources;
 
112
        uint32_t source_record_id;
 
113
        uint32_t sink_record_id;
 
114
        uint16_t version;
 
115
        gboolean sink_enabled;
 
116
        gboolean source_enabled;
 
117
};
 
118
 
 
119
static GSList *servers = NULL;
 
120
static GSList *setups = NULL;
 
121
static unsigned int cb_id = 0;
 
122
 
 
123
static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
 
124
{
 
125
        setup->ref++;
 
126
 
 
127
        DBG("%p: ref=%d", setup, setup->ref);
 
128
 
 
129
        return setup;
 
130
}
 
131
 
 
132
static struct audio_device *a2dp_get_dev(struct avdtp *session)
 
133
{
 
134
        bdaddr_t src, dst;
 
135
 
 
136
        avdtp_get_peers(session, &src, &dst);
 
137
 
 
138
        return manager_find_device(NULL, &src, &dst, NULL, FALSE);
 
139
}
 
140
 
 
141
static struct a2dp_setup *setup_new(struct avdtp *session)
 
142
{
 
143
        struct audio_device *dev;
 
144
        struct a2dp_setup *setup;
 
145
 
 
146
        dev = a2dp_get_dev(session);
 
147
        if (!dev) {
 
148
                error("Unable to create setup");
 
149
                return NULL;
 
150
        }
 
151
 
 
152
        setup = g_new0(struct a2dp_setup, 1);
 
153
        setup->session = avdtp_ref(session);
 
154
        setup->dev = a2dp_get_dev(session);
 
155
        setups = g_slist_append(setups, setup);
 
156
 
 
157
        return setup;
 
158
}
 
159
 
 
160
static void setup_free(struct a2dp_setup *s)
 
161
{
 
162
        DBG("%p", s);
 
163
 
 
164
        setups = g_slist_remove(setups, s);
 
165
        if (s->session)
 
166
                avdtp_unref(s->session);
 
167
        g_slist_free_full(s->cb, g_free);
 
168
        g_slist_free_full(s->caps, g_free);
 
169
        g_free(s);
 
170
}
 
171
 
 
172
static void setup_unref(struct a2dp_setup *setup)
 
173
{
 
174
        setup->ref--;
 
175
 
 
176
        DBG("%p: ref=%d", setup, setup->ref);
 
177
 
 
178
        if (setup->ref > 0)
 
179
                return;
 
180
 
 
181
        setup_free(setup);
 
182
}
 
183
 
 
184
static struct a2dp_setup_cb *setup_cb_new(struct a2dp_setup *setup)
 
185
{
 
186
        struct a2dp_setup_cb *cb;
 
187
 
 
188
        cb = g_new0(struct a2dp_setup_cb, 1);
 
189
        cb->setup = setup;
 
190
        cb->id = ++cb_id;
 
191
 
 
192
        setup->cb = g_slist_append(setup->cb, cb);
 
193
        return cb;
 
194
}
 
195
 
 
196
static void setup_cb_free(struct a2dp_setup_cb *cb)
 
197
{
 
198
        struct a2dp_setup *setup = cb->setup;
 
199
 
 
200
        if (cb->source_id)
 
201
                g_source_remove(cb->source_id);
 
202
 
 
203
        setup->cb = g_slist_remove(setup->cb, cb);
 
204
        setup_unref(cb->setup);
 
205
        g_free(cb);
 
206
}
 
207
 
 
208
static void finalize_setup_errno(struct a2dp_setup *s, int err,
 
209
                                        GSourceFunc cb1, ...)
 
210
{
 
211
        GSourceFunc finalize;
 
212
        va_list args;
 
213
        struct avdtp_error avdtp_err;
 
214
 
 
215
        if (err < 0) {
 
216
                avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err);
 
217
                s->err = &avdtp_err;
 
218
        }
 
219
 
 
220
        va_start(args, cb1);
 
221
        finalize = cb1;
 
222
        setup_ref(s);
 
223
        while (finalize != NULL) {
 
224
                finalize(s);
 
225
                finalize = va_arg(args, GSourceFunc);
 
226
        }
 
227
        setup_unref(s);
 
228
        va_end(args);
 
229
}
 
230
 
 
231
static gboolean finalize_config(gpointer data)
 
232
{
 
233
        struct a2dp_setup *s = data;
 
234
        GSList *l;
 
235
        struct avdtp_stream *stream = s->err ? NULL : s->stream;
 
236
 
 
237
        for (l = s->cb; l != NULL; ) {
 
238
                struct a2dp_setup_cb *cb = l->data;
 
239
 
 
240
                l = l->next;
 
241
 
 
242
                if (!cb->config_cb)
 
243
                        continue;
 
244
 
 
245
                cb->config_cb(s->session, s->sep, stream, s->err,
 
246
                                                        cb->user_data);
 
247
                setup_cb_free(cb);
 
248
        }
 
249
 
 
250
        return FALSE;
 
251
}
 
252
 
 
253
static gboolean finalize_resume(gpointer data)
 
254
{
 
255
        struct a2dp_setup *s = data;
 
256
        GSList *l;
 
257
 
 
258
        for (l = s->cb; l != NULL; ) {
 
259
                struct a2dp_setup_cb *cb = l->data;
 
260
 
 
261
                l = l->next;
 
262
 
 
263
                if (!cb->resume_cb)
 
264
                        continue;
 
265
 
 
266
                cb->resume_cb(s->session, s->err, cb->user_data);
 
267
                setup_cb_free(cb);
 
268
        }
 
269
 
 
270
        return FALSE;
 
271
}
 
272
 
 
273
static gboolean finalize_suspend(gpointer data)
 
274
{
 
275
        struct a2dp_setup *s = data;
 
276
        GSList *l;
 
277
 
 
278
        for (l = s->cb; l != NULL; ) {
 
279
                struct a2dp_setup_cb *cb = l->data;
 
280
 
 
281
                l = l->next;
 
282
 
 
283
                if (!cb->suspend_cb)
 
284
                        continue;
 
285
 
 
286
                cb->suspend_cb(s->session, s->err, cb->user_data);
 
287
                setup_cb_free(cb);
 
288
        }
 
289
 
 
290
        return FALSE;
 
291
}
 
292
 
 
293
static void finalize_select(struct a2dp_setup *s)
 
294
{
 
295
        GSList *l;
 
296
 
 
297
        for (l = s->cb; l != NULL; ) {
 
298
                struct a2dp_setup_cb *cb = l->data;
 
299
 
 
300
                l = l->next;
 
301
 
 
302
                if (!cb->select_cb)
 
303
                        continue;
 
304
 
 
305
                cb->select_cb(s->session, s->sep, s->caps, cb->user_data);
 
306
                setup_cb_free(cb);
 
307
        }
 
308
}
 
309
 
 
310
static struct a2dp_setup *find_setup_by_session(struct avdtp *session)
 
311
{
 
312
        GSList *l;
 
313
 
 
314
        for (l = setups; l != NULL; l = l->next) {
 
315
                struct a2dp_setup *setup = l->data;
 
316
 
 
317
                if (setup->session == session)
 
318
                        return setup;
 
319
        }
 
320
 
 
321
        return NULL;
 
322
}
 
323
 
 
324
static struct a2dp_setup *a2dp_setup_get(struct avdtp *session)
 
325
{
 
326
        struct a2dp_setup *setup;
 
327
 
 
328
        setup = find_setup_by_session(session);
 
329
        if (!setup) {
 
330
                setup = setup_new(session);
 
331
                if (!setup)
 
332
                        return NULL;
 
333
        }
 
334
 
 
335
        return setup_ref(setup);
 
336
}
 
337
 
 
338
static struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
 
339
{
 
340
        GSList *l;
 
341
 
 
342
        for (l = setups; l != NULL; l = l->next) {
 
343
                struct a2dp_setup *setup = l->data;
 
344
 
 
345
                if (setup->dev == dev)
 
346
                        return setup;
 
347
        }
 
348
 
 
349
        return NULL;
 
350
}
 
351
 
 
352
static void stream_state_changed(struct avdtp_stream *stream,
 
353
                                        avdtp_state_t old_state,
 
354
                                        avdtp_state_t new_state,
 
355
                                        struct avdtp_error *err,
 
356
                                        void *user_data)
 
357
{
 
358
        struct a2dp_sep *sep = user_data;
 
359
 
 
360
        if (new_state != AVDTP_STATE_IDLE)
 
361
                return;
 
362
 
 
363
        if (sep->suspend_timer) {
 
364
                g_source_remove(sep->suspend_timer);
 
365
                sep->suspend_timer = 0;
 
366
        }
 
367
 
 
368
        if (sep->session) {
 
369
                avdtp_unref(sep->session);
 
370
                sep->session = NULL;
 
371
        }
 
372
 
 
373
        sep->stream = NULL;
 
374
 
 
375
        if (sep->endpoint && sep->endpoint->clear_configuration)
 
376
                sep->endpoint->clear_configuration(sep, sep->user_data);
 
377
}
 
378
 
 
379
static gboolean auto_config(gpointer data)
 
380
{
 
381
        struct a2dp_setup *setup = data;
 
382
        struct avdtp_error *err = NULL;
 
383
 
 
384
        /* Check if configuration was aborted */
 
385
        if (setup->sep->stream == NULL)
 
386
                return FALSE;
 
387
 
 
388
        if (setup->err != NULL) {
 
389
                err = setup->err;
 
390
                goto done;
 
391
        }
 
392
 
 
393
        avdtp_stream_add_cb(setup->session, setup->stream,
 
394
                                stream_state_changed, setup->sep);
 
395
 
 
396
        if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE)
 
397
                sink_new_stream(setup->dev, setup->session, setup->stream);
 
398
        else
 
399
                source_new_stream(setup->dev, setup->session, setup->stream);
 
400
 
 
401
done:
 
402
        if (setup->setconf_cb)
 
403
                setup->setconf_cb(setup->session, setup->stream, setup->err);
 
404
 
 
405
        finalize_config(setup);
 
406
 
 
407
        if (err)
 
408
                g_free(err);
 
409
 
 
410
        setup_unref(setup);
 
411
 
 
412
        return FALSE;
 
413
}
 
414
 
 
415
static gboolean sbc_setconf_ind(struct avdtp *session,
 
416
                                        struct avdtp_local_sep *sep,
 
417
                                        struct avdtp_stream *stream,
 
418
                                        GSList *caps,
 
419
                                        avdtp_set_configuration_cb cb,
 
420
                                        void *user_data)
 
421
{
 
422
        struct a2dp_sep *a2dp_sep = user_data;
 
423
        struct a2dp_setup *setup;
 
424
 
 
425
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
426
                DBG("Sink %p: Set_Configuration_Ind", sep);
 
427
        else
 
428
                DBG("Source %p: Set_Configuration_Ind", sep);
 
429
 
 
430
        setup = a2dp_setup_get(session);
 
431
        if (!setup)
 
432
                return FALSE;
 
433
 
 
434
        a2dp_sep->stream = stream;
 
435
        setup->sep = a2dp_sep;
 
436
        setup->stream = stream;
 
437
        setup->setconf_cb = cb;
 
438
 
 
439
        /* Check valid settings */
 
440
        for (; caps != NULL; caps = g_slist_next(caps)) {
 
441
                struct avdtp_service_capability *cap = caps->data;
 
442
                struct avdtp_media_codec_capability *codec_cap;
 
443
                struct sbc_codec_cap *sbc_cap;
 
444
 
 
445
                if (cap->category == AVDTP_DELAY_REPORTING &&
 
446
                                        !a2dp_sep->delay_reporting) {
 
447
                        setup->err = g_new(struct avdtp_error, 1);
 
448
                        avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
 
449
                                                AVDTP_UNSUPPORTED_CONFIGURATION);
 
450
                        goto done;
 
451
                }
 
452
 
 
453
                if (cap->category != AVDTP_MEDIA_CODEC)
 
454
                        continue;
 
455
 
 
456
                if (cap->length < sizeof(struct sbc_codec_cap))
 
457
                        continue;
 
458
 
 
459
                codec_cap = (void *) cap->data;
 
460
 
 
461
                if (codec_cap->media_codec_type != A2DP_CODEC_SBC)
 
462
                        continue;
 
463
 
 
464
                sbc_cap = (void *) codec_cap;
 
465
 
 
466
                if (sbc_cap->min_bitpool < MIN_BITPOOL ||
 
467
                                        sbc_cap->max_bitpool > MAX_BITPOOL) {
 
468
                        setup->err = g_new(struct avdtp_error, 1);
 
469
                        avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
 
470
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
471
                        goto done;
 
472
                }
 
473
        }
 
474
 
 
475
done:
 
476
        g_idle_add(auto_config, setup);
 
477
        return TRUE;
 
478
}
 
479
 
 
480
static gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
481
                                gboolean get_all, GSList **caps, uint8_t *err,
 
482
                                void *user_data)
 
483
{
 
484
        struct a2dp_sep *a2dp_sep = user_data;
 
485
        struct avdtp_service_capability *media_transport, *media_codec;
 
486
        struct sbc_codec_cap sbc_cap;
 
487
 
 
488
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
489
                DBG("Sink %p: Get_Capability_Ind", sep);
 
490
        else
 
491
                DBG("Source %p: Get_Capability_Ind", sep);
 
492
 
 
493
        *caps = NULL;
 
494
 
 
495
        media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
 
496
                                                NULL, 0);
 
497
 
 
498
        *caps = g_slist_append(*caps, media_transport);
 
499
 
 
500
        memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
 
501
 
 
502
        sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
 
503
        sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
 
504
 
 
505
        sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
 
506
                                SBC_SAMPLING_FREQ_44100 |
 
507
                                SBC_SAMPLING_FREQ_32000 |
 
508
                                SBC_SAMPLING_FREQ_16000 );
 
509
 
 
510
        sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
 
511
                                        SBC_CHANNEL_MODE_STEREO |
 
512
                                        SBC_CHANNEL_MODE_DUAL_CHANNEL |
 
513
                                        SBC_CHANNEL_MODE_MONO );
 
514
 
 
515
        sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
 
516
                                        SBC_BLOCK_LENGTH_12 |
 
517
                                        SBC_BLOCK_LENGTH_8 |
 
518
                                        SBC_BLOCK_LENGTH_4 );
 
519
 
 
520
        sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
 
521
 
 
522
        sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
 
523
                                        SBC_ALLOCATION_SNR );
 
524
 
 
525
        sbc_cap.min_bitpool = MIN_BITPOOL;
 
526
        sbc_cap.max_bitpool = MAX_BITPOOL;
 
527
 
 
528
        media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
 
529
                                                sizeof(sbc_cap));
 
530
 
 
531
        *caps = g_slist_append(*caps, media_codec);
 
532
 
 
533
        if (get_all) {
 
534
                struct avdtp_service_capability *delay_reporting;
 
535
                delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
 
536
                                                                NULL, 0);
 
537
                *caps = g_slist_append(*caps, delay_reporting);
 
538
        }
 
539
 
 
540
        return TRUE;
 
541
}
 
542
 
 
543
static gboolean mpeg_setconf_ind(struct avdtp *session,
 
544
                                        struct avdtp_local_sep *sep,
 
545
                                        struct avdtp_stream *stream,
 
546
                                        GSList *caps,
 
547
                                        avdtp_set_configuration_cb cb,
 
548
                                        void *user_data)
 
549
{
 
550
        struct a2dp_sep *a2dp_sep = user_data;
 
551
        struct a2dp_setup *setup;
 
552
 
 
553
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
554
                DBG("Sink %p: Set_Configuration_Ind", sep);
 
555
        else
 
556
                DBG("Source %p: Set_Configuration_Ind", sep);
 
557
 
 
558
        setup = a2dp_setup_get(session);
 
559
        if (!setup)
 
560
                return FALSE;
 
561
 
 
562
        a2dp_sep->stream = stream;
 
563
        setup->sep = a2dp_sep;
 
564
        setup->stream = stream;
 
565
        setup->setconf_cb = cb;
 
566
 
 
567
        for (; caps != NULL; caps = g_slist_next(caps)) {
 
568
                struct avdtp_service_capability *cap = caps->data;
 
569
 
 
570
                if (cap->category == AVDTP_DELAY_REPORTING &&
 
571
                                        !a2dp_sep->delay_reporting) {
 
572
                        setup->err = g_new(struct avdtp_error, 1);
 
573
                        avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
 
574
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
575
                        goto done;
 
576
                }
 
577
        }
 
578
 
 
579
done:
 
580
        g_idle_add(auto_config, setup);
 
581
        return TRUE;
 
582
}
 
583
 
 
584
static gboolean mpeg_getcap_ind(struct avdtp *session,
 
585
                                struct avdtp_local_sep *sep,
 
586
                                gboolean get_all,
 
587
                                GSList **caps, uint8_t *err, void *user_data)
 
588
{
 
589
        struct a2dp_sep *a2dp_sep = user_data;
 
590
        struct avdtp_service_capability *media_transport, *media_codec;
 
591
        struct mpeg_codec_cap mpeg_cap;
 
592
 
 
593
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
594
                DBG("Sink %p: Get_Capability_Ind", sep);
 
595
        else
 
596
                DBG("Source %p: Get_Capability_Ind", sep);
 
597
 
 
598
        *caps = NULL;
 
599
 
 
600
        media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
 
601
                                                NULL, 0);
 
602
 
 
603
        *caps = g_slist_append(*caps, media_transport);
 
604
 
 
605
        memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
 
606
 
 
607
        mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
 
608
        mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
 
609
 
 
610
        mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
 
611
                                MPEG_SAMPLING_FREQ_44100 |
 
612
                                MPEG_SAMPLING_FREQ_32000 |
 
613
                                MPEG_SAMPLING_FREQ_24000 |
 
614
                                MPEG_SAMPLING_FREQ_22050 |
 
615
                                MPEG_SAMPLING_FREQ_16000 );
 
616
 
 
617
        mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
 
618
                                        MPEG_CHANNEL_MODE_STEREO |
 
619
                                        MPEG_CHANNEL_MODE_DUAL_CHANNEL |
 
620
                                        MPEG_CHANNEL_MODE_MONO );
 
621
 
 
622
        mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
 
623
 
 
624
        mpeg_cap.bitrate = 0xFFFF;
 
625
 
 
626
        media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
 
627
                                                sizeof(mpeg_cap));
 
628
 
 
629
        *caps = g_slist_append(*caps, media_codec);
 
630
 
 
631
        if (get_all) {
 
632
                struct avdtp_service_capability *delay_reporting;
 
633
                delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
 
634
                                                                NULL, 0);
 
635
                *caps = g_slist_append(*caps, delay_reporting);
 
636
        }
 
637
 
 
638
        return TRUE;
 
639
}
 
640
 
 
641
 
 
642
static void endpoint_setconf_cb(struct a2dp_setup *setup, gboolean ret)
 
643
{
 
644
        if (ret == FALSE) {
 
645
                setup->err = g_new(struct avdtp_error, 1);
 
646
                avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
 
647
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
648
        }
 
649
 
 
650
        auto_config(setup);
 
651
}
 
652
 
 
653
static gboolean endpoint_setconf_ind(struct avdtp *session,
 
654
                                                struct avdtp_local_sep *sep,
 
655
                                                struct avdtp_stream *stream,
 
656
                                                GSList *caps,
 
657
                                                avdtp_set_configuration_cb cb,
 
658
                                                void *user_data)
 
659
{
 
660
        struct a2dp_sep *a2dp_sep = user_data;
 
661
        struct a2dp_setup *setup;
 
662
 
 
663
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
664
                DBG("Sink %p: Set_Configuration_Ind", sep);
 
665
        else
 
666
                DBG("Source %p: Set_Configuration_Ind", sep);
 
667
 
 
668
        setup = a2dp_setup_get(session);
 
669
        if (!session)
 
670
                return FALSE;
 
671
 
 
672
        a2dp_sep->stream = stream;
 
673
        setup->sep = a2dp_sep;
 
674
        setup->stream = stream;
 
675
        setup->setconf_cb = cb;
 
676
 
 
677
        for (; caps != NULL; caps = g_slist_next(caps)) {
 
678
                struct avdtp_service_capability *cap = caps->data;
 
679
                struct avdtp_media_codec_capability *codec;
 
680
                gboolean ret;
 
681
 
 
682
                if (cap->category == AVDTP_DELAY_REPORTING &&
 
683
                                        !a2dp_sep->delay_reporting) {
 
684
                        setup->err = g_new(struct avdtp_error, 1);
 
685
                        avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
 
686
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
687
                        goto done;
 
688
                }
 
689
 
 
690
                if (cap->category != AVDTP_MEDIA_CODEC)
 
691
                        continue;
 
692
 
 
693
                codec = (struct avdtp_media_codec_capability *) cap->data;
 
694
 
 
695
                if (codec->media_codec_type != a2dp_sep->codec) {
 
696
                        setup->err = g_new(struct avdtp_error, 1);
 
697
                        avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
 
698
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
699
                        goto done;
 
700
                }
 
701
 
 
702
                ret = a2dp_sep->endpoint->set_configuration(a2dp_sep,
 
703
                                                setup->dev, codec->data,
 
704
                                                cap->length - sizeof(*codec),
 
705
                                                setup,
 
706
                                                endpoint_setconf_cb,
 
707
                                                a2dp_sep->user_data);
 
708
                if (ret == 0)
 
709
                        return TRUE;
 
710
 
 
711
                setup->err = g_new(struct avdtp_error, 1);
 
712
                avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
 
713
                                        AVDTP_UNSUPPORTED_CONFIGURATION);
 
714
                break;
 
715
        }
 
716
 
 
717
done:
 
718
        g_idle_add(auto_config, setup);
 
719
        return TRUE;
 
720
}
 
721
 
 
722
static gboolean endpoint_getcap_ind(struct avdtp *session,
 
723
                                        struct avdtp_local_sep *sep,
 
724
                                        gboolean get_all, GSList **caps,
 
725
                                        uint8_t *err, void *user_data)
 
726
{
 
727
        struct a2dp_sep *a2dp_sep = user_data;
 
728
        struct avdtp_service_capability *media_transport, *media_codec;
 
729
        struct avdtp_media_codec_capability *codec_caps;
 
730
        uint8_t *capabilities;
 
731
        size_t length;
 
732
 
 
733
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
734
                DBG("Sink %p: Get_Capability_Ind", sep);
 
735
        else
 
736
                DBG("Source %p: Get_Capability_Ind", sep);
 
737
 
 
738
        *caps = NULL;
 
739
 
 
740
        media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
 
741
                                                NULL, 0);
 
742
 
 
743
        *caps = g_slist_append(*caps, media_transport);
 
744
 
 
745
        length = a2dp_sep->endpoint->get_capabilities(a2dp_sep, &capabilities,
 
746
                                                        a2dp_sep->user_data);
 
747
 
 
748
        codec_caps = g_malloc0(sizeof(*codec_caps) + length);
 
749
        codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
 
750
        codec_caps->media_codec_type = a2dp_sep->codec;
 
751
        memcpy(codec_caps->data, capabilities, length);
 
752
 
 
753
        media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
 
754
                                                sizeof(*codec_caps) + length);
 
755
 
 
756
        *caps = g_slist_append(*caps, media_codec);
 
757
        g_free(codec_caps);
 
758
 
 
759
        if (get_all) {
 
760
                struct avdtp_service_capability *delay_reporting;
 
761
                delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
 
762
                                                                NULL, 0);
 
763
                *caps = g_slist_append(*caps, delay_reporting);
 
764
        }
 
765
 
 
766
        return TRUE;
 
767
}
 
768
 
 
769
static void endpoint_open_cb(struct a2dp_setup *setup, gboolean ret)
 
770
{
 
771
        int err;
 
772
 
 
773
        if (ret == FALSE) {
 
774
                setup->stream = NULL;
 
775
                finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
 
776
                return;
 
777
        }
 
778
 
 
779
        err = avdtp_open(setup->session, setup->stream);
 
780
        if (err == 0)
 
781
                return;
 
782
 
 
783
        error("Error on avdtp_open %s (%d)", strerror(-err), -err);
 
784
        setup->stream = NULL;
 
785
        finalize_setup_errno(setup, err, finalize_config, NULL);
 
786
}
 
787
 
 
788
static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
789
                                struct avdtp_stream *stream,
 
790
                                struct avdtp_error *err, void *user_data)
 
791
{
 
792
        struct a2dp_sep *a2dp_sep = user_data;
 
793
        struct a2dp_setup *setup;
 
794
        struct audio_device *dev;
 
795
        int ret;
 
796
 
 
797
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
798
                DBG("Sink %p: Set_Configuration_Cfm", sep);
 
799
        else
 
800
                DBG("Source %p: Set_Configuration_Cfm", sep);
 
801
 
 
802
        setup = find_setup_by_session(session);
 
803
 
 
804
        if (err) {
 
805
                if (setup) {
 
806
                        setup->err = err;
 
807
                        finalize_config(setup);
 
808
                }
 
809
                return;
 
810
        }
 
811
 
 
812
        avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
 
813
        a2dp_sep->stream = stream;
 
814
 
 
815
        if (!setup)
 
816
                return;
 
817
 
 
818
        dev = a2dp_get_dev(session);
 
819
 
 
820
        /* Notify D-Bus interface of the new stream */
 
821
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
 
822
                sink_new_stream(dev, session, setup->stream);
 
823
        else
 
824
                source_new_stream(dev, session, setup->stream);
 
825
 
 
826
        /* Notify Endpoint */
 
827
        if (a2dp_sep->endpoint) {
 
828
                struct avdtp_service_capability *service;
 
829
                struct avdtp_media_codec_capability *codec;
 
830
                int err;
 
831
 
 
832
                service = avdtp_stream_get_codec(stream);
 
833
                codec = (struct avdtp_media_codec_capability *) service->data;
 
834
 
 
835
                err = a2dp_sep->endpoint->set_configuration(a2dp_sep, dev,
 
836
                                                codec->data, service->length -
 
837
                                                sizeof(*codec),
 
838
                                                setup,
 
839
                                                endpoint_open_cb,
 
840
                                                a2dp_sep->user_data);
 
841
                if (err == 0)
 
842
                        return;
 
843
 
 
844
                setup->stream = NULL;
 
845
                finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
 
846
                return;
 
847
        }
 
848
 
 
849
        ret = avdtp_open(session, stream);
 
850
        if (ret < 0) {
 
851
                error("Error on avdtp_open %s (%d)", strerror(-ret), -ret);
 
852
                setup->stream = NULL;
 
853
                finalize_setup_errno(setup, ret, finalize_config, NULL);
 
854
        }
 
855
}
 
856
 
 
857
static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
858
                                uint8_t *err, void *user_data)
 
859
{
 
860
        struct a2dp_sep *a2dp_sep = user_data;
 
861
 
 
862
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
863
                DBG("Sink %p: Get_Configuration_Ind", sep);
 
864
        else
 
865
                DBG("Source %p: Get_Configuration_Ind", sep);
 
866
        return TRUE;
 
867
}
 
868
 
 
869
static void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
870
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
871
                        void *user_data)
 
872
{
 
873
        struct a2dp_sep *a2dp_sep = user_data;
 
874
 
 
875
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
876
                DBG("Sink %p: Set_Configuration_Cfm", sep);
 
877
        else
 
878
                DBG("Source %p: Set_Configuration_Cfm", sep);
 
879
}
 
880
 
 
881
static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
882
                                struct avdtp_stream *stream, uint8_t *err,
 
883
                                void *user_data)
 
884
{
 
885
        struct a2dp_sep *a2dp_sep = user_data;
 
886
        struct a2dp_setup *setup;
 
887
 
 
888
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
889
                DBG("Sink %p: Open_Ind", sep);
 
890
        else
 
891
                DBG("Source %p: Open_Ind", sep);
 
892
 
 
893
        setup = find_setup_by_session(session);
 
894
        if (!setup)
 
895
                return TRUE;
 
896
 
 
897
        if (setup->reconfigure)
 
898
                setup->reconfigure = FALSE;
 
899
 
 
900
        finalize_config(setup);
 
901
 
 
902
        return TRUE;
 
903
}
 
904
 
 
905
static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
906
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
907
                        void *user_data)
 
908
{
 
909
        struct a2dp_sep *a2dp_sep = user_data;
 
910
        struct a2dp_setup *setup;
 
911
 
 
912
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
913
                DBG("Sink %p: Open_Cfm", sep);
 
914
        else
 
915
                DBG("Source %p: Open_Cfm", sep);
 
916
 
 
917
        setup = find_setup_by_session(session);
 
918
        if (!setup)
 
919
                return;
 
920
 
 
921
        if (setup->reconfigure)
 
922
                setup->reconfigure = FALSE;
 
923
 
 
924
        if (err) {
 
925
                setup->stream = NULL;
 
926
                setup->err = err;
 
927
        }
 
928
 
 
929
        finalize_config(setup);
 
930
}
 
931
 
 
932
static gboolean suspend_timeout(struct a2dp_sep *sep)
 
933
{
 
934
        if (avdtp_suspend(sep->session, sep->stream) == 0)
 
935
                sep->suspending = TRUE;
 
936
 
 
937
        sep->suspend_timer = 0;
 
938
 
 
939
        avdtp_unref(sep->session);
 
940
        sep->session = NULL;
 
941
 
 
942
        return FALSE;
 
943
}
 
944
 
 
945
static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
946
                                struct avdtp_stream *stream, uint8_t *err,
 
947
                                void *user_data)
 
948
{
 
949
        struct a2dp_sep *a2dp_sep = user_data;
 
950
        struct a2dp_setup *setup;
 
951
 
 
952
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
953
                DBG("Sink %p: Start_Ind", sep);
 
954
        else
 
955
                DBG("Source %p: Start_Ind", sep);
 
956
 
 
957
        if (!a2dp_sep->locked) {
 
958
                a2dp_sep->session = avdtp_ref(session);
 
959
                a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
 
960
                                                (GSourceFunc) suspend_timeout,
 
961
                                                a2dp_sep);
 
962
        }
 
963
 
 
964
        if (!a2dp_sep->starting)
 
965
                return TRUE;
 
966
 
 
967
        a2dp_sep->starting = FALSE;
 
968
 
 
969
        setup = find_setup_by_session(session);
 
970
        if (setup)
 
971
                finalize_resume(setup);
 
972
 
 
973
        return TRUE;
 
974
}
 
975
 
 
976
static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
977
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
978
                        void *user_data)
 
979
{
 
980
        struct a2dp_sep *a2dp_sep = user_data;
 
981
        struct a2dp_setup *setup;
 
982
 
 
983
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
984
                DBG("Sink %p: Start_Cfm", sep);
 
985
        else
 
986
                DBG("Source %p: Start_Cfm", sep);
 
987
 
 
988
        a2dp_sep->starting = FALSE;
 
989
 
 
990
        setup = find_setup_by_session(session);
 
991
        if (!setup)
 
992
                return;
 
993
 
 
994
        if (err) {
 
995
                setup->stream = NULL;
 
996
                setup->err = err;
 
997
        }
 
998
 
 
999
        finalize_resume(setup);
 
1000
}
 
1001
 
 
1002
static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
1003
                                struct avdtp_stream *stream, uint8_t *err,
 
1004
                                void *user_data)
 
1005
{
 
1006
        struct a2dp_sep *a2dp_sep = user_data;
 
1007
        struct a2dp_setup *setup;
 
1008
        gboolean start;
 
1009
        int start_err;
 
1010
 
 
1011
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1012
                DBG("Sink %p: Suspend_Ind", sep);
 
1013
        else
 
1014
                DBG("Source %p: Suspend_Ind", sep);
 
1015
 
 
1016
        if (a2dp_sep->suspend_timer) {
 
1017
                g_source_remove(a2dp_sep->suspend_timer);
 
1018
                a2dp_sep->suspend_timer = 0;
 
1019
                avdtp_unref(a2dp_sep->session);
 
1020
                a2dp_sep->session = NULL;
 
1021
        }
 
1022
 
 
1023
        if (!a2dp_sep->suspending)
 
1024
                return TRUE;
 
1025
 
 
1026
        a2dp_sep->suspending = FALSE;
 
1027
 
 
1028
        setup = find_setup_by_session(session);
 
1029
        if (!setup)
 
1030
                return TRUE;
 
1031
 
 
1032
        start = setup->start;
 
1033
        setup->start = FALSE;
 
1034
 
 
1035
        finalize_suspend(setup);
 
1036
 
 
1037
        if (!start)
 
1038
                return TRUE;
 
1039
 
 
1040
        start_err = avdtp_start(session, a2dp_sep->stream);
 
1041
        if (start_err < 0 && start_err != -EINPROGRESS) {
 
1042
                error("avdtp_start: %s (%d)", strerror(-start_err),
 
1043
                                                                -start_err);
 
1044
                finalize_setup_errno(setup, start_err, finalize_resume);
 
1045
        }
 
1046
 
 
1047
        return TRUE;
 
1048
}
 
1049
 
 
1050
static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
1051
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
1052
                        void *user_data)
 
1053
{
 
1054
        struct a2dp_sep *a2dp_sep = user_data;
 
1055
        struct a2dp_setup *setup;
 
1056
        gboolean start;
 
1057
        int start_err;
 
1058
 
 
1059
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1060
                DBG("Sink %p: Suspend_Cfm", sep);
 
1061
        else
 
1062
                DBG("Source %p: Suspend_Cfm", sep);
 
1063
 
 
1064
        a2dp_sep->suspending = FALSE;
 
1065
 
 
1066
        setup = find_setup_by_session(session);
 
1067
        if (!setup)
 
1068
                return;
 
1069
 
 
1070
        start = setup->start;
 
1071
        setup->start = FALSE;
 
1072
 
 
1073
        if (err) {
 
1074
                setup->stream = NULL;
 
1075
                setup->err = err;
 
1076
        }
 
1077
 
 
1078
        finalize_suspend(setup);
 
1079
 
 
1080
        if (!start)
 
1081
                return;
 
1082
 
 
1083
        if (err) {
 
1084
                finalize_resume(setup);
 
1085
                return;
 
1086
        }
 
1087
 
 
1088
        start_err = avdtp_start(session, a2dp_sep->stream);
 
1089
        if (start_err < 0 && start_err != -EINPROGRESS) {
 
1090
                error("avdtp_start: %s (%d)", strerror(-start_err),
 
1091
                                                                -start_err);
 
1092
                finalize_setup_errno(setup, start_err, finalize_suspend, NULL);
 
1093
        }
 
1094
}
 
1095
 
 
1096
static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
1097
                                struct avdtp_stream *stream, uint8_t *err,
 
1098
                                void *user_data)
 
1099
{
 
1100
        struct a2dp_sep *a2dp_sep = user_data;
 
1101
        struct a2dp_setup *setup;
 
1102
 
 
1103
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1104
                DBG("Sink %p: Close_Ind", sep);
 
1105
        else
 
1106
                DBG("Source %p: Close_Ind", sep);
 
1107
 
 
1108
        setup = find_setup_by_session(session);
 
1109
        if (!setup)
 
1110
                return TRUE;
 
1111
 
 
1112
        finalize_setup_errno(setup, -ECONNRESET, finalize_suspend,
 
1113
                                                        finalize_resume, NULL);
 
1114
 
 
1115
        return TRUE;
 
1116
}
 
1117
 
 
1118
static gboolean a2dp_reconfigure(gpointer data)
 
1119
{
 
1120
        struct a2dp_setup *setup = data;
 
1121
        struct a2dp_sep *sep = setup->sep;
 
1122
        int posix_err;
 
1123
        struct avdtp_media_codec_capability *rsep_codec;
 
1124
        struct avdtp_service_capability *cap;
 
1125
 
 
1126
        if (setup->rsep) {
 
1127
                cap = avdtp_get_codec(setup->rsep);
 
1128
                rsep_codec = (struct avdtp_media_codec_capability *) cap->data;
 
1129
        }
 
1130
 
 
1131
        if (!setup->rsep || sep->codec != rsep_codec->media_codec_type)
 
1132
                setup->rsep = avdtp_find_remote_sep(setup->session, sep->lsep);
 
1133
 
 
1134
        posix_err = avdtp_set_configuration(setup->session, setup->rsep,
 
1135
                                                sep->lsep,
 
1136
                                                setup->caps,
 
1137
                                                &setup->stream);
 
1138
        if (posix_err < 0) {
 
1139
                error("avdtp_set_configuration: %s", strerror(-posix_err));
 
1140
                goto failed;
 
1141
        }
 
1142
 
 
1143
        return FALSE;
 
1144
 
 
1145
failed:
 
1146
        finalize_setup_errno(setup, posix_err, finalize_config, NULL);
 
1147
        return FALSE;
 
1148
}
 
1149
 
 
1150
static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
1151
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
1152
                        void *user_data)
 
1153
{
 
1154
        struct a2dp_sep *a2dp_sep = user_data;
 
1155
        struct a2dp_setup *setup;
 
1156
 
 
1157
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1158
                DBG("Sink %p: Close_Cfm", sep);
 
1159
        else
 
1160
                DBG("Source %p: Close_Cfm", sep);
 
1161
 
 
1162
        setup = find_setup_by_session(session);
 
1163
        if (!setup)
 
1164
                return;
 
1165
 
 
1166
        if (err) {
 
1167
                setup->stream = NULL;
 
1168
                setup->err = err;
 
1169
                finalize_config(setup);
 
1170
                return;
 
1171
        }
 
1172
 
 
1173
        if (!setup->rsep)
 
1174
                setup->rsep = avdtp_stream_get_remote_sep(stream);
 
1175
 
 
1176
        if (setup->reconfigure)
 
1177
                g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
 
1178
}
 
1179
 
 
1180
static void abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
1181
                                struct avdtp_stream *stream, uint8_t *err,
 
1182
                                void *user_data)
 
1183
{
 
1184
        struct a2dp_sep *a2dp_sep = user_data;
 
1185
        struct a2dp_setup *setup;
 
1186
 
 
1187
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1188
                DBG("Sink %p: Abort_Ind", sep);
 
1189
        else
 
1190
                DBG("Source %p: Abort_Ind", sep);
 
1191
 
 
1192
        a2dp_sep->stream = NULL;
 
1193
 
 
1194
        setup = find_setup_by_session(session);
 
1195
        if (!setup)
 
1196
                return;
 
1197
 
 
1198
        finalize_setup_errno(setup, -ECONNRESET, finalize_suspend,
 
1199
                                                        finalize_resume,
 
1200
                                                        finalize_config);
 
1201
 
 
1202
        return;
 
1203
}
 
1204
 
 
1205
static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
1206
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
1207
                        void *user_data)
 
1208
{
 
1209
        struct a2dp_sep *a2dp_sep = user_data;
 
1210
        struct a2dp_setup *setup;
 
1211
 
 
1212
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1213
                DBG("Sink %p: Abort_Cfm", sep);
 
1214
        else
 
1215
                DBG("Source %p: Abort_Cfm", sep);
 
1216
 
 
1217
        setup = find_setup_by_session(session);
 
1218
        if (!setup)
 
1219
                return;
 
1220
 
 
1221
        setup_unref(setup);
 
1222
}
 
1223
 
 
1224
static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 
1225
                                uint8_t *err, void *user_data)
 
1226
{
 
1227
        struct a2dp_sep *a2dp_sep = user_data;
 
1228
 
 
1229
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1230
                DBG("Sink %p: ReConfigure_Ind", sep);
 
1231
        else
 
1232
                DBG("Source %p: ReConfigure_Ind", sep);
 
1233
 
 
1234
        return TRUE;
 
1235
}
 
1236
 
 
1237
static gboolean delayreport_ind(struct avdtp *session,
 
1238
                                struct avdtp_local_sep *sep,
 
1239
                                uint8_t rseid, uint16_t delay,
 
1240
                                uint8_t *err, void *user_data)
 
1241
{
 
1242
        struct a2dp_sep *a2dp_sep = user_data;
 
1243
        struct audio_device *dev = a2dp_get_dev(session);
 
1244
 
 
1245
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1246
                DBG("Sink %p: DelayReport_Ind", sep);
 
1247
        else
 
1248
                DBG("Source %p: DelayReport_Ind", sep);
 
1249
 
 
1250
        unix_delay_report(dev, rseid, delay);
 
1251
 
 
1252
        return TRUE;
 
1253
}
 
1254
 
 
1255
static gboolean endpoint_delayreport_ind(struct avdtp *session,
 
1256
                                                struct avdtp_local_sep *sep,
 
1257
                                                uint8_t rseid, uint16_t delay,
 
1258
                                                uint8_t *err, void *user_data)
 
1259
{
 
1260
        struct a2dp_sep *a2dp_sep = user_data;
 
1261
 
 
1262
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1263
                DBG("Sink %p: DelayReport_Ind", sep);
 
1264
        else
 
1265
                DBG("Source %p: DelayReport_Ind", sep);
 
1266
 
 
1267
        if (a2dp_sep->endpoint == NULL ||
 
1268
                                a2dp_sep->endpoint->set_delay == NULL)
 
1269
                return FALSE;
 
1270
 
 
1271
        a2dp_sep->endpoint->set_delay(a2dp_sep, delay, a2dp_sep->user_data);
 
1272
 
 
1273
        return TRUE;
 
1274
}
 
1275
 
 
1276
static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
1277
                        struct avdtp_stream *stream, struct avdtp_error *err,
 
1278
                        void *user_data)
 
1279
{
 
1280
        struct a2dp_sep *a2dp_sep = user_data;
 
1281
        struct a2dp_setup *setup;
 
1282
 
 
1283
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1284
                DBG("Sink %p: ReConfigure_Cfm", sep);
 
1285
        else
 
1286
                DBG("Source %p: ReConfigure_Cfm", sep);
 
1287
 
 
1288
        setup = find_setup_by_session(session);
 
1289
        if (!setup)
 
1290
                return;
 
1291
 
 
1292
        if (err) {
 
1293
                setup->stream = NULL;
 
1294
                setup->err = err;
 
1295
        }
 
1296
 
 
1297
        finalize_config(setup);
 
1298
}
 
1299
 
 
1300
static void delay_report_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
 
1301
                                struct avdtp_stream *stream,
 
1302
                                struct avdtp_error *err, void *user_data)
 
1303
{
 
1304
        struct a2dp_sep *a2dp_sep = user_data;
 
1305
 
 
1306
        if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
 
1307
                DBG("Sink %p: DelayReport_Cfm", sep);
 
1308
        else
 
1309
                DBG("Source %p: DelayReport_Cfm", sep);
 
1310
}
 
1311
 
 
1312
static struct avdtp_sep_cfm cfm = {
 
1313
        .set_configuration      = setconf_cfm,
 
1314
        .get_configuration      = getconf_cfm,
 
1315
        .open                   = open_cfm,
 
1316
        .start                  = start_cfm,
 
1317
        .suspend                = suspend_cfm,
 
1318
        .close                  = close_cfm,
 
1319
        .abort                  = abort_cfm,
 
1320
        .reconfigure            = reconf_cfm,
 
1321
        .delay_report           = delay_report_cfm,
 
1322
};
 
1323
 
 
1324
static struct avdtp_sep_ind sbc_ind = {
 
1325
        .get_capability         = sbc_getcap_ind,
 
1326
        .set_configuration      = sbc_setconf_ind,
 
1327
        .get_configuration      = getconf_ind,
 
1328
        .open                   = open_ind,
 
1329
        .start                  = start_ind,
 
1330
        .suspend                = suspend_ind,
 
1331
        .close                  = close_ind,
 
1332
        .abort                  = abort_ind,
 
1333
        .reconfigure            = reconf_ind,
 
1334
        .delayreport            = delayreport_ind,
 
1335
};
 
1336
 
 
1337
static struct avdtp_sep_ind mpeg_ind = {
 
1338
        .get_capability         = mpeg_getcap_ind,
 
1339
        .set_configuration      = mpeg_setconf_ind,
 
1340
        .get_configuration      = getconf_ind,
 
1341
        .open                   = open_ind,
 
1342
        .start                  = start_ind,
 
1343
        .suspend                = suspend_ind,
 
1344
        .close                  = close_ind,
 
1345
        .abort                  = abort_ind,
 
1346
        .reconfigure            = reconf_ind,
 
1347
        .delayreport            = delayreport_ind,
 
1348
};
 
1349
 
 
1350
static struct avdtp_sep_ind endpoint_ind = {
 
1351
        .get_capability         = endpoint_getcap_ind,
 
1352
        .set_configuration      = endpoint_setconf_ind,
 
1353
        .get_configuration      = getconf_ind,
 
1354
        .open                   = open_ind,
 
1355
        .start                  = start_ind,
 
1356
        .suspend                = suspend_ind,
 
1357
        .close                  = close_ind,
 
1358
        .abort                  = abort_ind,
 
1359
        .reconfigure            = reconf_ind,
 
1360
        .delayreport            = endpoint_delayreport_ind,
 
1361
};
 
1362
 
 
1363
static sdp_record_t *a2dp_record(uint8_t type, uint16_t avdtp_ver)
 
1364
{
 
1365
        sdp_list_t *svclass_id, *pfseq, *apseq, *root;
 
1366
        uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
 
1367
        sdp_profile_desc_t profile[1];
 
1368
        sdp_list_t *aproto, *proto[2];
 
1369
        sdp_record_t *record;
 
1370
        sdp_data_t *psm, *version, *features;
 
1371
        uint16_t lp = AVDTP_UUID;
 
1372
        uint16_t a2dp_ver = 0x0102, feat = 0x000f;
 
1373
 
 
1374
        record = sdp_record_alloc();
 
1375
        if (!record)
 
1376
                return NULL;
 
1377
 
 
1378
        sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
 
1379
        root = sdp_list_append(0, &root_uuid);
 
1380
        sdp_set_browse_groups(record, root);
 
1381
 
 
1382
        if (type == AVDTP_SEP_TYPE_SOURCE)
 
1383
                sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
 
1384
        else
 
1385
                sdp_uuid16_create(&a2dp_uuid, AUDIO_SINK_SVCLASS_ID);
 
1386
        svclass_id = sdp_list_append(0, &a2dp_uuid);
 
1387
        sdp_set_service_classes(record, svclass_id);
 
1388
 
 
1389
        sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
 
1390
        profile[0].version = a2dp_ver;
 
1391
        pfseq = sdp_list_append(0, &profile[0]);
 
1392
        sdp_set_profile_descs(record, pfseq);
 
1393
 
 
1394
        sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
 
1395
        proto[0] = sdp_list_append(0, &l2cap_uuid);
 
1396
        psm = sdp_data_alloc(SDP_UINT16, &lp);
 
1397
        proto[0] = sdp_list_append(proto[0], psm);
 
1398
        apseq = sdp_list_append(0, proto[0]);
 
1399
 
 
1400
        sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
 
1401
        proto[1] = sdp_list_append(0, &avdtp_uuid);
 
1402
        version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
 
1403
        proto[1] = sdp_list_append(proto[1], version);
 
1404
        apseq = sdp_list_append(apseq, proto[1]);
 
1405
 
 
1406
        aproto = sdp_list_append(0, apseq);
 
1407
        sdp_set_access_protos(record, aproto);
 
1408
 
 
1409
        features = sdp_data_alloc(SDP_UINT16, &feat);
 
1410
        sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
 
1411
 
 
1412
        if (type == AVDTP_SEP_TYPE_SOURCE)
 
1413
                sdp_set_info_attr(record, "Audio Source", 0, 0);
 
1414
        else
 
1415
                sdp_set_info_attr(record, "Audio Sink", 0, 0);
 
1416
 
 
1417
        free(psm);
 
1418
        free(version);
 
1419
        sdp_list_free(proto[0], 0);
 
1420
        sdp_list_free(proto[1], 0);
 
1421
        sdp_list_free(apseq, 0);
 
1422
        sdp_list_free(pfseq, 0);
 
1423
        sdp_list_free(aproto, 0);
 
1424
        sdp_list_free(root, 0);
 
1425
        sdp_list_free(svclass_id, 0);
 
1426
 
 
1427
        return record;
 
1428
}
 
1429
 
 
1430
static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
 
1431
{
 
1432
 
 
1433
        for (; list; list = list->next) {
 
1434
                struct a2dp_server *server = list->data;
 
1435
 
 
1436
                if (bacmp(&server->src, src) == 0)
 
1437
                        return server;
 
1438
        }
 
1439
 
 
1440
        return NULL;
 
1441
}
 
1442
 
 
1443
int a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
 
1444
{
 
1445
        int sbc_srcs = 0, sbc_sinks = 0;
 
1446
        int mpeg12_srcs = 0, mpeg12_sinks = 0;
 
1447
        gboolean source = TRUE, sink = TRUE, socket = FALSE;
 
1448
        gboolean delay_reporting = FALSE;
 
1449
        char *str;
 
1450
        GError *err = NULL;
 
1451
        int i;
 
1452
        struct a2dp_server *server;
 
1453
 
 
1454
        if (!config)
 
1455
                goto proceed;
 
1456
 
 
1457
        str = g_key_file_get_string(config, "General", "Enable", &err);
 
1458
 
 
1459
        if (err) {
 
1460
                DBG("audio.conf: %s", err->message);
 
1461
                g_clear_error(&err);
 
1462
        } else {
 
1463
                if (strstr(str, "Sink"))
 
1464
                        source = TRUE;
 
1465
                if (strstr(str, "Source"))
 
1466
                        sink = TRUE;
 
1467
                if (strstr(str, "Socket"))
 
1468
                        socket = TRUE;
 
1469
                g_free(str);
 
1470
        }
 
1471
 
 
1472
        str = g_key_file_get_string(config, "General", "Disable", &err);
 
1473
 
 
1474
        if (err) {
 
1475
                DBG("audio.conf: %s", err->message);
 
1476
                g_clear_error(&err);
 
1477
        } else {
 
1478
                if (strstr(str, "Sink"))
 
1479
                        source = FALSE;
 
1480
                if (strstr(str, "Source"))
 
1481
                        sink = FALSE;
 
1482
                if (strstr(str, "Socket"))
 
1483
                        socket = FALSE;
 
1484
                g_free(str);
 
1485
        }
 
1486
 
 
1487
        /* Don't register any local sep if Socket is disabled */
 
1488
        if (socket == FALSE)
 
1489
                goto proceed;
 
1490
 
 
1491
        str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
 
1492
        if (err) {
 
1493
                DBG("audio.conf: %s", err->message);
 
1494
                g_clear_error(&err);
 
1495
                sbc_srcs = 1;
 
1496
        } else {
 
1497
                sbc_srcs = atoi(str);
 
1498
                g_free(str);
 
1499
        }
 
1500
 
 
1501
        str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
 
1502
        if (err) {
 
1503
                DBG("audio.conf: %s", err->message);
 
1504
                g_clear_error(&err);
 
1505
        } else {
 
1506
                mpeg12_srcs = atoi(str);
 
1507
                g_free(str);
 
1508
        }
 
1509
 
 
1510
        str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
 
1511
        if (err) {
 
1512
                DBG("audio.conf: %s", err->message);
 
1513
                g_clear_error(&err);
 
1514
                sbc_sinks = 1;
 
1515
        } else {
 
1516
                sbc_sinks = atoi(str);
 
1517
                g_free(str);
 
1518
        }
 
1519
 
 
1520
        str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
 
1521
        if (err) {
 
1522
                DBG("audio.conf: %s", err->message);
 
1523
                g_clear_error(&err);
 
1524
        } else {
 
1525
                mpeg12_sinks = atoi(str);
 
1526
                g_free(str);
 
1527
        }
 
1528
 
 
1529
proceed:
 
1530
        if (!connection)
 
1531
                connection = dbus_connection_ref(conn);
 
1532
 
 
1533
        server = find_server(servers, src);
 
1534
        if (!server) {
 
1535
                int av_err;
 
1536
 
 
1537
                server = g_new0(struct a2dp_server, 1);
 
1538
                if (!server)
 
1539
                        return -ENOMEM;
 
1540
 
 
1541
                av_err = avdtp_init(src, config, &server->version);
 
1542
                if (av_err < 0) {
 
1543
                        g_free(server);
 
1544
                        return av_err;
 
1545
                }
 
1546
 
 
1547
                bacpy(&server->src, src);
 
1548
                servers = g_slist_append(servers, server);
 
1549
        }
 
1550
 
 
1551
        if (config)
 
1552
                delay_reporting = g_key_file_get_boolean(config, "A2DP",
 
1553
                                                "DelayReporting", NULL);
 
1554
 
 
1555
        if (delay_reporting)
 
1556
                server->version = 0x0103;
 
1557
        else
 
1558
                server->version = 0x0102;
 
1559
 
 
1560
        server->source_enabled = source;
 
1561
        if (source) {
 
1562
                for (i = 0; i < sbc_srcs; i++)
 
1563
                        a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
 
1564
                                        A2DP_CODEC_SBC, delay_reporting,
 
1565
                                        NULL, NULL, NULL, NULL);
 
1566
 
 
1567
                for (i = 0; i < mpeg12_srcs; i++)
 
1568
                        a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
 
1569
                                        A2DP_CODEC_MPEG12, delay_reporting,
 
1570
                                        NULL, NULL, NULL, NULL);
 
1571
        }
 
1572
        server->sink_enabled = sink;
 
1573
        if (sink) {
 
1574
                for (i = 0; i < sbc_sinks; i++)
 
1575
                        a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
 
1576
                                        A2DP_CODEC_SBC, delay_reporting,
 
1577
                                        NULL, NULL, NULL, NULL);
 
1578
 
 
1579
                for (i = 0; i < mpeg12_sinks; i++)
 
1580
                        a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
 
1581
                                        A2DP_CODEC_MPEG12, delay_reporting,
 
1582
                                        NULL, NULL, NULL, NULL);
 
1583
        }
 
1584
 
 
1585
        return 0;
 
1586
}
 
1587
 
 
1588
static void a2dp_unregister_sep(struct a2dp_sep *sep)
 
1589
{
 
1590
        if (sep->destroy) {
 
1591
                sep->destroy(sep->user_data);
 
1592
                sep->endpoint = NULL;
 
1593
        }
 
1594
 
 
1595
        avdtp_unregister_sep(sep->lsep);
 
1596
        g_free(sep);
 
1597
}
 
1598
 
 
1599
void a2dp_unregister(const bdaddr_t *src)
 
1600
{
 
1601
        struct a2dp_server *server;
 
1602
 
 
1603
        server = find_server(servers, src);
 
1604
        if (!server)
 
1605
                return;
 
1606
 
 
1607
        g_slist_free_full(server->sinks, (GDestroyNotify) a2dp_unregister_sep);
 
1608
        g_slist_free_full(server->sources,
 
1609
                                        (GDestroyNotify) a2dp_unregister_sep);
 
1610
 
 
1611
        avdtp_exit(src);
 
1612
 
 
1613
        servers = g_slist_remove(servers, server);
 
1614
 
 
1615
        if (server->source_record_id)
 
1616
                remove_record_from_server(server->source_record_id);
 
1617
 
 
1618
        if (server->sink_record_id)
 
1619
                remove_record_from_server(server->sink_record_id);
 
1620
 
 
1621
        g_free(server);
 
1622
 
 
1623
        if (servers)
 
1624
                return;
 
1625
 
 
1626
        dbus_connection_unref(connection);
 
1627
        connection = NULL;
 
1628
}
 
1629
 
 
1630
struct a2dp_sep *a2dp_add_sep(const bdaddr_t *src, uint8_t type,
 
1631
                                uint8_t codec, gboolean delay_reporting,
 
1632
                                struct a2dp_endpoint *endpoint,
 
1633
                                void *user_data, GDestroyNotify destroy,
 
1634
                                int *err)
 
1635
{
 
1636
        struct a2dp_server *server;
 
1637
        struct a2dp_sep *sep;
 
1638
        GSList **l;
 
1639
        uint32_t *record_id;
 
1640
        sdp_record_t *record;
 
1641
        struct avdtp_sep_ind *ind;
 
1642
 
 
1643
        server = find_server(servers, src);
 
1644
        if (server == NULL) {
 
1645
                if (err)
 
1646
                        *err = -EPROTONOSUPPORT;
 
1647
                return NULL;
 
1648
        }
 
1649
 
 
1650
        if (type == AVDTP_SEP_TYPE_SINK && !server->sink_enabled) {
 
1651
                if (err)
 
1652
                        *err = -EPROTONOSUPPORT;
 
1653
                return NULL;
 
1654
        }
 
1655
 
 
1656
        if (type == AVDTP_SEP_TYPE_SOURCE && !server->source_enabled) {
 
1657
                if (err)
 
1658
                        *err = -EPROTONOSUPPORT;
 
1659
                return NULL;
 
1660
        }
 
1661
 
 
1662
        sep = g_new0(struct a2dp_sep, 1);
 
1663
 
 
1664
        if (endpoint) {
 
1665
                ind = &endpoint_ind;
 
1666
                goto proceed;
 
1667
        }
 
1668
 
 
1669
        ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
 
1670
 
 
1671
proceed:
 
1672
        sep->lsep = avdtp_register_sep(&server->src, type,
 
1673
                                        AVDTP_MEDIA_TYPE_AUDIO, codec,
 
1674
                                        delay_reporting, ind, &cfm, sep);
 
1675
        if (sep->lsep == NULL) {
 
1676
                g_free(sep);
 
1677
                if (err)
 
1678
                        *err = -EINVAL;
 
1679
                return NULL;
 
1680
        }
 
1681
 
 
1682
        sep->server = server;
 
1683
        sep->endpoint = endpoint;
 
1684
        sep->codec = codec;
 
1685
        sep->type = type;
 
1686
        sep->delay_reporting = delay_reporting;
 
1687
        sep->user_data = user_data;
 
1688
        sep->destroy = destroy;
 
1689
 
 
1690
        if (type == AVDTP_SEP_TYPE_SOURCE) {
 
1691
                l = &server->sources;
 
1692
                record_id = &server->source_record_id;
 
1693
        } else {
 
1694
                l = &server->sinks;
 
1695
                record_id = &server->sink_record_id;
 
1696
        }
 
1697
 
 
1698
        if (*record_id != 0)
 
1699
                goto add;
 
1700
 
 
1701
        record = a2dp_record(type, server->version);
 
1702
        if (!record) {
 
1703
                error("Unable to allocate new service record");
 
1704
                avdtp_unregister_sep(sep->lsep);
 
1705
                g_free(sep);
 
1706
                if (err)
 
1707
                        *err = -EINVAL;
 
1708
                return NULL;
 
1709
        }
 
1710
 
 
1711
        if (add_record_to_server(&server->src, record) < 0) {
 
1712
                error("Unable to register A2DP service record");\
 
1713
                sdp_record_free(record);
 
1714
                avdtp_unregister_sep(sep->lsep);
 
1715
                g_free(sep);
 
1716
                if (err)
 
1717
                        *err = -EINVAL;
 
1718
                return NULL;
 
1719
        }
 
1720
        *record_id = record->handle;
 
1721
 
 
1722
add:
 
1723
        *l = g_slist_append(*l, sep);
 
1724
 
 
1725
        if (err)
 
1726
                *err = 0;
 
1727
        return sep;
 
1728
}
 
1729
 
 
1730
void a2dp_remove_sep(struct a2dp_sep *sep)
 
1731
{
 
1732
        struct a2dp_server *server = sep->server;
 
1733
 
 
1734
        if (sep->type == AVDTP_SEP_TYPE_SOURCE) {
 
1735
                if (g_slist_find(server->sources, sep) == NULL)
 
1736
                        return;
 
1737
                server->sources = g_slist_remove(server->sources, sep);
 
1738
                if (server->sources == NULL && server->source_record_id) {
 
1739
                        remove_record_from_server(server->source_record_id);
 
1740
                        server->source_record_id = 0;
 
1741
                }
 
1742
        } else {
 
1743
                if (g_slist_find(server->sinks, sep) == NULL)
 
1744
                        return;
 
1745
                server->sinks = g_slist_remove(server->sinks, sep);
 
1746
                if (server->sinks == NULL && server->sink_record_id) {
 
1747
                        remove_record_from_server(server->sink_record_id);
 
1748
                        server->sink_record_id = 0;
 
1749
                }
 
1750
        }
 
1751
 
 
1752
        if (sep->locked)
 
1753
                return;
 
1754
 
 
1755
        a2dp_unregister_sep(sep);
 
1756
}
 
1757
 
 
1758
struct a2dp_sep *a2dp_get(struct avdtp *session,
 
1759
                                struct avdtp_remote_sep *rsep)
 
1760
{
 
1761
        GSList *l;
 
1762
        struct a2dp_server *server;
 
1763
        struct avdtp_service_capability *cap;
 
1764
        struct avdtp_media_codec_capability *codec_cap = NULL;
 
1765
        bdaddr_t src;
 
1766
 
 
1767
        avdtp_get_peers(session, &src, NULL);
 
1768
        server = find_server(servers, &src);
 
1769
        if (!server)
 
1770
                return NULL;
 
1771
 
 
1772
        cap = avdtp_get_codec(rsep);
 
1773
        codec_cap = (void *) cap->data;
 
1774
 
 
1775
        if (avdtp_get_type(rsep) == AVDTP_SEP_TYPE_SINK)
 
1776
                l = server->sources;
 
1777
        else
 
1778
                l = server->sinks;
 
1779
 
 
1780
        for (; l != NULL; l = l->next) {
 
1781
                struct a2dp_sep *sep = l->data;
 
1782
 
 
1783
                if (sep->locked)
 
1784
                        continue;
 
1785
 
 
1786
                if (sep->codec != codec_cap->media_codec_type)
 
1787
                        continue;
 
1788
 
 
1789
                if (!sep->stream || avdtp_has_stream(session, sep->stream))
 
1790
                        return sep;
 
1791
        }
 
1792
 
 
1793
        return NULL;
 
1794
}
 
1795
 
 
1796
static uint8_t default_bitpool(uint8_t freq, uint8_t mode)
 
1797
{
 
1798
        switch (freq) {
 
1799
        case SBC_SAMPLING_FREQ_16000:
 
1800
        case SBC_SAMPLING_FREQ_32000:
 
1801
                return 53;
 
1802
        case SBC_SAMPLING_FREQ_44100:
 
1803
                switch (mode) {
 
1804
                case SBC_CHANNEL_MODE_MONO:
 
1805
                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
 
1806
                        return 31;
 
1807
                case SBC_CHANNEL_MODE_STEREO:
 
1808
                case SBC_CHANNEL_MODE_JOINT_STEREO:
 
1809
                        return 53;
 
1810
                default:
 
1811
                        error("Invalid channel mode %u", mode);
 
1812
                        return 53;
 
1813
                }
 
1814
        case SBC_SAMPLING_FREQ_48000:
 
1815
                switch (mode) {
 
1816
                case SBC_CHANNEL_MODE_MONO:
 
1817
                case SBC_CHANNEL_MODE_DUAL_CHANNEL:
 
1818
                        return 29;
 
1819
                case SBC_CHANNEL_MODE_STEREO:
 
1820
                case SBC_CHANNEL_MODE_JOINT_STEREO:
 
1821
                        return 51;
 
1822
                default:
 
1823
                        error("Invalid channel mode %u", mode);
 
1824
                        return 51;
 
1825
                }
 
1826
        default:
 
1827
                error("Invalid sampling freq %u", freq);
 
1828
                return 53;
 
1829
        }
 
1830
}
 
1831
 
 
1832
static gboolean select_sbc_params(struct sbc_codec_cap *cap,
 
1833
                                        struct sbc_codec_cap *supported)
 
1834
{
 
1835
        unsigned int max_bitpool, min_bitpool;
 
1836
 
 
1837
        memset(cap, 0, sizeof(struct sbc_codec_cap));
 
1838
 
 
1839
        cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
 
1840
        cap->cap.media_codec_type = A2DP_CODEC_SBC;
 
1841
 
 
1842
        if (supported->frequency & SBC_SAMPLING_FREQ_44100)
 
1843
                cap->frequency = SBC_SAMPLING_FREQ_44100;
 
1844
        else if (supported->frequency & SBC_SAMPLING_FREQ_48000)
 
1845
                cap->frequency = SBC_SAMPLING_FREQ_48000;
 
1846
        else if (supported->frequency & SBC_SAMPLING_FREQ_32000)
 
1847
                cap->frequency = SBC_SAMPLING_FREQ_32000;
 
1848
        else if (supported->frequency & SBC_SAMPLING_FREQ_16000)
 
1849
                cap->frequency = SBC_SAMPLING_FREQ_16000;
 
1850
        else {
 
1851
                error("No supported frequencies");
 
1852
                return FALSE;
 
1853
        }
 
1854
 
 
1855
        if (supported->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
 
1856
                cap->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
 
1857
        else if (supported->channel_mode & SBC_CHANNEL_MODE_STEREO)
 
1858
                cap->channel_mode = SBC_CHANNEL_MODE_STEREO;
 
1859
        else if (supported->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
 
1860
                cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
 
1861
        else if (supported->channel_mode & SBC_CHANNEL_MODE_MONO)
 
1862
                cap->channel_mode = SBC_CHANNEL_MODE_MONO;
 
1863
        else {
 
1864
                error("No supported channel modes");
 
1865
                return FALSE;
 
1866
        }
 
1867
 
 
1868
        if (supported->block_length & SBC_BLOCK_LENGTH_16)
 
1869
                cap->block_length = SBC_BLOCK_LENGTH_16;
 
1870
        else if (supported->block_length & SBC_BLOCK_LENGTH_12)
 
1871
                cap->block_length = SBC_BLOCK_LENGTH_12;
 
1872
        else if (supported->block_length & SBC_BLOCK_LENGTH_8)
 
1873
                cap->block_length = SBC_BLOCK_LENGTH_8;
 
1874
        else if (supported->block_length & SBC_BLOCK_LENGTH_4)
 
1875
                cap->block_length = SBC_BLOCK_LENGTH_4;
 
1876
        else {
 
1877
                error("No supported block lengths");
 
1878
                return FALSE;
 
1879
        }
 
1880
 
 
1881
        if (supported->subbands & SBC_SUBBANDS_8)
 
1882
                cap->subbands = SBC_SUBBANDS_8;
 
1883
        else if (supported->subbands & SBC_SUBBANDS_4)
 
1884
                cap->subbands = SBC_SUBBANDS_4;
 
1885
        else {
 
1886
                error("No supported subbands");
 
1887
                return FALSE;
 
1888
        }
 
1889
 
 
1890
        if (supported->allocation_method & SBC_ALLOCATION_LOUDNESS)
 
1891
                cap->allocation_method = SBC_ALLOCATION_LOUDNESS;
 
1892
        else if (supported->allocation_method & SBC_ALLOCATION_SNR)
 
1893
                cap->allocation_method = SBC_ALLOCATION_SNR;
 
1894
 
 
1895
        min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool);
 
1896
        max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),
 
1897
                                                        supported->max_bitpool);
 
1898
 
 
1899
        cap->min_bitpool = min_bitpool;
 
1900
        cap->max_bitpool = max_bitpool;
 
1901
 
 
1902
        return TRUE;
 
1903
}
 
1904
 
 
1905
static gboolean select_capabilities(struct avdtp *session,
 
1906
                                        struct avdtp_remote_sep *rsep,
 
1907
                                        GSList **caps)
 
1908
{
 
1909
        struct avdtp_service_capability *media_transport, *media_codec;
 
1910
        struct sbc_codec_cap sbc_cap;
 
1911
 
 
1912
        media_codec = avdtp_get_codec(rsep);
 
1913
        if (!media_codec)
 
1914
                return FALSE;
 
1915
 
 
1916
        select_sbc_params(&sbc_cap, (struct sbc_codec_cap *) media_codec->data);
 
1917
 
 
1918
        media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
 
1919
                                                NULL, 0);
 
1920
 
 
1921
        *caps = g_slist_append(*caps, media_transport);
 
1922
 
 
1923
        media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
 
1924
                                                sizeof(sbc_cap));
 
1925
 
 
1926
        *caps = g_slist_append(*caps, media_codec);
 
1927
 
 
1928
        if (avdtp_get_delay_reporting(rsep)) {
 
1929
                struct avdtp_service_capability *delay_reporting;
 
1930
                delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
 
1931
                                                                NULL, 0);
 
1932
                *caps = g_slist_append(*caps, delay_reporting);
 
1933
        }
 
1934
 
 
1935
        return TRUE;
 
1936
}
 
1937
 
 
1938
static void select_cb(struct a2dp_setup *setup, void *ret, int size)
 
1939
{
 
1940
        struct avdtp_service_capability *media_transport, *media_codec;
 
1941
        struct avdtp_media_codec_capability *cap;
 
1942
 
 
1943
        if (size < 0) {
 
1944
                DBG("Endpoint replied an invalid configuration");
 
1945
                goto done;
 
1946
        }
 
1947
 
 
1948
        media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
 
1949
                                                NULL, 0);
 
1950
 
 
1951
        setup->caps = g_slist_append(setup->caps, media_transport);
 
1952
 
 
1953
        cap = g_malloc0(sizeof(*cap) + size);
 
1954
        cap->media_type = AVDTP_MEDIA_TYPE_AUDIO;
 
1955
        cap->media_codec_type = setup->sep->codec;
 
1956
        memcpy(cap->data, ret, size);
 
1957
 
 
1958
        media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, cap,
 
1959
                                                sizeof(*cap) + size);
 
1960
 
 
1961
        setup->caps = g_slist_append(setup->caps, media_codec);
 
1962
        g_free(cap);
 
1963
 
 
1964
done:
 
1965
        finalize_select(setup);
 
1966
}
 
1967
 
 
1968
static gboolean auto_select(gpointer data)
 
1969
{
 
1970
        struct a2dp_setup *setup = data;
 
1971
 
 
1972
        finalize_select(setup);
 
1973
 
 
1974
        return FALSE;
 
1975
}
 
1976
 
 
1977
static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
 
1978
                                        const char *sender)
 
1979
{
 
1980
        for (; list; list = list->next) {
 
1981
                struct a2dp_sep *sep = list->data;
 
1982
 
 
1983
                /* Use sender's endpoint if available */
 
1984
                if (sender) {
 
1985
                        const char *name;
 
1986
 
 
1987
                        if (sep->endpoint == NULL)
 
1988
                                continue;
 
1989
 
 
1990
                        name = sep->endpoint->get_name(sep, sep->user_data);
 
1991
                        if (g_strcmp0(sender, name) != 0)
 
1992
                                continue;
 
1993
                }
 
1994
 
 
1995
                if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
 
1996
                        continue;
 
1997
 
 
1998
                return sep;
 
1999
        }
 
2000
 
 
2001
        return NULL;
 
2002
}
 
2003
 
 
2004
static struct a2dp_sep *a2dp_select_sep(struct avdtp *session, uint8_t type,
 
2005
                                        const char *sender)
 
2006
{
 
2007
        struct a2dp_server *server;
 
2008
        struct a2dp_sep *sep;
 
2009
        GSList *l;
 
2010
        bdaddr_t src;
 
2011
 
 
2012
        avdtp_get_peers(session, &src, NULL);
 
2013
        server = find_server(servers, &src);
 
2014
        if (!server)
 
2015
                return NULL;
 
2016
 
 
2017
        l = type == AVDTP_SEP_TYPE_SINK ? server->sources : server->sinks;
 
2018
 
 
2019
        /* Check sender's seps first */
 
2020
        sep = a2dp_find_sep(session, l, sender);
 
2021
        if (sep != NULL)
 
2022
                return sep;
 
2023
 
 
2024
        return a2dp_find_sep(session, l, NULL);
 
2025
}
 
2026
 
 
2027
unsigned int a2dp_select_capabilities(struct avdtp *session,
 
2028
                                        uint8_t type, const char *sender,
 
2029
                                        a2dp_select_cb_t cb,
 
2030
                                        void *user_data)
 
2031
{
 
2032
        struct a2dp_setup *setup;
 
2033
        struct a2dp_setup_cb *cb_data;
 
2034
        struct a2dp_sep *sep;
 
2035
        struct avdtp_service_capability *service;
 
2036
        struct avdtp_media_codec_capability *codec;
 
2037
        int err;
 
2038
 
 
2039
        sep = a2dp_select_sep(session, type, sender);
 
2040
        if (!sep) {
 
2041
                error("Unable to select SEP");
 
2042
                return 0;
 
2043
        }
 
2044
 
 
2045
        setup = a2dp_setup_get(session);
 
2046
        if (!setup)
 
2047
                return 0;
 
2048
 
 
2049
        cb_data = setup_cb_new(setup);
 
2050
        cb_data->select_cb = cb;
 
2051
        cb_data->user_data = user_data;
 
2052
 
 
2053
        setup->sep = sep;
 
2054
        setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
 
2055
 
 
2056
        if (setup->rsep == NULL) {
 
2057
                error("Could not find remote sep");
 
2058
                goto fail;
 
2059
        }
 
2060
 
 
2061
        /* FIXME: Remove auto select when it is not longer possible to register
 
2062
        endpoint in the configuration file */
 
2063
        if (sep->endpoint == NULL) {
 
2064
                if (!select_capabilities(session, setup->rsep,
 
2065
                                        &setup->caps)) {
 
2066
                        error("Unable to auto select remote SEP capabilities");
 
2067
                        goto fail;
 
2068
                }
 
2069
 
 
2070
                g_idle_add(auto_select, setup);
 
2071
 
 
2072
                return cb_data->id;
 
2073
        }
 
2074
 
 
2075
        service = avdtp_get_codec(setup->rsep);
 
2076
        codec = (struct avdtp_media_codec_capability *) service->data;
 
2077
 
 
2078
        err = sep->endpoint->select_configuration(sep, codec->data,
 
2079
                                        service->length - sizeof(*codec),
 
2080
                                        setup,
 
2081
                                        select_cb, sep->user_data);
 
2082
        if (err == 0)
 
2083
                return cb_data->id;
 
2084
 
 
2085
fail:
 
2086
        setup_cb_free(cb_data);
 
2087
        return 0;
 
2088
 
 
2089
}
 
2090
 
 
2091
unsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
 
2092
                                a2dp_config_cb_t cb, GSList *caps,
 
2093
                                void *user_data)
 
2094
{
 
2095
        struct a2dp_setup_cb *cb_data;
 
2096
        GSList *l;
 
2097
        struct a2dp_server *server;
 
2098
        struct a2dp_setup *setup;
 
2099
        struct a2dp_sep *tmp;
 
2100
        struct avdtp_service_capability *cap;
 
2101
        struct avdtp_media_codec_capability *codec_cap = NULL;
 
2102
        int posix_err;
 
2103
        bdaddr_t src;
 
2104
 
 
2105
        avdtp_get_peers(session, &src, NULL);
 
2106
        server = find_server(servers, &src);
 
2107
        if (!server)
 
2108
                return 0;
 
2109
 
 
2110
        for (l = caps; l != NULL; l = l->next) {
 
2111
                cap = l->data;
 
2112
 
 
2113
                if (cap->category != AVDTP_MEDIA_CODEC)
 
2114
                        continue;
 
2115
 
 
2116
                codec_cap = (void *) cap->data;
 
2117
                break;
 
2118
        }
 
2119
 
 
2120
        if (!codec_cap)
 
2121
                return 0;
 
2122
 
 
2123
        if (sep->codec != codec_cap->media_codec_type)
 
2124
                return 0;
 
2125
 
 
2126
        DBG("a2dp_config: selected SEP %p", sep->lsep);
 
2127
 
 
2128
        setup = a2dp_setup_get(session);
 
2129
        if (!setup)
 
2130
                return 0;
 
2131
 
 
2132
        cb_data = setup_cb_new(setup);
 
2133
        cb_data->config_cb = cb;
 
2134
        cb_data->user_data = user_data;
 
2135
 
 
2136
        setup->sep = sep;
 
2137
        setup->stream = sep->stream;
 
2138
 
 
2139
        /* Copy given caps if they are different than current caps */
 
2140
        if (setup->caps != caps) {
 
2141
                g_slist_free_full(setup->caps, g_free);
 
2142
                setup->caps = g_slist_copy(caps);
 
2143
        }
 
2144
 
 
2145
        switch (avdtp_sep_get_state(sep->lsep)) {
 
2146
        case AVDTP_STATE_IDLE:
 
2147
                if (sep->type == AVDTP_SEP_TYPE_SOURCE)
 
2148
                        l = server->sources;
 
2149
                else
 
2150
                        l = server->sinks;
 
2151
 
 
2152
                for (; l != NULL; l = l->next) {
 
2153
                        tmp = l->data;
 
2154
                        if (avdtp_has_stream(session, tmp->stream))
 
2155
                                break;
 
2156
                }
 
2157
 
 
2158
                if (l != NULL) {
 
2159
                        if (a2dp_sep_get_lock(tmp))
 
2160
                                goto failed;
 
2161
                        setup->reconfigure = TRUE;
 
2162
                        if (avdtp_close(session, tmp->stream, FALSE) < 0) {
 
2163
                                error("avdtp_close failed");
 
2164
                                goto failed;
 
2165
                        }
 
2166
                        break;
 
2167
                }
 
2168
 
 
2169
                setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
 
2170
                if (setup->rsep == NULL) {
 
2171
                        error("No matching ACP and INT SEPs found");
 
2172
                        goto failed;
 
2173
                }
 
2174
 
 
2175
                posix_err = avdtp_set_configuration(session, setup->rsep,
 
2176
                                                        sep->lsep, caps,
 
2177
                                                        &setup->stream);
 
2178
                if (posix_err < 0) {
 
2179
                        error("avdtp_set_configuration: %s",
 
2180
                                strerror(-posix_err));
 
2181
                        goto failed;
 
2182
                }
 
2183
                break;
 
2184
        case AVDTP_STATE_OPEN:
 
2185
        case AVDTP_STATE_STREAMING:
 
2186
                if (avdtp_stream_has_capabilities(setup->stream, caps)) {
 
2187
                        DBG("Configuration match: resuming");
 
2188
                        cb_data->source_id = g_idle_add(finalize_config,
 
2189
                                                                setup);
 
2190
                } else if (!setup->reconfigure) {
 
2191
                        setup->reconfigure = TRUE;
 
2192
                        if (avdtp_close(session, sep->stream, FALSE) < 0) {
 
2193
                                error("avdtp_close failed");
 
2194
                                goto failed;
 
2195
                        }
 
2196
                }
 
2197
                break;
 
2198
        default:
 
2199
                error("SEP in bad state for requesting a new stream");
 
2200
                goto failed;
 
2201
        }
 
2202
 
 
2203
        return cb_data->id;
 
2204
 
 
2205
failed:
 
2206
        setup_cb_free(cb_data);
 
2207
        return 0;
 
2208
}
 
2209
 
 
2210
unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
 
2211
                                a2dp_stream_cb_t cb, void *user_data)
 
2212
{
 
2213
        struct a2dp_setup_cb *cb_data;
 
2214
        struct a2dp_setup *setup;
 
2215
 
 
2216
        setup = a2dp_setup_get(session);
 
2217
        if (!setup)
 
2218
                return 0;
 
2219
 
 
2220
        cb_data = setup_cb_new(setup);
 
2221
        cb_data->resume_cb = cb;
 
2222
        cb_data->user_data = user_data;
 
2223
 
 
2224
        setup->sep = sep;
 
2225
        setup->stream = sep->stream;
 
2226
 
 
2227
        switch (avdtp_sep_get_state(sep->lsep)) {
 
2228
        case AVDTP_STATE_IDLE:
 
2229
                goto failed;
 
2230
                break;
 
2231
        case AVDTP_STATE_OPEN:
 
2232
                if (avdtp_start(session, sep->stream) < 0) {
 
2233
                        error("avdtp_start failed");
 
2234
                        goto failed;
 
2235
                }
 
2236
                sep->starting = TRUE;
 
2237
                break;
 
2238
        case AVDTP_STATE_STREAMING:
 
2239
                if (!sep->suspending && sep->suspend_timer) {
 
2240
                        g_source_remove(sep->suspend_timer);
 
2241
                        sep->suspend_timer = 0;
 
2242
                        avdtp_unref(sep->session);
 
2243
                        sep->session = NULL;
 
2244
                }
 
2245
                if (sep->suspending)
 
2246
                        setup->start = TRUE;
 
2247
                else
 
2248
                        cb_data->source_id = g_idle_add(finalize_resume,
 
2249
                                                                setup);
 
2250
                break;
 
2251
        default:
 
2252
                error("SEP in bad state for resume");
 
2253
                goto failed;
 
2254
        }
 
2255
 
 
2256
        return cb_data->id;
 
2257
 
 
2258
failed:
 
2259
        setup_cb_free(cb_data);
 
2260
        return 0;
 
2261
}
 
2262
 
 
2263
unsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
 
2264
                                a2dp_stream_cb_t cb, void *user_data)
 
2265
{
 
2266
        struct a2dp_setup_cb *cb_data;
 
2267
        struct a2dp_setup *setup;
 
2268
 
 
2269
        setup = a2dp_setup_get(session);
 
2270
        if (!setup)
 
2271
                return 0;
 
2272
 
 
2273
        cb_data = setup_cb_new(setup);
 
2274
        cb_data->suspend_cb = cb;
 
2275
        cb_data->user_data = user_data;
 
2276
 
 
2277
        setup->sep = sep;
 
2278
        setup->stream = sep->stream;
 
2279
 
 
2280
        switch (avdtp_sep_get_state(sep->lsep)) {
 
2281
        case AVDTP_STATE_IDLE:
 
2282
                error("a2dp_suspend: no stream to suspend");
 
2283
                goto failed;
 
2284
                break;
 
2285
        case AVDTP_STATE_OPEN:
 
2286
                cb_data->source_id = g_idle_add(finalize_suspend, setup);
 
2287
                break;
 
2288
        case AVDTP_STATE_STREAMING:
 
2289
                if (avdtp_suspend(session, sep->stream) < 0) {
 
2290
                        error("avdtp_suspend failed");
 
2291
                        goto failed;
 
2292
                }
 
2293
                sep->suspending = TRUE;
 
2294
                break;
 
2295
        default:
 
2296
                error("SEP in bad state for suspend");
 
2297
                goto failed;
 
2298
        }
 
2299
 
 
2300
        return cb_data->id;
 
2301
 
 
2302
failed:
 
2303
        setup_cb_free(cb_data);
 
2304
        return 0;
 
2305
}
 
2306
 
 
2307
gboolean a2dp_cancel(struct audio_device *dev, unsigned int id)
 
2308
{
 
2309
        struct a2dp_setup *setup;
 
2310
        GSList *l;
 
2311
 
 
2312
        setup = find_setup_by_dev(dev);
 
2313
        if (!setup)
 
2314
                return FALSE;
 
2315
 
 
2316
        for (l = setup->cb; l != NULL; l = g_slist_next(l)) {
 
2317
                struct a2dp_setup_cb *cb = l->data;
 
2318
 
 
2319
                if (cb->id != id)
 
2320
                        continue;
 
2321
 
 
2322
                setup_ref(setup);
 
2323
                setup_cb_free(cb);
 
2324
 
 
2325
                if (!setup->cb) {
 
2326
                        DBG("aborting setup %p", setup);
 
2327
                        avdtp_abort(setup->session, setup->stream);
 
2328
                        return TRUE;
 
2329
                }
 
2330
 
 
2331
                setup_unref(setup);
 
2332
                return TRUE;
 
2333
        }
 
2334
 
 
2335
        return FALSE;
 
2336
}
 
2337
 
 
2338
gboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
 
2339
{
 
2340
        if (sep->locked)
 
2341
                return FALSE;
 
2342
 
 
2343
        DBG("SEP %p locked", sep->lsep);
 
2344
        sep->locked = TRUE;
 
2345
 
 
2346
        return TRUE;
 
2347
}
 
2348
 
 
2349
gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
 
2350
{
 
2351
        struct a2dp_server *server = sep->server;
 
2352
        avdtp_state_t state;
 
2353
        GSList *l;
 
2354
 
 
2355
        state = avdtp_sep_get_state(sep->lsep);
 
2356
 
 
2357
        sep->locked = FALSE;
 
2358
 
 
2359
        DBG("SEP %p unlocked", sep->lsep);
 
2360
 
 
2361
        if (sep->type == AVDTP_SEP_TYPE_SOURCE)
 
2362
                l = server->sources;
 
2363
        else
 
2364
                l = server->sinks;
 
2365
 
 
2366
        /* Unregister sep if it was removed */
 
2367
        if (g_slist_find(l, sep) == NULL) {
 
2368
                a2dp_unregister_sep(sep);
 
2369
                return TRUE;
 
2370
        }
 
2371
 
 
2372
        if (!sep->stream || state == AVDTP_STATE_IDLE)
 
2373
                return TRUE;
 
2374
 
 
2375
        switch (state) {
 
2376
        case AVDTP_STATE_OPEN:
 
2377
                /* Set timer here */
 
2378
                break;
 
2379
        case AVDTP_STATE_STREAMING:
 
2380
                if (avdtp_suspend(session, sep->stream) == 0)
 
2381
                        sep->suspending = TRUE;
 
2382
                break;
 
2383
        default:
 
2384
                break;
 
2385
        }
 
2386
 
 
2387
        return TRUE;
 
2388
}
 
2389
 
 
2390
gboolean a2dp_sep_get_lock(struct a2dp_sep *sep)
 
2391
{
 
2392
        return sep->locked;
 
2393
}
 
2394
 
 
2395
static int stream_cmp(gconstpointer data, gconstpointer user_data)
 
2396
{
 
2397
        const struct a2dp_sep *sep = data;
 
2398
        const struct avdtp_stream *stream = user_data;
 
2399
 
 
2400
        return (sep->stream != stream);
 
2401
}
 
2402
 
 
2403
struct a2dp_sep *a2dp_get_sep(struct avdtp *session,
 
2404
                                struct avdtp_stream *stream)
 
2405
{
 
2406
        struct a2dp_server *server;
 
2407
        bdaddr_t src, dst;
 
2408
        GSList *l;
 
2409
 
 
2410
        avdtp_get_peers(session, &src, &dst);
 
2411
 
 
2412
        for (l = servers; l; l = l->next) {
 
2413
                server = l->data;
 
2414
 
 
2415
                if (bacmp(&src, &server->src) == 0)
 
2416
                        break;
 
2417
        }
 
2418
 
 
2419
        if (!l)
 
2420
                return NULL;
 
2421
 
 
2422
        l = g_slist_find_custom(server->sources, stream, stream_cmp);
 
2423
        if (l)
 
2424
                return l->data;
 
2425
 
 
2426
        l = g_slist_find_custom(server->sinks, stream, stream_cmp);
 
2427
        if (l)
 
2428
                return l->data;
 
2429
 
 
2430
        return NULL;
 
2431
}
 
2432
 
 
2433
struct avdtp_stream *a2dp_sep_get_stream(struct a2dp_sep *sep)
 
2434
{
 
2435
        return sep->stream;
 
2436
}