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