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
37 #include <sys/types.h>
40 #include <netinet/in.h>
44 #include "lib/bluetooth.h"
46 #include "lib/l2cap.h"
49 #include "btio/btio.h"
50 #include "src/adapter.h"
51 #include "src/device.h"
53 #include "src/error.h"
54 #include "src/uinput.h"
59 /* AV/C Panel 1.23, page 76:
60 * command with the pressed value is valid for two seconds
62 #define AVC_PRESS_TIMEOUT 2
64 #define QUIRK_NO_RELEASE 1 << 0
67 #define AVCTP_COMMAND 0
68 #define AVCTP_RESPONSE 1
71 #define AVCTP_PACKET_SINGLE 0
72 #define AVCTP_PACKET_START 1
73 #define AVCTP_PACKET_CONTINUE 2
74 #define AVCTP_PACKET_END 3
76 #if __BYTE_ORDER == __LITTLE_ENDIAN
81 uint8_t packet_type:2;
82 uint8_t transaction:4;
84 } __attribute__ ((packed));
85 #define AVCTP_HEADER_LENGTH 3
91 uint8_t subunit_type:5;
93 } __attribute__ ((packed));
95 #elif __BYTE_ORDER == __BIG_ENDIAN
98 uint8_t transaction:4;
99 uint8_t packet_type:2;
103 } __attribute__ ((packed));
104 #define AVCTP_HEADER_LENGTH 3
109 uint8_t subunit_type:5;
110 uint8_t subunit_id:3;
112 } __attribute__ ((packed));
115 #error "Unknown byte order"
118 struct avctp_state_callback {
120 struct btd_device *dev;
125 struct avctp_server {
126 struct btd_adapter *adapter;
127 GIOChannel *control_io;
128 GIOChannel *browsing_io;
132 struct avctp_control_req {
133 struct avctp_pending_req *p;
138 uint16_t operand_count;
143 struct avctp_browsing_req {
144 struct avctp_pending_req *p;
146 uint16_t operand_count;
147 avctp_browsing_rsp_cb func;
151 typedef int (*avctp_process_cb) (void *data);
153 struct avctp_pending_req {
154 struct avctp_channel *chan;
158 avctp_process_cb process;
160 GDestroyNotify destroy;
163 struct avctp_channel {
164 struct avctp *session;
172 struct avctp_pending_req *p;
176 GDestroyNotify destroy;
185 struct avctp_server *server;
186 struct btd_device *device;
193 unsigned int passthrough_id;
194 unsigned int unit_id;
195 unsigned int subunit_id;
197 struct avctp_channel *control;
198 struct avctp_channel *browsing;
200 struct avctp_passthrough_handler *handler;
202 uint8_t key_quirks[256];
203 struct key_pressed key;
207 struct avctp_passthrough_handler {
208 avctp_passthrough_cb cb;
213 struct avctp_pdu_handler {
215 avctp_control_pdu_cb cb;
220 struct avctp_browsing_pdu_handler {
221 avctp_browsing_pdu_cb cb;
224 GDestroyNotify destroy;
232 { "SELECT", AVC_SELECT, KEY_SELECT },
233 { "UP", AVC_UP, KEY_UP },
234 { "DOWN", AVC_DOWN, KEY_DOWN },
235 { "LEFT", AVC_LEFT, KEY_LEFT },
236 { "RIGHT", AVC_RIGHT, KEY_RIGHT },
237 { "ROOT MENU", AVC_ROOT_MENU, KEY_MENU },
238 { "CONTENTS MENU", AVC_CONTENTS_MENU, KEY_PROGRAM },
239 { "FAVORITE MENU", AVC_FAVORITE_MENU, KEY_FAVORITES },
240 { "EXIT", AVC_EXIT, KEY_EXIT },
241 { "ON DEMAND MENU", AVC_ON_DEMAND_MENU, KEY_MENU },
242 { "APPS MENU", AVC_APPS_MENU, KEY_MENU },
243 { "0", AVC_0, KEY_0 },
244 { "1", AVC_1, KEY_1 },
245 { "2", AVC_2, KEY_2 },
246 { "3", AVC_3, KEY_3 },
247 { "4", AVC_4, KEY_4 },
248 { "5", AVC_5, KEY_5 },
249 { "6", AVC_6, KEY_6 },
250 { "7", AVC_7, KEY_7 },
251 { "8", AVC_8, KEY_8 },
252 { "9", AVC_9, KEY_9 },
253 { "DOT", AVC_DOT, KEY_DOT },
254 { "ENTER", AVC_ENTER, KEY_ENTER },
255 { "CHANNEL UP", AVC_CHANNEL_UP, KEY_CHANNELUP },
256 { "CHANNEL DOWN", AVC_CHANNEL_DOWN, KEY_CHANNELDOWN },
257 { "CHANNEL PREVIOUS", AVC_CHANNEL_PREVIOUS, KEY_LAST },
258 { "INPUT SELECT", AVC_INPUT_SELECT, KEY_CONFIG },
259 { "INFO", AVC_INFO, KEY_INFO },
260 { "HELP", AVC_HELP, KEY_HELP },
261 { "POWER", AVC_POWER, KEY_POWER2 },
262 { "VOLUME UP", AVC_VOLUME_UP, KEY_VOLUMEUP },
263 { "VOLUME DOWN", AVC_VOLUME_DOWN, KEY_VOLUMEDOWN },
264 { "MUTE", AVC_MUTE, KEY_MUTE },
265 { "PLAY", AVC_PLAY, KEY_PLAYCD },
266 { "STOP", AVC_STOP, KEY_STOPCD },
267 { "PAUSE", AVC_PAUSE, KEY_PAUSECD },
268 { "FORWARD", AVC_FORWARD, KEY_NEXTSONG },
269 { "BACKWARD", AVC_BACKWARD, KEY_PREVIOUSSONG },
270 { "RECORD", AVC_RECORD, KEY_RECORD },
271 { "REWIND", AVC_REWIND, KEY_REWIND },
272 { "FAST FORWARD", AVC_FAST_FORWARD, KEY_FASTFORWARD },
273 { "LIST", AVC_LIST, KEY_LIST },
274 { "F1", AVC_F1, KEY_F1 },
275 { "F2", AVC_F2, KEY_F2 },
276 { "F3", AVC_F3, KEY_F3 },
277 { "F4", AVC_F4, KEY_F4 },
278 { "F5", AVC_F5, KEY_F5 },
279 { "F6", AVC_F6, KEY_F6 },
280 { "F7", AVC_F7, KEY_F7 },
281 { "F8", AVC_F8, KEY_F8 },
282 { "F9", AVC_F9, KEY_F9 },
283 { "RED", AVC_RED, KEY_RED },
284 { "GREEN", AVC_GREEN, KEY_GREEN },
285 { "BLUE", AVC_BLUE, KEY_BLUE },
286 { "YELLOW", AVC_YELLOW, KEY_YELLOW },
290 static GSList *callbacks = NULL;
291 static GSList *servers = NULL;
293 static void auth_cb(DBusError *derr, void *user_data);
294 static gboolean process_queue(gpointer user_data);
295 static gboolean avctp_passthrough_rsp(struct avctp *session, uint8_t code,
296 uint8_t subunit, uint8_t *operands,
297 size_t operand_count, void *user_data);
299 static int send_event(int fd, uint16_t type, uint16_t code, int32_t value)
301 struct uinput_event event;
303 memset(&event, 0, sizeof(event));
308 return write(fd, &event, sizeof(event));
311 static void send_key(int fd, uint16_t key, int pressed)
316 send_event(fd, EV_KEY, key, pressed);
317 send_event(fd, EV_SYN, SYN_REPORT, 0);
320 static gboolean auto_release(gpointer user_data)
322 struct avctp *session = user_data;
323 #ifdef __TIZEN_PATCH__
324 uint16_t op = session->key.op;
327 DBG("AV/C: key press timeout");
329 #ifdef __TIZEN_PATCH__
330 if (op != KEY_FASTFORWARD && op != KEY_REWIND) {
331 session->key.timer = 0;
332 send_key(session->uinput, op, 0);
337 session->key.timer = 0;
338 send_key(session->uinput, session->key.op, 0);
344 #ifdef __TIZEN_PATCH__
345 extern void avrcp_stop_position_timer(void);
348 static void handle_press(struct avctp *session, uint16_t op)
350 if (session->key.timer > 0) {
351 g_source_remove(session->key.timer);
353 /* Only auto release if keys are different */
354 if (session->key.op == op)
356 #ifndef __TIZEN_PATCH__
357 send_key(session->uinput, session->key.op, 0);
361 session->key.op = op;
363 send_key(session->uinput, op, 1);
366 session->key.timer = g_timeout_add_seconds(AVC_PRESS_TIMEOUT,
367 auto_release, session);
370 static void handle_release(struct avctp *session, uint16_t op)
372 if (session->key.timer > 0) {
373 g_source_remove(session->key.timer);
374 session->key.timer = 0;
377 send_key(session->uinput, op, 0);
379 #ifdef __TIZEN_PATCH__
380 extern void avrcp_stop_position_timer(void);
383 static size_t handle_panel_passthrough(struct avctp *session,
384 uint8_t transaction, uint8_t *code,
385 uint8_t *subunit, uint8_t *operands,
386 size_t operand_count, void *user_data)
388 struct avctp_passthrough_handler *handler = session->handler;
392 if (*code != AVC_CTYPE_CONTROL || *subunit != AVC_SUBUNIT_PANEL) {
393 *code = AVC_CTYPE_REJECTED;
394 return operand_count;
397 if (operand_count == 0)
400 if (operands[0] & 0x80) {
408 if (session->key.timer == 0 && handler != NULL) {
409 if (handler->cb(session, operands[0] & 0x7F,
410 pressed, handler->user_data))
414 for (i = 0; key_map[i].name != NULL; i++) {
417 if ((operands[0] & 0x7F) != key_map[i].avc)
420 DBG("AV/C: %s %s", key_map[i].name, status);
422 key_quirks = session->key_quirks[key_map[i].avc];
424 if (key_quirks & QUIRK_NO_RELEASE) {
426 DBG("AV/C: Ignoring release");
430 DBG("AV/C: treating key press as press + release");
431 send_key(session->uinput, key_map[i].uinput, 1);
432 send_key(session->uinput, key_map[i].uinput, 0);
437 handle_press(session, key_map[i].uinput);
438 #ifdef __TIZEN_PATCH__
439 if (key_map[i].avc == AVC_REWIND)
440 avrcp_stop_position_timer();
443 handle_release(session, key_map[i].uinput);
448 if (key_map[i].name == NULL) {
449 DBG("AV/C: unknown button 0x%02X %s",
450 operands[0] & 0x7F, status);
451 *code = AVC_CTYPE_NOT_IMPLEMENTED;
452 return operand_count;
456 *code = AVC_CTYPE_ACCEPTED;
457 return operand_count;
460 static size_t handle_unit_info(struct avctp *session,
461 uint8_t transaction, uint8_t *code,
462 uint8_t *subunit, uint8_t *operands,
463 size_t operand_count, void *user_data)
465 if (*code != AVC_CTYPE_STATUS) {
466 *code = AVC_CTYPE_REJECTED;
470 *code = AVC_CTYPE_STABLE;
472 /* The first operand should be 0x07 for the UNITINFO response.
473 * Neither AVRCP (section 22.1, page 117) nor AVC Digital
474 * Interface Command Set (section 9.2.1, page 45) specs
475 * explain this value but both use it */
476 if (operand_count >= 1)
478 if (operand_count >= 2)
479 operands[1] = AVC_SUBUNIT_PANEL << 3;
481 DBG("reply to AVC_OP_UNITINFO");
483 return operand_count;
486 static size_t handle_subunit_info(struct avctp *session,
487 uint8_t transaction, uint8_t *code,
488 uint8_t *subunit, uint8_t *operands,
489 size_t operand_count, void *user_data)
491 if (*code != AVC_CTYPE_STATUS) {
492 *code = AVC_CTYPE_REJECTED;
496 *code = AVC_CTYPE_STABLE;
498 /* The first operand should be 0x07 for the UNITINFO response.
499 * Neither AVRCP (section 22.1, page 117) nor AVC Digital
500 * Interface Command Set (section 9.2.1, page 45) specs
501 * explain this value but both use it */
502 if (operand_count >= 2)
503 operands[1] = AVC_SUBUNIT_PANEL << 3;
505 DBG("reply to AVC_OP_SUBUNITINFO");
507 return operand_count;
510 static struct avctp_pdu_handler *find_handler(GSList *list, uint8_t opcode)
512 for (; list; list = list->next) {
513 struct avctp_pdu_handler *handler = list->data;
515 if (handler->opcode == opcode)
522 static void pending_destroy(gpointer data, gpointer user_data)
524 struct avctp_pending_req *req = data;
527 req->destroy(req->data);
529 if (req->timeout > 0)
530 g_source_remove(req->timeout);
535 static void avctp_channel_destroy(struct avctp_channel *chan)
537 g_io_channel_shutdown(chan->io, TRUE, NULL);
538 g_io_channel_unref(chan->io);
541 g_source_remove(chan->watch);
544 pending_destroy(chan->p, NULL);
546 if (chan->process_id > 0)
547 g_source_remove(chan->process_id);
552 g_free(chan->buffer);
553 g_queue_foreach(chan->queue, pending_destroy, NULL);
554 g_queue_free(chan->queue);
555 g_slist_foreach(chan->processed, pending_destroy, NULL);
556 g_slist_free(chan->processed);
557 g_slist_free_full(chan->handlers, g_free);
561 static void avctp_disconnected(struct avctp *session)
563 struct avctp_server *server;
568 if (session->browsing)
569 avctp_channel_destroy(session->browsing);
571 if (session->control)
572 avctp_channel_destroy(session->control);
574 if (session->auth_id != 0) {
575 btd_cancel_authorization(session->auth_id);
576 session->auth_id = 0;
579 if (session->key.timer > 0)
580 g_source_remove(session->key.timer);
582 if (session->uinput >= 0) {
585 ba2str(device_get_address(session->device), address);
586 DBG("AVCTP: closing uinput for %s", address);
588 ioctl(session->uinput, UI_DEV_DESTROY);
589 close(session->uinput);
590 session->uinput = -1;
593 server = session->server;
594 server->sessions = g_slist_remove(server->sessions, session);
595 btd_device_unref(session->device);
599 static void avctp_set_state(struct avctp *session, avctp_state_t new_state,
603 avctp_state_t old_state = session->state;
605 session->state = new_state;
607 for (l = callbacks; l != NULL; l = l->next) {
608 struct avctp_state_callback *cb = l->data;
610 if (cb->dev && cb->dev != session->device)
613 cb->cb(session->device, old_state, new_state, err,
618 case AVCTP_STATE_DISCONNECTED:
619 DBG("AVCTP Disconnected");
620 avctp_disconnected(session);
622 case AVCTP_STATE_CONNECTING:
623 DBG("AVCTP Connecting");
625 case AVCTP_STATE_CONNECTED:
626 DBG("AVCTP Connected");
628 case AVCTP_STATE_BROWSING_CONNECTING:
629 DBG("AVCTP Browsing Connecting");
631 case AVCTP_STATE_BROWSING_CONNECTED:
632 DBG("AVCTP Browsing Connected");
635 error("Invalid AVCTP state %d", new_state);
640 static int avctp_send(struct avctp_channel *control, uint8_t transaction,
641 uint8_t cr, uint8_t code,
642 uint8_t subunit, uint8_t opcode,
643 uint8_t *operands, size_t operand_count)
645 struct avctp_header *avctp;
646 struct avc_header *avc;
651 iov[0].iov_base = control->buffer;
652 iov[0].iov_len = sizeof(*avctp) + sizeof(*avc);
653 iov[1].iov_base = operands;
654 iov[1].iov_len = operand_count;
656 if (control->omtu < (iov[0].iov_len + iov[1].iov_len))
659 sk = g_io_channel_unix_get_fd(control->io);
661 memset(control->buffer, 0, iov[0].iov_len);
663 avctp = (void *) control->buffer;
664 avc = (void *) avctp + sizeof(*avctp);
666 avctp->transaction = transaction;
667 avctp->packet_type = AVCTP_PACKET_SINGLE;
669 avctp->pid = htons(AV_REMOTE_SVCLASS_ID);
672 avc->subunit_type = subunit;
673 avc->opcode = opcode;
675 memset(&msg, 0, sizeof(msg));
679 if (sendmsg(sk, &msg, 0) < 0)
685 static int avctp_browsing_send(struct avctp_channel *browsing,
686 uint8_t transaction, uint8_t cr,
687 uint8_t *operands, size_t operand_count)
689 struct avctp_header *avctp;
694 iov[0].iov_base = browsing->buffer;
695 iov[0].iov_len = sizeof(*avctp);
696 iov[1].iov_base = operands;
697 iov[1].iov_len = operand_count;
699 if (browsing->omtu < (iov[0].iov_len + iov[1].iov_len))
702 sk = g_io_channel_unix_get_fd(browsing->io);
704 memset(browsing->buffer, 0, iov[0].iov_len);
706 avctp = (void *) browsing->buffer;
708 avctp->transaction = transaction;
709 avctp->packet_type = AVCTP_PACKET_SINGLE;
711 avctp->pid = htons(AV_REMOTE_SVCLASS_ID);
713 memset(&msg, 0, sizeof(msg));
717 if (sendmsg(sk, &msg, 0) < 0)
723 static void control_req_destroy(void *data)
725 struct avctp_control_req *req = data;
726 struct avctp_pending_req *p = req->p;
727 struct avctp *session = p->chan->session;
729 if (p->err == 0 || req->func == NULL)
732 req->func(session, AVC_CTYPE_REJECTED, req->subunit, NULL, 0,
736 g_free(req->operands);
740 static void browsing_req_destroy(void *data)
742 struct avctp_browsing_req *req = data;
743 struct avctp_pending_req *p = req->p;
744 struct avctp *session = p->chan->session;
746 if (p->err == 0 || req->func == NULL)
749 req->func(session, NULL, 0, req->user_data);
752 g_free(req->operands);
756 static gboolean req_timeout(gpointer user_data)
758 struct avctp_channel *chan = user_data;
759 struct avctp_pending_req *p = chan->p;
761 DBG("transaction %u", p->transaction);
766 pending_destroy(p, NULL);
769 if (chan->process_id == 0)
770 chan->process_id = g_idle_add(process_queue, chan);
775 static int process_control(void *data)
777 struct avctp_control_req *req = data;
778 struct avctp_pending_req *p = req->p;
780 return avctp_send(p->chan, p->transaction, AVCTP_COMMAND, req->code,
781 req->subunit, req->op,
782 req->operands, req->operand_count);
785 static int process_browsing(void *data)
787 struct avctp_browsing_req *req = data;
788 struct avctp_pending_req *p = req->p;
790 return avctp_browsing_send(p->chan, p->transaction, AVCTP_COMMAND,
791 req->operands, req->operand_count);
794 static gboolean process_queue(void *user_data)
796 struct avctp_channel *chan = user_data;
797 struct avctp_pending_req *p = chan->p;
799 chan->process_id = 0;
804 while ((p = g_queue_pop_head(chan->queue))) {
806 if (p->process(p->data) == 0)
809 pending_destroy(p, NULL);
816 #ifdef __TIZEN_PATCH__
817 p->timeout = g_timeout_add_seconds(5, req_timeout, chan);
819 p->timeout = g_timeout_add_seconds(2, req_timeout, chan);
826 static void control_response(struct avctp_channel *control,
827 struct avctp_header *avctp,
828 struct avc_header *avc,
830 size_t operand_count)
832 struct avctp_pending_req *p = control->p;
833 struct avctp_control_req *req;
836 if (p && p->transaction == avctp->transaction) {
837 control->processed = g_slist_prepend(control->processed, p);
839 if (p->timeout > 0) {
840 g_source_remove(p->timeout);
846 if (control->process_id == 0)
847 control->process_id = g_idle_add(process_queue,
851 for (l = control->processed; l; l = l->next) {
855 if (p->transaction != avctp->transaction)
858 if (req->func && req->func(control->session, avc->code,
860 operands, operand_count,
864 control->processed = g_slist_remove(control->processed, p);
865 pending_destroy(p, NULL);
871 static void browsing_response(struct avctp_channel *browsing,
872 struct avctp_header *avctp,
874 size_t operand_count)
876 struct avctp_pending_req *p = browsing->p;
877 struct avctp_browsing_req *req;
880 if (p && p->transaction == avctp->transaction) {
881 browsing->processed = g_slist_prepend(browsing->processed, p);
883 if (p->timeout > 0) {
884 g_source_remove(p->timeout);
890 if (browsing->process_id == 0)
891 browsing->process_id = g_idle_add(process_queue,
895 for (l = browsing->processed; l; l = l->next) {
899 if (p->transaction != avctp->transaction)
902 if (req->func && req->func(browsing->session, operands,
903 operand_count, req->user_data))
906 browsing->processed = g_slist_remove(browsing->processed, p);
907 pending_destroy(p, NULL);
913 static gboolean session_browsing_cb(GIOChannel *chan, GIOCondition cond,
916 struct avctp *session = data;
917 struct avctp_channel *browsing = session->browsing;
918 uint8_t *buf = browsing->buffer;
920 struct avctp_header *avctp;
921 int sock, ret, packet_size, operand_count;
922 struct avctp_browsing_pdu_handler *handler;
924 if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
927 sock = g_io_channel_unix_get_fd(chan);
929 ret = read(sock, buf, browsing->imtu);
933 avctp = (struct avctp_header *) buf;
935 if (avctp->packet_type != AVCTP_PACKET_SINGLE)
938 operands = buf + AVCTP_HEADER_LENGTH;
939 ret -= AVCTP_HEADER_LENGTH;
942 if (avctp->cr == AVCTP_RESPONSE) {
943 browsing_response(browsing, avctp, operands, operand_count);
947 packet_size = AVCTP_HEADER_LENGTH;
948 avctp->cr = AVCTP_RESPONSE;
950 handler = g_slist_nth_data(browsing->handlers, 0);
951 if (handler == NULL) {
952 DBG("handler not found");
953 packet_size += avrcp_browsing_general_reject(operands);
957 packet_size += handler->cb(session, avctp->transaction,
958 operands, operand_count,
962 if (packet_size != 0) {
963 ret = write(sock, buf, packet_size);
964 if (ret != packet_size)
971 DBG("AVCTP Browsing: disconnected");
972 avctp_set_state(session, AVCTP_STATE_CONNECTED, 0);
974 if (session->browsing) {
975 avctp_channel_destroy(session->browsing);
976 session->browsing = NULL;
982 static gboolean session_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
984 struct avctp *session = data;
985 struct avctp_channel *control = session->control;
986 uint8_t *buf = control->buffer;
987 uint8_t *operands, code, subunit;
988 struct avctp_header *avctp;
989 struct avc_header *avc;
990 int ret, packet_size, operand_count, sock;
991 struct avctp_pdu_handler *handler;
993 if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
996 sock = g_io_channel_unix_get_fd(chan);
998 ret = read(sock, buf, control->imtu);
1002 if (ret < AVCTP_HEADER_LENGTH) {
1003 error("Too small AVCTP packet");
1007 avctp = (struct avctp_header *) buf;
1009 ret -= AVCTP_HEADER_LENGTH;
1010 if (ret < AVC_HEADER_LENGTH) {
1011 error("Too small AVC packet");
1015 avc = (struct avc_header *) (buf + AVCTP_HEADER_LENGTH);
1017 ret -= AVC_HEADER_LENGTH;
1019 operands = (uint8_t *) avc + AVC_HEADER_LENGTH;
1020 operand_count = ret;
1022 if (avctp->cr == AVCTP_RESPONSE) {
1023 control_response(control, avctp, avc, operands, operand_count);
1027 packet_size = AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH;
1028 avctp->cr = AVCTP_RESPONSE;
1030 if (avctp->packet_type != AVCTP_PACKET_SINGLE) {
1031 avc->code = AVC_CTYPE_NOT_IMPLEMENTED;
1035 if (avctp->pid != htons(AV_REMOTE_SVCLASS_ID)) {
1037 packet_size = AVCTP_HEADER_LENGTH;
1041 handler = find_handler(control->handlers, avc->opcode);
1043 DBG("handler not found for 0x%02x", avc->opcode);
1044 packet_size += avrcp_handle_vendor_reject(&code, operands);
1050 subunit = avc->subunit_type;
1052 packet_size += handler->cb(session, avctp->transaction, &code,
1053 &subunit, operands, operand_count,
1054 handler->user_data);
1057 avc->subunit_type = subunit;
1060 ret = write(sock, buf, packet_size);
1061 if (ret != packet_size)
1067 DBG("AVCTP session %p got disconnected", session);
1068 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1072 static int uinput_create(char *name)
1074 struct uinput_dev dev;
1077 fd = open("/dev/uinput", O_RDWR);
1079 fd = open("/dev/input/uinput", O_RDWR);
1081 fd = open("/dev/misc/uinput", O_RDWR);
1084 error("Can't open input device: %s (%d)",
1085 strerror(-err), -err);
1091 memset(&dev, 0, sizeof(dev));
1093 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE - 1);
1095 dev.id.bustype = BUS_BLUETOOTH;
1096 dev.id.vendor = 0x0000;
1097 dev.id.product = 0x0000;
1098 dev.id.version = 0x0000;
1100 if (write(fd, &dev, sizeof(dev)) < 0) {
1102 error("Can't write device information: %s (%d)",
1103 strerror(-err), -err);
1108 ioctl(fd, UI_SET_EVBIT, EV_KEY);
1109 ioctl(fd, UI_SET_EVBIT, EV_REL);
1110 ioctl(fd, UI_SET_EVBIT, EV_REP);
1111 ioctl(fd, UI_SET_EVBIT, EV_SYN);
1113 for (i = 0; key_map[i].name != NULL; i++)
1114 ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput);
1116 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
1118 error("Can't create uinput device: %s (%d)",
1119 strerror(-err), -err);
1124 send_event(fd, EV_REP, REP_DELAY, 300);
1129 static void init_uinput(struct avctp *session)
1131 char address[18], name[248 + 1];
1133 device_get_name(session->device, name, sizeof(name));
1134 if (g_str_equal(name, "Nokia CK-20W")) {
1135 session->key_quirks[AVC_FORWARD] |= QUIRK_NO_RELEASE;
1136 session->key_quirks[AVC_BACKWARD] |= QUIRK_NO_RELEASE;
1137 session->key_quirks[AVC_PLAY] |= QUIRK_NO_RELEASE;
1138 session->key_quirks[AVC_PAUSE] |= QUIRK_NO_RELEASE;
1141 ba2str(device_get_address(session->device), address);
1142 session->uinput = uinput_create(address);
1143 if (session->uinput < 0)
1144 error("AVRCP: failed to init uinput for %s", address);
1146 DBG("AVRCP: uinput initialized for %s", address);
1149 static struct avctp_channel *avctp_channel_create(struct avctp *session,
1151 GDestroyNotify destroy)
1153 struct avctp_channel *chan;
1155 chan = g_new0(struct avctp_channel, 1);
1156 chan->session = session;
1157 chan->io = g_io_channel_ref(io);
1158 chan->queue = g_queue_new();
1159 chan->destroy = destroy;
1164 static void handler_free(void *data)
1166 struct avctp_browsing_pdu_handler *handler = data;
1168 if (handler->destroy)
1169 handler->destroy(handler->user_data);
1174 static void avctp_destroy_browsing(void *data)
1176 struct avctp_channel *chan = data;
1178 g_slist_free_full(chan->handlers, handler_free);
1180 chan->handlers = NULL;
1183 static void avctp_connect_browsing_cb(GIOChannel *chan, GError *err,
1186 struct avctp *session = data;
1187 struct avctp_channel *browsing = session->browsing;
1189 uint16_t imtu, omtu;
1190 GError *gerr = NULL;
1193 error("Browsing: %s", err->message);
1197 bt_io_get(chan, &gerr,
1198 BT_IO_OPT_DEST, &address,
1199 BT_IO_OPT_IMTU, &imtu,
1200 BT_IO_OPT_OMTU, &omtu,
1203 error("%s", gerr->message);
1204 g_io_channel_shutdown(chan, TRUE, NULL);
1205 g_io_channel_unref(chan);
1210 DBG("AVCTP Browsing: connected to %s", address);
1212 if (browsing == NULL) {
1213 browsing = avctp_channel_create(session, chan,
1214 avctp_destroy_browsing);
1215 session->browsing = browsing;
1218 browsing->imtu = imtu;
1219 browsing->omtu = omtu;
1220 browsing->buffer = g_malloc0(MAX(imtu, omtu));
1221 browsing->watch = g_io_add_watch(session->browsing->io,
1222 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1223 (GIOFunc) session_browsing_cb, session);
1225 avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTED, 0);
1227 /* Process any request that was pending the connection to complete */
1228 if (browsing->process_id == 0 && !g_queue_is_empty(browsing->queue))
1229 browsing->process_id = g_idle_add(process_queue, browsing);
1234 avctp_set_state(session, AVCTP_STATE_CONNECTED, 0);
1236 if (session->browsing) {
1237 avctp_channel_destroy(session->browsing);
1238 session->browsing = NULL;
1242 static void avctp_connect_cb(GIOChannel *chan, GError *err, gpointer data)
1244 struct avctp *session = data;
1246 uint16_t imtu, omtu;
1247 GError *gerr = NULL;
1250 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1251 error("%s", err->message);
1255 bt_io_get(chan, &gerr,
1256 BT_IO_OPT_DEST, &address,
1257 BT_IO_OPT_IMTU, &imtu,
1258 BT_IO_OPT_IMTU, &omtu,
1261 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1262 error("%s", gerr->message);
1267 DBG("AVCTP: connected to %s", address);
1269 if (session->control == NULL)
1270 session->control = avctp_channel_create(session, chan, NULL);
1272 session->control->imtu = imtu;
1273 session->control->omtu = omtu;
1274 session->control->buffer = g_malloc0(MAX(imtu, omtu));
1275 session->control->watch = g_io_add_watch(session->control->io,
1276 G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
1277 (GIOFunc) session_cb, session);
1279 session->passthrough_id = avctp_register_pdu_handler(session,
1281 handle_panel_passthrough,
1283 session->unit_id = avctp_register_pdu_handler(session,
1287 session->subunit_id = avctp_register_pdu_handler(session,
1289 handle_subunit_info,
1292 init_uinput(session);
1294 avctp_set_state(session, AVCTP_STATE_CONNECTED, 0);
1297 static void auth_cb(DBusError *derr, void *user_data)
1299 struct avctp *session = user_data;
1302 session->auth_id = 0;
1304 if (session->control->watch > 0) {
1305 g_source_remove(session->control->watch);
1306 session->control->watch = 0;
1309 if (derr && dbus_error_is_set(derr)) {
1310 error("Access denied: %s", derr->message);
1311 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1315 if (!bt_io_accept(session->control->io, avctp_connect_cb, session,
1317 error("bt_io_accept: %s", err->message);
1319 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1323 static struct avctp_server *find_server(GSList *list, struct btd_adapter *a)
1325 for (; list; list = list->next) {
1326 struct avctp_server *server = list->data;
1328 if (server->adapter == a)
1335 static struct avctp *find_session(GSList *list, struct btd_device *device)
1337 for (; list != NULL; list = g_slist_next(list)) {
1338 struct avctp *s = list->data;
1340 if (s->device == device)
1347 static struct avctp *avctp_get_internal(struct btd_device *device)
1349 struct avctp_server *server;
1350 struct avctp *session;
1352 server = find_server(servers, device_get_adapter(device));
1356 session = find_session(server->sessions, device);
1360 session = g_new0(struct avctp, 1);
1362 session->server = server;
1363 session->device = btd_device_ref(device);
1364 session->state = AVCTP_STATE_DISCONNECTED;
1365 session->uinput = -1;
1367 server->sessions = g_slist_append(server->sessions, session);
1372 static void avctp_control_confirm(struct avctp *session, GIOChannel *chan,
1373 struct btd_device *dev)
1375 const bdaddr_t *src;
1376 const bdaddr_t *dst;
1378 if (session->control != NULL) {
1379 error("Control: Refusing unexpected connect");
1380 g_io_channel_shutdown(chan, TRUE, NULL);
1383 * Close AVCTP channel if remote tried connect
1385 * AVRCP SPEC V1.5 4.1.1 Connection Establishment
1387 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EAGAIN);
1391 avctp_set_state(session, AVCTP_STATE_CONNECTING, 0);
1392 session->control = avctp_channel_create(session, chan, NULL);
1394 src = btd_adapter_get_address(device_get_adapter(dev));
1395 dst = device_get_address(dev);
1397 #ifdef __TIZEN_PATCH__
1398 session->auth_id = btd_request_authorization(src, dst,
1402 session->auth_id = btd_request_authorization(src, dst,
1406 if (session->auth_id == 0)
1409 session->control->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP |
1410 G_IO_NVAL, session_cb, session);
1414 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
1417 static void avctp_browsing_confirm(struct avctp *session, GIOChannel *chan,
1418 struct btd_device *dev)
1422 if (session->control == NULL || session->browsing != NULL) {
1423 error("Browsing: Refusing unexpected connect");
1424 g_io_channel_shutdown(chan, TRUE, NULL);
1428 if (bt_io_accept(chan, avctp_connect_browsing_cb, session, NULL,
1430 avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING, 0);
1434 error("Browsing: %s", err->message);
1440 static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
1442 struct avctp *session;
1447 struct btd_device *device;
1449 bt_io_get(chan, &err,
1450 BT_IO_OPT_SOURCE_BDADDR, &src,
1451 BT_IO_OPT_DEST_BDADDR, &dst,
1452 BT_IO_OPT_DEST, address,
1453 BT_IO_OPT_PSM, &psm,
1456 error("%s", err->message);
1458 g_io_channel_shutdown(chan, TRUE, NULL);
1462 DBG("AVCTP: incoming connect from %s", address);
1464 device = btd_adapter_find_device(adapter_find(&src), &dst,
1469 #ifdef __TIZEN_PATCH__
1471 device_get_name(device, name, sizeof(name));
1472 DBG("name : %s", name);
1473 if (g_str_equal(name, "PLT_M50")) {
1474 DBG("Don't accept avrcp connection with this headset");
1479 session = avctp_get_internal(device);
1480 if (session == NULL)
1483 if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
1484 btd_device_add_uuid(device, AVRCP_REMOTE_UUID);
1486 if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
1487 btd_device_add_uuid(device, AVRCP_TARGET_UUID);
1490 case AVCTP_CONTROL_PSM:
1491 avctp_control_confirm(session, chan, device);
1493 case AVCTP_BROWSING_PSM:
1494 avctp_browsing_confirm(session, chan, device);
1501 static GIOChannel *avctp_server_socket(const bdaddr_t *src, gboolean master,
1502 uint8_t mode, uint16_t psm)
1507 io = bt_io_listen(NULL, avctp_confirm_cb, NULL,
1509 BT_IO_OPT_SOURCE_BDADDR, src,
1511 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
1512 BT_IO_OPT_MASTER, master,
1513 BT_IO_OPT_MODE, mode,
1516 error("%s", err->message);
1523 int avctp_register(struct btd_adapter *adapter, gboolean master)
1525 struct avctp_server *server;
1526 const bdaddr_t *src = btd_adapter_get_address(adapter);
1528 server = g_new0(struct avctp_server, 1);
1530 server->control_io = avctp_server_socket(src, master, L2CAP_MODE_BASIC,
1532 if (!server->control_io) {
1536 server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM,
1537 AVCTP_BROWSING_PSM);
1538 if (!server->browsing_io) {
1539 if (server->control_io) {
1540 g_io_channel_shutdown(server->control_io, TRUE, NULL);
1541 g_io_channel_unref(server->control_io);
1542 server->control_io = NULL;
1548 server->adapter = btd_adapter_ref(adapter);
1550 servers = g_slist_append(servers, server);
1555 void avctp_unregister(struct btd_adapter *adapter)
1557 struct avctp_server *server;
1559 server = find_server(servers, adapter);
1563 while (server->sessions)
1564 avctp_disconnected(server->sessions->data);
1566 servers = g_slist_remove(servers, server);
1568 g_io_channel_shutdown(server->browsing_io, TRUE, NULL);
1569 g_io_channel_unref(server->browsing_io);
1570 server->browsing_io = NULL;
1572 g_io_channel_shutdown(server->control_io, TRUE, NULL);
1573 g_io_channel_unref(server->control_io);
1574 btd_adapter_unref(server->adapter);
1578 static struct avctp_pending_req *pending_create(struct avctp_channel *chan,
1579 avctp_process_cb process,
1581 GDestroyNotify destroy)
1583 struct avctp_pending_req *p;
1586 if (!chan->processed)
1589 tmp = g_slist_copy(chan->processed);
1591 /* Find first unused transaction id */
1592 for (l = tmp; l; l = g_slist_next(l)) {
1593 struct avctp_pending_req *req = l->data;
1595 if (req->transaction == chan->transaction) {
1596 chan->transaction++;
1597 chan->transaction %= 16;
1598 tmp = g_slist_delete_link(tmp, l);
1606 p = g_new0(struct avctp_pending_req, 1);
1608 p->transaction = chan->transaction;
1609 p->process = process;
1611 p->destroy = destroy;
1613 chan->transaction++;
1614 chan->transaction %= 16;
1619 static int avctp_send_req(struct avctp *session, uint8_t code,
1620 uint8_t subunit, uint8_t opcode,
1621 uint8_t *operands, size_t operand_count,
1622 avctp_rsp_cb func, void *user_data)
1624 struct avctp_channel *control = session->control;
1625 struct avctp_pending_req *p;
1626 struct avctp_control_req *req;
1628 if (control == NULL)
1631 req = g_new0(struct avctp_control_req, 1);
1633 req->subunit = subunit;
1636 req->operands = g_memdup(operands, operand_count);
1637 req->operand_count = operand_count;
1638 req->user_data = user_data;
1640 p = pending_create(control, process_control, req, control_req_destroy);
1644 g_queue_push_tail(control->queue, p);
1646 if (control->process_id == 0)
1647 control->process_id = g_idle_add(process_queue, control);
1652 int avctp_send_browsing_req(struct avctp *session,
1653 uint8_t *operands, size_t operand_count,
1654 avctp_browsing_rsp_cb func, void *user_data)
1656 struct avctp_channel *browsing = session->browsing;
1657 struct avctp_pending_req *p;
1658 struct avctp_browsing_req *req;
1660 if (browsing == NULL)
1663 req = g_new0(struct avctp_browsing_req, 1);
1665 req->operands = g_memdup(operands, operand_count);
1666 req->operand_count = operand_count;
1667 req->user_data = user_data;
1669 p = pending_create(browsing, process_browsing, req,
1670 browsing_req_destroy);
1674 g_queue_push_tail(browsing->queue, p);
1676 /* Connection did not complete, delay process of the request */
1677 if (browsing->watch == 0)
1680 if (browsing->process_id == 0)
1681 browsing->process_id = g_idle_add(process_queue, browsing);
1686 static const char *op2str(uint8_t op)
1690 for (i = 0; key_map[i].name != NULL; i++) {
1691 if ((op & 0x7F) == key_map[i].avc)
1692 return key_map[i].name;
1698 static int avctp_passthrough_press(struct avctp *session, uint8_t op)
1700 uint8_t operands[2];
1702 DBG("%s", op2str(op));
1704 /* Button pressed */
1705 operands[0] = op & 0x7f;
1708 return avctp_send_req(session, AVC_CTYPE_CONTROL,
1709 AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
1710 operands, sizeof(operands),
1711 avctp_passthrough_rsp, NULL);
1714 static int avctp_passthrough_release(struct avctp *session, uint8_t op)
1716 uint8_t operands[2];
1718 DBG("%s", op2str(op));
1720 /* Button released */
1721 operands[0] = op | 0x80;
1724 return avctp_send_req(session, AVC_CTYPE_CONTROL,
1725 AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
1726 operands, sizeof(operands),
1730 static gboolean repeat_timeout(gpointer user_data)
1732 struct avctp *session = user_data;
1734 avctp_passthrough_release(session, session->key.op);
1735 #ifndef __TIZEN_PATCH__
1736 avctp_passthrough_press(session, session->key.op);
1744 static void release_pressed(struct avctp *session)
1746 #ifdef __TIZEN_PATCH__
1747 if (session->key.op != AVC_FAST_FORWARD && session->key.op != AVC_REWIND)
1749 avctp_passthrough_release(session, session->key.op);
1751 if (session->key.timer > 0)
1752 g_source_remove(session->key.timer);
1754 session->key.timer = 0;
1757 static bool set_pressed(struct avctp *session, uint8_t op)
1759 if (session->key.timer > 0) {
1760 if (session->key.op == op)
1762 release_pressed(session);
1765 if (op != AVC_FAST_FORWARD && op != AVC_REWIND)
1768 session->key.op = op;
1769 session->key.timer = g_timeout_add_seconds(AVC_PRESS_TIMEOUT,
1776 static gboolean avctp_passthrough_rsp(struct avctp *session, uint8_t code,
1777 uint8_t subunit, uint8_t *operands,
1778 size_t operand_count, void *user_data)
1780 if (code != AVC_CTYPE_ACCEPTED)
1783 if (set_pressed(session, operands[0]))
1786 avctp_passthrough_release(session, operands[0]);
1791 int avctp_send_passthrough(struct avctp *session, uint8_t op)
1793 /* Auto release if key pressed */
1794 if (session->key.timer > 0)
1795 release_pressed(session);
1797 return avctp_passthrough_press(session, op);
1799 #ifdef __TIZEN_PATCH__
1800 int avctp_send_release_passthrough(struct avctp *session, uint8_t op)
1804 if (op != AVC_FAST_FORWARD && op != AVC_REWIND)
1807 /* Auto release if key pressed */
1808 if (session->key.timer > 0)
1809 g_source_remove(session->key.timer);
1810 session->key.timer = 0;
1813 return avctp_passthrough_release(session, op);
1816 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
1817 uint8_t code, uint8_t subunit,
1818 uint8_t *operands, size_t operand_count)
1820 struct avctp_channel *control = session->control;
1822 if (control == NULL)
1825 return avctp_send(control, transaction, AVCTP_RESPONSE, code, subunit,
1826 AVC_OP_VENDORDEP, operands, operand_count);
1829 int avctp_send_vendordep_req(struct avctp *session, uint8_t code,
1830 uint8_t subunit, uint8_t *operands,
1831 size_t operand_count,
1832 avctp_rsp_cb func, void *user_data)
1834 return avctp_send_req(session, code, subunit, AVC_OP_VENDORDEP,
1835 operands, operand_count,
1839 unsigned int avctp_add_state_cb(struct btd_device *dev, avctp_state_cb cb,
1842 struct avctp_state_callback *state_cb;
1843 static unsigned int id = 0;
1845 state_cb = g_new(struct avctp_state_callback, 1);
1847 state_cb->dev = dev;
1848 state_cb->id = ++id;
1849 state_cb->user_data = user_data;
1851 callbacks = g_slist_append(callbacks, state_cb);
1853 return state_cb->id;
1856 gboolean avctp_remove_state_cb(unsigned int id)
1860 for (l = callbacks; l != NULL; l = l->next) {
1861 struct avctp_state_callback *cb = l->data;
1862 if (cb && cb->id == id) {
1863 callbacks = g_slist_remove(callbacks, cb);
1872 unsigned int avctp_register_passthrough_handler(struct avctp *session,
1873 avctp_passthrough_cb cb,
1876 struct avctp_channel *control = session->control;
1877 struct avctp_passthrough_handler *handler;
1878 static unsigned int id = 0;
1880 if (control == NULL || session->handler != NULL)
1883 handler = g_new(struct avctp_passthrough_handler, 1);
1885 handler->user_data = user_data;
1888 session->handler = handler;
1893 bool avctp_unregister_passthrough_handler(unsigned int id)
1897 for (l = servers; l; l = l->next) {
1898 struct avctp_server *server = l->data;
1901 for (s = server->sessions; s; s = s->next) {
1902 struct avctp *session = s->data;
1904 if (session->handler == NULL)
1907 if (session->handler->id == id) {
1908 g_free(session->handler);
1909 session->handler = NULL;
1918 unsigned int avctp_register_pdu_handler(struct avctp *session, uint8_t opcode,
1919 avctp_control_pdu_cb cb,
1922 struct avctp_channel *control = session->control;
1923 struct avctp_pdu_handler *handler;
1924 static unsigned int id = 0;
1926 if (control == NULL)
1929 handler = find_handler(control->handlers, opcode);
1933 handler = g_new(struct avctp_pdu_handler, 1);
1934 handler->opcode = opcode;
1936 handler->user_data = user_data;
1939 control->handlers = g_slist_append(control->handlers, handler);
1944 unsigned int avctp_register_browsing_pdu_handler(struct avctp *session,
1945 avctp_browsing_pdu_cb cb,
1947 GDestroyNotify destroy)
1949 struct avctp_channel *browsing = session->browsing;
1950 struct avctp_browsing_pdu_handler *handler;
1951 static unsigned int id = 0;
1953 if (browsing == NULL)
1956 if (browsing->handlers != NULL)
1959 handler = g_new(struct avctp_browsing_pdu_handler, 1);
1961 handler->user_data = user_data;
1963 handler->destroy = destroy;
1965 browsing->handlers = g_slist_append(browsing->handlers, handler);
1970 gboolean avctp_unregister_pdu_handler(unsigned int id)
1974 for (l = servers; l; l = l->next) {
1975 struct avctp_server *server = l->data;
1978 for (s = server->sessions; s; s = s->next) {
1979 struct avctp *session = s->data;
1980 struct avctp_channel *control = session->control;
1983 if (control == NULL)
1986 for (h = control->handlers; h; h = h->next) {
1987 struct avctp_pdu_handler *handler = h->data;
1989 if (handler->id != id)
1992 control->handlers = g_slist_remove(
2004 gboolean avctp_unregister_browsing_pdu_handler(unsigned int id)
2008 for (l = servers; l; l = l->next) {
2009 struct avctp_server *server = l->data;
2012 for (s = server->sessions; s; s = s->next) {
2013 struct avctp *session = s->data;
2014 struct avctp_channel *browsing = session->browsing;
2017 if (browsing == NULL)
2020 for (h = browsing->handlers; h; h = h->next) {
2021 struct avctp_browsing_pdu_handler *handler =
2024 if (handler->id != id)
2027 browsing->handlers = g_slist_remove(
2039 struct avctp *avctp_connect(struct btd_device *device)
2041 struct avctp *session;
2044 const bdaddr_t *src;
2046 session = avctp_get_internal(device);
2050 if (session->state > AVCTP_STATE_DISCONNECTED)
2053 avctp_set_state(session, AVCTP_STATE_CONNECTING, 0);
2055 src = btd_adapter_get_address(session->server->adapter);
2057 io = bt_io_connect(avctp_connect_cb, session, NULL, &err,
2058 BT_IO_OPT_SOURCE_BDADDR, src,
2059 BT_IO_OPT_DEST_BDADDR,
2060 device_get_address(session->device),
2061 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2062 BT_IO_OPT_PSM, AVCTP_CONTROL_PSM,
2065 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
2066 error("%s", err->message);
2071 session->control = avctp_channel_create(session, io, NULL);
2072 session->initiator = true;
2073 g_io_channel_unref(io);
2078 int avctp_connect_browsing(struct avctp *session)
2080 const bdaddr_t *src;
2084 if (session->state != AVCTP_STATE_CONNECTED)
2087 if (session->browsing != NULL)
2090 avctp_set_state(session, AVCTP_STATE_BROWSING_CONNECTING, 0);
2092 src = btd_adapter_get_address(session->server->adapter);
2094 io = bt_io_connect(avctp_connect_browsing_cb, session, NULL, &err,
2095 BT_IO_OPT_SOURCE_BDADDR, src,
2096 BT_IO_OPT_DEST_BDADDR,
2097 device_get_address(session->device),
2098 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
2099 BT_IO_OPT_PSM, AVCTP_BROWSING_PSM,
2100 BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
2103 error("%s", err->message);
2108 session->browsing = avctp_channel_create(session, io,
2109 avctp_destroy_browsing);
2110 g_io_channel_unref(io);
2115 void avctp_disconnect(struct avctp *session)
2117 if (session->state == AVCTP_STATE_DISCONNECTED)
2120 avctp_set_state(session, AVCTP_STATE_DISCONNECTED, -EIO);
2123 struct avctp *avctp_get(struct btd_device *device)
2125 return avctp_get_internal(device);
2128 bool avctp_is_initiator(struct avctp *session)
2130 return session->initiator;