3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2006-2010 Nokia Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
7 * Copyright (C) 2011 Texas Instruments, Inc.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 #include <sys/types.h>
39 #include <netinet/in.h>
41 #include <bluetooth/bluetooth.h>
42 #include <bluetooth/sdp.h>
43 #include <bluetooth/uuid.h>
48 #include "../src/device.h"
59 #define QUIRK_NO_RELEASE 1 << 0
62 #define AVCTP_COMMAND 0
63 #define AVCTP_RESPONSE 1
66 #define AVCTP_PACKET_SINGLE 0
67 #define AVCTP_PACKET_START 1
68 #define AVCTP_PACKET_CONTINUE 2
69 #define AVCTP_PACKET_END 3
71 #if __BYTE_ORDER == __LITTLE_ENDIAN
76 uint8_t packet_type:2;
77 uint8_t transaction:4;
79 } __attribute__ ((packed));
80 #define AVCTP_HEADER_LENGTH 3
86 uint8_t subunit_type:5;
88 } __attribute__ ((packed));
90 #elif __BYTE_ORDER == __BIG_ENDIAN
93 uint8_t transaction:4;
94 uint8_t packet_type:2;
98 } __attribute__ ((packed));
99 #define AVCTP_HEADER_LENGTH 3
104 uint8_t subunit_type:5;
105 uint8_t subunit_id:3;
107 } __attribute__ ((packed));
110 #error "Unknown byte order"
113 struct avctp_state_callback {
119 struct avctp_server {
125 struct avctp_rsp_handler {
132 struct avctp_server *server;
144 uint8_t key_quirks[256];
148 struct avctp_pdu_handler {
160 { "PLAY", PLAY_OP, KEY_PLAYCD },
161 { "STOP", STAVC_OP_OP, KEY_STOPCD },
162 { "PAUSE", PAUSE_OP, KEY_PAUSECD },
163 { "FORWARD", FORWARD_OP, KEY_NEXTSONG },
164 { "BACKWARD", BACKWARD_OP, KEY_PREVIOUSSONG },
165 { "REWIND", REWIND_OP, KEY_REWIND },
166 { "FAST FORWARD", FAST_FORWARD_OP, KEY_FASTFORWARD },
170 static GSList *callbacks = NULL;
171 static GSList *servers = NULL;
172 static GSList *handlers = NULL;
173 static uint8_t id = 0;
175 static void auth_cb(DBusError *derr, void *user_data);
177 static int send_event(int fd, uint16_t type, uint16_t code, int32_t value)
179 struct uinput_event event;
181 memset(&event, 0, sizeof(event));
186 return write(fd, &event, sizeof(event));
189 static void send_key(int fd, uint16_t key, int pressed)
194 send_event(fd, EV_KEY, key, pressed);
195 send_event(fd, EV_SYN, SYN_REPORT, 0);
198 static size_t handle_panel_passthrough(struct avctp *session,
199 uint8_t transaction, uint8_t *code,
200 uint8_t *subunit, uint8_t *operands,
201 size_t operand_count, void *user_data)
206 if (*code != AVC_CTYPE_CONTROL || *subunit != AVC_SUBUNIT_PANEL) {
207 *code = AVC_CTYPE_REJECTED;
211 if (operand_count == 0)
214 if (operands[0] & 0x80) {
222 for (i = 0; key_map[i].name != NULL; i++) {
225 if ((operands[0] & 0x7F) != key_map[i].avc)
228 DBG("AV/C: %s %s", key_map[i].name, status);
230 key_quirks = session->key_quirks[key_map[i].avc];
232 if (key_quirks & QUIRK_NO_RELEASE) {
234 DBG("AV/C: Ignoring release");
238 DBG("AV/C: treating key press as press + release");
239 send_key(session->uinput, key_map[i].uinput, 1);
240 send_key(session->uinput, key_map[i].uinput, 0);
244 send_key(session->uinput, key_map[i].uinput, pressed);
248 if (key_map[i].name == NULL) {
249 DBG("AV/C: unknown button 0x%02X %s",
250 operands[0] & 0x7F, status);
251 *code = AVC_CTYPE_NOT_IMPLEMENTED;
256 *code = AVC_CTYPE_ACCEPTED;
257 return operand_count;
260 static size_t handle_unit_info(struct avctp *session,
261 uint8_t transaction, uint8_t *code,
262 uint8_t *subunit, uint8_t *operands,
263 size_t operand_count, void *user_data)
265 if (*code != AVC_CTYPE_STATUS) {
266 *code = AVC_CTYPE_REJECTED;
270 *code = AVC_CTYPE_STABLE;
272 /* The first operand should be 0x07 for the UNITINFO response.
273 * Neither AVRCP (section 22.1, page 117) nor AVC Digital
274 * Interface Command Set (section 9.2.1, page 45) specs
275 * explain this value but both use it */
276 if (operand_count >= 1)
278 if (operand_count >= 2)
279 operands[1] = AVC_SUBUNIT_PANEL << 3;
281 DBG("reply to AVC_OP_UNITINFO");
283 return operand_count;
286 static size_t handle_subunit_info(struct avctp *session,
287 uint8_t transaction, uint8_t *code,
288 uint8_t *subunit, uint8_t *operands,
289 size_t operand_count, void *user_data)
291 if (*code != AVC_CTYPE_STATUS) {
292 *code = AVC_CTYPE_REJECTED;
296 *code = AVC_CTYPE_STABLE;
298 /* The first operand should be 0x07 for the UNITINFO response.
299 * Neither AVRCP (section 22.1, page 117) nor AVC Digital
300 * Interface Command Set (section 9.2.1, page 45) specs
301 * explain this value but both use it */
302 if (operand_count >= 2)
303 operands[1] = AVC_SUBUNIT_PANEL << 3;
305 DBG("reply to AVC_OP_SUBUNITINFO");
307 return operand_count;
310 static struct avctp_pdu_handler *find_handler(GSList *list, uint8_t opcode)
312 for (; list; list = list->next) {
313 struct avctp_pdu_handler *handler = list->data;
315 if (handler->opcode == opcode)
322 static void avctp_disconnected(struct avctp *session)
324 struct avctp_server *server;
330 g_io_channel_shutdown(session->io, TRUE, NULL);
331 g_io_channel_unref(session->io);
335 if (session->io_id) {
336 g_source_remove(session->io_id);
339 if (session->state == AVCTP_STATE_CONNECTING) {
340 struct audio_device *dev;
342 dev = manager_get_device(&session->server->src,
343 &session->dst, FALSE);
344 audio_device_cancel_authorization(dev, auth_cb,
349 if (session->uinput >= 0) {
352 ba2str(&session->dst, address);
353 DBG("AVCTP: closing uinput for %s", address);
355 ioctl(session->uinput, UI_DEV_DESTROY);
356 close(session->uinput);
357 session->uinput = -1;
360 server = session->server;
361 server->sessions = g_slist_remove(server->sessions, session);
362 g_slist_free_full(session->handlers, g_free);
366 static void avctp_set_state(struct avctp *session, avctp_state_t new_state)
369 struct audio_device *dev;
370 avctp_state_t old_state = session->state;
372 dev = manager_get_device(&session->server->src, &session->dst, FALSE);
374 error("avdtp_set_state(): no matching audio device");
378 session->state = new_state;
380 for (l = callbacks; l != NULL; l = l->next) {
381 struct avctp_state_callback *cb = l->data;
382 cb->cb(dev, old_state, new_state, cb->user_data);
386 case AVCTP_STATE_DISCONNECTED:
387 DBG("AVCTP Disconnected");
389 avctp_disconnected(session);
391 if (old_state != AVCTP_STATE_CONNECTED)
394 if (!audio_device_is_active(dev, NULL))
395 audio_device_set_authorized(dev, FALSE);
398 case AVCTP_STATE_CONNECTING:
399 DBG("AVCTP Connecting");
401 case AVCTP_STATE_CONNECTED:
402 DBG("AVCTP Connected");
405 error("Invalid AVCTP state %d", new_state);
410 static void handle_response(struct avctp *session, struct avctp_header *avctp,
411 struct avc_header *avc, uint8_t *operands,
412 size_t operand_count)
416 for (l = session->handlers; l; l = l->next) {
417 struct avctp_rsp_handler *handler = l->data;
419 if (handler->id != avctp->transaction)
422 if (handler->func && handler->func(session, avc->code,
424 operands, operand_count,
428 session->handlers = g_slist_remove(session->handlers, handler);
435 static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
438 struct avctp *session = data;
439 uint8_t buf[1024], *operands, code, subunit;
440 struct avctp_header *avctp;
441 struct avc_header *avc;
442 int ret, packet_size, operand_count, sock;
443 struct avctp_pdu_handler *handler;
445 if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
448 sock = g_io_channel_unix_get_fd(session->io);
450 ret = read(sock, buf, sizeof(buf));
454 DBG("Got %d bytes of data for AVCTP session %p", ret, session);
456 if ((unsigned int) ret < sizeof(struct avctp_header)) {
457 error("Too small AVCTP packet");
461 avctp = (struct avctp_header *) buf;
463 DBG("AVCTP transaction %u, packet type %u, C/R %u, IPID %u, "
465 avctp->transaction, avctp->packet_type,
466 avctp->cr, avctp->ipid, ntohs(avctp->pid));
468 ret -= sizeof(struct avctp_header);
469 if ((unsigned int) ret < sizeof(struct avc_header)) {
470 error("Too small AVCTP packet");
474 avc = (struct avc_header *) (buf + sizeof(struct avctp_header));
476 ret -= sizeof(struct avc_header);
478 operands = buf + sizeof(struct avctp_header) + sizeof(struct avc_header);
481 DBG("AV/C %s 0x%01X, subunit_type 0x%02X, subunit_id 0x%01X, "
482 "opcode 0x%02X, %d operands",
483 avctp->cr ? "response" : "command",
484 avc->code, avc->subunit_type, avc->subunit_id,
485 avc->opcode, operand_count);
487 if (avctp->cr == AVCTP_RESPONSE) {
488 handle_response(session, avctp, avc, operands, operand_count);
492 packet_size = AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH;
493 avctp->cr = AVCTP_RESPONSE;
495 if (avctp->packet_type != AVCTP_PACKET_SINGLE) {
496 avc->code = AVC_CTYPE_NOT_IMPLEMENTED;
500 if (avctp->pid != htons(AV_REMOTE_SVCLASS_ID)) {
502 avc->code = AVC_CTYPE_REJECTED;
506 handler = find_handler(handlers, avc->opcode);
508 DBG("handler not found for 0x%02x", avc->opcode);
509 packet_size += avrcp_handle_vendor_reject(&code, operands);
515 subunit = avc->subunit_type;
517 packet_size += handler->cb(session, avctp->transaction, &code,
518 &subunit, operands, operand_count,
522 avc->subunit_type = subunit;
525 ret = write(sock, buf, packet_size);
526 if (ret != packet_size)
532 DBG("AVCTP session %p got disconnected", session);
533 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
537 static int uinput_create(char *name)
539 struct uinput_dev dev;
542 fd = open("/dev/uinput", O_RDWR);
544 fd = open("/dev/input/uinput", O_RDWR);
546 fd = open("/dev/misc/uinput", O_RDWR);
549 error("Can't open input device: %s (%d)",
550 strerror(-err), -err);
556 memset(&dev, 0, sizeof(dev));
558 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1);
560 dev.id.bustype = BUS_BLUETOOTH;
561 dev.id.vendor = 0x0000;
562 dev.id.product = 0x0000;
563 dev.id.version = 0x0000;
565 if (write(fd, &dev, sizeof(dev)) < 0) {
567 error("Can't write device information: %s (%d)",
568 strerror(-err), -err);
573 ioctl(fd, UI_SET_EVBIT, EV_KEY);
574 ioctl(fd, UI_SET_EVBIT, EV_REL);
575 ioctl(fd, UI_SET_EVBIT, EV_REP);
576 ioctl(fd, UI_SET_EVBIT, EV_SYN);
578 for (i = 0; key_map[i].name != NULL; i++)
579 ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput);
581 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
583 error("Can't create uinput device: %s (%d)",
584 strerror(-err), -err);
592 static void init_uinput(struct avctp *session)
594 struct audio_device *dev;
595 char address[18], name[248 + 1];
597 dev = manager_get_device(&session->server->src, &session->dst, FALSE);
599 device_get_name(dev->btd_dev, name, sizeof(name));
600 if (g_str_equal(name, "Nokia CK-20W")) {
601 session->key_quirks[FORWARD_OP] |= QUIRK_NO_RELEASE;
602 session->key_quirks[BACKWARD_OP] |= QUIRK_NO_RELEASE;
603 session->key_quirks[PLAY_OP] |= QUIRK_NO_RELEASE;
604 session->key_quirks[PAUSE_OP] |= QUIRK_NO_RELEASE;
607 ba2str(&session->dst, address);
609 session->uinput = uinput_create(address);
610 if (session->uinput < 0)
611 error("AVRCP: failed to init uinput for %s", address);
613 DBG("AVRCP: uinput initialized for %s", address);
616 static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
618 struct avctp *session = data;
624 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
625 error("%s", err->message);
629 bt_io_get(chan, BT_IO_L2CAP, &gerr,
630 BT_IO_OPT_DEST, &address,
631 BT_IO_OPT_IMTU, &imtu,
634 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
635 error("%s", gerr->message);
640 DBG("AVCTP: connected to %s", address);
643 session->io = g_io_channel_ref(chan);
645 init_uinput(session);
647 avctp_set_state(session, AVCTP_STATE_CONNECTED);
649 session->io_id = g_io_add_watch(chan,
650 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
651 (GIOFunc) session_cb, session);
654 static void auth_cb(DBusError *derr, void *user_data)
656 struct avctp *session = user_data;
659 if (session->io_id) {
660 g_source_remove(session->io_id);
664 if (derr && dbus_error_is_set(derr)) {
665 error("Access denied: %s", derr->message);
666 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
670 if (!bt_io_accept(session->io, avctp_connect_cb, session,
672 error("bt_io_accept: %s", err->message);
674 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
678 static struct avctp_server *find_server(GSList *list, const bdaddr_t *src)
680 for (; list; list = list->next) {
681 struct avctp_server *server = list->data;
683 if (bacmp(&server->src, src) == 0)
690 static struct avctp *find_session(GSList *list, const bdaddr_t *dst)
692 for (; list != NULL; list = g_slist_next(list)) {
693 struct avctp *s = list->data;
695 if (bacmp(dst, &s->dst))
704 static struct avctp *avctp_get_internal(const bdaddr_t *src,
707 struct avctp_server *server;
708 struct avctp *session;
713 server = find_server(servers, src);
717 session = find_session(server->sessions, dst);
721 session = g_new0(struct avctp, 1);
723 session->server = server;
724 bacpy(&session->dst, dst);
725 session->state = AVCTP_STATE_DISCONNECTED;
727 server->sessions = g_slist_append(server->sessions, session);
732 static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
734 struct avctp *session;
735 struct audio_device *dev;
740 bt_io_get(chan, BT_IO_L2CAP, &err,
741 BT_IO_OPT_SOURCE_BDADDR, &src,
742 BT_IO_OPT_DEST_BDADDR, &dst,
743 BT_IO_OPT_DEST, address,
746 error("%s", err->message);
748 g_io_channel_shutdown(chan, TRUE, NULL);
752 DBG("AVCTP: incoming connect from %s", address);
754 session = avctp_get_internal(&src, &dst);
758 dev = manager_get_device(&src, &dst, FALSE);
760 dev = manager_get_device(&src, &dst, TRUE);
762 error("Unable to get audio device object for %s",
768 if (dev->control == NULL) {
769 btd_device_add_uuid(dev->btd_dev, AVRCP_REMOTE_UUID);
770 if (dev->control == NULL)
775 error("Refusing unexpected connect from %s", address);
779 avctp_set_state(session, AVCTP_STATE_CONNECTING);
780 session->io = g_io_channel_ref(chan);
782 if (audio_device_request_authorization(dev, AVRCP_TARGET_UUID,
783 auth_cb, session) < 0)
786 session->io_id = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
787 session_cb, session);
791 if (!session || !session->io)
792 g_io_channel_shutdown(chan, TRUE, NULL);
794 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
797 static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master)
802 io = bt_io_listen(BT_IO_L2CAP, NULL, avctp_confirm_cb, NULL,
804 BT_IO_OPT_SOURCE_BDADDR, src,
805 BT_IO_OPT_PSM, AVCTP_PSM,
806 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
807 BT_IO_OPT_MASTER, master,
810 error("%s", err->message);
817 static unsigned int passthrough_id = 0;
818 static unsigned int unit_id = 0;
819 static unsigned int subunit_id = 0;
821 int avctp_register(const bdaddr_t *src, gboolean master)
823 struct avctp_server *server;
825 server = g_new0(struct avctp_server, 1);
829 server->io = avctp_server_socket(src, master);
835 bacpy(&server->src, src);
837 servers = g_slist_append(servers, server);
840 passthrough_id = avctp_register_pdu_handler(AVC_OP_PASSTHROUGH,
841 handle_panel_passthrough, NULL);
844 unit_id = avctp_register_pdu_handler(AVC_OP_UNITINFO, handle_unit_info,
848 subunit_id = avctp_register_pdu_handler(AVC_OP_SUBUNITINFO,
849 handle_subunit_info, NULL);
854 void avctp_unregister(const bdaddr_t *src)
856 struct avctp_server *server;
858 server = find_server(servers, src);
862 while (server->sessions)
863 avctp_disconnected(server->sessions->data);
865 servers = g_slist_remove(servers, server);
867 g_io_channel_shutdown(server->io, TRUE, NULL);
868 g_io_channel_unref(server->io);
874 if (passthrough_id) {
875 avctp_unregister_pdu_handler(passthrough_id);
880 avctp_unregister_pdu_handler(unit_id);
885 avctp_unregister_pdu_handler(subunit_id);
890 int avctp_send_passthrough(struct avctp *session, uint8_t op)
892 unsigned char buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH + 2];
893 struct avctp_header *avctp = (void *) buf;
894 struct avc_header *avc = (void *) &buf[AVCTP_HEADER_LENGTH];
895 uint8_t *operands = &buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH];
898 if (session->state != AVCTP_STATE_CONNECTED)
901 memset(buf, 0, sizeof(buf));
903 avctp->transaction = id++;
904 avctp->packet_type = AVCTP_PACKET_SINGLE;
905 avctp->cr = AVCTP_COMMAND;
906 avctp->pid = htons(AV_REMOTE_SVCLASS_ID);
908 avc->code = AVC_CTYPE_CONTROL;
909 avc->subunit_type = AVC_SUBUNIT_PANEL;
910 avc->opcode = AVC_OP_PASSTHROUGH;
912 operands[0] = op & 0x7f;
915 sk = g_io_channel_unix_get_fd(session->io);
917 if (write(sk, buf, sizeof(buf)) < 0)
921 avctp->transaction = id++;
924 if (write(sk, buf, sizeof(buf)) < 0)
930 static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
931 uint8_t code, uint8_t subunit, uint8_t opcode,
932 uint8_t *operands, size_t operand_count)
935 struct avctp_header *avctp;
936 struct avc_header *avc;
941 if (session->state != AVCTP_STATE_CONNECTED)
944 sk = g_io_channel_unix_get_fd(session->io);
945 size = AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH + operand_count;
946 buf = g_malloc0(size);
948 avctp = (void *) buf;
949 avc = (void *) &buf[AVCTP_HEADER_LENGTH];
950 pdu = (void *) &buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH];
952 avctp->transaction = transaction;
953 avctp->packet_type = AVCTP_PACKET_SINGLE;
955 avctp->pid = htons(AV_REMOTE_SVCLASS_ID);
958 avc->subunit_type = subunit;
959 avc->opcode = opcode;
961 memcpy(pdu, operands, operand_count);
963 if (write(sk, buf, size) < 0)
970 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
971 uint8_t code, uint8_t subunit,
972 uint8_t *operands, size_t operand_count)
974 return avctp_send(session, transaction, AVCTP_RESPONSE, code, subunit,
975 AVC_OP_VENDORDEP, operands, operand_count);
978 int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
979 uint8_t subunit, uint8_t *operands,
980 size_t operand_count,
981 avctp_rsp_cb func, void *user_data)
983 struct avctp_rsp_handler *handler;
986 err = avctp_send(session, id, AVCTP_COMMAND, code, subunit,
987 AVC_OP_VENDORDEP, operands, operand_count);
991 handler = g_new0(struct avctp_rsp_handler, 1);
993 handler->func = func;
994 handler->user_data = user_data;
996 session->handlers = g_slist_prepend(session->handlers, handler);
1003 unsigned int avctp_add_state_cb(avctp_state_cb cb, void *user_data)
1005 struct avctp_state_callback *state_cb;
1006 static unsigned int id = 0;
1008 state_cb = g_new(struct avctp_state_callback, 1);
1010 state_cb->user_data = user_data;
1011 state_cb->id = ++id;
1013 callbacks = g_slist_append(callbacks, state_cb);
1015 return state_cb->id;
1018 gboolean avctp_remove_state_cb(unsigned int id)
1022 for (l = callbacks; l != NULL; l = l->next) {
1023 struct avctp_state_callback *cb = l->data;
1024 if (cb && cb->id == id) {
1025 callbacks = g_slist_remove(callbacks, cb);
1034 unsigned int avctp_register_pdu_handler(uint8_t opcode, avctp_pdu_cb cb,
1037 struct avctp_pdu_handler *handler;
1038 static unsigned int id = 0;
1040 handler = find_handler(handlers, opcode);
1044 handler = g_new(struct avctp_pdu_handler, 1);
1045 handler->opcode = opcode;
1047 handler->user_data = user_data;
1050 handlers = g_slist_append(handlers, handler);
1055 gboolean avctp_unregister_pdu_handler(unsigned int id)
1059 for (l = handlers; l != NULL; l = l->next) {
1060 struct avctp_pdu_handler *handler = l->data;
1062 if (handler->id == id) {
1063 handlers = g_slist_remove(handlers, handler);
1072 struct avctp *avctp_connect(const bdaddr_t *src, const bdaddr_t *dst)
1074 struct avctp *session;
1078 session = avctp_get_internal(src, dst);
1082 if (session->state > AVCTP_STATE_DISCONNECTED)
1085 avctp_set_state(session, AVCTP_STATE_CONNECTING);
1087 io = bt_io_connect(BT_IO_L2CAP, avctp_connect_cb, session, NULL, &err,
1088 BT_IO_OPT_SOURCE_BDADDR, &session->server->src,
1089 BT_IO_OPT_DEST_BDADDR, &session->dst,
1090 BT_IO_OPT_PSM, AVCTP_PSM,
1093 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
1094 error("%s", err->message);
1104 void avctp_disconnect(struct avctp *session)
1109 avctp_set_state(session, AVCTP_STATE_DISCONNECTED);
1112 struct avctp *avctp_get(const bdaddr_t *src, const bdaddr_t *dst)
1114 return avctp_get_internal(src, dst);