9298ae136177ec98d10ac397aa2cbc4178b5f441
[platform/upstream/bluez.git] / profiles / audio / avdtp.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  *
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <stdint.h>
32 #include <stdbool.h>
33 #include <errno.h>
34 #include <unistd.h>
35 #include <assert.h>
36
37 #include <glib.h>
38
39 #include "lib/bluetooth.h"
40 #include "lib/sdp.h"
41 #include "lib/sdp_lib.h"
42 #include "lib/uuid.h"
43
44 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
45 #include <sys/ioctl.h>
46 #include <bluetooth/hci.h>
47 #endif  /* TIZEN_FEATURE_BLUEZ_MODIFY */
48
49 #include "btio/btio.h"
50 #include "src/hcid.h"
51 #include "src/log.h"
52 #include "src/shared/util.h"
53 #include "src/shared/queue.h"
54 #include "src/adapter.h"
55 #include "src/device.h"
56
57 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
58 #include "src/service.h"
59 #include "../../profile.h"
60 #ifdef TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM
61 #include "avrcp.h"
62 #endif
63 #endif
64
65 #include "avdtp.h"
66 #include "sink.h"
67 #include "source.h"
68
69 #define AVDTP_PSM 25
70
71 #define MAX_SEID 0x3E
72 static unsigned int seids;
73
74 #ifndef MAX
75 # define MAX(x, y) ((x) > (y) ? (x) : (y))
76 #endif
77
78 #define AVDTP_DISCOVER                          0x01
79 #define AVDTP_GET_CAPABILITIES                  0x02
80 #define AVDTP_SET_CONFIGURATION                 0x03
81 #define AVDTP_GET_CONFIGURATION                 0x04
82 #define AVDTP_RECONFIGURE                       0x05
83 #define AVDTP_OPEN                              0x06
84 #define AVDTP_START                             0x07
85 #define AVDTP_CLOSE                             0x08
86 #define AVDTP_SUSPEND                           0x09
87 #define AVDTP_ABORT                             0x0A
88 #define AVDTP_SECURITY_CONTROL                  0x0B
89 #define AVDTP_GET_ALL_CAPABILITIES              0x0C
90 #define AVDTP_DELAY_REPORT                      0x0D
91
92 #define AVDTP_PKT_TYPE_SINGLE                   0x00
93 #define AVDTP_PKT_TYPE_START                    0x01
94 #define AVDTP_PKT_TYPE_CONTINUE                 0x02
95 #define AVDTP_PKT_TYPE_END                      0x03
96
97 #define AVDTP_MSG_TYPE_COMMAND                  0x00
98 #define AVDTP_MSG_TYPE_GEN_REJECT               0x01
99 #define AVDTP_MSG_TYPE_ACCEPT                   0x02
100 #define AVDTP_MSG_TYPE_REJECT                   0x03
101
102 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
103 #define REQ_TIMEOUT 10
104 #else
105 #define REQ_TIMEOUT 6
106 #endif
107 #define SUSPEND_TIMEOUT 10
108 #define ABORT_TIMEOUT 2
109 #define DISCONNECT_TIMEOUT 1
110 #define START_TIMEOUT 1
111
112 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
113 struct avdtp *configured_session;
114 struct avdtp_stream *configured_stream;
115 #endif
116
117 #if __BYTE_ORDER == __LITTLE_ENDIAN
118
119 struct avdtp_common_header {
120         uint8_t message_type:2;
121         uint8_t packet_type:2;
122         uint8_t transaction:4;
123 } __attribute__ ((packed));
124
125 struct avdtp_single_header {
126         uint8_t message_type:2;
127         uint8_t packet_type:2;
128         uint8_t transaction:4;
129         uint8_t signal_id:6;
130         uint8_t rfa0:2;
131 } __attribute__ ((packed));
132
133 struct avdtp_start_header {
134         uint8_t message_type:2;
135         uint8_t packet_type:2;
136         uint8_t transaction:4;
137         uint8_t no_of_packets;
138         uint8_t signal_id:6;
139         uint8_t rfa0:2;
140 } __attribute__ ((packed));
141
142 struct avdtp_continue_header {
143         uint8_t message_type:2;
144         uint8_t packet_type:2;
145         uint8_t transaction:4;
146 } __attribute__ ((packed));
147
148 struct seid_info {
149         uint8_t rfa0:1;
150         uint8_t inuse:1;
151         uint8_t seid:6;
152         uint8_t rfa2:3;
153         uint8_t type:1;
154         uint8_t media_type:4;
155 } __attribute__ ((packed));
156
157 struct seid {
158         uint8_t rfa0:2;
159         uint8_t seid:6;
160 } __attribute__ ((packed));
161
162 #elif __BYTE_ORDER == __BIG_ENDIAN
163
164 struct avdtp_common_header {
165         uint8_t transaction:4;
166         uint8_t packet_type:2;
167         uint8_t message_type:2;
168 } __attribute__ ((packed));
169
170 struct avdtp_single_header {
171         uint8_t transaction:4;
172         uint8_t packet_type:2;
173         uint8_t message_type:2;
174         uint8_t rfa0:2;
175         uint8_t signal_id:6;
176 } __attribute__ ((packed));
177
178 struct avdtp_start_header {
179         uint8_t transaction:4;
180         uint8_t packet_type:2;
181         uint8_t message_type:2;
182         uint8_t no_of_packets;
183         uint8_t rfa0:2;
184         uint8_t signal_id:6;
185 } __attribute__ ((packed));
186
187 struct avdtp_continue_header {
188         uint8_t transaction:4;
189         uint8_t packet_type:2;
190         uint8_t message_type:2;
191 } __attribute__ ((packed));
192
193 struct seid_info {
194         uint8_t seid:6;
195         uint8_t inuse:1;
196         uint8_t rfa0:1;
197         uint8_t media_type:4;
198         uint8_t type:1;
199         uint8_t rfa2:3;
200 } __attribute__ ((packed));
201
202 struct seid {
203         uint8_t seid:6;
204         uint8_t rfa0:2;
205 } __attribute__ ((packed));
206
207 #else
208 #error "Unknown byte order"
209 #endif
210
211 /* packets */
212
213 struct discover_resp {
214         struct seid_info seps[0];
215 } __attribute__ ((packed));
216
217 struct getcap_resp {
218         uint8_t caps[0];
219 } __attribute__ ((packed));
220
221 struct start_req {
222         struct seid first_seid;
223         struct seid other_seids[0];
224 } __attribute__ ((packed));
225
226 struct suspend_req {
227         struct seid first_seid;
228         struct seid other_seids[0];
229 } __attribute__ ((packed));
230
231 struct seid_rej {
232         uint8_t error;
233 } __attribute__ ((packed));
234
235 struct conf_rej {
236         uint8_t category;
237         uint8_t error;
238 } __attribute__ ((packed));
239
240 #if __BYTE_ORDER == __LITTLE_ENDIAN
241
242 struct seid_req {
243         uint8_t rfa0:2;
244         uint8_t acp_seid:6;
245 } __attribute__ ((packed));
246
247 struct setconf_req {
248         uint8_t rfa0:2;
249         uint8_t acp_seid:6;
250         uint8_t rfa1:2;
251         uint8_t int_seid:6;
252
253         uint8_t caps[0];
254 } __attribute__ ((packed));
255
256 struct stream_rej {
257         uint8_t rfa0:2;
258         uint8_t acp_seid:6;
259         uint8_t error;
260 } __attribute__ ((packed));
261
262 struct reconf_req {
263         uint8_t rfa0:2;
264         uint8_t acp_seid:6;
265
266         uint8_t serv_cap;
267         uint8_t serv_cap_len;
268
269         uint8_t caps[0];
270 } __attribute__ ((packed));
271
272 struct delay_req {
273         uint8_t rfa0:2;
274         uint8_t acp_seid:6;
275         uint16_t delay;
276 } __attribute__ ((packed));
277
278 #elif __BYTE_ORDER == __BIG_ENDIAN
279
280 struct seid_req {
281         uint8_t acp_seid:6;
282         uint8_t rfa0:2;
283 } __attribute__ ((packed));
284
285 struct setconf_req {
286         uint8_t acp_seid:6;
287         uint8_t rfa0:2;
288         uint8_t int_seid:6;
289         uint8_t rfa1:2;
290
291         uint8_t caps[0];
292 } __attribute__ ((packed));
293
294 struct stream_rej {
295         uint8_t acp_seid:6;
296         uint8_t rfa0:2;
297         uint8_t error;
298 } __attribute__ ((packed));
299
300 struct reconf_req {
301         uint8_t acp_seid:6;
302         uint8_t rfa0:2;
303
304         uint8_t serv_cap;
305         uint8_t serv_cap_len;
306
307         uint8_t caps[0];
308 } __attribute__ ((packed));
309
310 struct delay_req {
311         uint8_t acp_seid:6;
312         uint8_t rfa0:2;
313         uint16_t delay;
314 } __attribute__ ((packed));
315
316 #else
317 #error "Unknown byte order"
318 #endif
319
320 struct in_buf {
321         gboolean active;
322         int no_of_packets;
323         uint8_t transaction;
324         uint8_t message_type;
325         uint8_t signal_id;
326         uint8_t buf[1024];
327         uint8_t data_size;
328 };
329
330 struct pending_req {
331         uint8_t transaction;
332         uint8_t signal_id;
333         void *data;
334         size_t data_size;
335         struct avdtp_stream *stream; /* Set if the request targeted a stream */
336         guint timeout;
337         gboolean collided;
338 };
339
340 struct avdtp_remote_sep {
341         uint8_t seid;
342         uint8_t type;
343         uint8_t media_type;
344         struct avdtp_service_capability *codec;
345         gboolean delay_reporting;
346         GSList *caps; /* of type struct avdtp_service_capability */
347         struct avdtp_stream *stream;
348 };
349
350 struct avdtp_local_sep {
351         avdtp_state_t state;
352         struct avdtp_stream *stream;
353         struct seid_info info;
354         uint8_t codec;
355         gboolean delay_reporting;
356         GSList *caps;
357         struct avdtp_sep_ind *ind;
358         struct avdtp_sep_cfm *cfm;
359         void *user_data;
360 };
361
362 struct stream_callback {
363         avdtp_stream_state_cb cb;
364         void *user_data;
365         unsigned int id;
366 };
367
368 struct avdtp_state_callback {
369         avdtp_session_state_cb cb;
370         struct btd_device *dev;
371         unsigned int id;
372         void *user_data;
373 };
374
375 struct discover_callback {
376         unsigned int id;
377         avdtp_discover_cb_t cb;
378         void *user_data;
379 };
380
381 struct avdtp_stream {
382         GIOChannel *io;
383         uint16_t imtu;
384         uint16_t omtu;
385         struct avdtp *session;
386         struct avdtp_local_sep *lsep;
387         uint8_t rseid;
388         GSList *caps;
389         GSList *callbacks;
390         struct avdtp_service_capability *codec;
391         guint io_id;            /* Transport GSource ID */
392         guint timer;            /* Waiting for other side to close or open
393                                  * the transport channel */
394         gboolean open_acp;      /* If we are in ACT role for Open */
395         gboolean close_int;     /* If we are in INT role for Close */
396         gboolean abort_int;     /* If we are in INT role for Abort */
397         guint start_timer;      /* Wait START command timer */
398         gboolean delay_reporting;
399         uint16_t delay;         /* AVDTP 1.3 Delay Reporting feature */
400         gboolean starting;      /* only valid while sep state == OPEN */
401 };
402
403 /* Structure describing an AVDTP connection between two devices */
404
405 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
406 struct avdtp_source_info {
407         struct btd_device *dev;
408         bool pause;
409 };
410 #endif
411
412 struct avdtp {
413         unsigned int ref;
414
415         uint16_t version;
416
417         struct queue *lseps;
418         struct btd_device *device;
419
420         avdtp_session_state_t state;
421
422         GIOChannel *io;
423         guint io_id;
424
425         GSList *seps; /* Elements of type struct avdtp_remote_sep * */
426
427         GSList *streams; /* Elements of type struct avdtp_stream * */
428
429         GSList *req_queue; /* Elements of type struct pending_req * */
430         GSList *prio_queue; /* Same as req_queue but is processed before it */
431
432         struct avdtp_stream *pending_open;
433
434         uint32_t phy;
435         uint16_t imtu;
436         uint16_t omtu;
437
438         struct in_buf in;
439
440         char *buf;
441
442         struct discover_callback *discover;
443         struct pending_req *req;
444
445         guint dc_timer;
446         int dc_timeout;
447
448         /* Attempt stream setup instead of disconnecting */
449         gboolean stream_setup;
450 };
451
452 static GSList *state_callbacks = NULL;
453
454 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
455 static GSList *list_source = NULL;
456 #endif
457
458 static int send_request(struct avdtp *session, gboolean priority,
459                         struct avdtp_stream *stream, uint8_t signal_id,
460                         void *buffer, size_t size);
461 static gboolean avdtp_parse_resp(struct avdtp *session,
462                                         struct avdtp_stream *stream,
463                                         uint8_t transaction, uint8_t signal_id,
464                                         void *buf, int size);
465 static gboolean avdtp_parse_rej(struct avdtp *session,
466                                         struct avdtp_stream *stream,
467                                         uint8_t transaction, uint8_t signal_id,
468                                         void *buf, int size);
469 static int process_queue(struct avdtp *session);
470 static void avdtp_sep_set_state(struct avdtp *session,
471                                 struct avdtp_local_sep *sep,
472                                 avdtp_state_t state);
473
474 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
475 void avdtp_set_source_status(struct btd_device *dev, bool pause)
476 {
477         GSList *l = list_source;
478
479         while (l) {
480                 struct avdtp_source_info *ldev = l->data;
481
482                 if (ldev->dev != dev && pause == false && ldev->pause == false) {
483                         avrcp_pause(ldev->dev);
484                         DBG("sending pause from status");
485                         ldev->pause = true;
486                 } else if (ldev->dev == dev) {
487                         ldev->pause = pause;
488                 }
489
490                 l = l->next;
491         }
492 }
493
494 static void avdtp_add_source_device(struct btd_device *dev)
495 {
496         bool found = false;
497         GSList *l = list_source;
498
499         while (l) {
500                 struct avdtp_source_info *ldev = l->data;
501
502                 if (ldev->dev == dev) {
503                         DBG("in device %p", dev);
504                         ldev->pause = false;
505                         found = true;
506                 } else {
507                         if (ldev->pause == false) {
508                                 avrcp_pause(ldev->dev);
509                                 DBG("Sending pause from steam");
510                                 ldev->pause = true;
511                         }
512                 }
513
514                 l = l->next;
515         }
516
517         if (!found) {
518                 struct avdtp_source_info *p;
519
520                 p = g_new0(struct avdtp_source_info, 1);
521                 p->dev = dev;
522                 p->pause = false;
523                 list_source = g_slist_append(list_source, p);
524         }
525 }
526
527 static void avdtp_remove_source_devce(struct btd_device *dev)
528 {
529         GSList *l;
530
531         for (l = list_source; l != NULL; l = l->next) {
532                 struct avdtp_source_info *ldev = l->data;
533                 if (ldev && ldev->dev == dev) {
534                         list_source = g_slist_remove(list_source, ldev);
535                         g_free(ldev);
536                         return;
537                 }
538         }
539 }
540 #endif
541
542 static const char *avdtp_statestr(avdtp_state_t state)
543 {
544         switch (state) {
545         case AVDTP_STATE_IDLE:
546                 return "IDLE";
547         case AVDTP_STATE_CONFIGURED:
548                 return "CONFIGURED";
549         case AVDTP_STATE_OPEN:
550                 return "OPEN";
551         case AVDTP_STATE_STREAMING:
552                 return "STREAMING";
553         case AVDTP_STATE_CLOSING:
554                 return "CLOSING";
555         case AVDTP_STATE_ABORTING:
556                 return "ABORTING";
557         default:
558                 return "<unknown state>";
559         }
560 }
561
562 static gboolean try_send(int sk, void *data, size_t len)
563 {
564         int err;
565
566         do {
567                 err = send(sk, data, len, 0);
568         } while (err < 0 && errno == EINTR);
569
570         if (err < 0) {
571                 error("send: %s (%d)", strerror(errno), errno);
572                 return FALSE;
573         } else if ((size_t) err != len) {
574                 error("try_send: complete buffer not sent (%d/%zu bytes)",
575                                                                 err, len);
576                 return FALSE;
577         }
578
579         return TRUE;
580 }
581
582 static gboolean avdtp_send(struct avdtp *session, uint8_t transaction,
583                                 uint8_t message_type, uint8_t signal_id,
584                                 void *data, size_t len)
585 {
586         unsigned int cont_fragments, sent;
587         struct avdtp_start_header start;
588         struct avdtp_continue_header cont;
589         int sock;
590
591         if (session->io == NULL) {
592                 error("avdtp_send: session is closed");
593                 return FALSE;
594         }
595
596         sock = g_io_channel_unix_get_fd(session->io);
597
598         /* Single packet - no fragmentation */
599         if (sizeof(struct avdtp_single_header) + len <= session->omtu) {
600                 struct avdtp_single_header single;
601
602                 memset(&single, 0, sizeof(single));
603
604                 single.transaction = transaction;
605                 single.packet_type = AVDTP_PKT_TYPE_SINGLE;
606                 single.message_type = message_type;
607                 single.signal_id = signal_id;
608
609                 memcpy(session->buf, &single, sizeof(single));
610                 memcpy(session->buf + sizeof(single), data, len);
611
612                 return try_send(sock, session->buf, sizeof(single) + len);
613         }
614
615         /* Check if there is enough space to start packet */
616         if (session->omtu < sizeof(start)) {
617                 error("No enough space to fragment packet");
618                 return FALSE;
619         }
620
621         /* Count the number of needed fragments */
622         cont_fragments = (len - (session->omtu - sizeof(start))) /
623                                         (session->omtu - sizeof(cont)) + 1;
624
625         DBG("%zu bytes split into %d fragments", len, cont_fragments + 1);
626
627         /* Send the start packet */
628         memset(&start, 0, sizeof(start));
629         start.transaction = transaction;
630         start.packet_type = AVDTP_PKT_TYPE_START;
631         start.message_type = message_type;
632         start.no_of_packets = cont_fragments + 1;
633         start.signal_id = signal_id;
634
635         memcpy(session->buf, &start, sizeof(start));
636         memcpy(session->buf + sizeof(start), data,
637                                         session->omtu - sizeof(start));
638
639         if (!try_send(sock, session->buf, session->omtu))
640                 return FALSE;
641
642         DBG("first packet with %zu bytes sent", session->omtu - sizeof(start));
643
644         sent = session->omtu - sizeof(start);
645
646         /* Send the continue fragments and the end packet */
647         while (sent < len) {
648                 int left, to_copy;
649
650                 left = len - sent;
651                 if (left + sizeof(cont) > session->omtu) {
652                         cont.packet_type = AVDTP_PKT_TYPE_CONTINUE;
653                         to_copy = session->omtu - sizeof(cont);
654                         DBG("sending continue with %d bytes", to_copy);
655                 } else {
656                         cont.packet_type = AVDTP_PKT_TYPE_END;
657                         to_copy = left;
658                         DBG("sending end with %d bytes", to_copy);
659                 }
660
661                 cont.transaction = transaction;
662                 cont.message_type = message_type;
663
664                 memcpy(session->buf, &cont, sizeof(cont));
665                 memcpy(session->buf + sizeof(cont), data + sent, to_copy);
666
667                 if (!try_send(sock, session->buf, to_copy + sizeof(cont)))
668                         return FALSE;
669
670                 sent += to_copy;
671         }
672
673         return TRUE;
674 }
675
676 static void pending_req_free(void *data)
677 {
678         struct pending_req *req = data;
679
680         if (req->timeout)
681                 g_source_remove(req->timeout);
682         g_free(req->data);
683         g_free(req);
684 }
685
686 static void close_stream(struct avdtp_stream *stream)
687 {
688         int sock;
689
690         if (stream->io == NULL)
691                 return;
692
693         sock = g_io_channel_unix_get_fd(stream->io);
694
695         shutdown(sock, SHUT_RDWR);
696
697         g_io_channel_shutdown(stream->io, FALSE, NULL);
698
699         g_io_channel_unref(stream->io);
700         stream->io = NULL;
701 }
702
703 static gboolean stream_close_timeout(gpointer user_data)
704 {
705         struct avdtp_stream *stream = user_data;
706
707         DBG("Timed out waiting for peer to close the transport channel");
708
709         stream->timer = 0;
710
711         close_stream(stream);
712
713         return FALSE;
714 }
715
716 static gboolean stream_open_timeout(gpointer user_data)
717 {
718         struct avdtp_stream *stream = user_data;
719
720         DBG("Timed out waiting for peer to open the transport channel");
721
722         stream->timer = 0;
723
724         stream->session->pending_open = NULL;
725
726         avdtp_abort(stream->session, stream);
727
728         return FALSE;
729 }
730
731 void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
732 {
733         err->category = category;
734
735         if (category == AVDTP_ERRNO)
736                 err->err.posix_errno = id;
737         else
738                 err->err.error_code = id;
739 }
740
741 uint8_t avdtp_error_category(struct avdtp_error *err)
742 {
743         return err->category;
744 }
745
746 int avdtp_error_error_code(struct avdtp_error *err)
747 {
748         assert(err->category != AVDTP_ERRNO);
749         return err->err.error_code;
750 }
751
752 int avdtp_error_posix_errno(struct avdtp_error *err)
753 {
754         assert(err->category == AVDTP_ERRNO);
755         return err->err.posix_errno;
756 }
757
758 static struct avdtp_stream *find_stream_by_rseid(struct avdtp *session,
759                                                         uint8_t rseid)
760 {
761         GSList *l;
762
763         for (l = session->streams; l != NULL; l = g_slist_next(l)) {
764                 struct avdtp_stream *stream = l->data;
765
766                 if (stream->rseid == rseid)
767                         return stream;
768         }
769
770         return NULL;
771 }
772
773 static struct avdtp_remote_sep *find_remote_sep(GSList *seps, uint8_t seid)
774 {
775         GSList *l;
776
777         for (l = seps; l != NULL; l = g_slist_next(l)) {
778                 struct avdtp_remote_sep *sep = l->data;
779
780                 if (sep->seid == seid)
781                         return sep;
782         }
783
784         return NULL;
785 }
786
787 static void avdtp_set_state(struct avdtp *session,
788                                         avdtp_session_state_t new_state)
789 {
790         GSList *l;
791         avdtp_session_state_t old_state = session->state;
792
793         session->state = new_state;
794
795         for (l = state_callbacks; l != NULL;) {
796                 struct avdtp_state_callback *cb = l->data;
797
798                 l = g_slist_next(l);
799
800                 if (session->device != cb->dev)
801                         continue;
802
803                 cb->cb(cb->dev, session, old_state, new_state, cb->user_data);
804         }
805 }
806
807 static void stream_free(void *data)
808 {
809         struct avdtp_stream *stream = data;
810         struct avdtp_remote_sep *rsep;
811
812         stream->lsep->info.inuse = 0;
813         stream->lsep->stream = NULL;
814
815         rsep = find_remote_sep(stream->session->seps, stream->rseid);
816         if (rsep)
817                 rsep->stream = NULL;
818
819         if (stream->timer)
820                 g_source_remove(stream->timer);
821
822         if (stream->io)
823                 close_stream(stream);
824
825         if (stream->io_id)
826                 g_source_remove(stream->io_id);
827
828         g_slist_free_full(stream->callbacks, g_free);
829         g_slist_free_full(stream->caps, g_free);
830
831         g_free(stream);
832 }
833
834 static gboolean transport_cb(GIOChannel *chan, GIOCondition cond,
835                                 gpointer data)
836 {
837         struct avdtp_stream *stream = data;
838         struct avdtp_local_sep *sep = stream->lsep;
839
840         if (stream->close_int && sep->cfm && sep->cfm->close)
841                 sep->cfm->close(stream->session, sep, stream, NULL,
842                                 sep->user_data);
843
844         if (!(cond & G_IO_NVAL))
845                 close_stream(stream);
846
847         stream->io_id = 0;
848
849         if (!stream->abort_int)
850                 avdtp_sep_set_state(stream->session, sep, AVDTP_STATE_IDLE);
851
852         return FALSE;
853 }
854
855 static int get_send_buffer_size(int sk)
856 {
857         int size;
858         socklen_t optlen = sizeof(size);
859
860         if (getsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, &optlen) < 0) {
861                 int err = -errno;
862                 error("getsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
863                                                                         -err);
864                 return err;
865         }
866
867         /*
868          * Doubled value is returned by getsockopt since kernel uses that
869          * space for its own purposes (see man 7 socket, bookkeeping overhead
870          * for SO_SNDBUF).
871          */
872         return size / 2;
873 }
874
875 static int set_send_buffer_size(int sk, int size)
876 {
877         socklen_t optlen = sizeof(size);
878
879         if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, optlen) < 0) {
880                 int err = -errno;
881                 error("setsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
882                                                                         -err);
883                 return err;
884         }
885
886         return 0;
887 }
888
889 static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
890                                         uint16_t imtu, uint16_t omtu)
891 {
892         struct avdtp_stream *stream = session->pending_open;
893         struct avdtp_local_sep *sep = stream->lsep;
894         int sk, buf_size, min_buf_size;
895         GError *err = NULL;
896
897         session->pending_open = NULL;
898
899         if (stream->timer) {
900                 g_source_remove(stream->timer);
901                 stream->timer = 0;
902         }
903
904         if (io == NULL) {
905                 if (!stream->open_acp && sep->cfm && sep->cfm->open) {
906                         struct avdtp_error err;
907                         avdtp_error_init(&err, AVDTP_ERRNO, EIO);
908                         sep->cfm->open(session, sep, NULL, &err,
909                                         sep->user_data);
910                 }
911                 return;
912         }
913
914         if (stream->io == NULL)
915                 stream->io = g_io_channel_ref(io);
916
917         stream->omtu = omtu;
918         stream->imtu = imtu;
919
920         /* Apply special settings only if local SEP is of type SRC */
921         if (sep->info.type != AVDTP_SEP_TYPE_SOURCE)
922                 goto proceed;
923
924         bt_io_set(stream->io, &err, BT_IO_OPT_FLUSHABLE, TRUE,
925                                                         BT_IO_OPT_INVALID);
926         if (err != NULL) {
927                 error("Enabling flushable packets failed: %s", err->message);
928                 g_error_free(err);
929         } else
930                 DBG("Flushable packets enabled");
931
932         sk = g_io_channel_unix_get_fd(stream->io);
933         buf_size = get_send_buffer_size(sk);
934         if (buf_size < 0)
935                 goto proceed;
936
937         DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size);
938 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
939         min_buf_size = omtu * 10;
940 #else
941         min_buf_size = omtu * 2;
942 #endif
943         if (buf_size < min_buf_size) {
944                 DBG("send buffer size to be increassed to %d",
945                                 min_buf_size);
946                 set_send_buffer_size(sk, min_buf_size);
947         }
948 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
949         else {
950                 DBG("send buffer size to be decreassed to %d",
951                                 min_buf_size);
952                 set_send_buffer_size(sk, min_buf_size);
953         }
954 #endif
955 proceed:
956         if (!stream->open_acp && sep->cfm && sep->cfm->open)
957                 sep->cfm->open(session, sep, stream, NULL, sep->user_data);
958
959         avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN);
960
961         stream->io_id = g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
962                                         (GIOFunc) transport_cb, stream);
963 }
964
965 static int pending_req_cmp(gconstpointer a, gconstpointer b)
966 {
967         const struct pending_req *req = a;
968         const struct avdtp_stream *stream = b;
969
970         if (req->stream == stream)
971                 return 0;
972
973         return -1;
974 }
975
976 static void cleanup_queue(struct avdtp *session, struct avdtp_stream *stream)
977 {
978         GSList *l;
979         struct pending_req *req;
980
981         while ((l = g_slist_find_custom(session->prio_queue, stream,
982                                                         pending_req_cmp))) {
983                 req = l->data;
984                 pending_req_free(req);
985                 session->prio_queue = g_slist_remove(session->prio_queue, req);
986         }
987
988         while ((l = g_slist_find_custom(session->req_queue, stream,
989                                                         pending_req_cmp))) {
990                 req = l->data;
991                 pending_req_free(req);
992                 session->req_queue = g_slist_remove(session->req_queue, req);
993         }
994 }
995
996 static void handle_unanswered_req(struct avdtp *session,
997                                                 struct avdtp_stream *stream)
998 {
999         struct pending_req *req;
1000         struct avdtp_local_sep *lsep;
1001         struct avdtp_error err;
1002
1003         if (session->req->signal_id == AVDTP_ABORT) {
1004                 /* Avoid freeing the Abort request here */
1005                 DBG("handle_unanswered_req: Abort req, returning");
1006                 session->req->stream = NULL;
1007                 return;
1008         }
1009
1010         req = session->req;
1011         session->req = NULL;
1012
1013         avdtp_error_init(&err, AVDTP_ERRNO, EIO);
1014
1015         lsep = stream->lsep;
1016
1017         switch (req->signal_id) {
1018         case AVDTP_RECONFIGURE:
1019                 error("No reply to Reconfigure request");
1020                 if (lsep && lsep->cfm && lsep->cfm->reconfigure)
1021                         lsep->cfm->reconfigure(session, lsep, stream, &err,
1022                                                 lsep->user_data);
1023                 break;
1024         case AVDTP_OPEN:
1025                 error("No reply to Open request");
1026                 if (lsep && lsep->cfm && lsep->cfm->open)
1027                         lsep->cfm->open(session, lsep, stream, &err,
1028                                         lsep->user_data);
1029                 break;
1030         case AVDTP_START:
1031                 error("No reply to Start request");
1032                 if (lsep && lsep->cfm && lsep->cfm->start)
1033                         lsep->cfm->start(session, lsep, stream, &err,
1034                                                 lsep->user_data);
1035                 break;
1036         case AVDTP_SUSPEND:
1037                 error("No reply to Suspend request");
1038                 if (lsep && lsep->cfm && lsep->cfm->suspend)
1039                         lsep->cfm->suspend(session, lsep, stream, &err,
1040                                                 lsep->user_data);
1041                 break;
1042         case AVDTP_CLOSE:
1043                 error("No reply to Close request");
1044                 if (lsep && lsep->cfm && lsep->cfm->close)
1045                         lsep->cfm->close(session, lsep, stream, &err,
1046                                                 lsep->user_data);
1047                 break;
1048         case AVDTP_SET_CONFIGURATION:
1049                 error("No reply to SetConfiguration request");
1050                 if (lsep && lsep->cfm && lsep->cfm->set_configuration)
1051                         lsep->cfm->set_configuration(session, lsep, stream,
1052                                                         &err, lsep->user_data);
1053         }
1054
1055         pending_req_free(req);
1056 }
1057
1058 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1059 static gboolean send_broadcom_a2dp_qos(const bdaddr_t *dst, gboolean qos_high)
1060 {
1061         int dd;
1062         int err = 0;
1063         struct hci_conn_info_req *cr;
1064         broadcom_qos_cp cp;
1065
1066         dd = hci_open_dev(0);
1067
1068         if (dd < 0)
1069                 return FALSE;
1070
1071         cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
1072
1073         cr->type = ACL_LINK;
1074         bacpy(&cr->bdaddr, dst);
1075
1076         err = ioctl(dd, HCIGETCONNINFO, cr);
1077         if (err < 0) {
1078                 error("Fail to get HCIGETCOINFO");
1079                 g_free(cr);
1080                 hci_close_dev(dd);
1081                 return FALSE;
1082         }
1083
1084         cp.handle = cr->conn_info->handle;
1085         DBG("Handle %d", cp.handle);
1086         g_free(cr);
1087
1088         if (qos_high)
1089                 cp.priority = BRCM_QOS_PRIORITY_HIGH;
1090         else
1091                 cp.priority = BRCM_QOS_PRIORITY_NORMAL;
1092
1093         if (hci_send_cmd(dd, OGF_VENDOR_CMD, BROADCOM_QOS_CMD,
1094                                 BROADCOM_QOS_CP_SIZE, &cp) < 0) {
1095                 hci_close_dev(dd);
1096                 return FALSE;
1097         }
1098         DBG("Send Broadcom Qos Patch %s", qos_high ? "High" : "Low");
1099
1100         hci_close_dev(dd);
1101
1102         return TRUE;
1103 }
1104
1105 static gboolean send_sprd_a2dp_qos(const bdaddr_t *dst, gboolean qos_high)
1106 {
1107         int dd;
1108         int err = 0;
1109         struct hci_conn_info_req *cr;
1110         qos_setup_cp cp;
1111
1112         dd = hci_open_dev(0);
1113         if (dd < 0)
1114                 return FALSE;
1115
1116         cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
1117
1118         cr->type = ACL_LINK;
1119         bacpy(&cr->bdaddr, dst);
1120
1121         err = ioctl(dd, HCIGETCONNINFO, cr);
1122         if (err < 0) {
1123                 error("Fail to get HCIGETCOINFO");
1124                 g_free(cr);
1125                 hci_close_dev(dd);
1126                 return FALSE;
1127         }
1128
1129         cp.handle = cr->conn_info->handle;
1130         cp.flags = 0x00;
1131         DBG("Handle %d", cp.handle);
1132         g_free(cr);
1133
1134         if (qos_high) {
1135                 cp.qos.service_type = 0x02;
1136                 cp.qos.token_rate = 0X000000C8;
1137                 cp.qos.peak_bandwidth = 0X000000C8;
1138                 cp.qos.latency = 0x00000001;
1139                 cp.qos.delay_variation = 0xFFFFFFFF;
1140         } else {
1141                 cp.qos.service_type = 0x01;
1142                 cp.qos.token_rate = 0X00000000;
1143                 cp.qos.peak_bandwidth = 0X00000000;
1144                 cp.qos.latency = 0x00000001;
1145                 cp.qos.delay_variation = 0xFFFFFFFF;
1146         }
1147
1148         if (hci_send_cmd(dd, OGF_LINK_POLICY, OCF_QOS_SETUP,
1149                                 QOS_SETUP_CP_SIZE, &cp) < 0) {
1150                 hci_close_dev(dd);
1151                 return FALSE;
1152         }
1153         DBG("Send Spreadtrum Qos Patch %s", qos_high ? "High" : "Low");
1154
1155         hci_close_dev(dd);
1156
1157         return TRUE;
1158 }
1159
1160 static gboolean fix_role_to_master(const bdaddr_t *dst, gboolean fix_to_master)
1161 {
1162         int dd;
1163         int err = 0;
1164         struct hci_conn_info_req *cr;
1165         switch_role_cp sr_cp;
1166         write_link_policy_cp lp_cp;
1167
1168         dd = hci_open_dev(0);
1169         if (dd < 0) {
1170                 error("hci_open_dev is failed");
1171                 return FALSE;
1172         }
1173
1174         cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
1175
1176         cr->type = ACL_LINK;
1177         bacpy(&cr->bdaddr, dst);
1178         err = ioctl(dd, HCIGETCONNINFO, cr);
1179         if (err < 0) {
1180                 error("Fail to get HCIGETCOINFO : %d", err);
1181                 g_free(cr);
1182                 hci_close_dev(dd);
1183                 return FALSE;
1184         }
1185
1186         if (!(cr->conn_info->link_mode & HCI_LM_MASTER) && fix_to_master) {
1187                 DBG("Need to role switch");
1188
1189                 bacpy(&sr_cp.bdaddr, dst);
1190                 sr_cp.role = 0x00;      /* 0x00 : Master, 0x01 : Slave */
1191                 if (hci_send_cmd(dd, OGF_LINK_POLICY, OCF_SWITCH_ROLE,
1192                                         SWITCH_ROLE_CP_SIZE, &sr_cp) < 0) {
1193                         error("switch role is failed");
1194                         g_free(cr);
1195                         hci_close_dev(dd);
1196                         return FALSE;
1197                 }
1198         }
1199
1200         lp_cp.handle = cr->conn_info->handle;
1201         DBG("Handle %d", lp_cp.handle);
1202         g_free(cr);
1203
1204         lp_cp.policy = fix_to_master ? 0x00 : HCI_LP_SNIFF | HCI_LP_RSWITCH;
1205         DBG("Request link policy : 0x%X", lp_cp.policy);
1206
1207         if (hci_send_cmd(dd, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
1208                                 WRITE_LINK_POLICY_CP_SIZE, &lp_cp) < 0) {
1209                 error("write link policy is failed : %d", lp_cp.policy);
1210                 hci_close_dev(dd);
1211                 return FALSE;
1212         }
1213
1214         hci_close_dev(dd);
1215
1216         return TRUE;
1217 }
1218 #endif  /* TIZEN_FEATURE_BLUEZ_MODIFY */
1219
1220 static void avdtp_sep_set_state(struct avdtp *session,
1221                                 struct avdtp_local_sep *sep,
1222                                 avdtp_state_t state)
1223 {
1224         struct avdtp_stream *stream = sep->stream;
1225 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1226         struct btd_adapter *adapter = device_get_adapter(session->device);
1227         const bdaddr_t *dst;
1228
1229         dst = device_get_address(session->device);
1230 #endif
1231         avdtp_state_t old_state;
1232         struct avdtp_error err, *err_ptr = NULL;
1233         GSList *l;
1234
1235         if (!stream) {
1236                 error("Error changing sep state: stream not available");
1237                 return;
1238         }
1239
1240         if (sep->state == state) {
1241                 avdtp_error_init(&err, AVDTP_ERRNO, EIO);
1242                 DBG("stream state change failed: %s", avdtp_strerror(&err));
1243                 err_ptr = &err;
1244         } else {
1245                 err_ptr = NULL;
1246                 DBG("stream state changed: %s -> %s",
1247                                 avdtp_statestr(sep->state),
1248                                 avdtp_statestr(state));
1249         }
1250
1251         old_state = sep->state;
1252         sep->state = state;
1253
1254         switch (state) {
1255         case AVDTP_STATE_CONFIGURED:
1256                 if (sep->info.type == AVDTP_SEP_TYPE_SINK) {
1257 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1258                         configured_session = session;
1259                         configured_stream = stream;
1260 #endif
1261                         avdtp_delay_report(session, stream, stream->delay);
1262                 }
1263                 break;
1264         case AVDTP_STATE_OPEN:
1265                 stream->starting = FALSE;
1266 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1267                 if (TIZEN_FEATURE_BLUEZ_BRCM_QOS || TIZEN_FEATURE_BLUEZ_SPEAKER_REFERENCE) {
1268                         send_broadcom_a2dp_qos(dst, FALSE);
1269                 } else if (TIZEN_FEATURE_BLUEZ_SPRD_QOS) {
1270                         if (old_state == AVDTP_STATE_STREAMING)
1271                                 send_sprd_a2dp_qos(dst, FALSE);
1272                 }
1273
1274                 if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE)
1275                         fix_role_to_master(dst, FALSE);
1276
1277                 btd_adapter_set_streaming_mode(adapter, dst, FALSE);
1278 #endif  /* TIZEN_FEATURE_BLUEZ_MODIFY */
1279                 break;
1280         case AVDTP_STATE_STREAMING:
1281                 if (stream->start_timer) {
1282                         g_source_remove(stream->start_timer);
1283                         stream->start_timer = 0;
1284                 }
1285
1286 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1287                 if (TIZEN_FEATURE_BLUEZ_BRCM_QOS || TIZEN_FEATURE_BLUEZ_SPEAKER_REFERENCE) {
1288                         send_broadcom_a2dp_qos(dst, TRUE);
1289                 } else if (TIZEN_FEATURE_BLUEZ_SPRD_QOS) {
1290                         if (old_state == AVDTP_STATE_OPEN)
1291                                 send_sprd_a2dp_qos(dst, TRUE);
1292                 }
1293                 if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE)
1294                         fix_role_to_master(dst, TRUE);
1295
1296                 btd_adapter_set_streaming_mode(adapter, dst, TRUE);
1297 #endif  /* TIZEN_FEATURE_BLUEZ_MODIFY */
1298                 stream->open_acp = FALSE;
1299                 break;
1300         case AVDTP_STATE_CLOSING:
1301         case AVDTP_STATE_ABORTING:
1302                 if (stream->start_timer) {
1303                         g_source_remove(stream->start_timer);
1304                         stream->start_timer = 0;
1305                 }
1306                 break;
1307         case AVDTP_STATE_IDLE:
1308                 if (stream->start_timer) {
1309                         g_source_remove(stream->start_timer);
1310                         stream->start_timer = 0;
1311                 }
1312                 if (session->pending_open == stream)
1313                         handle_transport_connect(session, NULL, 0, 0);
1314                 if (session->req && session->req->stream == stream)
1315                         handle_unanswered_req(session, stream);
1316                 /* Remove pending commands for this stream from the queue */
1317                 cleanup_queue(session, stream);
1318                 session->streams = g_slist_remove(session->streams, stream);
1319                 break;
1320         default:
1321                 break;
1322         }
1323
1324         l = stream->callbacks;
1325         while (l != NULL) {
1326                 struct stream_callback *cb = l->data;
1327                 l = g_slist_next(l);
1328                 cb->cb(stream, old_state, state, err_ptr, cb->user_data);
1329         }
1330
1331         if (state == AVDTP_STATE_IDLE)
1332                 stream_free(stream);
1333 }
1334
1335 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1336 void finalize_discovery(struct avdtp *session, int err)
1337 #else
1338 static void finalize_discovery(struct avdtp *session, int err)
1339 #endif
1340 {
1341         struct discover_callback *discover = session->discover;
1342         struct avdtp_error avdtp_err;
1343
1344         if (!discover)
1345                 return;
1346
1347         avdtp_error_init(&avdtp_err, AVDTP_ERRNO, err);
1348
1349         if (discover->id > 0)
1350                 g_source_remove(discover->id);
1351
1352         if (discover->cb)
1353                 discover->cb(session, session->seps, err ? &avdtp_err : NULL,
1354                                                         discover->user_data);
1355         g_free(discover);
1356         session->discover = NULL;
1357 }
1358
1359 static void release_stream(struct avdtp_stream *stream, struct avdtp *session)
1360 {
1361         struct avdtp_local_sep *sep = stream->lsep;
1362
1363 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
1364         /* Connection lost */
1365         avdtp_remove_source_devce(session->device);
1366 #endif
1367
1368         if (sep->cfm && sep->cfm->abort &&
1369                                 (sep->state != AVDTP_STATE_ABORTING ||
1370                                                         stream->abort_int))
1371                 sep->cfm->abort(session, sep, stream, NULL, sep->user_data);
1372
1373         avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE);
1374 }
1375
1376 static void sep_free(gpointer data)
1377 {
1378         struct avdtp_remote_sep *sep = data;
1379
1380         g_slist_free_full(sep->caps, g_free);
1381         g_free(sep);
1382 }
1383
1384 static void remove_disconnect_timer(struct avdtp *session)
1385 {
1386         if (!session->dc_timer)
1387                 return;
1388
1389         g_source_remove(session->dc_timer);
1390         session->dc_timer = 0;
1391         session->stream_setup = FALSE;
1392
1393         /* Release disconnect timer reference */
1394         avdtp_unref(session);
1395 }
1396
1397 static void avdtp_free(void *data)
1398 {
1399         struct avdtp *session = data;
1400
1401         DBG("%p", session);
1402
1403         g_slist_free_full(session->streams, stream_free);
1404
1405         if (session->io) {
1406                 g_io_channel_shutdown(session->io, FALSE, NULL);
1407                 g_io_channel_unref(session->io);
1408         }
1409
1410         if (session->io_id) {
1411                 g_source_remove(session->io_id);
1412                 session->io_id = 0;
1413         }
1414
1415         if (session->req)
1416                 pending_req_free(session->req);
1417
1418         g_slist_free_full(session->req_queue, pending_req_free);
1419         g_slist_free_full(session->prio_queue, pending_req_free);
1420         g_slist_free_full(session->seps, sep_free);
1421
1422         g_free(session->buf);
1423
1424         btd_device_unref(session->device);
1425         g_free(session);
1426 }
1427
1428 static void connection_lost(struct avdtp *session, int err)
1429 {
1430         char address[18];
1431 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1432         struct btd_service *service;
1433 #endif
1434
1435         session = avdtp_ref(session);
1436
1437         ba2str(device_get_address(session->device), address);
1438         DBG("Disconnected from %s", address);
1439
1440 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1441         service = btd_device_get_service(session->device, A2DP_SINK_UUID);
1442         if (service)
1443                 btd_service_connecting_complete(service, -err);
1444 #endif
1445         g_slist_foreach(session->streams, (GFunc) release_stream, session);
1446         session->streams = NULL;
1447
1448         finalize_discovery(session, err);
1449
1450         avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
1451
1452         DBG("%p: ref=%d", session, session->ref);
1453
1454         avdtp_unref(session);
1455 }
1456
1457 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1458 static gboolean disconnect_acl_timeout(gpointer user_data)
1459 {
1460         struct btd_device *device = user_data;
1461
1462         DBG("");
1463
1464         btd_device_disconnect(device);
1465
1466         return FALSE;
1467 }
1468 #endif
1469
1470 static gboolean disconnect_timeout(gpointer user_data)
1471 {
1472         struct avdtp *session = user_data;
1473         struct btd_service *service;
1474         gboolean stream_setup;
1475 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1476         struct btd_device *device = NULL;
1477         struct btd_adapter *adapter = NULL;
1478         const bdaddr_t *bdaddr = NULL;
1479
1480         DBG("");
1481 #endif
1482
1483 /* Fix : REVERSE_INULL */
1484 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1485         if (session->device == NULL) {
1486                 error("session device NOT found");
1487                 return FALSE;
1488         }
1489 #endif
1490
1491         session->dc_timer = 0;
1492
1493         stream_setup = session->stream_setup;
1494         session->stream_setup = FALSE;
1495
1496         service = btd_device_get_service(session->device, A2DP_SINK_UUID);
1497         if (service && stream_setup) {
1498                 sink_setup_stream(service, session);
1499                 goto done;
1500         }
1501
1502         service = btd_device_get_service(session->device, A2DP_SOURCE_UUID);
1503         if (service && stream_setup) {
1504                 source_setup_stream(service, session);
1505                 goto done;
1506         }
1507
1508 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1509         if (session->device) {
1510                 adapter = device_get_adapter(session->device);
1511                 bdaddr = device_get_address(session->device);
1512                 if (adapter && bdaddr)
1513                         device = btd_adapter_find_device(adapter, bdaddr, BDADDR_BREDR);
1514                 if (device) {
1515                         DBG("device exists");
1516                         goto done;
1517                 }
1518
1519                 error("device is NOT found");
1520         }
1521 #endif
1522
1523         connection_lost(session, ETIMEDOUT);
1524
1525 done:
1526         /* Release disconnect timer reference */
1527         avdtp_unref(session);
1528
1529 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1530         if (device)
1531                 g_timeout_add(100,
1532                         disconnect_acl_timeout,
1533                         device);
1534 #endif
1535
1536         return FALSE;
1537 }
1538
1539 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
1540 static void set_disconnect_timer_for_sink(struct avdtp *session, gboolean disconn)
1541 {
1542         char name[6];
1543
1544         if (session->dc_timer)
1545                 remove_disconnect_timer(session);
1546
1547         device_get_name(session->device, name, sizeof(name));
1548         DBG("name : [%s]", name);
1549         if (g_str_equal(name, "VW BT") || g_str_equal(name, "VW MI") ||
1550                                                 g_str_equal(name, "Seat ")) {
1551                 session->dc_timer = g_timeout_add_seconds(3, disconnect_timeout,
1552                                 session);
1553         } else if (g_str_equal(name, "CAR M")) {
1554                 session->dc_timer = g_timeout_add(200, disconnect_timeout,
1555                                 session);
1556         } else {
1557                 if (disconn == TRUE)
1558                         session->dc_timer = g_timeout_add(100,
1559                                         disconnect_timeout,
1560                                         session);
1561                 else
1562                         session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
1563                                         disconnect_timeout,
1564                                         session);
1565         }
1566 }
1567 #endif
1568
1569 static void set_disconnect_timer(struct avdtp *session)
1570 {
1571 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1572         char name[6];
1573 #endif
1574         /* Take a ref while disconnect timer is active */
1575         avdtp_ref(session);
1576
1577 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1578         device_get_name(session->device, name, sizeof(name));
1579         DBG("name : [%s]", name);
1580         if (g_str_equal(name, "VW BT") || g_str_equal(name, "VW MI") ||
1581                                                 g_str_equal(name, "Seat ")) {
1582                 session->dc_timer = g_timeout_add_seconds(3, disconnect_timeout,
1583                                 session);
1584         } else if (g_str_equal(name, "CAR M")) {
1585                 session->dc_timer = g_timeout_add(200, disconnect_timeout,
1586                                 session);
1587         } else {
1588                 session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
1589                                 disconnect_timeout,
1590                                 session);
1591         }
1592 #else
1593         DBG("timeout %d", session->dc_timeout);
1594         if (!session->dc_timeout)
1595                 session->dc_timer = g_idle_add(disconnect_timeout, session);
1596         else
1597                 session->dc_timer = g_timeout_add_seconds(session->dc_timeout,
1598                                                         disconnect_timeout,
1599                                                         session);
1600 #endif
1601 }
1602
1603 void avdtp_unref(struct avdtp *session)
1604 {
1605         if (!session)
1606                 return;
1607
1608         session->ref--;
1609 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
1610         struct btd_adapter *adapter;
1611         adapter = avdtp_get_adapter(session);
1612 #endif
1613
1614         DBG("%p: ref=%d", session, session->ref);
1615
1616         if (session->ref > 0)
1617                 return;
1618
1619         switch (session->state) {
1620         case AVDTP_SESSION_STATE_CONNECTED:
1621 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
1622                 if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE)
1623                         set_disconnect_timer_for_sink(session, TRUE);
1624                 else
1625                         set_disconnect_timer(session);
1626 #else
1627                 set_disconnect_timer(session);
1628 #endif
1629                 break;
1630         case AVDTP_SESSION_STATE_CONNECTING:
1631                 connection_lost(session, ECONNABORTED);
1632                 break;
1633         case AVDTP_SESSION_STATE_DISCONNECTED:
1634         default:
1635                 avdtp_free(session);
1636                 break;
1637         }
1638 }
1639
1640 struct avdtp *avdtp_ref(struct avdtp *session)
1641 {
1642         session->ref++;
1643         DBG("%p: ref=%d", session, session->ref);
1644         remove_disconnect_timer(session);
1645         return session;
1646 }
1647
1648 static bool match_by_seid(const void *data, const void *user_data)
1649 {
1650         const struct avdtp_local_sep *sep = data;
1651         uint8_t seid = PTR_TO_UINT(user_data);
1652
1653         return sep->info.seid == seid;
1654 }
1655
1656 static struct avdtp_local_sep *find_local_sep_by_seid(struct avdtp *session,
1657                                                                 uint8_t seid)
1658 {
1659         return queue_find(session->lseps, match_by_seid, INT_TO_PTR(seid));
1660 }
1661
1662 struct avdtp_remote_sep *avdtp_find_remote_sep(struct avdtp *session,
1663                                                 struct avdtp_local_sep *lsep)
1664 {
1665         GSList *l;
1666
1667         if (lsep->info.inuse)
1668                 return NULL;
1669
1670         for (l = session->seps; l != NULL; l = g_slist_next(l)) {
1671                 struct avdtp_remote_sep *sep = l->data;
1672                 struct avdtp_service_capability *cap;
1673                 struct avdtp_media_codec_capability *codec_data;
1674
1675                 /* Type must be different: source <-> sink */
1676                 if (sep->type == lsep->info.type)
1677                         continue;
1678
1679                 if (sep->media_type != lsep->info.media_type)
1680                         continue;
1681
1682                 if (!sep->codec)
1683                         continue;
1684
1685                 cap = sep->codec;
1686                 codec_data = (void *) cap->data;
1687
1688                 if (codec_data->media_codec_type != lsep->codec)
1689                         continue;
1690
1691                 if (lsep->ind && lsep->ind->match_codec)
1692                         if (!lsep->ind->match_codec(session, codec_data,
1693                                                         lsep->user_data))
1694                                 continue;
1695
1696                 if (sep->stream == NULL)
1697                         return sep;
1698         }
1699
1700         return NULL;
1701 }
1702
1703 static GSList *caps_to_list(uint8_t *data, int size,
1704                                 struct avdtp_service_capability **codec,
1705                                 gboolean *delay_reporting)
1706 {
1707         GSList *caps;
1708         int processed;
1709
1710         if (delay_reporting)
1711                 *delay_reporting = FALSE;
1712
1713         for (processed = 0, caps = NULL; processed + 2 <= size;) {
1714                 struct avdtp_service_capability *cap;
1715                 uint8_t length, category;
1716
1717                 category = data[0];
1718                 length = data[1];
1719
1720                 if (processed + 2 + length > size) {
1721                         error("Invalid capability data in getcap resp");
1722                         break;
1723                 }
1724
1725                 cap = g_malloc(sizeof(struct avdtp_service_capability) +
1726                                         length);
1727                 memcpy(cap, data, 2 + length);
1728
1729                 processed += 2 + length;
1730                 data += 2 + length;
1731
1732                 caps = g_slist_append(caps, cap);
1733
1734                 if (category == AVDTP_MEDIA_CODEC &&
1735                                 length >=
1736                                 sizeof(struct avdtp_media_codec_capability))
1737                         *codec = cap;
1738                 else if (category == AVDTP_DELAY_REPORTING && delay_reporting)
1739                         *delay_reporting = TRUE;
1740         }
1741
1742         return caps;
1743 }
1744
1745 static gboolean avdtp_unknown_cmd(struct avdtp *session, uint8_t transaction,
1746                                                         uint8_t signal_id)
1747 {
1748         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_GEN_REJECT,
1749                                                         signal_id, NULL, 0);
1750 }
1751
1752 static void copy_seps(void *data, void *user_data)
1753 {
1754         struct avdtp_local_sep *sep = data;
1755         struct seid_info **p = user_data;
1756
1757         memcpy(*p, &sep->info, sizeof(struct seid_info));
1758         *p = *p + 1;
1759 }
1760
1761 static gboolean avdtp_discover_cmd(struct avdtp *session, uint8_t transaction,
1762                                                         void *buf, int size)
1763 {
1764         unsigned int rsp_size, sep_count;
1765         struct seid_info *seps, *p;
1766         gboolean ret;
1767
1768         sep_count = queue_length(session->lseps);
1769
1770         if (sep_count == 0) {
1771                 uint8_t err = AVDTP_NOT_SUPPORTED_COMMAND;
1772                 return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
1773                                         AVDTP_DISCOVER, &err, sizeof(err));
1774         }
1775
1776         rsp_size = sep_count * sizeof(struct seid_info);
1777
1778         seps = g_new0(struct seid_info, sep_count);
1779         p = seps;
1780
1781         queue_foreach(session->lseps, copy_seps, &p);
1782
1783         ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1784                                 AVDTP_DISCOVER, seps, rsp_size);
1785         g_free(seps);
1786
1787         return ret;
1788 }
1789
1790 static gboolean avdtp_getcap_cmd(struct avdtp *session, uint8_t transaction,
1791                                         struct seid_req *req, unsigned int size,
1792                                         gboolean get_all)
1793 {
1794         GSList *l, *caps;
1795         struct avdtp_local_sep *sep = NULL;
1796         unsigned int rsp_size;
1797         uint8_t err, buf[1024], *ptr = buf;
1798         uint8_t cmd;
1799
1800         cmd = get_all ? AVDTP_GET_ALL_CAPABILITIES : AVDTP_GET_CAPABILITIES;
1801
1802         if (size < sizeof(struct seid_req)) {
1803                 err = AVDTP_BAD_LENGTH;
1804                 goto failed;
1805         }
1806
1807         sep = find_local_sep_by_seid(session, req->acp_seid);
1808         if (!sep) {
1809                 err = AVDTP_BAD_ACP_SEID;
1810                 goto failed;
1811         }
1812
1813         if (!sep->ind->get_capability(session, sep, get_all, &caps,
1814                                                         &err, sep->user_data))
1815                 goto failed;
1816
1817         for (l = caps, rsp_size = 0; l != NULL; l = g_slist_next(l)) {
1818                 struct avdtp_service_capability *cap = l->data;
1819
1820                 if (rsp_size + cap->length + 2 > sizeof(buf))
1821                         break;
1822
1823                 memcpy(ptr, cap, cap->length + 2);
1824                 rsp_size += cap->length + 2;
1825                 ptr += cap->length + 2;
1826
1827                 g_free(cap);
1828         }
1829
1830         g_slist_free(caps);
1831
1832         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT, cmd,
1833                                                                 buf, rsp_size);
1834
1835 failed:
1836         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT, cmd,
1837                                                         &err, sizeof(err));
1838 }
1839
1840 static void setconf_cb(struct avdtp *session, struct avdtp_stream *stream,
1841                                                 struct avdtp_error *err)
1842 {
1843         struct conf_rej rej;
1844         struct avdtp_local_sep *sep;
1845
1846         if (err != NULL) {
1847                 rej.error = AVDTP_UNSUPPORTED_CONFIGURATION;
1848                 rej.category = err->err.error_code;
1849                 avdtp_send(session, session->in.transaction,
1850                                 AVDTP_MSG_TYPE_REJECT, AVDTP_SET_CONFIGURATION,
1851                                 &rej, sizeof(rej));
1852                 stream_free(stream);
1853                 return;
1854         }
1855
1856         if (!avdtp_send(session, session->in.transaction, AVDTP_MSG_TYPE_ACCEPT,
1857                                         AVDTP_SET_CONFIGURATION, NULL, 0)) {
1858                 stream_free(stream);
1859                 return;
1860         }
1861
1862         sep = stream->lsep;
1863         sep->stream = stream;
1864         sep->info.inuse = 1;
1865         session->streams = g_slist_append(session->streams, stream);
1866
1867         avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
1868 }
1869
1870 static gboolean avdtp_setconf_cmd(struct avdtp *session, uint8_t transaction,
1871                                 struct setconf_req *req, unsigned int size)
1872 {
1873         struct conf_rej rej;
1874         struct avdtp_local_sep *sep;
1875         struct avdtp_stream *stream;
1876         uint8_t err, category = 0x00;
1877         struct btd_service *service;
1878         GSList *l;
1879
1880         if (size < sizeof(struct setconf_req)) {
1881                 error("Too short getcap request");
1882                 return FALSE;
1883         }
1884
1885         sep = find_local_sep_by_seid(session, req->acp_seid);
1886         if (!sep) {
1887                 err = AVDTP_BAD_ACP_SEID;
1888                 goto failed;
1889         }
1890
1891         if (sep->stream) {
1892                 err = AVDTP_SEP_IN_USE;
1893                 goto failed;
1894         }
1895
1896         switch (sep->info.type) {
1897         case AVDTP_SEP_TYPE_SOURCE:
1898                 service = btd_device_get_service(session->device,
1899                                                         A2DP_SINK_UUID);
1900                 if (service == NULL) {
1901                         btd_device_add_uuid(session->device, A2DP_SINK_UUID);
1902                         service = btd_device_get_service(session->device,
1903                                                         A2DP_SINK_UUID);
1904                         if (service == NULL) {
1905                                 error("Unable to get a audio sink object");
1906                                 err = AVDTP_BAD_STATE;
1907                                 goto failed;
1908                         }
1909                 }
1910                 break;
1911         case AVDTP_SEP_TYPE_SINK:
1912                 service = btd_device_get_service(session->device,
1913                                                         A2DP_SOURCE_UUID);
1914                 if (service == NULL) {
1915                         btd_device_add_uuid(session->device, A2DP_SOURCE_UUID);
1916                         service = btd_device_get_service(session->device,
1917                                                         A2DP_SOURCE_UUID);
1918                         if (service == NULL) {
1919                                 error("Unable to get a audio source object");
1920                                 err = AVDTP_BAD_STATE;
1921                                 goto failed;
1922                         }
1923                 }
1924                 break;
1925         }
1926
1927         stream = g_new0(struct avdtp_stream, 1);
1928         stream->session = session;
1929         stream->lsep = sep;
1930         stream->rseid = req->int_seid;
1931         stream->caps = caps_to_list(req->caps,
1932                                         size - sizeof(struct setconf_req),
1933                                         &stream->codec,
1934                                         &stream->delay_reporting);
1935
1936         /* Verify that the Media Transport capability's length = 0. Reject otherwise */
1937         for (l = stream->caps; l != NULL; l = g_slist_next(l)) {
1938                 struct avdtp_service_capability *cap = l->data;
1939
1940                 if (cap->category == AVDTP_MEDIA_TRANSPORT && cap->length != 0) {
1941                         err = AVDTP_BAD_MEDIA_TRANSPORT_FORMAT;
1942                         goto failed_stream;
1943                 }
1944         }
1945
1946         if (stream->delay_reporting && session->version < 0x0103)
1947                 session->version = 0x0103;
1948
1949         if (sep->ind && sep->ind->set_configuration) {
1950                 if (!sep->ind->set_configuration(session, sep, stream,
1951                                                         stream->caps,
1952                                                         setconf_cb,
1953                                                         sep->user_data)) {
1954                         err = AVDTP_UNSUPPORTED_CONFIGURATION;
1955                         category = 0x00;
1956                         goto failed_stream;
1957                 }
1958         } else {
1959                 if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
1960                                         AVDTP_SET_CONFIGURATION, NULL, 0)) {
1961                         stream_free(stream);
1962                         return FALSE;
1963                 }
1964
1965                 sep->stream = stream;
1966                 sep->info.inuse = 1;
1967                 session->streams = g_slist_append(session->streams, stream);
1968
1969                 avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
1970         }
1971
1972         return TRUE;
1973
1974 failed_stream:
1975         stream_free(stream);
1976 failed:
1977         rej.error = err;
1978         rej.category = category;
1979         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
1980                                 AVDTP_SET_CONFIGURATION, &rej, sizeof(rej));
1981 }
1982
1983 static gboolean avdtp_getconf_cmd(struct avdtp *session, uint8_t transaction,
1984                                         struct seid_req *req, int size)
1985 {
1986         GSList *l;
1987         struct avdtp_local_sep *sep = NULL;
1988         int rsp_size;
1989         uint8_t err;
1990         uint8_t buf[1024];
1991         uint8_t *ptr = buf;
1992
1993         if (size < (int) sizeof(struct seid_req)) {
1994                 error("Too short getconf request");
1995                 return FALSE;
1996         }
1997
1998         memset(buf, 0, sizeof(buf));
1999
2000         sep = find_local_sep_by_seid(session, req->acp_seid);
2001         if (!sep) {
2002                 err = AVDTP_BAD_ACP_SEID;
2003                 goto failed;
2004         }
2005         if (!sep->stream || !sep->stream->caps) {
2006                 err = AVDTP_UNSUPPORTED_CONFIGURATION;
2007                 goto failed;
2008         }
2009
2010         for (l = sep->stream->caps, rsp_size = 0; l != NULL; l = g_slist_next(l)) {
2011                 struct avdtp_service_capability *cap = l->data;
2012
2013                 if (rsp_size + cap->length + 2 > (int) sizeof(buf))
2014                         break;
2015
2016                 memcpy(ptr, cap, cap->length + 2);
2017                 rsp_size += cap->length + 2;
2018                 ptr += cap->length + 2;
2019         }
2020
2021         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2022                                 AVDTP_GET_CONFIGURATION, buf, rsp_size);
2023
2024 failed:
2025         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2026                                 AVDTP_GET_CONFIGURATION, &err, sizeof(err));
2027 }
2028
2029 static gboolean avdtp_reconf_cmd(struct avdtp *session, uint8_t transaction,
2030                                         struct seid_req *req, int size)
2031 {
2032         struct conf_rej rej;
2033
2034         rej.error = AVDTP_NOT_SUPPORTED_COMMAND;
2035         rej.category = 0x00;
2036
2037         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2038                                         AVDTP_RECONFIGURE, &rej, sizeof(rej));
2039 }
2040
2041 static void check_seid_collision(struct pending_req *req, uint8_t id)
2042 {
2043         struct seid_req *seid = req->data;
2044
2045         if (seid->acp_seid == id)
2046                 req->collided = TRUE;
2047 }
2048
2049 static void check_start_collision(struct pending_req *req, uint8_t id)
2050 {
2051         struct start_req *start = req->data;
2052         struct seid *seid = &start->first_seid;
2053         int count = 1 + req->data_size - sizeof(struct start_req);
2054         int i;
2055
2056         for (i = 0; i < count; i++, seid++) {
2057                 if (seid->seid == id) {
2058                         req->collided = TRUE;
2059                         return;
2060                 }
2061         }
2062 }
2063
2064 static void check_suspend_collision(struct pending_req *req, uint8_t id)
2065 {
2066         struct suspend_req *suspend = req->data;
2067         struct seid *seid = &suspend->first_seid;
2068         int count = 1 + req->data_size - sizeof(struct suspend_req);
2069         int i;
2070
2071         for (i = 0; i < count; i++, seid++) {
2072                 if (seid->seid == id) {
2073                         req->collided = TRUE;
2074                         return;
2075                 }
2076         }
2077 }
2078
2079 static void avdtp_check_collision(struct avdtp *session, uint8_t cmd,
2080                                         struct avdtp_stream *stream)
2081 {
2082         struct pending_req *req = session->req;
2083
2084         if (req == NULL || (req->signal_id != cmd && cmd != AVDTP_ABORT))
2085                 return;
2086
2087         if (cmd == AVDTP_ABORT)
2088                 cmd = req->signal_id;
2089
2090         switch (cmd) {
2091         case AVDTP_OPEN:
2092         case AVDTP_CLOSE:
2093                 check_seid_collision(req, stream->rseid);
2094                 break;
2095         case AVDTP_START:
2096                 check_start_collision(req, stream->rseid);
2097                 break;
2098         case AVDTP_SUSPEND:
2099                 check_suspend_collision(req, stream->rseid);
2100                 break;
2101         }
2102 }
2103
2104 static gboolean avdtp_open_cmd(struct avdtp *session, uint8_t transaction,
2105                                 struct seid_req *req, unsigned int size)
2106 {
2107         struct avdtp_local_sep *sep;
2108         struct avdtp_stream *stream;
2109         uint8_t err;
2110
2111         if (size < sizeof(struct seid_req)) {
2112                 error("Too short abort request");
2113                 return FALSE;
2114         }
2115
2116         sep = find_local_sep_by_seid(session, req->acp_seid);
2117         if (!sep) {
2118                 err = AVDTP_BAD_ACP_SEID;
2119                 goto failed;
2120         }
2121
2122         if (sep->state != AVDTP_STATE_CONFIGURED) {
2123                 err = AVDTP_BAD_STATE;
2124                 goto failed;
2125         }
2126
2127         stream = sep->stream;
2128
2129         if (sep->ind && sep->ind->open) {
2130                 if (!sep->ind->open(session, sep, stream, &err,
2131                                         sep->user_data))
2132                         goto failed;
2133         }
2134
2135         avdtp_check_collision(session, AVDTP_OPEN, stream);
2136
2137         if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2138                                                 AVDTP_OPEN, NULL, 0))
2139                 return FALSE;
2140
2141         stream->open_acp = TRUE;
2142         session->pending_open = stream;
2143         stream->timer = g_timeout_add_seconds(REQ_TIMEOUT,
2144                                                 stream_open_timeout,
2145                                                 stream);
2146
2147         return TRUE;
2148
2149 failed:
2150         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2151                                 AVDTP_OPEN, &err, sizeof(err));
2152 }
2153
2154 static gboolean avdtp_start_cmd(struct avdtp *session, uint8_t transaction,
2155                                 struct start_req *req, unsigned int size)
2156 {
2157
2158         struct avdtp_local_sep *sep;
2159         struct avdtp_stream *stream;
2160         struct stream_rej rej;
2161         struct seid *seid;
2162         uint8_t err, failed_seid;
2163         int seid_count;
2164         int i;
2165
2166         if (size < sizeof(struct start_req)) {
2167                 error("Too short start request");
2168                 return FALSE;
2169         }
2170
2171         seid_count = 1 + size - sizeof(struct start_req);
2172
2173         seid = &req->first_seid;
2174
2175         for (i = 0; i < seid_count; i++, seid++) {
2176                 failed_seid = seid->seid;
2177
2178                 sep = find_local_sep_by_seid(session, seid->seid);
2179                 if (!sep || !sep->stream) {
2180                         err = AVDTP_BAD_ACP_SEID;
2181                         goto failed;
2182                 }
2183
2184                 stream = sep->stream;
2185
2186                 /* Also reject start cmd if state is not open */
2187                 if (sep->state != AVDTP_STATE_OPEN) {
2188                         err = AVDTP_BAD_STATE;
2189                         goto failed;
2190                 }
2191                 stream->starting = TRUE;
2192
2193                 if (sep->ind && sep->ind->start) {
2194                         if (!sep->ind->start(session, sep, stream, &err,
2195                                                 sep->user_data))
2196                                 goto failed;
2197                 }
2198
2199                 avdtp_check_collision(session, AVDTP_START, stream);
2200
2201 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
2202                 avdtp_add_source_device(session->device);
2203 #endif
2204
2205                 avdtp_sep_set_state(session, sep, AVDTP_STATE_STREAMING);
2206         }
2207
2208         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2209                                                 AVDTP_START, NULL, 0);
2210
2211 failed:
2212         DBG("Rejecting (%d)", err);
2213         memset(&rej, 0, sizeof(rej));
2214         rej.acp_seid = failed_seid;
2215         rej.error = err;
2216         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2217                                 AVDTP_START, &rej, sizeof(rej));
2218 }
2219
2220 static gboolean avdtp_close_cmd(struct avdtp *session, uint8_t transaction,
2221                                 struct seid_req *req, unsigned int size)
2222 {
2223         struct avdtp_local_sep *sep;
2224         struct avdtp_stream *stream;
2225         uint8_t err;
2226
2227 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
2228         avdtp_remove_source_devce(session->device);
2229 #endif
2230
2231         if (size < sizeof(struct seid_req)) {
2232                 error("Too short close request");
2233                 return FALSE;
2234         }
2235
2236         sep = find_local_sep_by_seid(session, req->acp_seid);
2237         if (!sep || !sep->stream) {
2238                 err = AVDTP_BAD_ACP_SEID;
2239                 goto failed;
2240         }
2241
2242         if (sep->state != AVDTP_STATE_OPEN &&
2243                         sep->state != AVDTP_STATE_STREAMING) {
2244                 err = AVDTP_BAD_STATE;
2245                 goto failed;
2246         }
2247
2248         stream = sep->stream;
2249
2250         if (sep->ind && sep->ind->close) {
2251                 if (!sep->ind->close(session, sep, stream, &err,
2252                                         sep->user_data))
2253                         goto failed;
2254         }
2255
2256         avdtp_check_collision(session, AVDTP_CLOSE, stream);
2257
2258         avdtp_sep_set_state(session, sep, AVDTP_STATE_CLOSING);
2259
2260         session->dc_timeout = DISCONNECT_TIMEOUT;
2261
2262         if (!avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2263                                                 AVDTP_CLOSE, NULL, 0))
2264                 return FALSE;
2265
2266         stream->timer = g_timeout_add_seconds(REQ_TIMEOUT,
2267                                         stream_close_timeout,
2268                                         stream);
2269
2270         return TRUE;
2271
2272 failed:
2273         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2274                                         AVDTP_CLOSE, &err, sizeof(err));
2275 }
2276
2277 static gboolean avdtp_suspend_cmd(struct avdtp *session, uint8_t transaction,
2278                                 struct suspend_req *req, unsigned int size)
2279 {
2280         struct avdtp_local_sep *sep;
2281         struct avdtp_stream *stream;
2282         struct stream_rej rej;
2283         struct seid *seid;
2284         uint8_t err, failed_seid;
2285         int seid_count, i;
2286
2287         if (size < sizeof(struct suspend_req)) {
2288                 error("Too short suspend request");
2289                 return FALSE;
2290         }
2291
2292         seid_count = 1 + size - sizeof(struct suspend_req);
2293
2294         seid = &req->first_seid;
2295
2296         for (i = 0; i < seid_count; i++, seid++) {
2297                 failed_seid = seid->seid;
2298
2299                 sep = find_local_sep_by_seid(session, seid->seid);
2300                 if (!sep || !sep->stream) {
2301                         err = AVDTP_BAD_ACP_SEID;
2302                         goto failed;
2303                 }
2304
2305                 stream = sep->stream;
2306
2307 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
2308                 if (sep->state != AVDTP_STATE_STREAMING) {
2309                         DBG("Not streaming state: %d", sep->state);
2310                         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2311                                                                 AVDTP_SUSPEND, NULL, 0);
2312                 }
2313 #else
2314                 if (sep->state != AVDTP_STATE_STREAMING) {
2315                         err = AVDTP_BAD_STATE;
2316                         goto failed;
2317                 }
2318 #endif
2319
2320                 if (sep->ind && sep->ind->suspend) {
2321                         if (!sep->ind->suspend(session, sep, stream, &err,
2322                                                 sep->user_data))
2323                                 goto failed;
2324                 }
2325
2326                 avdtp_check_collision(session, AVDTP_SUSPEND, stream);
2327
2328                 avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN);
2329         }
2330
2331         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2332                                                 AVDTP_SUSPEND, NULL, 0);
2333
2334 failed:
2335         memset(&rej, 0, sizeof(rej));
2336         rej.acp_seid = failed_seid;
2337         rej.error = err;
2338         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2339                                 AVDTP_SUSPEND, &rej, sizeof(rej));
2340 }
2341
2342 static gboolean avdtp_abort_cmd(struct avdtp *session, uint8_t transaction,
2343                                 struct seid_req *req, unsigned int size)
2344 {
2345         struct avdtp_local_sep *sep;
2346         uint8_t err;
2347         gboolean ret;
2348
2349         if (size < sizeof(struct seid_req)) {
2350                 error("Too short abort request");
2351                 return FALSE;
2352         }
2353
2354         sep = find_local_sep_by_seid(session, req->acp_seid);
2355         if (!sep || !sep->stream)
2356                 return TRUE;
2357
2358         if (sep->ind && sep->ind->abort)
2359                 sep->ind->abort(session, sep, sep->stream, &err,
2360                                                         sep->user_data);
2361
2362         avdtp_check_collision(session, AVDTP_ABORT, sep->stream);
2363
2364         ret = avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2365                                                 AVDTP_ABORT, NULL, 0);
2366         if (ret) {
2367                 avdtp_sep_set_state(session, sep, AVDTP_STATE_ABORTING);
2368                 session->dc_timeout = DISCONNECT_TIMEOUT;
2369         }
2370
2371         return ret;
2372 }
2373
2374 static gboolean avdtp_secctl_cmd(struct avdtp *session, uint8_t transaction,
2375                                         struct seid_req *req, int size)
2376 {
2377         return avdtp_unknown_cmd(session, transaction, AVDTP_SECURITY_CONTROL);
2378 }
2379
2380 static gboolean avdtp_delayreport_cmd(struct avdtp *session,
2381                                         uint8_t transaction,
2382                                         struct delay_req *req,
2383                                         unsigned int size)
2384 {
2385         struct avdtp_local_sep *sep;
2386         struct avdtp_stream *stream;
2387         uint8_t err;
2388
2389         if (size < sizeof(struct delay_req)) {
2390                 error("Too short delay report request");
2391                 return FALSE;
2392         }
2393
2394         sep = find_local_sep_by_seid(session, req->acp_seid);
2395         if (!sep || !sep->stream) {
2396                 err = AVDTP_BAD_ACP_SEID;
2397                 goto failed;
2398         }
2399
2400         stream = sep->stream;
2401
2402         if (sep->state != AVDTP_STATE_CONFIGURED &&
2403                                         sep->state != AVDTP_STATE_OPEN &&
2404                                         sep->state != AVDTP_STATE_STREAMING) {
2405                 err = AVDTP_BAD_STATE;
2406                 goto failed;
2407         }
2408
2409         stream->delay = ntohs(req->delay);
2410
2411         if (sep->ind && sep->ind->delayreport) {
2412                 if (!sep->ind->delayreport(session, sep, stream->rseid,
2413                                                 stream->delay, &err,
2414                                                 sep->user_data))
2415                         goto failed;
2416         }
2417
2418         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_ACCEPT,
2419                                                 AVDTP_DELAY_REPORT, NULL, 0);
2420
2421 failed:
2422         return avdtp_send(session, transaction, AVDTP_MSG_TYPE_REJECT,
2423                                         AVDTP_DELAY_REPORT, &err, sizeof(err));
2424 }
2425
2426 static gboolean avdtp_parse_cmd(struct avdtp *session, uint8_t transaction,
2427                                 uint8_t signal_id, void *buf, int size)
2428 {
2429         switch (signal_id) {
2430         case AVDTP_DISCOVER:
2431                 DBG("Received DISCOVER_CMD");
2432                 return avdtp_discover_cmd(session, transaction, buf, size);
2433         case AVDTP_GET_CAPABILITIES:
2434                 DBG("Received  GET_CAPABILITIES_CMD");
2435                 return avdtp_getcap_cmd(session, transaction, buf, size,
2436                                                                         FALSE);
2437         case AVDTP_GET_ALL_CAPABILITIES:
2438                 DBG("Received  GET_ALL_CAPABILITIES_CMD");
2439                 return avdtp_getcap_cmd(session, transaction, buf, size, TRUE);
2440         case AVDTP_SET_CONFIGURATION:
2441                 DBG("Received SET_CONFIGURATION_CMD");
2442                 return avdtp_setconf_cmd(session, transaction, buf, size);
2443         case AVDTP_GET_CONFIGURATION:
2444                 DBG("Received GET_CONFIGURATION_CMD");
2445                 return avdtp_getconf_cmd(session, transaction, buf, size);
2446         case AVDTP_RECONFIGURE:
2447                 DBG("Received RECONFIGURE_CMD");
2448                 return avdtp_reconf_cmd(session, transaction, buf, size);
2449         case AVDTP_OPEN:
2450                 DBG("Received OPEN_CMD");
2451                 return avdtp_open_cmd(session, transaction, buf, size);
2452         case AVDTP_START:
2453                 DBG("Received START_CMD");
2454                 return avdtp_start_cmd(session, transaction, buf, size);
2455         case AVDTP_CLOSE:
2456                 DBG("Received CLOSE_CMD");
2457                 return avdtp_close_cmd(session, transaction, buf, size);
2458         case AVDTP_SUSPEND:
2459                 DBG("Received SUSPEND_CMD");
2460                 return avdtp_suspend_cmd(session, transaction, buf, size);
2461         case AVDTP_ABORT:
2462                 DBG("Received ABORT_CMD");
2463                 return avdtp_abort_cmd(session, transaction, buf, size);
2464         case AVDTP_SECURITY_CONTROL:
2465                 DBG("Received SECURITY_CONTROL_CMD");
2466                 return avdtp_secctl_cmd(session, transaction, buf, size);
2467         case AVDTP_DELAY_REPORT:
2468                 DBG("Received DELAY_REPORT_CMD");
2469                 return avdtp_delayreport_cmd(session, transaction, buf, size);
2470         default:
2471                 DBG("Received unknown request id %u", signal_id);
2472                 return avdtp_unknown_cmd(session, transaction, signal_id);
2473         }
2474 }
2475
2476 enum avdtp_parse_result { PARSE_ERROR, PARSE_FRAGMENT, PARSE_SUCCESS };
2477
2478 static enum avdtp_parse_result avdtp_parse_data(struct avdtp *session,
2479                                                         void *buf, size_t size)
2480 {
2481         struct avdtp_common_header *header = buf;
2482         struct avdtp_single_header *single = (void *) session->buf;
2483         struct avdtp_start_header *start = (void *) session->buf;
2484         void *payload;
2485         gsize payload_size;
2486
2487         switch (header->packet_type) {
2488         case AVDTP_PKT_TYPE_SINGLE:
2489                 if (size < sizeof(*single)) {
2490                         error("Received too small single packet (%zu bytes)", size);
2491                         return PARSE_ERROR;
2492                 }
2493                 if (session->in.active) {
2494                         error("SINGLE: Invalid AVDTP packet fragmentation");
2495                         return PARSE_ERROR;
2496                 }
2497
2498                 payload = session->buf + sizeof(*single);
2499                 payload_size = size - sizeof(*single);
2500
2501                 session->in.active = TRUE;
2502                 session->in.data_size = 0;
2503                 session->in.no_of_packets = 1;
2504                 session->in.transaction = header->transaction;
2505                 session->in.message_type = header->message_type;
2506                 session->in.signal_id = single->signal_id;
2507
2508                 break;
2509         case AVDTP_PKT_TYPE_START:
2510                 if (size < sizeof(*start)) {
2511                         error("Received too small start packet (%zu bytes)", size);
2512                         return PARSE_ERROR;
2513                 }
2514                 if (session->in.active) {
2515                         error("START: Invalid AVDTP packet fragmentation");
2516                         return PARSE_ERROR;
2517                 }
2518
2519                 session->in.active = TRUE;
2520                 session->in.data_size = 0;
2521                 session->in.transaction = header->transaction;
2522                 session->in.message_type = header->message_type;
2523                 session->in.no_of_packets = start->no_of_packets;
2524                 session->in.signal_id = start->signal_id;
2525
2526                 payload = session->buf + sizeof(*start);
2527                 payload_size = size - sizeof(*start);
2528
2529                 break;
2530         case AVDTP_PKT_TYPE_CONTINUE:
2531                 if (size < sizeof(struct avdtp_continue_header)) {
2532                         error("Received too small continue packet (%zu bytes)",
2533                                                                         size);
2534                         return PARSE_ERROR;
2535                 }
2536                 if (!session->in.active) {
2537                         error("CONTINUE: Invalid AVDTP packet fragmentation");
2538                         return PARSE_ERROR;
2539                 }
2540                 if (session->in.transaction != header->transaction) {
2541                         error("Continue transaction id doesn't match");
2542                         return PARSE_ERROR;
2543                 }
2544                 if (session->in.no_of_packets <= 1) {
2545                         error("Too few continue packets");
2546                         return PARSE_ERROR;
2547                 }
2548
2549                 payload = session->buf + sizeof(struct avdtp_continue_header);
2550                 payload_size = size - sizeof(struct avdtp_continue_header);
2551
2552                 break;
2553         case AVDTP_PKT_TYPE_END:
2554                 if (size < sizeof(struct avdtp_continue_header)) {
2555                         error("Received too small end packet (%zu bytes)", size);
2556                         return PARSE_ERROR;
2557                 }
2558                 if (!session->in.active) {
2559                         error("END: Invalid AVDTP packet fragmentation");
2560                         return PARSE_ERROR;
2561                 }
2562                 if (session->in.transaction != header->transaction) {
2563                         error("End transaction id doesn't match");
2564                         return PARSE_ERROR;
2565                 }
2566                 if (session->in.no_of_packets > 1) {
2567                         error("Got an end packet too early");
2568                         return PARSE_ERROR;
2569                 }
2570
2571                 payload = session->buf + sizeof(struct avdtp_continue_header);
2572                 payload_size = size - sizeof(struct avdtp_continue_header);
2573
2574                 break;
2575         default:
2576                 error("Invalid AVDTP packet type 0x%02X", header->packet_type);
2577                 return PARSE_ERROR;
2578         }
2579
2580         if (session->in.data_size + payload_size >
2581                                         sizeof(session->in.buf)) {
2582                 error("Not enough incoming buffer space!");
2583                 return PARSE_ERROR;
2584         }
2585
2586         memcpy(session->in.buf + session->in.data_size, payload, payload_size);
2587         session->in.data_size += payload_size;
2588
2589         if (session->in.no_of_packets > 1) {
2590                 session->in.no_of_packets--;
2591                 DBG("Received AVDTP fragment. %d to go",
2592                                                 session->in.no_of_packets);
2593                 return PARSE_FRAGMENT;
2594         }
2595
2596         session->in.active = FALSE;
2597
2598         return PARSE_SUCCESS;
2599 }
2600
2601 static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
2602                                 gpointer data)
2603 {
2604         struct avdtp *session = data;
2605         struct avdtp_common_header *header;
2606         ssize_t size;
2607         int fd;
2608
2609         DBG("");
2610
2611         if (cond & G_IO_NVAL)
2612                 return FALSE;
2613
2614         header = (void *) session->buf;
2615
2616         if (cond & (G_IO_HUP | G_IO_ERR))
2617                 goto failed;
2618
2619         fd = g_io_channel_unix_get_fd(chan);
2620         size = read(fd, session->buf, session->imtu);
2621         if (size < 0) {
2622                 error("IO Channel read error");
2623                 goto failed;
2624         }
2625
2626         if ((size_t) size < sizeof(struct avdtp_common_header)) {
2627                 error("Received too small packet (%zu bytes)", size);
2628                 goto failed;
2629         }
2630
2631         switch (avdtp_parse_data(session, session->buf, size)) {
2632         case PARSE_ERROR:
2633                 goto failed;
2634         case PARSE_FRAGMENT:
2635                 return TRUE;
2636         case PARSE_SUCCESS:
2637                 break;
2638         }
2639
2640         if (session->in.message_type == AVDTP_MSG_TYPE_COMMAND) {
2641 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2642                 struct btd_service *service;
2643
2644                 service = btd_device_get_service(session->device, A2DP_SINK_UUID);
2645                 if (service != NULL) {
2646                         DBG("A2dp state %d", btd_service_get_state(
2647                                         btd_device_get_service(session->device, A2DP_SINK_UUID)));
2648
2649                         if (btd_service_get_state(btd_device_get_service(session->device,
2650                                         A2DP_SINK_UUID)) == BTD_SERVICE_STATE_DISCONNECTING) {
2651                                 DBG("avdtp:%p , disconnect timer is going on", session);
2652                                 return FALSE;
2653                         }
2654                 }
2655 #endif
2656                 if (!avdtp_parse_cmd(session, session->in.transaction,
2657                                         session->in.signal_id,
2658                                         session->in.buf,
2659                                         session->in.data_size)) {
2660                         error("Unable to handle command. Disconnecting");
2661                         goto failed;
2662                 }
2663
2664                 if (session->req && session->req->collided) {
2665                         DBG("Collision detected");
2666                         goto next;
2667                 }
2668
2669                 return TRUE;
2670         }
2671
2672         if (session->req == NULL) {
2673                 error("No pending request, ignoring message");
2674                 return TRUE;
2675         }
2676
2677         if (header->transaction != session->req->transaction) {
2678                 error("Transaction label doesn't match");
2679                 return TRUE;
2680         }
2681
2682         if (session->in.signal_id != session->req->signal_id) {
2683                 error("Response signal doesn't match");
2684                 return TRUE;
2685         }
2686
2687         g_source_remove(session->req->timeout);
2688         session->req->timeout = 0;
2689
2690         switch (header->message_type) {
2691         case AVDTP_MSG_TYPE_ACCEPT:
2692                 if (!avdtp_parse_resp(session, session->req->stream,
2693                                                 session->in.transaction,
2694                                                 session->in.signal_id,
2695                                                 session->in.buf,
2696                                                 session->in.data_size)) {
2697                         error("Unable to parse accept response");
2698                         goto failed;
2699                 }
2700                 break;
2701         case AVDTP_MSG_TYPE_REJECT:
2702                 if (!avdtp_parse_rej(session, session->req->stream,
2703                                                 session->in.transaction,
2704                                                 session->in.signal_id,
2705                                                 session->in.buf,
2706                                                 session->in.data_size)) {
2707                         error("Unable to parse reject response");
2708                         goto failed;
2709                 }
2710                 break;
2711         case AVDTP_MSG_TYPE_GEN_REJECT:
2712                 error("Received a General Reject message");
2713                 break;
2714         default:
2715                 error("Unknown message type 0x%02X", header->message_type);
2716                 break;
2717         }
2718
2719 next:
2720         pending_req_free(session->req);
2721         session->req = NULL;
2722
2723         process_queue(session);
2724
2725         return TRUE;
2726
2727 failed:
2728         connection_lost(session, EIO);
2729
2730         return FALSE;
2731 }
2732
2733 static uint16_t get_version(struct avdtp *session)
2734 {
2735         const sdp_record_t *rec;
2736         sdp_list_t *protos;
2737         sdp_data_t *proto_desc;
2738         uint16_t ver = 0x0000;
2739
2740         rec = btd_device_get_record(session->device, A2DP_SINK_UUID);
2741         if (!rec)
2742                 rec = btd_device_get_record(session->device, A2DP_SOURCE_UUID);
2743
2744         if (!rec)
2745                 return ver;
2746
2747         if (sdp_get_access_protos(rec, &protos) < 0)
2748                 return ver;
2749
2750         proto_desc = sdp_get_proto_desc(protos, AVDTP_UUID);
2751         if (proto_desc && proto_desc->dtd == SDP_UINT16)
2752                 ver = proto_desc->val.uint16;
2753
2754         sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL);
2755         sdp_list_free(protos, NULL);
2756
2757         return ver;
2758 }
2759
2760 static void avdtp_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
2761 {
2762         struct avdtp *session = user_data;
2763         char address[18];
2764         int err_no = EIO;
2765 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
2766         struct btd_adapter *adapter;
2767         adapter = avdtp_get_adapter(session);
2768 #endif
2769
2770         if (err) {
2771                 err_no = err->code;
2772                 error("%s", err->message);
2773                 goto failed;
2774         }
2775
2776         if (!session->io)
2777                 session->io = g_io_channel_ref(chan);
2778
2779         /* Check if kernel supports reading packet types */
2780         bt_io_get(chan, NULL, BT_IO_OPT_PHY, &session->phy, BT_IO_OPT_INVALID);
2781
2782         bt_io_get(chan, &err,
2783                         BT_IO_OPT_OMTU, &session->omtu,
2784                         BT_IO_OPT_IMTU, &session->imtu,
2785                         BT_IO_OPT_INVALID);
2786         if (err) {
2787                 err_no = err->code;
2788                 error("%s", err->message);
2789                 goto failed;
2790         }
2791
2792         ba2str(device_get_address(session->device), address);
2793         DBG("AVDTP: connected %s channel to %s",
2794                         session->pending_open ? "transport" : "signaling",
2795                         address);
2796
2797         if (session->state == AVDTP_SESSION_STATE_CONNECTING) {
2798                 DBG("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu);
2799
2800                 session->buf = g_malloc0(MAX(session->imtu, session->omtu));
2801                 avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTED);
2802
2803                 if (session->io_id)
2804                         g_source_remove(session->io_id);
2805
2806                 /* This watch should be low priority since otherwise the
2807                  * connect callback might be dispatched before the session
2808                  * callback if the kernel wakes us up at the same time for
2809                  * them. This could happen if a headset is very quick in
2810                  * sending the Start command after connecting the stream
2811                  * transport channel.
2812                  */
2813                 session->io_id = g_io_add_watch_full(chan,
2814                                                 G_PRIORITY_LOW,
2815                                                 G_IO_IN | G_IO_ERR | G_IO_HUP
2816                                                 | G_IO_NVAL,
2817                                                 (GIOFunc) session_cb, session,
2818                                                 NULL);
2819
2820                 if (session->stream_setup) {
2821 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
2822                         if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE)
2823                                 set_disconnect_timer_for_sink(session, FALSE);
2824                         else
2825                                 set_disconnect_timer(session);
2826 #else
2827                         set_disconnect_timer(session);
2828 #endif
2829                 }
2830         } else if (session->pending_open)
2831                 handle_transport_connect(session, chan, session->imtu,
2832                                                                 session->omtu);
2833         else
2834                 goto failed;
2835
2836         process_queue(session);
2837
2838         return;
2839
2840 failed:
2841         if (session->pending_open) {
2842                 struct avdtp_stream *stream = session->pending_open;
2843
2844                 handle_transport_connect(session, NULL, 0, 0);
2845
2846                 if (avdtp_abort(session, stream) < 0)
2847                         avdtp_sep_set_state(session, stream->lsep,
2848                                                 AVDTP_STATE_IDLE);
2849         } else
2850                 connection_lost(session, err_no);
2851 }
2852
2853 struct avdtp *avdtp_new(GIOChannel *chan, struct btd_device *device,
2854                                                         struct queue *lseps)
2855 {
2856         struct avdtp *session;
2857
2858         session = g_new0(struct avdtp, 1);
2859
2860         session->device = btd_device_ref(device);
2861         /* We don't use avdtp_set_state() here since this isn't a state change
2862          * but just setting of the initial state */
2863         session->state = AVDTP_SESSION_STATE_DISCONNECTED;
2864         session->lseps = lseps;
2865
2866         session->version = get_version(session);
2867
2868         if (!chan)
2869                 return session;
2870
2871         avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING);
2872
2873         btd_device_add_uuid(device, ADVANCED_AUDIO_UUID);
2874
2875         session->io = g_io_channel_ref(chan);
2876         session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
2877                                         (GIOFunc) session_cb, session);
2878
2879         /* This is so that avdtp_connect_cb will know to do the right thing
2880          * with respect to the disconnect timer */
2881         session->stream_setup = TRUE;
2882
2883         session->dc_timeout = DISCONNECT_TIMEOUT;
2884
2885         avdtp_connect_cb(chan, NULL, session);
2886
2887         return session;
2888 }
2889
2890 uint16_t avdtp_get_version(struct avdtp *session)
2891 {
2892         return session->version;
2893 }
2894
2895 static GIOChannel *l2cap_connect(struct avdtp *session)
2896 {
2897         GError *err = NULL;
2898         GIOChannel *io;
2899         const bdaddr_t *src;
2900         BtIOMode mode;
2901 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
2902         struct btd_adapter *adapter;
2903         adapter = avdtp_get_adapter(session);
2904 #endif
2905
2906         src = btd_adapter_get_address(device_get_adapter(session->device));
2907         if (main_opts.mps == MPS_OFF)
2908                 mode = BT_IO_MODE_BASIC;
2909         else
2910                 mode = BT_IO_MODE_STREAMING;
2911
2912 #if defined TIZEN_FEATURE_BLUEZ_MODIFY
2913         if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
2914                 io = bt_io_connect(avdtp_connect_cb, session,
2915                                 NULL, &err,
2916                                 BT_IO_OPT_SOURCE_BDADDR, src,
2917                                 BT_IO_OPT_DEST_BDADDR,
2918                                 device_get_address(session->device),
2919                                 BT_IO_OPT_PSM, AVDTP_PSM,
2920                                 BT_IO_OPT_MODE, mode,
2921                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2922                                 BT_IO_OPT_IMTU, 895,
2923                                 BT_IO_OPT_INVALID);
2924         }
2925         else {
2926                 io = bt_io_connect(avdtp_connect_cb, session,
2927                                 NULL, &err,
2928                                 BT_IO_OPT_SOURCE_BDADDR, src,
2929                                 BT_IO_OPT_DEST_BDADDR,
2930                                 device_get_address(session->device),
2931                                 BT_IO_OPT_PSM, AVDTP_PSM,
2932                                 BT_IO_OPT_MODE, mode,
2933                                 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2934                                 BT_IO_OPT_INVALID);
2935         }
2936 #else
2937         if (session->phy)
2938                 io = bt_io_connect(avdtp_connect_cb, session,
2939                                         NULL, &err,
2940                                         BT_IO_OPT_SOURCE_BDADDR, src,
2941                                         BT_IO_OPT_DEST_BDADDR,
2942                                         device_get_address(session->device),
2943                                         BT_IO_OPT_PSM, AVDTP_PSM,
2944                                         BT_IO_OPT_MODE, mode,
2945                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2946                                         /* Set Input MTU to 0 to auto-tune */
2947                                         BT_IO_OPT_IMTU, 0,
2948                                         BT_IO_OPT_INVALID);
2949         else
2950                 io = bt_io_connect(avdtp_connect_cb, session,
2951                                         NULL, &err,
2952                                         BT_IO_OPT_SOURCE_BDADDR, src,
2953                                         BT_IO_OPT_DEST_BDADDR,
2954                                         device_get_address(session->device),
2955                                         BT_IO_OPT_PSM, AVDTP_PSM,
2956                                         BT_IO_OPT_MODE, mode,
2957                                         BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2958                                         BT_IO_OPT_INVALID);
2959 #endif
2960
2961         if (!io) {
2962                 error("%s", err->message);
2963                 g_error_free(err);
2964                 return NULL;
2965         }
2966
2967         return io;
2968 }
2969
2970 static void queue_request(struct avdtp *session, struct pending_req *req,
2971                         gboolean priority)
2972 {
2973         if (priority)
2974                 session->prio_queue = g_slist_append(session->prio_queue, req);
2975         else
2976                 session->req_queue = g_slist_append(session->req_queue, req);
2977 }
2978
2979 static uint8_t req_get_seid(struct pending_req *req)
2980 {
2981         if (req->signal_id == AVDTP_DISCOVER)
2982                 return 0;
2983
2984         return ((struct seid_req *) (req->data))->acp_seid;
2985 }
2986
2987 static int cancel_request(struct avdtp *session, int err)
2988 {
2989         struct pending_req *req;
2990         struct seid_req sreq;
2991         struct avdtp_local_sep *lsep;
2992         struct avdtp_stream *stream;
2993         uint8_t seid;
2994         struct avdtp_error averr;
2995
2996         req = session->req;
2997         session->req = NULL;
2998
2999         avdtp_error_init(&averr, AVDTP_ERRNO, err);
3000
3001         seid = req_get_seid(req);
3002         if (seid)
3003                 stream = find_stream_by_rseid(session, seid);
3004         else
3005                 stream = NULL;
3006
3007         if (stream)
3008                 lsep = stream->lsep;
3009         else
3010                 lsep = NULL;
3011
3012         switch (req->signal_id) {
3013         case AVDTP_RECONFIGURE:
3014                 error("Reconfigure: %s (%d)", strerror(err), err);
3015                 if (lsep && lsep->cfm && lsep->cfm->reconfigure)
3016                         lsep->cfm->reconfigure(session, lsep, stream, &averr,
3017                                                 lsep->user_data);
3018                 break;
3019         case AVDTP_OPEN:
3020                 error("Open: %s (%d)", strerror(err), err);
3021                 if (lsep && lsep->cfm && lsep->cfm->open)
3022                         lsep->cfm->open(session, lsep, stream, &averr,
3023                                         lsep->user_data);
3024                 break;
3025         case AVDTP_START:
3026                 error("Start: %s (%d)", strerror(err), err);
3027                 if (lsep && lsep->cfm && lsep->cfm->start) {
3028                         lsep->cfm->start(session, lsep, stream, &averr,
3029                                                 lsep->user_data);
3030                         if (stream)
3031                                 stream->starting = FALSE;
3032                 }
3033                 break;
3034         case AVDTP_SUSPEND:
3035                 error("Suspend: %s (%d)", strerror(err), err);
3036                 if (lsep && lsep->cfm && lsep->cfm->suspend)
3037                         lsep->cfm->suspend(session, lsep, stream, &averr,
3038                                                 lsep->user_data);
3039                 break;
3040         case AVDTP_CLOSE:
3041                 error("Close: %s (%d)", strerror(err), err);
3042                 if (lsep && lsep->cfm && lsep->cfm->close) {
3043                         lsep->cfm->close(session, lsep, stream, &averr,
3044                                                 lsep->user_data);
3045                         if (stream)
3046                                 stream->close_int = FALSE;
3047                 }
3048                 break;
3049         case AVDTP_SET_CONFIGURATION:
3050                 error("SetConfiguration: %s (%d)", strerror(err), err);
3051                 if (lsep && lsep->cfm && lsep->cfm->set_configuration)
3052                         lsep->cfm->set_configuration(session, lsep, stream,
3053                                                         &averr, lsep->user_data);
3054                 break;
3055         case AVDTP_DISCOVER:
3056                 error("Discover: %s (%d)", strerror(err), err);
3057                 goto failed;
3058         case AVDTP_GET_CAPABILITIES:
3059                 error("GetCapabilities: %s (%d)", strerror(err), err);
3060                 goto failed;
3061         case AVDTP_ABORT:
3062                 error("Abort: %s (%d)", strerror(err), err);
3063                 goto failed;
3064         }
3065
3066         if (!stream)
3067                 goto failed;
3068
3069         memset(&sreq, 0, sizeof(sreq));
3070         sreq.acp_seid = seid;
3071
3072         err = send_request(session, TRUE, stream, AVDTP_ABORT, &sreq,
3073                                 sizeof(sreq));
3074         if (err < 0) {
3075                 error("Unable to send abort request");
3076                 goto failed;
3077         }
3078
3079         stream->abort_int = TRUE;
3080
3081         goto done;
3082
3083 failed:
3084         connection_lost(session, err);
3085 done:
3086         pending_req_free(req);
3087         return err;
3088 }
3089
3090 static gboolean request_timeout(gpointer user_data)
3091 {
3092         struct avdtp *session = user_data;
3093
3094         cancel_request(session, ETIMEDOUT);
3095
3096         return FALSE;
3097 }
3098
3099 static int send_req(struct avdtp *session, gboolean priority,
3100                         struct pending_req *req)
3101 {
3102         static int transaction = 0;
3103         int err, timeout;
3104
3105         if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) {
3106                 session->io = l2cap_connect(session);
3107                 if (!session->io) {
3108                         err = -EIO;
3109                         goto failed;
3110                 }
3111                 avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING);
3112         }
3113
3114         if (session->state < AVDTP_SESSION_STATE_CONNECTED ||
3115                         session->req != NULL) {
3116                 queue_request(session, req, priority);
3117                 return 0;
3118         }
3119
3120         req->transaction = transaction++;
3121         transaction %= 16;
3122
3123         /* FIXME: Should we retry to send if the buffer
3124         was not totally sent or in case of EINTR? */
3125         if (!avdtp_send(session, req->transaction, AVDTP_MSG_TYPE_COMMAND,
3126                                 req->signal_id, req->data, req->data_size)) {
3127                 err = -EIO;
3128                 goto failed;
3129         }
3130
3131         session->req = req;
3132
3133         switch (req->signal_id) {
3134         case AVDTP_ABORT:
3135                 timeout = ABORT_TIMEOUT;
3136                 break;
3137         case AVDTP_SUSPEND:
3138                 timeout = SUSPEND_TIMEOUT;
3139                 break;
3140         default:
3141                 timeout = REQ_TIMEOUT;
3142         }
3143
3144         req->timeout = g_timeout_add_seconds(timeout, request_timeout, session);
3145         return 0;
3146
3147 failed:
3148         g_free(req->data);
3149         g_free(req);
3150         return err;
3151 }
3152
3153 static int send_request(struct avdtp *session, gboolean priority,
3154                         struct avdtp_stream *stream, uint8_t signal_id,
3155                         void *buffer, size_t size)
3156 {
3157         struct pending_req *req;
3158
3159         if (stream && stream->abort_int && signal_id != AVDTP_ABORT) {
3160                 DBG("Unable to send requests while aborting");
3161                 return -EINVAL;
3162         }
3163
3164         req = g_new0(struct pending_req, 1);
3165         req->signal_id = signal_id;
3166         req->data = g_malloc(size);
3167         memcpy(req->data, buffer, size);
3168         req->data_size = size;
3169         req->stream = stream;
3170
3171         return send_req(session, priority, req);
3172 }
3173
3174 static gboolean avdtp_discover_resp(struct avdtp *session,
3175                                         struct discover_resp *resp, int size)
3176 {
3177         int sep_count, i;
3178         uint8_t getcap_cmd;
3179         int ret = 0;
3180         gboolean getcap_pending = FALSE;
3181
3182         if (session->version >= 0x0103)
3183                 getcap_cmd = AVDTP_GET_ALL_CAPABILITIES;
3184         else
3185                 getcap_cmd = AVDTP_GET_CAPABILITIES;
3186
3187         sep_count = size / sizeof(struct seid_info);
3188
3189         for (i = 0; i < sep_count; i++) {
3190                 struct avdtp_remote_sep *sep;
3191                 struct avdtp_stream *stream;
3192                 struct seid_req req;
3193
3194                 DBG("seid %d type %d media %d in use %d",
3195                                 resp->seps[i].seid, resp->seps[i].type,
3196                                 resp->seps[i].media_type, resp->seps[i].inuse);
3197
3198                 stream = find_stream_by_rseid(session, resp->seps[i].seid);
3199
3200                 sep = find_remote_sep(session->seps, resp->seps[i].seid);
3201                 if (sep && sep->type == resp->seps[i].type &&
3202                                 sep->media_type == resp->seps[i].media_type)
3203                         continue;
3204
3205                 if (resp->seps[i].inuse && !stream)
3206                         continue;
3207
3208                 sep = g_new0(struct avdtp_remote_sep, 1);
3209                 session->seps = g_slist_append(session->seps, sep);
3210
3211                 sep->stream = stream;
3212                 sep->seid = resp->seps[i].seid;
3213                 sep->type = resp->seps[i].type;
3214                 sep->media_type = resp->seps[i].media_type;
3215
3216                 memset(&req, 0, sizeof(req));
3217                 req.acp_seid = sep->seid;
3218
3219                 ret = send_request(session, TRUE, NULL, getcap_cmd,
3220                                                         &req, sizeof(req));
3221                 if (ret < 0)
3222                         break;
3223                 getcap_pending = TRUE;
3224         }
3225
3226         if (!getcap_pending)
3227                 finalize_discovery(session, -ret);
3228
3229         return TRUE;
3230 }
3231
3232 static gboolean avdtp_get_capabilities_resp(struct avdtp *session,
3233                                                 struct getcap_resp *resp,
3234                                                 unsigned int size)
3235 {
3236         struct avdtp_remote_sep *sep;
3237         uint8_t seid;
3238
3239         /* Check for minimum required packet size includes:
3240          *   1. getcap resp header
3241          *   2. media transport capability (2 bytes)
3242          *   3. media codec capability type + length (2 bytes)
3243          *   4. the actual media codec elements
3244          * */
3245         if (size < (sizeof(struct getcap_resp) + 4 +
3246                                 sizeof(struct avdtp_media_codec_capability))) {
3247                 error("Too short getcap resp packet");
3248                 return FALSE;
3249         }
3250
3251         seid = ((struct seid_req *) session->req->data)->acp_seid;
3252
3253         sep = find_remote_sep(session->seps, seid);
3254
3255         DBG("seid %d type %d media %d", sep->seid,
3256                                         sep->type, sep->media_type);
3257
3258         if (sep->caps) {
3259                 g_slist_free_full(sep->caps, g_free);
3260                 sep->caps = NULL;
3261                 sep->codec = NULL;
3262                 sep->delay_reporting = FALSE;
3263         }
3264
3265         sep->caps = caps_to_list(resp->caps, size - sizeof(struct getcap_resp),
3266                                         &sep->codec, &sep->delay_reporting);
3267
3268         return TRUE;
3269 }
3270
3271 static gboolean avdtp_set_configuration_resp(struct avdtp *session,
3272                                                 struct avdtp_stream *stream,
3273                                                 struct avdtp_single_header *resp,
3274                                                 int size)
3275 {
3276         struct avdtp_local_sep *sep = stream->lsep;
3277
3278         if (sep->cfm && sep->cfm->set_configuration)
3279                 sep->cfm->set_configuration(session, sep, stream, NULL,
3280                                                 sep->user_data);
3281
3282         avdtp_sep_set_state(session, sep, AVDTP_STATE_CONFIGURED);
3283
3284         return TRUE;
3285 }
3286
3287 static gboolean avdtp_reconfigure_resp(struct avdtp *session,
3288                                         struct avdtp_stream *stream,
3289                                         struct avdtp_single_header *resp, int size)
3290 {
3291         return TRUE;
3292 }
3293
3294 static gboolean avdtp_open_resp(struct avdtp *session, struct avdtp_stream *stream,
3295                                 struct seid_rej *resp, int size)
3296 {
3297         struct avdtp_local_sep *sep = stream->lsep;
3298
3299         stream->io = l2cap_connect(session);
3300         if (!stream->io) {
3301                 avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE);
3302                 return FALSE;
3303         }
3304
3305         session->pending_open = stream;
3306
3307         return TRUE;
3308 }
3309
3310 static gboolean avdtp_start_resp(struct avdtp *session,
3311                                         struct avdtp_stream *stream,
3312                                         struct seid_rej *resp, int size)
3313 {
3314         struct avdtp_local_sep *sep = stream->lsep;
3315
3316         if (sep->cfm && sep->cfm->start)
3317                 sep->cfm->start(session, sep, stream, NULL, sep->user_data);
3318
3319         /* We might be in STREAMING already if both sides send START_CMD at the
3320          * same time and the one in SNK role doesn't reject it as it should */
3321         if (sep->state != AVDTP_STATE_STREAMING)
3322                 avdtp_sep_set_state(session, sep, AVDTP_STATE_STREAMING);
3323
3324         return TRUE;
3325 }
3326
3327 static gboolean avdtp_close_resp(struct avdtp *session,
3328                                         struct avdtp_stream *stream,
3329                                         struct seid_rej *resp, int size)
3330 {
3331         struct avdtp_local_sep *sep = stream->lsep;
3332
3333         avdtp_sep_set_state(session, sep, AVDTP_STATE_CLOSING);
3334
3335         close_stream(stream);
3336
3337         return TRUE;
3338 }
3339
3340 static gboolean avdtp_suspend_resp(struct avdtp *session,
3341                                         struct avdtp_stream *stream,
3342                                         void *data, int size)
3343 {
3344         struct avdtp_local_sep *sep = stream->lsep;
3345
3346         avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN);
3347
3348         if (sep->cfm && sep->cfm->suspend)
3349                 sep->cfm->suspend(session, sep, stream, NULL, sep->user_data);
3350
3351         return TRUE;
3352 }
3353
3354 static gboolean avdtp_abort_resp(struct avdtp *session,
3355                                         struct avdtp_stream *stream,
3356                                         struct seid_rej *resp, int size)
3357 {
3358         struct avdtp_local_sep *sep = stream->lsep;
3359 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3360         if (!sep) {
3361                 error("Error in getting sep");
3362                 return FALSE;
3363         }
3364 #endif
3365
3366         avdtp_sep_set_state(session, sep, AVDTP_STATE_ABORTING);
3367
3368         if (sep->cfm && sep->cfm->abort)
3369                 sep->cfm->abort(session, sep, stream, NULL, sep->user_data);
3370
3371         avdtp_sep_set_state(session, sep, AVDTP_STATE_IDLE);
3372
3373         return TRUE;
3374 }
3375
3376 static gboolean avdtp_delay_report_resp(struct avdtp *session,
3377                                         struct avdtp_stream *stream,
3378                                         void *data, int size)
3379 {
3380         struct avdtp_local_sep *sep = stream->lsep;
3381
3382         if (sep->cfm && sep->cfm->delay_report)
3383                 sep->cfm->delay_report(session, sep, stream, NULL, sep->user_data);
3384
3385         return TRUE;
3386 }
3387
3388 static gboolean avdtp_parse_resp(struct avdtp *session,
3389                                         struct avdtp_stream *stream,
3390                                         uint8_t transaction, uint8_t signal_id,
3391                                         void *buf, int size)
3392 {
3393         struct pending_req *next;
3394         const char *get_all = "";
3395
3396         if (session->prio_queue)
3397                 next = session->prio_queue->data;
3398         else if (session->req_queue)
3399                 next = session->req_queue->data;
3400         else
3401                 next = NULL;
3402
3403         switch (signal_id) {
3404         case AVDTP_DISCOVER:
3405                 DBG("DISCOVER request succeeded");
3406                 return avdtp_discover_resp(session, buf, size);
3407         case AVDTP_GET_ALL_CAPABILITIES:
3408                 get_all = "ALL_";
3409                 /* fall through */
3410         case AVDTP_GET_CAPABILITIES:
3411                 DBG("GET_%sCAPABILITIES request succeeded", get_all);
3412                 if (!avdtp_get_capabilities_resp(session, buf, size))
3413                         return FALSE;
3414                 if (!(next && (next->signal_id == AVDTP_GET_CAPABILITIES ||
3415                                 next->signal_id == AVDTP_GET_ALL_CAPABILITIES)))
3416                         finalize_discovery(session, 0);
3417                 return TRUE;
3418         }
3419
3420         /* The remaining commands require an existing stream so bail out
3421          * here if the stream got unexpectedly disconnected */
3422         if (!stream) {
3423                 DBG("AVDTP: stream was closed while waiting for reply");
3424                 return TRUE;
3425         }
3426
3427         switch (signal_id) {
3428         case AVDTP_SET_CONFIGURATION:
3429                 DBG("SET_CONFIGURATION request succeeded");
3430                 return avdtp_set_configuration_resp(session, stream,
3431                                                                 buf, size);
3432         case AVDTP_RECONFIGURE:
3433                 DBG("RECONFIGURE request succeeded");
3434                 return avdtp_reconfigure_resp(session, stream, buf, size);
3435         case AVDTP_OPEN:
3436                 DBG("OPEN request succeeded");
3437                 return avdtp_open_resp(session, stream, buf, size);
3438         case AVDTP_SUSPEND:
3439                 DBG("SUSPEND request succeeded");
3440                 return avdtp_suspend_resp(session, stream, buf, size);
3441         case AVDTP_START:
3442                 DBG("START request succeeded");
3443                 return avdtp_start_resp(session, stream, buf, size);
3444         case AVDTP_CLOSE:
3445                 DBG("CLOSE request succeeded");
3446                 return avdtp_close_resp(session, stream, buf, size);
3447         case AVDTP_ABORT:
3448                 DBG("ABORT request succeeded");
3449                 return avdtp_abort_resp(session, stream, buf, size);
3450         case AVDTP_DELAY_REPORT:
3451                 DBG("DELAY_REPORT request succeeded");
3452                 return avdtp_delay_report_resp(session, stream, buf, size);
3453         }
3454
3455         error("Unknown signal id in accept response: %u", signal_id);
3456         return TRUE;
3457 }
3458
3459 static gboolean seid_rej_to_err(struct seid_rej *rej, unsigned int size,
3460                                         struct avdtp_error *err)
3461 {
3462         if (size < sizeof(struct seid_rej)) {
3463                 error("Too small packet for seid_rej");
3464                 return FALSE;
3465         }
3466
3467         avdtp_error_init(err, 0x00, rej->error);
3468
3469         return TRUE;
3470 }
3471
3472 static gboolean conf_rej_to_err(struct conf_rej *rej, unsigned int size,
3473                                 struct avdtp_error *err)
3474 {
3475         if (size < sizeof(struct conf_rej)) {
3476                 error("Too small packet for conf_rej");
3477                 return FALSE;
3478         }
3479
3480         avdtp_error_init(err, rej->category, rej->error);
3481
3482         return TRUE;
3483 }
3484
3485 static gboolean stream_rej_to_err(struct stream_rej *rej, unsigned int size,
3486                                         struct avdtp_error *err,
3487                                         uint8_t *acp_seid)
3488 {
3489         if (size < sizeof(struct stream_rej)) {
3490                 error("Too small packet for stream_rej");
3491                 return FALSE;
3492         }
3493
3494         avdtp_error_init(err, 0x00, rej->error);
3495
3496         if (acp_seid)
3497                 *acp_seid = rej->acp_seid;
3498
3499         return TRUE;
3500 }
3501
3502 static gboolean avdtp_parse_rej(struct avdtp *session,
3503                                         struct avdtp_stream *stream,
3504                                         uint8_t transaction, uint8_t signal_id,
3505                                         void *buf, int size)
3506 {
3507         struct avdtp_error err;
3508         uint8_t acp_seid;
3509         struct avdtp_local_sep *sep = stream ? stream->lsep : NULL;
3510
3511         switch (signal_id) {
3512         case AVDTP_DISCOVER:
3513                 if (!seid_rej_to_err(buf, size, &err))
3514                         return FALSE;
3515                 error("DISCOVER request rejected: %s (%d)",
3516                                 avdtp_strerror(&err), err.err.error_code);
3517                 return TRUE;
3518         case AVDTP_GET_CAPABILITIES:
3519         case AVDTP_GET_ALL_CAPABILITIES:
3520                 if (!seid_rej_to_err(buf, size, &err))
3521                         return FALSE;
3522                 error("GET_CAPABILITIES request rejected: %s (%d)",
3523                                 avdtp_strerror(&err), err.err.error_code);
3524                 return TRUE;
3525         case AVDTP_OPEN:
3526                 if (!seid_rej_to_err(buf, size, &err))
3527                         return FALSE;
3528                 error("OPEN request rejected: %s (%d)",
3529                                 avdtp_strerror(&err), err.err.error_code);
3530                 if (sep && sep->cfm && sep->cfm->open)
3531                         sep->cfm->open(session, sep, stream, &err,
3532                                         sep->user_data);
3533                 return TRUE;
3534         case AVDTP_SET_CONFIGURATION:
3535                 if (!conf_rej_to_err(buf, size, &err))
3536                         return FALSE;
3537                 error("SET_CONFIGURATION request rejected: %s (%d)",
3538                                 avdtp_strerror(&err), err.err.error_code);
3539                 if (sep && sep->cfm && sep->cfm->set_configuration)
3540                         sep->cfm->set_configuration(session, sep, stream,
3541                                                         &err, sep->user_data);
3542                 return TRUE;
3543         case AVDTP_RECONFIGURE:
3544                 if (!conf_rej_to_err(buf, size, &err))
3545                         return FALSE;
3546                 error("RECONFIGURE request rejected: %s (%d)",
3547                                 avdtp_strerror(&err), err.err.error_code);
3548                 if (sep && sep->cfm && sep->cfm->reconfigure)
3549                         sep->cfm->reconfigure(session, sep, stream, &err,
3550                                                 sep->user_data);
3551                 return TRUE;
3552         case AVDTP_START:
3553                 if (!stream_rej_to_err(buf, size, &err, &acp_seid))
3554                         return FALSE;
3555                 error("START request rejected: %s (%d)",
3556                                 avdtp_strerror(&err), err.err.error_code);
3557                 if (sep && sep->cfm && sep->cfm->start) {
3558                         sep->cfm->start(session, sep, stream, &err,
3559                                         sep->user_data);
3560                         stream->starting = FALSE;
3561                 }
3562                 return TRUE;
3563         case AVDTP_SUSPEND:
3564                 if (!stream_rej_to_err(buf, size, &err, &acp_seid))
3565                         return FALSE;
3566                 error("SUSPEND request rejected: %s (%d)",
3567                                 avdtp_strerror(&err), err.err.error_code);
3568                 if (sep && sep->cfm && sep->cfm->suspend)
3569                         sep->cfm->suspend(session, sep, stream, &err,
3570                                                 sep->user_data);
3571                 return TRUE;
3572         case AVDTP_CLOSE:
3573                 if (!stream_rej_to_err(buf, size, &err, &acp_seid))
3574                         return FALSE;
3575                 error("CLOSE request rejected: %s (%d)",
3576                                 avdtp_strerror(&err), err.err.error_code);
3577                 if (sep && sep->cfm && sep->cfm->close) {
3578                         sep->cfm->close(session, sep, stream, &err,
3579                                         sep->user_data);
3580                         stream->close_int = FALSE;
3581                 }
3582                 return TRUE;
3583         case AVDTP_ABORT:
3584                 if (!stream_rej_to_err(buf, size, &err, &acp_seid))
3585                         return FALSE;
3586                 error("ABORT request rejected: %s (%d)",
3587                                 avdtp_strerror(&err), err.err.error_code);
3588                 if (sep && sep->cfm && sep->cfm->abort)
3589                         sep->cfm->abort(session, sep, stream, &err,
3590                                         sep->user_data);
3591                 return FALSE;
3592         case AVDTP_DELAY_REPORT:
3593                 if (!stream_rej_to_err(buf, size, &err, &acp_seid))
3594                         return FALSE;
3595                 error("DELAY_REPORT request rejected: %s (%d)",
3596                                 avdtp_strerror(&err), err.err.error_code);
3597                 if (sep && sep->cfm && sep->cfm->delay_report)
3598                         sep->cfm->delay_report(session, sep, stream, &err,
3599                                                         sep->user_data);
3600                 return TRUE;
3601         default:
3602                 error("Unknown reject response signal id: %u", signal_id);
3603                 return TRUE;
3604         }
3605 }
3606
3607 struct avdtp_service_capability *avdtp_stream_get_codec(
3608                                                 struct avdtp_stream *stream)
3609 {
3610         GSList *l;
3611
3612         for (l = stream->caps; l; l = l->next) {
3613                 struct avdtp_service_capability *cap = l->data;
3614
3615                 if (cap->category == AVDTP_MEDIA_CODEC)
3616                         return cap;
3617         }
3618
3619         return NULL;
3620 }
3621
3622 static gboolean avdtp_stream_has_capability(struct avdtp_stream *stream,
3623                                         struct avdtp_service_capability *cap)
3624 {
3625         GSList *l;
3626         struct avdtp_service_capability *stream_cap;
3627
3628         for (l = stream->caps; l; l = g_slist_next(l)) {
3629                 stream_cap = l->data;
3630
3631                 if (stream_cap->category != cap->category ||
3632                         stream_cap->length != cap->length)
3633                         continue;
3634
3635                 if (memcmp(stream_cap->data, cap->data, cap->length) == 0)
3636                         return TRUE;
3637         }
3638
3639         return FALSE;
3640 }
3641
3642 gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream,
3643                                         GSList *caps)
3644 {
3645         for (; caps; caps = g_slist_next(caps)) {
3646                 struct avdtp_service_capability *cap = caps->data;
3647
3648                 if (!avdtp_stream_has_capability(stream, cap))
3649                         return FALSE;
3650         }
3651
3652         return TRUE;
3653 }
3654
3655 struct avdtp_remote_sep *avdtp_stream_get_remote_sep(
3656                                                 struct avdtp_stream *stream)
3657 {
3658         GSList *l;
3659
3660         for (l = stream->session->seps; l; l = l->next) {
3661                 struct avdtp_remote_sep *sep = l->data;
3662
3663                 if (sep->seid == stream->rseid)
3664                         return sep;
3665         }
3666
3667         return NULL;
3668 }
3669
3670 gboolean avdtp_stream_set_transport(struct avdtp_stream *stream, int fd,
3671                                                 size_t imtu, size_t omtu)
3672 {
3673         GIOChannel *io;
3674
3675         if (stream != stream->session->pending_open)
3676                 return FALSE;
3677
3678         io = g_io_channel_unix_new(fd);
3679
3680         handle_transport_connect(stream->session, io, imtu, omtu);
3681
3682         g_io_channel_unref(io);
3683
3684         return TRUE;
3685 }
3686
3687 gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock,
3688                                         uint16_t *imtu, uint16_t *omtu,
3689                                         GSList **caps)
3690 {
3691         if (stream->io == NULL)
3692                 return FALSE;
3693
3694         if (sock)
3695                 *sock = g_io_channel_unix_get_fd(stream->io);
3696
3697         if (omtu)
3698                 *omtu = stream->omtu;
3699
3700         if (imtu)
3701                 *imtu = stream->imtu;
3702
3703         if (caps)
3704                 *caps = stream->caps;
3705
3706         return TRUE;
3707 }
3708
3709 static int process_queue(struct avdtp *session)
3710 {
3711         GSList **queue, *l;
3712         struct pending_req *req;
3713
3714         if (session->req)
3715                 return 0;
3716
3717         if (session->prio_queue)
3718                 queue = &session->prio_queue;
3719         else
3720                 queue = &session->req_queue;
3721
3722         if (!*queue)
3723                 return 0;
3724
3725         l = *queue;
3726         req = l->data;
3727
3728         *queue = g_slist_remove(*queue, req);
3729
3730         return send_req(session, FALSE, req);
3731 }
3732
3733 uint8_t avdtp_get_seid(struct avdtp_remote_sep *sep)
3734 {
3735         return sep->seid;
3736 }
3737
3738 uint8_t avdtp_get_type(struct avdtp_remote_sep *sep)
3739 {
3740         return sep->type;
3741 }
3742
3743 struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep)
3744 {
3745         return sep->codec;
3746 }
3747
3748 bool avdtp_get_delay_reporting(struct avdtp_remote_sep *sep)
3749 {
3750         return sep->delay_reporting;
3751 }
3752
3753 struct avdtp_service_capability *avdtp_service_cap_new(uint8_t category,
3754                                                         void *data, int length)
3755 {
3756         struct avdtp_service_capability *cap;
3757
3758         if (category < AVDTP_MEDIA_TRANSPORT || category > AVDTP_DELAY_REPORTING)
3759                 return NULL;
3760
3761         cap = g_malloc(sizeof(struct avdtp_service_capability) + length);
3762         cap->category = category;
3763         cap->length = length;
3764         memcpy(cap->data, data, length);
3765
3766         return cap;
3767 }
3768
3769 struct avdtp_remote_sep *avdtp_register_remote_sep(struct avdtp *session,
3770                                                         uint8_t seid,
3771                                                         uint8_t type,
3772                                                         GSList *caps,
3773                                                         bool delay_reporting)
3774 {
3775         struct avdtp_remote_sep *sep;
3776         GSList *l;
3777
3778         sep = find_remote_sep(session->seps, seid);
3779         if (sep)
3780                 return sep;
3781
3782         sep = g_new0(struct avdtp_remote_sep, 1);
3783         session->seps = g_slist_append(session->seps, sep);
3784         sep->seid = seid;
3785         sep->type = type;
3786         sep->media_type = AVDTP_MEDIA_TYPE_AUDIO;
3787         sep->caps = caps;
3788         sep->delay_reporting = delay_reporting;
3789
3790         for (l = caps; l; l = g_slist_next(l)) {
3791                 struct avdtp_service_capability *cap = l->data;
3792
3793                 if (cap->category == AVDTP_MEDIA_CODEC)
3794                         sep->codec = cap;
3795         }
3796
3797         DBG("seid %d type %d media %d delay_reporting %s", sep->seid, sep->type,
3798                                 sep->media_type,
3799                                 sep->delay_reporting ? "true" : "false");
3800
3801         return sep;
3802 }
3803
3804 static gboolean process_discover(gpointer data)
3805 {
3806         struct avdtp *session = data;
3807
3808         session->discover->id = 0;
3809
3810         finalize_discovery(session, 0);
3811
3812         return FALSE;
3813 }
3814
3815 int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb,
3816                         void *user_data)
3817 {
3818         int err;
3819
3820         if (session->discover)
3821                 return -EBUSY;
3822
3823         session->discover = g_new0(struct discover_callback, 1);
3824
3825         if (session->seps) {
3826                 session->discover->cb = cb;
3827                 session->discover->user_data = user_data;
3828                 session->discover->id = g_idle_add(process_discover, session);
3829                 return 0;
3830         }
3831
3832         err = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0);
3833         if (err == 0) {
3834                 session->discover->cb = cb;
3835                 session->discover->user_data = user_data;
3836         }
3837
3838         return err;
3839 }
3840
3841 gboolean avdtp_stream_remove_cb(struct avdtp *session,
3842                                 struct avdtp_stream *stream,
3843                                 unsigned int id)
3844 {
3845         GSList *l;
3846         struct stream_callback *cb;
3847
3848         if (!stream)
3849                 return FALSE;
3850
3851         for (cb = NULL, l = stream->callbacks; l != NULL; l = l->next) {
3852                 struct stream_callback *tmp = l->data;
3853                 if (tmp && tmp->id == id) {
3854                         cb = tmp;
3855                         break;
3856                 }
3857         }
3858
3859         if (!cb)
3860                 return FALSE;
3861
3862         stream->callbacks = g_slist_remove(stream->callbacks, cb);
3863         g_free(cb);
3864
3865         return TRUE;
3866 }
3867
3868 unsigned int avdtp_stream_add_cb(struct avdtp *session,
3869                                         struct avdtp_stream *stream,
3870                                         avdtp_stream_state_cb cb, void *data)
3871 {
3872         struct stream_callback *stream_cb;
3873         static unsigned int id = 0;
3874
3875         stream_cb = g_new(struct stream_callback, 1);
3876         stream_cb->cb = cb;
3877         stream_cb->user_data = data;
3878         stream_cb->id = ++id;
3879
3880         stream->callbacks = g_slist_append(stream->callbacks, stream_cb);
3881
3882         return stream_cb->id;
3883 }
3884
3885 int avdtp_get_configuration(struct avdtp *session, struct avdtp_stream *stream)
3886 {
3887         struct seid_req req;
3888
3889         if (session->state < AVDTP_SESSION_STATE_CONNECTED)
3890                 return -EINVAL;
3891
3892         memset(&req, 0, sizeof(req));
3893         req.acp_seid = stream->rseid;
3894
3895         return send_request(session, FALSE, stream, AVDTP_GET_CONFIGURATION,
3896                                                         &req, sizeof(req));
3897 }
3898
3899 static void copy_capabilities(gpointer data, gpointer user_data)
3900 {
3901         struct avdtp_service_capability *src_cap = data;
3902         struct avdtp_service_capability *dst_cap;
3903         GSList **l = user_data;
3904
3905         dst_cap = avdtp_service_cap_new(src_cap->category, src_cap->data,
3906                                         src_cap->length);
3907
3908         *l = g_slist_append(*l, dst_cap);
3909 }
3910
3911 int avdtp_set_configuration(struct avdtp *session,
3912                                 struct avdtp_remote_sep *rsep,
3913                                 struct avdtp_local_sep *lsep,
3914                                 GSList *caps,
3915                                 struct avdtp_stream **stream)
3916 {
3917         struct setconf_req *req;
3918         struct avdtp_stream *new_stream;
3919         unsigned char *ptr;
3920         int err, caps_len;
3921         struct avdtp_service_capability *cap;
3922         GSList *l;
3923
3924         if (session->state != AVDTP_SESSION_STATE_CONNECTED)
3925                 return -ENOTCONN;
3926
3927         if (!(lsep && rsep))
3928                 return -EINVAL;
3929
3930         DBG("%p: int_seid=%u, acp_seid=%u", session,
3931                         lsep->info.seid, rsep->seid);
3932
3933         new_stream = g_new0(struct avdtp_stream, 1);
3934         new_stream->session = session;
3935         new_stream->lsep = lsep;
3936         new_stream->rseid = rsep->seid;
3937
3938         if (rsep->delay_reporting && lsep->delay_reporting) {
3939                 struct avdtp_service_capability *delay_reporting;
3940
3941                 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
3942                                                                 NULL, 0);
3943                 caps = g_slist_append(caps, delay_reporting);
3944                 new_stream->delay_reporting = TRUE;
3945         }
3946
3947         g_slist_foreach(caps, copy_capabilities, &new_stream->caps);
3948
3949         /* Calculate total size of request */
3950         for (l = caps, caps_len = 0; l != NULL; l = g_slist_next(l)) {
3951                 cap = l->data;
3952                 caps_len += cap->length + 2;
3953         }
3954
3955         req = g_malloc0(sizeof(struct setconf_req) + caps_len);
3956
3957         req->int_seid = lsep->info.seid;
3958         req->acp_seid = rsep->seid;
3959
3960         /* Copy the capabilities into the request */
3961         for (l = caps, ptr = req->caps; l != NULL; l = g_slist_next(l)) {
3962                 cap = l->data;
3963                 memcpy(ptr, cap, cap->length + 2);
3964                 ptr += cap->length + 2;
3965         }
3966
3967         err = send_request(session, FALSE, new_stream,
3968                                 AVDTP_SET_CONFIGURATION, req,
3969                                 sizeof(struct setconf_req) + caps_len);
3970         if (err < 0)
3971                 stream_free(new_stream);
3972         else {
3973                 lsep->info.inuse = 1;
3974                 lsep->stream = new_stream;
3975                 rsep->stream = new_stream;
3976                 session->streams = g_slist_append(session->streams, new_stream);
3977                 if (stream)
3978                         *stream = new_stream;
3979         }
3980
3981         g_free(req);
3982
3983         return err;
3984 }
3985
3986 int avdtp_open(struct avdtp *session, struct avdtp_stream *stream)
3987 {
3988         struct seid_req req;
3989
3990         if (!g_slist_find(session->streams, stream))
3991                 return -EINVAL;
3992
3993         if (stream->lsep->state > AVDTP_STATE_CONFIGURED)
3994                 return -EINVAL;
3995
3996         memset(&req, 0, sizeof(req));
3997         req.acp_seid = stream->rseid;
3998
3999         return send_request(session, FALSE, stream, AVDTP_OPEN,
4000                                                         &req, sizeof(req));
4001 }
4002
4003 static gboolean start_timeout(gpointer user_data)
4004 {
4005         struct avdtp_stream *stream = user_data;
4006         struct avdtp *session = stream->session;
4007
4008         stream->open_acp = FALSE;
4009
4010         if (avdtp_start(session, stream) < 0)
4011                 error("wait_timeout: avdtp_start failed");
4012
4013         stream->start_timer = 0;
4014
4015         return FALSE;
4016 }
4017
4018 int avdtp_start(struct avdtp *session, struct avdtp_stream *stream)
4019 {
4020         struct start_req req;
4021         int ret;
4022
4023         if (!g_slist_find(session->streams, stream))
4024                 return -EINVAL;
4025
4026         if (stream->lsep->state != AVDTP_STATE_OPEN)
4027                 return -EINVAL;
4028
4029         /* Recommendation 12:
4030          *  If the RD has configured and opened a stream it is also responsible
4031          *  to start the streaming via GAVDP_START.
4032          */
4033         if (stream->open_acp) {
4034                 /* If timer already active wait it */
4035                 if (stream->start_timer)
4036                         return 0;
4037 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4038                 else {
4039                         char address[18];
4040                         uint32_t timeout_sec = START_TIMEOUT;
4041
4042                         ba2str(device_get_address(session->device), address);
4043                         /* For Bose headset (Bose AE2w) 2 seconds timeout is required to avoid AVDTP ABORT_CMD */
4044                         if (!strncasecmp(address, "00:0C:8A", 8) ||
4045                                 !strncasecmp(address, "08:DF:1F", 8))
4046                                 timeout_sec = 2;
4047                         /* For Gear Circle, HS3000 headset, this headset doesn't initiate start command and
4048                          * when we add timer for 1 second so idle may trigger callback after 1.2 sec or
4049                          * 1.5 sec. So, don't timer for this headset.*/
4050                         if (!strncasecmp(address, "10:92:66", 8) ||
4051                                 !strncasecmp(address, "A8:9F:BA", 8) ||
4052                                 !strncasecmp(address, "00:26:B4", 8)) {
4053                                 start_timeout(stream);
4054                                 return 0;
4055                         }
4056                          /* Here we can't use Mac address as there are changing so check for name */
4057                         char name[10];
4058                         device_get_name(session->device, name, sizeof(name));
4059                         DBG("name : %s", name);
4060                         if (g_str_equal(name, "HS3000")) {
4061                                 start_timeout(stream);
4062                                 return 0;
4063                         }
4064
4065                         stream->start_timer = g_timeout_add_seconds(timeout_sec,
4066                                                                         start_timeout,
4067                                                                         stream);
4068                         return 0;
4069                 }
4070 #else
4071                 stream->start_timer = g_timeout_add_seconds(START_TIMEOUT,
4072                                                                 start_timeout,
4073                                                                 stream);
4074                 return 0;
4075 #endif
4076         }
4077
4078         if (stream->close_int == TRUE) {
4079                 error("avdtp_start: rejecting start since close is initiated");
4080                 return -EINVAL;
4081         }
4082
4083         if (stream->starting == TRUE) {
4084                 DBG("stream already started");
4085                 return -EINPROGRESS;
4086         }
4087
4088         memset(&req, 0, sizeof(req));
4089         req.first_seid.seid = stream->rseid;
4090
4091         ret = send_request(session, FALSE, stream, AVDTP_START,
4092                                                         &req, sizeof(req));
4093         if (ret == 0)
4094                 stream->starting = TRUE;
4095
4096         return ret;
4097 }
4098
4099 int avdtp_close(struct avdtp *session, struct avdtp_stream *stream,
4100                 gboolean immediate)
4101 {
4102         struct seid_req req;
4103         int ret;
4104
4105         if (!g_slist_find(session->streams, stream))
4106                 return -EINVAL;
4107
4108         if (stream->lsep->state < AVDTP_STATE_OPEN)
4109                 return -EINVAL;
4110
4111         if (stream->close_int == TRUE) {
4112                 error("avdtp_close: rejecting since close is already initiated");
4113                 return -EINVAL;
4114         }
4115
4116         if (immediate && session->req && stream == session->req->stream)
4117                 return avdtp_abort(session, stream);
4118
4119         memset(&req, 0, sizeof(req));
4120         req.acp_seid = stream->rseid;
4121
4122         ret = send_request(session, FALSE, stream, AVDTP_CLOSE,
4123                                                         &req, sizeof(req));
4124         if (ret == 0) {
4125                 stream->close_int = TRUE;
4126                 session->dc_timeout = 0;
4127         }
4128
4129         return ret;
4130 }
4131
4132 int avdtp_suspend(struct avdtp *session, struct avdtp_stream *stream)
4133 {
4134         struct seid_req req;
4135
4136         if (!g_slist_find(session->streams, stream))
4137                 return -EINVAL;
4138
4139         if (stream->lsep->state <= AVDTP_STATE_OPEN || stream->close_int)
4140                 return -EINVAL;
4141
4142         memset(&req, 0, sizeof(req));
4143         req.acp_seid = stream->rseid;
4144
4145         return send_request(session, FALSE, stream, AVDTP_SUSPEND,
4146                                                         &req, sizeof(req));
4147 }
4148
4149 int avdtp_abort(struct avdtp *session, struct avdtp_stream *stream)
4150 {
4151         struct seid_req req;
4152         int ret;
4153
4154         if (!stream && session->discover) {
4155                 /* Don't call cb since it being aborted */
4156                 session->discover->cb = NULL;
4157                 finalize_discovery(session, ECANCELED);
4158                 return -EALREADY;
4159         }
4160
4161         if (!g_slist_find(session->streams, stream))
4162                 return -EINVAL;
4163
4164         if (stream->lsep->state == AVDTP_STATE_ABORTING)
4165                 return -EINVAL;
4166
4167         avdtp_sep_set_state(session, stream->lsep, AVDTP_STATE_ABORTING);
4168
4169         if (session->req && stream == session->req->stream)
4170                 return cancel_request(session, ECANCELED);
4171
4172         memset(&req, 0, sizeof(req));
4173         req.acp_seid = stream->rseid;
4174
4175         ret = send_request(session, TRUE, stream, AVDTP_ABORT,
4176                                                         &req, sizeof(req));
4177         if (ret == 0) {
4178                 stream->abort_int = TRUE;
4179                 session->dc_timeout = 0;
4180         }
4181
4182         return ret;
4183 }
4184
4185 int avdtp_delay_report(struct avdtp *session, struct avdtp_stream *stream,
4186                                                         uint16_t delay)
4187 {
4188         struct delay_req req;
4189
4190         if (!g_slist_find(session->streams, stream))
4191                 return -EINVAL;
4192
4193         if (stream->lsep->state != AVDTP_STATE_CONFIGURED &&
4194                                 stream->lsep->state != AVDTP_STATE_STREAMING)
4195                 return -EINVAL;
4196
4197         if (!stream->delay_reporting || session->version < 0x0103)
4198                 return -EINVAL;
4199
4200         stream->delay = delay;
4201
4202         memset(&req, 0, sizeof(req));
4203         req.acp_seid = stream->rseid;
4204         req.delay = htons(delay);
4205
4206         return send_request(session, TRUE, stream, AVDTP_DELAY_REPORT,
4207                                                         &req, sizeof(req));
4208 }
4209
4210 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4211 int delay_report_req(uint16_t delay)
4212 {
4213         if (!configured_session)
4214                 return -EINVAL;
4215
4216         if (!configured_stream)
4217                 return -EINVAL;
4218
4219         return avdtp_delay_report(configured_session, configured_stream, delay);
4220 }
4221 #endif
4222
4223 struct avdtp_local_sep *avdtp_register_sep(struct queue *lseps, uint8_t type,
4224                                                 uint8_t media_type,
4225                                                 uint8_t codec_type,
4226                                                 gboolean delay_reporting,
4227                                                 struct avdtp_sep_ind *ind,
4228                                                 struct avdtp_sep_cfm *cfm,
4229                                                 void *user_data)
4230 {
4231         struct avdtp_local_sep *sep;
4232         uint8_t seid = util_get_uid(&seids, MAX_SEID);
4233
4234         if (!seid)
4235                 return NULL;
4236
4237         sep = g_new0(struct avdtp_local_sep, 1);
4238
4239         sep->state = AVDTP_STATE_IDLE;
4240         sep->info.seid = seid;
4241         sep->info.type = type;
4242         sep->info.media_type = media_type;
4243         sep->codec = codec_type;
4244         sep->ind = ind;
4245         sep->cfm = cfm;
4246         sep->user_data = user_data;
4247         sep->delay_reporting = delay_reporting;
4248
4249         DBG("SEP %p registered: type:%d codec:%d seid:%d", sep,
4250                         sep->info.type, sep->codec, sep->info.seid);
4251
4252         if (!queue_push_tail(lseps, sep)) {
4253                 g_free(sep);
4254                 return NULL;
4255         }
4256
4257         return sep;
4258 }
4259
4260 int avdtp_unregister_sep(struct queue *lseps, struct avdtp_local_sep *sep)
4261 {
4262         if (!sep)
4263                 return -EINVAL;
4264
4265         if (sep->stream)
4266                 release_stream(sep->stream, sep->stream->session);
4267
4268         DBG("SEP %p unregistered: type:%d codec:%d seid:%d", sep,
4269                         sep->info.type, sep->codec, sep->info.seid);
4270
4271         util_clear_uid(&seids, sep->info.seid);
4272         queue_remove(lseps, sep);
4273         g_free(sep);
4274
4275         return 0;
4276 }
4277
4278 const char *avdtp_strerror(struct avdtp_error *err)
4279 {
4280         if (err->category == AVDTP_ERRNO)
4281                 return strerror(err->err.posix_errno);
4282
4283         switch(err->err.error_code) {
4284         case AVDTP_BAD_HEADER_FORMAT:
4285                 return "Bad Header Format";
4286         case AVDTP_BAD_LENGTH:
4287                 return "Bad Packet Length";
4288         case AVDTP_BAD_ACP_SEID:
4289                 return "Bad Acceptor SEID";
4290         case AVDTP_SEP_IN_USE:
4291                 return "Stream End Point in Use";
4292         case AVDTP_SEP_NOT_IN_USE:
4293                 return "Stream End Point Not in Use";
4294         case AVDTP_BAD_SERV_CATEGORY:
4295                 return "Bad Service Category";
4296         case AVDTP_BAD_PAYLOAD_FORMAT:
4297                 return "Bad Payload format";
4298         case AVDTP_NOT_SUPPORTED_COMMAND:
4299                 return "Command Not Supported";
4300         case AVDTP_INVALID_CAPABILITIES:
4301                 return "Invalid Capabilities";
4302         case AVDTP_BAD_RECOVERY_TYPE:
4303                 return "Bad Recovery Type";
4304         case AVDTP_BAD_MEDIA_TRANSPORT_FORMAT:
4305                 return "Bad Media Transport Format";
4306         case AVDTP_BAD_RECOVERY_FORMAT:
4307                 return "Bad Recovery Format";
4308         case AVDTP_BAD_ROHC_FORMAT:
4309                 return "Bad Header Compression Format";
4310         case AVDTP_BAD_CP_FORMAT:
4311                 return "Bad Content Protection Format";
4312         case AVDTP_BAD_MULTIPLEXING_FORMAT:
4313                 return "Bad Multiplexing Format";
4314         case AVDTP_UNSUPPORTED_CONFIGURATION:
4315                 return "Configuration not supported";
4316         case AVDTP_BAD_STATE:
4317                 return "Bad State";
4318         default:
4319                 return "Unknown error";
4320         }
4321 }
4322
4323 avdtp_state_t avdtp_sep_get_state(struct avdtp_local_sep *sep)
4324 {
4325         return sep->state;
4326 }
4327
4328 uint8_t avdtp_sep_get_seid(struct avdtp_local_sep *sep)
4329 {
4330         return sep->info.seid;
4331 }
4332
4333 struct btd_adapter *avdtp_get_adapter(struct avdtp *session)
4334 {
4335         return device_get_adapter(session->device);
4336 }
4337
4338 struct btd_device *avdtp_get_device(struct avdtp *session)
4339 {
4340         return session->device;
4341 }
4342
4343 gboolean avdtp_has_stream(struct avdtp *session, struct avdtp_stream *stream)
4344 {
4345         return g_slist_find(session->streams, stream) ? TRUE : FALSE;
4346 }
4347
4348 unsigned int avdtp_add_state_cb(struct btd_device *dev,
4349                                 avdtp_session_state_cb cb, void *user_data)
4350 {
4351         struct avdtp_state_callback *state_cb;
4352         static unsigned int id = 0;
4353
4354         state_cb = g_new(struct avdtp_state_callback, 1);
4355         state_cb->cb = cb;
4356         state_cb->dev = dev;
4357         state_cb->id = ++id;
4358         state_cb->user_data = user_data;
4359
4360         state_callbacks = g_slist_append(state_callbacks, state_cb);
4361
4362         return state_cb->id;
4363 }
4364
4365 gboolean avdtp_remove_state_cb(unsigned int id)
4366 {
4367         GSList *l;
4368
4369         for (l = state_callbacks; l != NULL; l = l->next) {
4370                 struct avdtp_state_callback *cb = l->data;
4371                 if (cb && cb->id == id) {
4372                         state_callbacks = g_slist_remove(state_callbacks, cb);
4373                         g_free(cb);
4374                         return TRUE;
4375                 }
4376         }
4377
4378         return FALSE;
4379 }