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
38 #include <sys/types.h>
43 #include <dbus/dbus.h>
45 #include "bluetooth/bluetooth.h"
46 #include "bluetooth/sdp.h"
47 #include "bluetooth/sdp_lib.h"
50 #include "gdbus/gdbus.h"
52 #include "src/plugin.h"
53 #include "src/adapter.h"
54 #include "src/device.h"
55 #include "src/profile.h"
56 #include "src/service.h"
58 #include "src/error.h"
60 #include "src/dbus-common.h"
61 #include "src/shared/util.h"
67 #include "transport.h"
69 /* Company IDs for vendor dependent commands */
70 #define IEEEID_BTSIG 0x001958
73 #define AVRCP_STATUS_INVALID_COMMAND 0x00
74 #define AVRCP_STATUS_INVALID_PARAM 0x01
75 #define AVRCP_STATUS_PARAM_NOT_FOUND 0x02
76 #define AVRCP_STATUS_INTERNAL_ERROR 0x03
77 #define AVRCP_STATUS_SUCCESS 0x04
78 #define AVRCP_STATUS_OUT_OF_BOUNDS 0x0b
79 #define AVRCP_STATUS_INVALID_PLAYER_ID 0x11
80 #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE 0x12
81 #define AVRCP_STATUS_NO_AVAILABLE_PLAYERS 0x15
82 #define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED 0x16
85 #define AVRCP_PACKET_TYPE_SINGLE 0x00
86 #define AVRCP_PACKET_TYPE_START 0x01
87 #define AVRCP_PACKET_TYPE_CONTINUING 0x02
88 #define AVRCP_PACKET_TYPE_END 0x03
90 /* PDU types for metadata transfer */
91 #define AVRCP_GET_CAPABILITIES 0x10
92 #define AVRCP_LIST_PLAYER_ATTRIBUTES 0X11
93 #define AVRCP_LIST_PLAYER_VALUES 0x12
94 #define AVRCP_GET_CURRENT_PLAYER_VALUE 0x13
95 #define AVRCP_SET_PLAYER_VALUE 0x14
96 #define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15
97 #define AVRCP_GET_PLAYER_VALUE_TEXT 0x16
98 #define AVRCP_DISPLAYABLE_CHARSET 0x17
99 #define AVRCP_CT_BATTERY_STATUS 0x18
100 #define AVRCP_GET_ELEMENT_ATTRIBUTES 0x20
101 #define AVRCP_GET_PLAY_STATUS 0x30
102 #define AVRCP_REGISTER_NOTIFICATION 0x31
103 #define AVRCP_REQUEST_CONTINUING 0x40
104 #define AVRCP_ABORT_CONTINUING 0x41
105 #define AVRCP_SET_ABSOLUTE_VOLUME 0x50
106 #define AVRCP_SET_ADDRESSED_PLAYER 0x60
107 #define AVRCP_SET_BROWSED_PLAYER 0x70
108 #define AVRCP_GET_FOLDER_ITEMS 0x71
109 #define AVRCP_CHANGE_PATH 0x72
110 #define AVRCP_GET_ITEM_ATTRIBUTES 0x73
111 #define AVRCP_PLAY_ITEM 0x74
112 #define AVRCP_GET_TOTAL_NUMBER_OF_ITEMS 0x75
113 #define AVRCP_SEARCH 0x80
114 #define AVRCP_ADD_TO_NOW_PLAYING 0x90
115 #define AVRCP_GENERAL_REJECT 0xA0
117 /* Capabilities for AVRCP_GET_CAPABILITIES pdu */
118 #define CAP_COMPANY_ID 0x02
119 #define CAP_EVENTS_SUPPORTED 0x03
121 #define AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH 5
122 #define AVRCP_GET_CAPABILITIES_PARAM_LENGTH 1
124 #define AVRCP_FEATURE_CATEGORY_1 0x0001
125 #define AVRCP_FEATURE_CATEGORY_2 0x0002
126 #define AVRCP_FEATURE_CATEGORY_3 0x0004
127 #define AVRCP_FEATURE_CATEGORY_4 0x0008
128 #define AVRCP_FEATURE_PLAYER_SETTINGS 0x0010
129 #define AVRCP_FEATURE_BROWSING 0x0040
131 #define AVRCP_BATTERY_STATUS_NORMAL 0
132 #define AVRCP_BATTERY_STATUS_WARNING 1
133 #define AVRCP_BATTERY_STATUS_CRITICAL 2
134 #define AVRCP_BATTERY_STATUS_EXTERNAL 3
135 #define AVRCP_BATTERY_STATUS_FULL_CHARGE 4
137 #define AVRCP_CHARSET_UTF8 106
139 #define AVRCP_BROWSING_TIMEOUT 1
140 #ifdef __TIZEN_PATCH__
141 #define AVRCP_CT_VERSION 0x0103
142 #define AVRCP_TG_VERSION 0x0103
144 #define AVRCP_CT_VERSION 0x0106
145 #define AVRCP_TG_VERSION 0x0105
147 #define AVRCP_SCOPE_MEDIA_PLAYER_LIST 0x00
148 #define AVRCP_SCOPE_MEDIA_PLAYER_VFS 0x01
149 #define AVRCP_SCOPE_SEARCH 0x02
150 #define AVRCP_SCOPE_NOW_PLAYING 0x03
152 #if __BYTE_ORDER == __LITTLE_ENDIAN
154 struct avrcp_header {
155 uint8_t company_id[3];
157 uint8_t packet_type:2;
161 } __attribute__ ((packed));
162 #define AVRCP_HEADER_LENGTH 7
164 #elif __BYTE_ORDER == __BIG_ENDIAN
166 struct avrcp_header {
167 uint8_t company_id[3];
170 uint8_t packet_type:2;
173 } __attribute__ ((packed));
174 #define AVRCP_HEADER_LENGTH 7
177 #error "Unknown byte order"
180 #define AVRCP_MTU (AVC_MTU - AVC_HEADER_LENGTH)
181 #define AVRCP_PDU_MTU (AVRCP_MTU - AVRCP_HEADER_LENGTH)
183 struct avrcp_browsing_header {
187 } __attribute__ ((packed));
188 #define AVRCP_BROWSING_HEADER_LENGTH 3
190 struct get_folder_items_rsp {
192 uint16_t uid_counter;
195 } __attribute__ ((packed));
201 } __attribute__ ((packed));
208 uint8_t features[16];
212 } __attribute__ ((packed));
214 struct avrcp_server {
215 struct btd_adapter *adapter;
216 uint32_t tg_record_id;
217 uint32_t ct_record_id;
228 struct pending_list_items {
235 struct avrcp_player {
236 struct avrcp_server *server;
241 uint16_t uid_counter;
248 struct pending_list_items *p;
251 struct avrcp_player_cb *cb;
253 GDestroyNotify destroy;
257 struct avrcp_player *player;
264 struct avrcp_server *server;
266 struct btd_device *dev;
267 struct avrcp_data *target;
268 struct avrcp_data *controller;
270 const struct passthrough_handler *passthrough_handlers;
271 const struct control_pdu_handler *control_handlers;
273 unsigned int passthrough_id;
274 unsigned int control_id;
275 unsigned int browsing_id;
276 unsigned int browsing_timer;
277 uint16_t supported_events;
278 uint16_t registered_events;
280 uint8_t transaction_events[AVRCP_EVENT_LAST + 1];
281 struct pending_pdu *pending_pdu;
282 #ifdef __TIZEN_PATCH__
283 uint32_t playback_status_id;
287 struct passthrough_handler {
289 bool (*func) (struct avrcp *session);
292 struct control_pdu_handler {
295 uint8_t (*func) (struct avrcp *session, struct avrcp_header *pdu,
296 uint8_t transaction);
299 static GSList *servers = NULL;
300 static unsigned int avctp_id = 0;
302 #ifdef __TIZEN_PATCH__
303 #ifdef SUPPORT_AVRCP_TARGET
304 static uint16_t adapter_avrcp_tg_ver = 0;
306 #ifdef SUPPORT_AVRCP_CONTROL
307 static uint16_t adapter_avrcp_ct_ver = 0;
311 /* Default feature bit mask for media player as per avctp.c:key_map */
312 static const uint8_t features[16] = {
313 0xF8, 0xBF, 0xFF, 0xBF, 0x1F,
314 0xFB, 0x3F, 0x60, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00,
318 /* Company IDs supported by this device */
319 static uint32_t company_ids[] = {
323 static void avrcp_register_notification(struct avrcp *session, uint8_t event);
325 #ifdef __TIZEN_PATCH__
326 static GList *player_list_settings(struct avrcp_player *player);
327 void avrcp_stop_position_timer(void);
328 unsigned int pos_timer_id = 0;
331 #ifdef SUPPORT_AVRCP_CONTROL
332 static sdp_record_t *avrcp_ct_record(void)
334 sdp_list_t *svclass_id, *pfseq, *apseq, *apseq1, *root;
335 uuid_t root_uuid, l2cap, avctp, avrct, avrctr;
336 sdp_profile_desc_t profile[1];
337 sdp_list_t *aproto, *aproto1, *proto[2], *proto1[2];
338 sdp_record_t *record;
339 sdp_data_t *psm[2], *version, *features;
340 uint16_t lp = AVCTP_CONTROL_PSM, ap = AVCTP_BROWSING_PSM;
341 #ifdef __TIZEN_PATCH__
342 uint16_t avctp_ver = 0x0104;
344 #ifdef ENABLE_AVRCP_CATEGORY1
345 feat = AVRCP_FEATURE_CATEGORY_1;
347 #ifdef ENABLE_AVRCP_CATEGORY2
348 feat = feat | AVRCP_FEATURE_CATEGORY_2;
351 uint16_t avctp_ver = 0x0103;
352 uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
353 AVRCP_FEATURE_CATEGORY_2 |
354 AVRCP_FEATURE_CATEGORY_3 |
355 AVRCP_FEATURE_CATEGORY_4 |
356 AVRCP_FEATURE_BROWSING);
359 record = sdp_record_alloc();
363 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
364 root = sdp_list_append(NULL, &root_uuid);
365 sdp_set_browse_groups(record, root);
367 /* Service Class ID List */
368 sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID);
369 svclass_id = sdp_list_append(NULL, &avrct);
370 sdp_uuid16_create(&avrctr, AV_REMOTE_CONTROLLER_SVCLASS_ID);
371 svclass_id = sdp_list_append(svclass_id, &avrctr);
372 sdp_set_service_classes(record, svclass_id);
374 /* Protocol Descriptor List */
375 sdp_uuid16_create(&l2cap, L2CAP_UUID);
376 proto[0] = sdp_list_append(NULL, &l2cap);
377 psm[0] = sdp_data_alloc(SDP_UINT16, &lp);
378 proto[0] = sdp_list_append(proto[0], psm[0]);
379 apseq = sdp_list_append(NULL, proto[0]);
381 sdp_uuid16_create(&avctp, AVCTP_UUID);
382 proto[1] = sdp_list_append(NULL, &avctp);
383 version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
384 proto[1] = sdp_list_append(proto[1], version);
385 apseq = sdp_list_append(apseq, proto[1]);
387 aproto = sdp_list_append(NULL, apseq);
388 sdp_set_access_protos(record, aproto);
390 /* Additional Protocol Descriptor List */
391 sdp_uuid16_create(&l2cap, L2CAP_UUID);
392 proto1[0] = sdp_list_append(NULL, &l2cap);
393 psm[1] = sdp_data_alloc(SDP_UINT16, &ap);
394 proto1[0] = sdp_list_append(proto1[0], psm[1]);
395 apseq1 = sdp_list_append(NULL, proto1[0]);
397 sdp_uuid16_create(&avctp, AVCTP_UUID);
398 proto1[1] = sdp_list_append(NULL, &avctp);
399 proto1[1] = sdp_list_append(proto1[1], version);
400 apseq1 = sdp_list_append(apseq1, proto1[1]);
402 aproto1 = sdp_list_append(NULL, apseq1);
403 sdp_set_add_access_protos(record, aproto1);
405 /* Bluetooth Profile Descriptor List */
406 sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
407 profile[0].version = AVRCP_CT_VERSION;
408 #ifdef __TIZEN_PATCH__
409 adapter_avrcp_ct_ver = AVRCP_CT_VERSION;
411 pfseq = sdp_list_append(NULL, &profile[0]);
412 sdp_set_profile_descs(record, pfseq);
414 features = sdp_data_alloc(SDP_UINT16, &feat);
415 sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
417 sdp_set_info_attr(record, "AVRCP CT", NULL, NULL);
422 sdp_list_free(proto[0], NULL);
423 sdp_list_free(proto[1], NULL);
424 sdp_list_free(apseq, NULL);
425 sdp_list_free(proto1[0], NULL);
426 sdp_list_free(proto1[1], NULL);
427 sdp_list_free(aproto1, NULL);
428 sdp_list_free(apseq1, NULL);
429 sdp_list_free(pfseq, NULL);
430 sdp_list_free(aproto, NULL);
431 sdp_list_free(root, NULL);
432 sdp_list_free(svclass_id, NULL);
438 #ifdef SUPPORT_AVRCP_TARGET
439 static sdp_record_t *avrcp_tg_record(void)
441 sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
442 uuid_t root_uuid, l2cap, avctp, avrtg;
443 sdp_profile_desc_t profile[1];
444 sdp_list_t *aproto_control, *proto_control[2];
445 sdp_record_t *record;
446 sdp_data_t *psm_control, *version, *features, *psm_browsing;
447 #ifndef __TIZEN_PATCH__
448 sdp_list_t *aproto_browsing;
450 sdp_list_t *proto_browsing[2] = {0};
451 uint16_t lp = AVCTP_CONTROL_PSM;
452 uint16_t lp_browsing = AVCTP_BROWSING_PSM;
453 #ifdef __TIZEN_PATCH__
454 uint16_t avctp_ver = 0x0104;
456 #ifdef ENABLE_AVRCP_CATEGORY1
457 feat = AVRCP_FEATURE_CATEGORY_1 |
458 AVRCP_FEATURE_PLAYER_SETTINGS;
460 #ifdef ENABLE_AVRCP_CATEGORY2
461 feat = feat | AVRCP_FEATURE_CATEGORY_2;
464 uint16_t avctp_ver = 0x0103;
465 uint16_t feat = ( AVRCP_FEATURE_CATEGORY_1 |
466 AVRCP_FEATURE_CATEGORY_2 |
467 AVRCP_FEATURE_CATEGORY_3 |
468 AVRCP_FEATURE_CATEGORY_4 |
469 AVRCP_FEATURE_BROWSING |
470 AVRCP_FEATURE_PLAYER_SETTINGS );
472 record = sdp_record_alloc();
476 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
477 root = sdp_list_append(NULL, &root_uuid);
478 sdp_set_browse_groups(record, root);
480 /* Service Class ID List */
481 sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);
482 svclass_id = sdp_list_append(NULL, &avrtg);
483 sdp_set_service_classes(record, svclass_id);
485 /* Protocol Descriptor List */
486 sdp_uuid16_create(&l2cap, L2CAP_UUID);
487 proto_control[0] = sdp_list_append(NULL, &l2cap);
488 psm_control = sdp_data_alloc(SDP_UINT16, &lp);
489 proto_control[0] = sdp_list_append(proto_control[0], psm_control);
490 apseq = sdp_list_append(NULL, proto_control[0]);
492 sdp_uuid16_create(&avctp, AVCTP_UUID);
493 proto_control[1] = sdp_list_append(NULL, &avctp);
494 version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
495 proto_control[1] = sdp_list_append(proto_control[1], version);
496 apseq = sdp_list_append(apseq, proto_control[1]);
498 aproto_control = sdp_list_append(NULL, apseq);
499 sdp_set_access_protos(record, aproto_control);
500 proto_browsing[0] = sdp_list_append(NULL, &l2cap);
501 psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
502 proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
503 apseq_browsing = sdp_list_append(NULL, proto_browsing[0]);
505 proto_browsing[1] = sdp_list_append(NULL, &avctp);
506 proto_browsing[1] = sdp_list_append(proto_browsing[1], version);
507 apseq_browsing = sdp_list_append(apseq_browsing, proto_browsing[1]);
509 #ifndef __TIZEN_PATCH__
510 aproto_browsing = sdp_list_append(NULL, apseq_browsing);
511 sdp_set_add_access_protos(record, aproto_browsing);
514 /* Bluetooth Profile Descriptor List */
515 sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
516 profile[0].version = AVRCP_TG_VERSION;
517 #ifdef __TIZEN_PATCH__
518 adapter_avrcp_tg_ver = AVRCP_TG_VERSION;
520 pfseq = sdp_list_append(NULL, &profile[0]);
521 sdp_set_profile_descs(record, pfseq);
523 features = sdp_data_alloc(SDP_UINT16, &feat);
524 sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
526 sdp_set_info_attr(record, "AVRCP TG", NULL, NULL);
529 sdp_list_free(proto_browsing[0], NULL);
530 sdp_list_free(proto_browsing[1], NULL);
531 sdp_list_free(apseq_browsing, NULL);
532 #ifndef __TIZEN_PATCH__
533 sdp_list_free(aproto_browsing, NULL);
538 sdp_list_free(proto_control[0], NULL);
539 sdp_list_free(proto_control[1], NULL);
540 sdp_list_free(apseq, NULL);
541 sdp_list_free(aproto_control, NULL);
542 sdp_list_free(pfseq, NULL);
543 sdp_list_free(root, NULL);
544 sdp_list_free(svclass_id, NULL);
550 static unsigned int attr_get_max_val(uint8_t attr)
553 case AVRCP_ATTRIBUTE_EQUALIZER:
554 return AVRCP_EQUALIZER_ON;
555 case AVRCP_ATTRIBUTE_REPEAT_MODE:
556 #ifdef __TIZEN_PATCH__
557 return AVRCP_REPEAT_MODE_ALL;
559 return AVRCP_REPEAT_MODE_GROUP;
561 case AVRCP_ATTRIBUTE_SHUFFLE:
562 #ifdef __TIZEN_PATCH__
563 return AVRCP_SHUFFLE_ALL;
565 return AVRCP_SHUFFLE_GROUP;
567 case AVRCP_ATTRIBUTE_SCAN:
568 return AVRCP_SCAN_GROUP;
574 static const char *battery_status_to_str(uint8_t status)
577 case AVRCP_BATTERY_STATUS_NORMAL:
579 case AVRCP_BATTERY_STATUS_WARNING:
581 case AVRCP_BATTERY_STATUS_CRITICAL:
583 case AVRCP_BATTERY_STATUS_EXTERNAL:
585 case AVRCP_BATTERY_STATUS_FULL_CHARGE:
595 * Get three-byte Company_ID from incoming AVRCP message
597 static uint32_t get_company_id(const uint8_t cid[3])
599 return cid[0] << 16 | cid[1] << 8 | cid[2];
605 * Set three-byte Company_ID into outgoing AVRCP message
607 static void set_company_id(uint8_t cid[3], uint32_t cid_in)
609 cid[0] = (cid_in & 0xff0000) >> 16;
610 cid[1] = (cid_in & 0x00ff00) >> 8;
611 cid[2] = (cid_in & 0x0000ff);
614 static const char *attr_to_str(uint8_t attr)
617 case AVRCP_ATTRIBUTE_EQUALIZER:
619 case AVRCP_ATTRIBUTE_REPEAT_MODE:
621 case AVRCP_ATTRIBUTE_SHUFFLE:
623 case AVRCP_ATTRIBUTE_SCAN:
630 static int attrval_to_val(uint8_t attr, const char *value)
635 case AVRCP_ATTRIBUTE_EQUALIZER:
636 if (!strcmp(value, "off"))
637 ret = AVRCP_EQUALIZER_OFF;
638 else if (!strcmp(value, "on"))
639 ret = AVRCP_EQUALIZER_ON;
644 case AVRCP_ATTRIBUTE_REPEAT_MODE:
645 if (!strcmp(value, "off"))
646 ret = AVRCP_REPEAT_MODE_OFF;
647 else if (!strcmp(value, "singletrack"))
648 ret = AVRCP_REPEAT_MODE_SINGLE;
649 else if (!strcmp(value, "alltracks"))
650 ret = AVRCP_REPEAT_MODE_ALL;
651 else if (!strcmp(value, "group"))
652 ret = AVRCP_REPEAT_MODE_GROUP;
657 case AVRCP_ATTRIBUTE_SHUFFLE:
658 if (!strcmp(value, "off"))
659 ret = AVRCP_SHUFFLE_OFF;
660 else if (!strcmp(value, "alltracks"))
661 ret = AVRCP_SHUFFLE_ALL;
662 else if (!strcmp(value, "group"))
663 ret = AVRCP_SHUFFLE_GROUP;
668 case AVRCP_ATTRIBUTE_SCAN:
669 if (!strcmp(value, "off"))
670 ret = AVRCP_SCAN_OFF;
671 else if (!strcmp(value, "alltracks"))
672 ret = AVRCP_SCAN_ALL;
673 else if (!strcmp(value, "group"))
674 ret = AVRCP_SCAN_GROUP;
684 static int attr_to_val(const char *str)
686 if (!strcasecmp(str, "Equalizer"))
687 return AVRCP_ATTRIBUTE_EQUALIZER;
688 else if (!strcasecmp(str, "Repeat"))
689 return AVRCP_ATTRIBUTE_REPEAT_MODE;
690 else if (!strcasecmp(str, "Shuffle"))
691 return AVRCP_ATTRIBUTE_SHUFFLE;
692 else if (!strcasecmp(str, "Scan"))
693 return AVRCP_ATTRIBUTE_SCAN;
698 static int player_get_setting(struct avrcp_player *player, uint8_t id)
706 key = attr_to_str(id);
710 value = player->cb->get_setting(key, player->user_data);
714 return attrval_to_val(id, value);
717 static int play_status_to_val(const char *status)
719 if (!strcasecmp(status, "stopped"))
720 return AVRCP_PLAY_STATUS_STOPPED;
721 else if (!strcasecmp(status, "playing"))
722 return AVRCP_PLAY_STATUS_PLAYING;
723 else if (!strcasecmp(status, "paused"))
724 return AVRCP_PLAY_STATUS_PAUSED;
725 else if (!strcasecmp(status, "forward-seek"))
726 return AVRCP_PLAY_STATUS_FWD_SEEK;
727 else if (!strcasecmp(status, "reverse-seek"))
728 return AVRCP_PLAY_STATUS_REV_SEEK;
729 else if (!strcasecmp(status, "error"))
730 return AVRCP_PLAY_STATUS_ERROR;
735 void avrcp_player_event(struct avrcp_player *player, uint8_t id,
738 uint8_t buf[AVRCP_HEADER_LENGTH + 9];
739 struct avrcp_header *pdu = (void *) buf;
745 #ifdef __TIZEN_PATCH__
746 uint32_t *position_val = NULL;
750 if (player->sessions == NULL)
753 memset(buf, 0, sizeof(buf));
755 set_company_id(pdu->company_id, IEEEID_BTSIG);
757 pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
761 if (id != AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED && player->changed_id) {
762 code = AVC_CTYPE_REJECTED;
764 pdu->params[0] = AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED;
768 code = AVC_CTYPE_CHANGED;
772 case AVRCP_EVENT_STATUS_CHANGED:
774 pdu->params[1] = play_status_to_val(data);
777 case AVRCP_EVENT_TRACK_CHANGED:
779 memcpy(&pdu->params[1], data, sizeof(uint64_t));
782 case AVRCP_EVENT_TRACK_REACHED_END:
783 case AVRCP_EVENT_TRACK_REACHED_START:
786 case AVRCP_EVENT_SETTINGS_CHANGED:
788 #ifdef __TIZEN_PATCH__
789 settings = player_list_settings(player);
790 pdu->params[1] = g_list_length(settings);
791 for (; settings; settings = settings->next) {
792 const char *key = settings->data;
794 attr = attr_to_val(key);
798 val = player_get_setting(player, attr);
802 pdu->params[size++] = attr;
803 pdu->params[size++] = val;
808 attr = attr_to_val(data);
812 val = player_get_setting(player, attr);
816 pdu->params[size++] = attr;
817 pdu->params[size++] = val;
818 #endif /* __TIZEN__PATCH__ */
820 #ifdef __TIZEN_PATCH__
821 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
823 position_val = (uint32_t *) data;
824 *position_val = (*position_val & 0x000000ff) << 24 |
825 (*position_val & 0x0000ff00) << 8 |
826 (*position_val & 0x00ff0000) >> 8 |
827 (*position_val & 0xff000000) >> 24;
828 memcpy(&pdu->params[1], position_val, sizeof(uint32_t));
831 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
833 memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
834 memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
836 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
840 error("Unknown event %u", id);
845 pdu->params_len = htons(size);
846 #ifdef __TIZEN_PATCH__
847 if (id == AVRCP_EVENT_PLAYBACK_POS_CHANGED &&
849 /* Remove the timer function which was added for register notification.
850 * As we are sending changed event eariler then time interval.
852 DBG("Removing the timer function added by register notification");
853 g_source_remove(pos_timer_id);
858 for (l = player->sessions; l; l = l->next) {
859 struct avrcp *session = l->data;
862 if (!(session->registered_events & (1 << id)))
865 err = avctp_send_vendordep(session->conn,
866 session->transaction_events[id],
867 code, AVC_SUBUNIT_PANEL,
868 buf, size + AVRCP_HEADER_LENGTH);
873 /* Unregister event as per AVRCP 1.3 spec, section 5.4.2 */
874 session->registered_events ^= 1 << id;
880 static const char *metadata_to_str(uint32_t id)
883 case AVRCP_MEDIA_ATTRIBUTE_TITLE:
885 case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
887 case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
889 case AVRCP_MEDIA_ATTRIBUTE_GENRE:
891 case AVRCP_MEDIA_ATTRIBUTE_TRACK:
892 return "TrackNumber";
893 case AVRCP_MEDIA_ATTRIBUTE_N_TRACKS:
894 return "NumberOfTracks";
895 case AVRCP_MEDIA_ATTRIBUTE_DURATION:
902 static const char *player_get_metadata(struct avrcp_player *player,
907 key = metadata_to_str(id);
912 return player->cb->get_metadata(key, player->user_data);
914 if (id == AVRCP_MEDIA_ATTRIBUTE_TITLE)
920 static uint16_t player_write_media_attribute(struct avrcp_player *player,
921 uint32_t id, uint8_t *buf,
927 const char *value = NULL;
931 value = player_get_metadata(player, id);
937 attr_len = strlen(value);
938 value = ((char *) value) + *offset;
939 len = attr_len - *offset;
941 if (len > AVRCP_PDU_MTU - *pos) {
942 len = AVRCP_PDU_MTU - *pos;
948 memcpy(&buf[*pos], value, len);
954 static GList *player_fill_media_attribute(struct avrcp_player *player,
955 GList *attr_ids, uint8_t *buf,
956 uint16_t *pos, uint16_t *offset)
958 struct media_attribute_header {
965 for (l = attr_ids; l != NULL; l = g_list_delete_link(l, l)) {
966 uint32_t attr = GPOINTER_TO_UINT(l->data);
970 if (*pos + sizeof(*hdr) >= AVRCP_PDU_MTU)
973 hdr = (void *) &buf[*pos];
974 hdr->id = htonl(attr);
975 /* Always use UTF-8 */
976 hdr->charset = htons(AVRCP_CHARSET_UTF8);
977 *pos += sizeof(*hdr);
980 attr_len = player_write_media_attribute(player, attr, buf,
984 hdr->len = htons(attr_len);
993 static struct pending_pdu *pending_pdu_new(uint8_t pdu_id, GList *attr_ids,
996 struct pending_pdu *pending = g_new(struct pending_pdu, 1);
998 pending->pdu_id = pdu_id;
999 pending->attr_ids = attr_ids;
1000 pending->offset = offset;
1005 static gboolean session_abort_pending_pdu(struct avrcp *session)
1007 if (session->pending_pdu == NULL)
1010 g_list_free(session->pending_pdu->attr_ids);
1011 g_free(session->pending_pdu);
1012 session->pending_pdu = NULL;
1017 static const char *attrval_to_str(uint8_t attr, uint8_t value)
1020 case AVRCP_ATTRIBUTE_EQUALIZER:
1022 case AVRCP_EQUALIZER_ON:
1024 case AVRCP_EQUALIZER_OFF:
1029 case AVRCP_ATTRIBUTE_REPEAT_MODE:
1031 case AVRCP_REPEAT_MODE_OFF:
1033 case AVRCP_REPEAT_MODE_SINGLE:
1034 return "singletrack";
1035 case AVRCP_REPEAT_MODE_ALL:
1037 #ifndef __TIZEN_PATCH__
1038 case AVRCP_REPEAT_MODE_GROUP:
1044 /* Shuffle and scan have the same values */
1045 case AVRCP_ATTRIBUTE_SHUFFLE:
1046 case AVRCP_ATTRIBUTE_SCAN:
1048 case AVRCP_SCAN_OFF:
1050 case AVRCP_SCAN_ALL:
1052 #ifndef __TIZEN_PATCH__
1053 case AVRCP_SCAN_GROUP:
1064 static int player_set_setting(struct avrcp_player *player, uint8_t id,
1067 const char *key, *value;
1069 key = attr_to_str(id);
1073 value = attrval_to_str(id, val);
1080 return player->cb->set_setting(key, value, player->user_data);
1083 static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
1084 struct avrcp_header *pdu,
1085 uint8_t transaction)
1087 uint16_t len = ntohs(pdu->params_len);
1093 DBG("id=%u", pdu->params[0]);
1095 switch (pdu->params[0]) {
1096 case CAP_COMPANY_ID:
1097 for (i = 0; i < G_N_ELEMENTS(company_ids); i++) {
1098 set_company_id(&pdu->params[2 + i * 3],
1102 pdu->params_len = htons(2 + (3 * G_N_ELEMENTS(company_ids)));
1103 pdu->params[1] = G_N_ELEMENTS(company_ids);
1105 return AVC_CTYPE_STABLE;
1106 case CAP_EVENTS_SUPPORTED:
1108 for (i = 1; i <= AVRCP_EVENT_LAST; i++) {
1109 if (session->supported_events & (1 << i)) {
1111 pdu->params[pdu->params[1] + 1] = i;
1115 pdu->params_len = htons(2 + pdu->params[1]);
1116 return AVC_CTYPE_STABLE;
1120 pdu->params_len = htons(1);
1121 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1123 return AVC_CTYPE_REJECTED;
1126 static struct avrcp_player *target_get_player(struct avrcp *session)
1128 if (!session->target)
1131 return session->target->player;
1134 static uint8_t avrcp_handle_list_player_attributes(struct avrcp *session,
1135 struct avrcp_header *pdu,
1136 uint8_t transaction)
1138 struct avrcp_player *player = target_get_player(session);
1139 uint16_t len = ntohs(pdu->params_len);
1143 pdu->params_len = htons(1);
1144 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1145 return AVC_CTYPE_REJECTED;
1151 for (i = 1; i <= AVRCP_ATTRIBUTE_SCAN; i++) {
1152 if (player_get_setting(player, i) < 0)
1156 pdu->params[len] = i;
1160 pdu->params[0] = len;
1161 pdu->params_len = htons(len + 1);
1163 return AVC_CTYPE_STABLE;
1166 static uint8_t avrcp_handle_list_player_values(struct avrcp *session,
1167 struct avrcp_header *pdu,
1168 uint8_t transaction)
1170 struct avrcp_player *player = target_get_player(session);
1171 uint16_t len = ntohs(pdu->params_len);
1177 if (player_get_setting(player, pdu->params[0]) < 0)
1180 len = attr_get_max_val(pdu->params[0]);
1182 for (i = 1; i <= len; i++)
1185 pdu->params[0] = len;
1186 pdu->params_len = htons(len + 1);
1188 return AVC_CTYPE_STABLE;
1191 pdu->params_len = htons(1);
1192 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1193 return AVC_CTYPE_REJECTED;
1196 static uint32_t str_to_metadata(const char *str)
1198 if (strcasecmp(str, "Title") == 0)
1199 return AVRCP_MEDIA_ATTRIBUTE_TITLE;
1200 else if (strcasecmp(str, "Artist") == 0)
1201 return AVRCP_MEDIA_ATTRIBUTE_ARTIST;
1202 else if (strcasecmp(str, "Album") == 0)
1203 return AVRCP_MEDIA_ATTRIBUTE_ALBUM;
1204 else if (strcasecmp(str, "Genre") == 0)
1205 return AVRCP_MEDIA_ATTRIBUTE_GENRE;
1206 else if (strcasecmp(str, "TrackNumber") == 0)
1207 return AVRCP_MEDIA_ATTRIBUTE_TRACK;
1208 else if (strcasecmp(str, "NumberOfTracks") == 0)
1209 return AVRCP_MEDIA_ATTRIBUTE_N_TRACKS;
1210 else if (strcasecmp(str, "Duration") == 0)
1211 return AVRCP_MEDIA_ATTRIBUTE_DURATION;
1216 static GList *player_list_metadata(struct avrcp_player *player)
1218 GList *l, *attrs = NULL;
1221 return g_list_prepend(NULL,
1222 GUINT_TO_POINTER(AVRCP_MEDIA_ATTRIBUTE_TITLE));
1224 l = player->cb->list_metadata(player->user_data);
1225 for (; l; l = l->next) {
1226 const char *key = l->data;
1228 attrs = g_list_append(attrs,
1229 GUINT_TO_POINTER(str_to_metadata(key)));
1235 static uint8_t avrcp_handle_get_element_attributes(struct avrcp *session,
1236 struct avrcp_header *pdu,
1237 uint8_t transaction)
1239 struct avrcp_player *player = target_get_player(session);
1240 uint16_t len = ntohs(pdu->params_len);
1241 uint64_t identifier = get_le64(&pdu->params[0]);
1247 if (len < 9 || identifier != 0)
1250 nattr = pdu->params[8];
1252 if (len < nattr * sizeof(uint32_t) + 1)
1257 * Return all available information, at least
1258 * title must be returned if there's a track selected.
1260 attr_ids = player_list_metadata(player);
1261 len = g_list_length(attr_ids);
1264 for (i = 0, len = 0, attr_ids = NULL; i < nattr; i++) {
1267 id = get_be32(&pdu->params[9] + (i * sizeof(id)));
1269 /* Don't add invalid attributes */
1270 if (id == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
1271 id > AVRCP_MEDIA_ATTRIBUTE_LAST)
1275 attr_ids = g_list_prepend(attr_ids,
1276 GUINT_TO_POINTER(id));
1279 attr_ids = g_list_reverse(attr_ids);
1285 session_abort_pending_pdu(session);
1288 attr_ids = player_fill_media_attribute(player, attr_ids, pdu->params,
1291 if (attr_ids != NULL) {
1292 session->pending_pdu = pending_pdu_new(pdu->pdu_id, attr_ids,
1294 pdu->packet_type = AVRCP_PACKET_TYPE_START;
1297 pdu->params[0] = len;
1298 pdu->params_len = htons(pos);
1300 return AVC_CTYPE_STABLE;
1302 pdu->params_len = htons(1);
1303 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1304 return AVC_CTYPE_REJECTED;
1307 static uint8_t avrcp_handle_get_current_player_value(struct avrcp *session,
1308 struct avrcp_header *pdu,
1309 uint8_t transaction)
1311 struct avrcp_player *player = target_get_player(session);
1312 uint16_t len = ntohs(pdu->params_len);
1316 if (len <= 1 || pdu->params[0] != len - 1)
1320 * Save a copy of requested settings because we can override them
1323 settings = g_memdup(&pdu->params[1], pdu->params[0]);
1327 * From sec. 5.7 of AVRCP 1.3 spec, we should igore non-existent IDs
1328 * and send a response with the existent ones. Only if all IDs are
1329 * non-existent we should send an error.
1331 for (i = 0; i < pdu->params[0]; i++) {
1334 if (settings[i] < AVRCP_ATTRIBUTE_EQUALIZER ||
1335 settings[i] > AVRCP_ATTRIBUTE_SCAN) {
1336 DBG("Ignoring %u", settings[i]);
1340 val = player_get_setting(player, settings[i]);
1344 pdu->params[++len] = settings[i];
1345 pdu->params[++len] = val;
1351 pdu->params[0] = len / 2;
1352 pdu->params_len = htons(len + 1);
1354 return AVC_CTYPE_STABLE;
1357 error("No valid attributes in request");
1360 pdu->params_len = htons(1);
1361 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1363 return AVC_CTYPE_REJECTED;
1366 static uint8_t avrcp_handle_set_player_value(struct avrcp *session,
1367 struct avrcp_header *pdu,
1368 uint8_t transaction)
1370 struct avrcp_player *player = target_get_player(session);
1371 uint16_t len = ntohs(pdu->params_len);
1375 if (len < 3 || len > 2 * pdu->params[0] + 1U || player == NULL)
1379 * From sec. 5.7 of AVRCP 1.3 spec, we should igore non-existent IDs
1380 * and set the existent ones. Sec. 5.2.4 is not clear however how to
1381 * indicate that a certain ID was not accepted. If at least one
1382 * attribute is valid, we respond with no parameters. Otherwise an
1383 * AVRCP_STATUS_INVALID_PARAM is sent.
1385 for (len = 0, i = 0, param = &pdu->params[1]; i < pdu->params[0];
1387 if (player_set_setting(player, param[0], param[1]) < 0)
1394 pdu->params_len = 0;
1396 return AVC_CTYPE_ACCEPTED;
1400 pdu->params_len = htons(1);
1401 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1402 return AVC_CTYPE_REJECTED;
1405 static uint8_t avrcp_handle_displayable_charset(struct avrcp *session,
1406 struct avrcp_header *pdu,
1407 uint8_t transaction)
1409 uint16_t len = ntohs(pdu->params_len);
1412 pdu->params_len = htons(1);
1413 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1414 return AVC_CTYPE_REJECTED;
1418 * We acknowledge the commands, but we always use UTF-8 for
1419 * encoding since CT is obliged to support it.
1421 pdu->params_len = 0;
1422 return AVC_CTYPE_STABLE;
1425 static uint8_t avrcp_handle_ct_battery_status(struct avrcp *session,
1426 struct avrcp_header *pdu,
1427 uint8_t transaction)
1429 uint16_t len = ntohs(pdu->params_len);
1435 valstr = battery_status_to_str(pdu->params[0]);
1439 pdu->params_len = 0;
1441 return AVC_CTYPE_STABLE;
1444 pdu->params_len = htons(1);
1445 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1446 return AVC_CTYPE_REJECTED;
1449 static uint32_t player_get_position(struct avrcp_player *player)
1454 return player->cb->get_position(player->user_data);
1457 static uint32_t player_get_duration(struct avrcp_player *player)
1464 num = player->cb->get_duration(player->user_data);
1471 static uint8_t player_get_status(struct avrcp_player *player)
1476 return AVRCP_PLAY_STATUS_STOPPED;
1478 value = player->cb->get_status(player->user_data);
1480 return AVRCP_PLAY_STATUS_STOPPED;
1482 return play_status_to_val(value);
1485 static uint16_t player_get_id(struct avrcp_player *player)
1493 static uint16_t player_get_uid_counter(struct avrcp_player *player)
1498 return player->uid_counter;
1501 static uint8_t avrcp_handle_get_play_status(struct avrcp *session,
1502 struct avrcp_header *pdu,
1503 uint8_t transaction)
1505 struct avrcp_player *player = target_get_player(session);
1506 uint16_t len = ntohs(pdu->params_len);
1511 pdu->params_len = htons(1);
1512 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1513 return AVC_CTYPE_REJECTED;
1516 position = player_get_position(player);
1517 duration = player_get_duration(player);
1519 position = htonl(position);
1520 duration = htonl(duration);
1522 memcpy(&pdu->params[0], &duration, 4);
1523 memcpy(&pdu->params[4], &position, 4);
1524 pdu->params[8] = player_get_status(player);
1526 pdu->params_len = htons(9);
1528 return AVC_CTYPE_STABLE;
1531 static uint64_t player_get_uid(struct avrcp_player *player)
1536 return player->cb->get_uid(player->user_data);
1539 static GList *player_list_settings(struct avrcp_player *player)
1544 return player->cb->list_settings(player->user_data);
1547 #ifdef __TIZEN_PATCH__
1548 static uint32_t player_get_playback_position(struct avrcp_player *player)
1553 return player->cb->get_position(player->user_data);
1557 static bool avrcp_handle_play(struct avrcp *session)
1559 struct avrcp_player *player = target_get_player(session);
1564 return player->cb->play(player->user_data);
1567 static bool avrcp_handle_stop(struct avrcp *session)
1569 struct avrcp_player *player = target_get_player(session);
1574 return player->cb->stop(player->user_data);
1577 static bool avrcp_handle_pause(struct avrcp *session)
1579 struct avrcp_player *player = target_get_player(session);
1584 return player->cb->pause(player->user_data);
1587 static bool avrcp_handle_next(struct avrcp *session)
1589 struct avrcp_player *player = target_get_player(session);
1594 return player->cb->next(player->user_data);
1597 static bool avrcp_handle_previous(struct avrcp *session)
1599 struct avrcp_player *player = target_get_player(session);
1604 return player->cb->previous(player->user_data);
1607 static const struct passthrough_handler passthrough_handlers[] = {
1608 { AVC_PLAY, avrcp_handle_play },
1609 { AVC_STOP, avrcp_handle_stop },
1610 { AVC_PAUSE, avrcp_handle_pause },
1611 { AVC_FORWARD, avrcp_handle_next },
1612 { AVC_BACKWARD, avrcp_handle_previous },
1616 static bool handle_passthrough(struct avctp *conn, uint8_t op, bool pressed,
1619 struct avrcp *session = user_data;
1620 const struct passthrough_handler *handler;
1622 for (handler = session->passthrough_handlers; handler->func;
1624 if (handler->op == op)
1628 if (handler->func == NULL)
1631 /* Do not trigger handler on release */
1635 return handler->func(session);
1638 #ifdef __TIZEN_PATCH__
1639 void avrcp_stop_position_timer(void)
1641 if (pos_timer_id > 0) {
1642 DBG("Removing position timer id");
1643 g_source_remove(pos_timer_id);
1647 gboolean send_playback_position_event(gpointer user_data)
1649 struct avrcp_player *player = user_data;
1650 uint32_t playback_position;
1651 uint8_t play_status;
1653 play_status = player_get_status(player);
1654 if (play_status != AVRCP_PLAY_STATUS_PLAYING)
1657 playback_position = player_get_playback_position(player);
1659 avrcp_player_event(player, AVRCP_EVENT_PLAYBACK_POS_CHANGED,
1660 &playback_position);
1665 static uint8_t avrcp_handle_register_notification(struct avrcp *session,
1666 struct avrcp_header *pdu,
1667 uint8_t transaction)
1669 struct avrcp_player *player = target_get_player(session);
1670 struct btd_device *dev = session->dev;
1671 uint16_t len = ntohs(pdu->params_len);
1673 #ifdef __TIZEN_PATCH__
1674 uint32_t playback_interval;
1675 uint32_t playback_position;
1676 uint8_t play_status;
1681 * 1 byte for EventID, 4 bytes for Playback interval but the latest
1682 * one is applicable only for EVENT_PLAYBACK_POS_CHANGED. See AVRCP
1683 * 1.3 spec, section 5.4.2.
1688 /* Check if event is supported otherwise reject */
1689 if (!(session->supported_events & (1 << pdu->params[0])))
1692 switch (pdu->params[0]) {
1693 case AVRCP_EVENT_STATUS_CHANGED:
1695 pdu->params[1] = player_get_status(player);
1698 case AVRCP_EVENT_TRACK_CHANGED:
1700 uid = player_get_uid(player);
1701 memcpy(&pdu->params[1], &uid, sizeof(uint64_t));
1704 case AVRCP_EVENT_TRACK_REACHED_END:
1705 case AVRCP_EVENT_TRACK_REACHED_START:
1708 case AVRCP_EVENT_SETTINGS_CHANGED:
1710 settings = player_list_settings(player);
1712 pdu->params[len++] = g_list_length(settings);
1713 for (; settings; settings = settings->next) {
1714 const char *key = settings->data;
1718 attr = attr_to_val(key);
1722 val = player_get_setting(player, attr);
1726 pdu->params[len++] = attr;
1727 pdu->params[len++] = val;
1730 g_list_free(settings);
1733 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
1735 bt_put_be16(player_get_id(player), &pdu->params[1]);
1736 bt_put_be16(player_get_uid_counter(player), &pdu->params[3]);
1738 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
1741 case AVRCP_EVENT_VOLUME_CHANGED:
1742 pdu->params[1] = media_transport_get_device_volume(dev);
1743 if (pdu->params[1] > 127)
1749 #ifdef __TIZEN_PATCH__
1750 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
1753 /* time interval in seconds at which the change in playback position
1754 shall be notified */
1755 memcpy(&playback_interval, &pdu->params[1], sizeof(uint32_t));
1756 playback_interval = ((playback_interval>>24)&0xff) |
1757 ((playback_interval<<8)&0xff0000) |
1758 ((playback_interval>>8)&0xff00) |
1759 ((playback_interval<<24)&0xff000000);
1761 play_status = player_get_status(player);
1763 if (play_status != AVRCP_PLAY_STATUS_PLAYING) {
1764 DBG("Play Pos Changed Event is skipped(%d)", play_status);
1766 DBG("Playback interval : %d secs", playback_interval);
1767 pos_timer_id = g_timeout_add_seconds(
1769 send_playback_position_event, player);
1772 /* retrieve current playback position for interim response */
1773 playback_position = player_get_playback_position(player);
1774 playback_position = (playback_position & 0x000000ff) << 24 |
1775 (playback_position & 0x0000ff00) << 8 |
1776 (playback_position & 0x00ff0000) >> 8 |
1777 (playback_position & 0xff000000) >> 24;
1778 memcpy(&pdu->params[1], &playback_position, sizeof(uint32_t));
1784 /* All other events are not supported yet */
1788 /* Register event and save the transaction used */
1789 session->registered_events |= (1 << pdu->params[0]);
1790 session->transaction_events[pdu->params[0]] = transaction;
1792 pdu->params_len = htons(len);
1794 return AVC_CTYPE_INTERIM;
1797 pdu->params_len = htons(1);
1798 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1799 return AVC_CTYPE_REJECTED;
1802 static uint8_t avrcp_handle_request_continuing(struct avrcp *session,
1803 struct avrcp_header *pdu,
1804 uint8_t transaction)
1806 struct avrcp_player *player = target_get_player(session);
1807 uint16_t len = ntohs(pdu->params_len);
1808 struct pending_pdu *pending;
1810 if (len != 1 || session->pending_pdu == NULL)
1813 pending = session->pending_pdu;
1815 if (pending->pdu_id != pdu->params[0])
1820 pending->attr_ids = player_fill_media_attribute(player,
1824 pdu->pdu_id = pending->pdu_id;
1826 if (pending->attr_ids == NULL) {
1827 g_free(session->pending_pdu);
1828 session->pending_pdu = NULL;
1829 pdu->packet_type = AVRCP_PACKET_TYPE_END;
1831 pdu->packet_type = AVRCP_PACKET_TYPE_CONTINUING;
1834 pdu->params_len = htons(len);
1836 return AVC_CTYPE_STABLE;
1838 pdu->params_len = htons(1);
1839 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1840 return AVC_CTYPE_REJECTED;
1843 static uint8_t avrcp_handle_abort_continuing(struct avrcp *session,
1844 struct avrcp_header *pdu,
1845 uint8_t transaction)
1847 uint16_t len = ntohs(pdu->params_len);
1848 struct pending_pdu *pending;
1850 if (len != 1 || session->pending_pdu == NULL)
1853 pending = session->pending_pdu;
1855 if (pending->pdu_id != pdu->params[0])
1858 session_abort_pending_pdu(session);
1859 pdu->params_len = 0;
1861 return AVC_CTYPE_ACCEPTED;
1864 pdu->params_len = htons(1);
1865 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1866 return AVC_CTYPE_REJECTED;
1869 static uint8_t avrcp_handle_set_absolute_volume(struct avrcp *session,
1870 struct avrcp_header *pdu,
1871 uint8_t transaction)
1873 uint16_t len = ntohs(pdu->params_len);
1880 volume = pdu->params[0] & 0x7F;
1882 media_transport_update_device_volume(session->dev, volume);
1884 return AVC_CTYPE_ACCEPTED;
1887 pdu->params_len = htons(1);
1888 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1889 return AVC_CTYPE_REJECTED;
1892 static struct avrcp_player *find_tg_player(struct avrcp *session, uint16_t id)
1894 struct avrcp_server *server = session->server;
1897 for (l = server->players; l; l = l->next) {
1898 struct avrcp_player *player = l->data;
1900 if (player->id == id)
1907 static gboolean notify_addressed_player_changed(gpointer user_data)
1909 struct avrcp_player *player = user_data;
1910 uint8_t events[6] = { AVRCP_EVENT_STATUS_CHANGED,
1911 AVRCP_EVENT_TRACK_CHANGED,
1912 AVRCP_EVENT_TRACK_REACHED_START,
1913 AVRCP_EVENT_TRACK_REACHED_END,
1914 AVRCP_EVENT_SETTINGS_CHANGED,
1915 AVRCP_EVENT_PLAYBACK_POS_CHANGED
1919 avrcp_player_event(player, AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED, NULL);
1922 * TG shall complete all player specific
1923 * notifications with AV/C C-Type REJECTED
1924 * with error code as Addressed Player Changed.
1926 for (i = 0; i < sizeof(events); i++)
1927 avrcp_player_event(player, events[i], NULL);
1929 player->changed_id = 0;
1934 static uint8_t avrcp_handle_set_addressed_player(struct avrcp *session,
1935 struct avrcp_header *pdu,
1936 uint8_t transaction)
1938 struct avrcp_player *player;
1939 uint16_t len = ntohs(pdu->params_len);
1940 uint16_t player_id = 0;
1944 status = AVRCP_STATUS_INVALID_PARAM;
1948 player_id = bt_get_be16(&pdu->params[0]);
1949 player = find_tg_player(session, player_id);
1950 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
1953 player->addressed = true;
1954 status = AVRCP_STATUS_SUCCESS;
1955 pdu->params_len = htons(len);
1956 pdu->params[0] = status;
1958 status = AVRCP_STATUS_INVALID_PLAYER_ID;
1962 /* Don't emit player changed immediately since PTS expect the
1963 * response of SetAddressedPlayer before the event.
1965 player->changed_id = g_idle_add(notify_addressed_player_changed,
1968 return AVC_CTYPE_ACCEPTED;
1971 pdu->params_len = htons(sizeof(status));
1972 pdu->params[0] = status;
1973 return AVC_CTYPE_REJECTED;
1976 static const struct control_pdu_handler control_handlers[] = {
1977 { AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
1978 avrcp_handle_get_capabilities },
1979 { AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
1980 avrcp_handle_list_player_attributes },
1981 { AVRCP_LIST_PLAYER_VALUES, AVC_CTYPE_STATUS,
1982 avrcp_handle_list_player_values },
1983 { AVRCP_GET_ELEMENT_ATTRIBUTES, AVC_CTYPE_STATUS,
1984 avrcp_handle_get_element_attributes },
1985 { AVRCP_GET_CURRENT_PLAYER_VALUE, AVC_CTYPE_STATUS,
1986 avrcp_handle_get_current_player_value },
1987 { AVRCP_SET_PLAYER_VALUE, AVC_CTYPE_CONTROL,
1988 avrcp_handle_set_player_value },
1989 { AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, AVC_CTYPE_STATUS,
1991 { AVRCP_GET_PLAYER_VALUE_TEXT, AVC_CTYPE_STATUS,
1993 { AVRCP_DISPLAYABLE_CHARSET, AVC_CTYPE_STATUS,
1994 avrcp_handle_displayable_charset },
1995 { AVRCP_CT_BATTERY_STATUS, AVC_CTYPE_STATUS,
1996 avrcp_handle_ct_battery_status },
1997 { AVRCP_GET_PLAY_STATUS, AVC_CTYPE_STATUS,
1998 avrcp_handle_get_play_status },
1999 { AVRCP_REGISTER_NOTIFICATION, AVC_CTYPE_NOTIFY,
2000 avrcp_handle_register_notification },
2001 { AVRCP_SET_ABSOLUTE_VOLUME, AVC_CTYPE_CONTROL,
2002 avrcp_handle_set_absolute_volume },
2003 { AVRCP_REQUEST_CONTINUING, AVC_CTYPE_CONTROL,
2004 avrcp_handle_request_continuing },
2005 { AVRCP_ABORT_CONTINUING, AVC_CTYPE_CONTROL,
2006 avrcp_handle_abort_continuing },
2007 { AVRCP_SET_ADDRESSED_PLAYER, AVC_CTYPE_CONTROL,
2008 avrcp_handle_set_addressed_player },
2012 /* handle vendordep pdu inside an avctp packet */
2013 static size_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
2014 uint8_t *code, uint8_t *subunit,
2015 uint8_t *operands, size_t operand_count,
2018 struct avrcp *session = user_data;
2019 const struct control_pdu_handler *handler;
2020 struct avrcp_header *pdu = (void *) operands;
2021 uint32_t company_id = get_company_id(pdu->company_id);
2023 if (company_id != IEEEID_BTSIG) {
2024 *code = AVC_CTYPE_NOT_IMPLEMENTED;
2028 DBG("AVRCP PDU 0x%02X, company 0x%06X len 0x%04X",
2029 pdu->pdu_id, company_id, ntohs(pdu->params_len));
2031 pdu->packet_type = 0;
2034 if (operand_count < AVRCP_HEADER_LENGTH) {
2035 pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
2039 for (handler = session->control_handlers; handler->pdu_id; handler++) {
2040 if (handler->pdu_id == pdu->pdu_id)
2044 if (handler->pdu_id != pdu->pdu_id || handler->code != *code) {
2045 pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
2049 if (!handler->func) {
2050 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
2054 *code = handler->func(session, pdu, transaction);
2056 if (*code != AVC_CTYPE_REJECTED &&
2057 pdu->pdu_id != AVRCP_GET_ELEMENT_ATTRIBUTES &&
2058 pdu->pdu_id != AVRCP_REQUEST_CONTINUING &&
2059 pdu->pdu_id != AVRCP_ABORT_CONTINUING)
2060 session_abort_pending_pdu(session);
2062 return AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
2065 pdu->params_len = htons(1);
2066 *code = AVC_CTYPE_REJECTED;
2068 return AVRCP_HEADER_LENGTH + 1;
2071 static void avrcp_handle_media_player_list(struct avrcp *session,
2072 struct avrcp_browsing_header *pdu,
2073 uint32_t start_item, uint32_t end_item)
2075 struct avrcp_player *player = session->target->player;
2076 struct get_folder_items_rsp *rsp;
2077 const char *name = NULL;
2080 rsp = (void *)pdu->params;
2081 rsp->status = AVRCP_STATUS_SUCCESS;
2082 rsp->uid_counter = htons(player_get_uid_counter(player));
2084 pdu->param_len = sizeof(*rsp);
2086 for (l = g_slist_nth(session->server->players, start_item);
2087 l; l = g_slist_next(l)) {
2088 struct avrcp_player *player = l->data;
2089 struct folder_item *folder;
2090 struct player_item *item;
2093 if (rsp->num_items == (end_item - start_item) + 1)
2096 folder = (void *)&pdu->params[pdu->param_len];
2097 folder->type = 0x01; /* Media Player */
2099 pdu->param_len += sizeof(*folder);
2101 item = (void *)folder->data;
2102 item->player_id = htons(player->id);
2103 item->type = 0x01; /* Audio */
2104 item->subtype = htonl(0x01); /* Audio Book */
2105 item->status = player_get_status(player);
2106 /* Assign Default Feature Bit Mask */
2107 memcpy(&item->features, &features, sizeof(features));
2109 item->charset = htons(AVRCP_CHARSET_UTF8);
2111 name = player->cb->get_name(player->user_data);
2112 namelen = strlen(name);
2113 item->namelen = htons(namelen);
2114 memcpy(item->name, name, namelen);
2116 folder->len = htons(sizeof(*item) + namelen);
2117 pdu->param_len += sizeof(*item) + namelen;
2121 /* If no player could be found respond with an error */
2122 if (!rsp->num_items)
2125 rsp->num_items = htons(rsp->num_items);
2126 pdu->param_len = htons(pdu->param_len);
2131 pdu->params[0] = AVRCP_STATUS_OUT_OF_BOUNDS;
2132 pdu->param_len = htons(1);
2135 static void avrcp_handle_get_folder_items(struct avrcp *session,
2136 struct avrcp_browsing_header *pdu,
2137 uint8_t transaction)
2139 uint32_t start_item = 0;
2140 uint32_t end_item = 0;
2142 uint8_t status = AVRCP_STATUS_SUCCESS;
2144 if (ntohs(pdu->param_len) < 10) {
2145 status = AVRCP_STATUS_INVALID_PARAM;
2149 scope = pdu->params[0];
2150 start_item = bt_get_be32(&pdu->params[1]);
2151 end_item = bt_get_be32(&pdu->params[5]);
2153 DBG("scope 0x%02x start_item 0x%08x end_item 0x%08x", scope,
2154 start_item, end_item);
2156 if (end_item < start_item) {
2157 status = AVRCP_STATUS_INVALID_PARAM;
2162 case AVRCP_SCOPE_MEDIA_PLAYER_LIST:
2163 avrcp_handle_media_player_list(session, pdu,
2164 start_item, end_item);
2166 case AVRCP_SCOPE_MEDIA_PLAYER_VFS:
2167 case AVRCP_SCOPE_SEARCH:
2168 case AVRCP_SCOPE_NOW_PLAYING:
2170 status = AVRCP_STATUS_INVALID_PARAM;
2177 pdu->params[0] = status;
2178 pdu->param_len = htons(1);
2181 static struct browsing_pdu_handler {
2183 void (*func) (struct avrcp *session, struct avrcp_browsing_header *pdu,
2184 uint8_t transaction);
2185 } browsing_handlers[] = {
2186 { AVRCP_GET_FOLDER_ITEMS, avrcp_handle_get_folder_items },
2190 size_t avrcp_browsing_general_reject(uint8_t *operands)
2192 struct avrcp_browsing_header *pdu = (void *) operands;
2195 pdu->pdu_id = AVRCP_GENERAL_REJECT;
2196 status = AVRCP_STATUS_INVALID_COMMAND;
2198 pdu->param_len = htons(sizeof(status));
2199 memcpy(pdu->params, &status, (sizeof(status)));
2200 return AVRCP_BROWSING_HEADER_LENGTH + sizeof(status);
2203 static size_t handle_browsing_pdu(struct avctp *conn,
2204 uint8_t transaction, uint8_t *operands,
2205 size_t operand_count, void *user_data)
2207 struct avrcp *session = user_data;
2208 struct browsing_pdu_handler *handler;
2209 struct avrcp_browsing_header *pdu = (void *) operands;
2211 DBG("AVRCP Browsing PDU 0x%02X, len 0x%04X", pdu->pdu_id,
2212 ntohs(pdu->param_len));
2214 for (handler = browsing_handlers; handler->pdu_id; handler++) {
2215 if (handler->pdu_id == pdu->pdu_id)
2219 return avrcp_browsing_general_reject(operands);
2222 session->transaction = transaction;
2223 handler->func(session, pdu, transaction);
2224 return AVRCP_BROWSING_HEADER_LENGTH + ntohs(pdu->param_len);
2227 size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands)
2229 struct avrcp_header *pdu = (void *) operands;
2230 uint32_t company_id = get_company_id(pdu->company_id);
2232 *code = AVC_CTYPE_REJECTED;
2233 pdu->params_len = htons(1);
2234 pdu->params[0] = AVRCP_STATUS_INTERNAL_ERROR;
2236 DBG("rejecting AVRCP PDU 0x%02X, company 0x%06X len 0x%04X",
2237 pdu->pdu_id, company_id, ntohs(pdu->params_len));
2239 return AVRCP_HEADER_LENGTH + 1;
2242 static struct avrcp_server *find_server(GSList *list, struct btd_adapter *a)
2244 for (; list; list = list->next) {
2245 struct avrcp_server *server = list->data;
2247 if (server->adapter == a)
2254 static const char *status_to_string(uint8_t status)
2257 case AVRCP_PLAY_STATUS_STOPPED:
2259 case AVRCP_PLAY_STATUS_PLAYING:
2261 case AVRCP_PLAY_STATUS_PAUSED:
2263 case AVRCP_PLAY_STATUS_FWD_SEEK:
2264 return "forward-seek";
2265 case AVRCP_PLAY_STATUS_REV_SEEK:
2266 return "reverse-seek";
2267 case AVRCP_PLAY_STATUS_ERROR:
2274 static gboolean avrcp_get_play_status_rsp(struct avctp *conn,
2275 uint8_t code, uint8_t subunit,
2276 uint8_t *operands, size_t operand_count,
2279 struct avrcp *session = user_data;
2280 struct avrcp_player *player = session->controller->player;
2281 struct media_player *mp = player->user_data;
2282 struct avrcp_header *pdu = (void *) operands;
2287 if (pdu == NULL || code == AVC_CTYPE_REJECTED ||
2288 ntohs(pdu->params_len) != 9)
2291 memcpy(&duration, pdu->params, sizeof(uint32_t));
2292 duration = ntohl(duration);
2293 media_player_set_duration(mp, duration);
2295 memcpy(&position, pdu->params + 4, sizeof(uint32_t));
2296 position = ntohl(position);
2297 media_player_set_position(mp, position);
2299 memcpy(&status, pdu->params + 8, sizeof(uint8_t));
2300 media_player_set_status(mp, status_to_string(status));
2305 static void avrcp_get_play_status(struct avrcp *session)
2307 uint8_t buf[AVRCP_HEADER_LENGTH];
2308 struct avrcp_header *pdu = (void *) buf;
2310 memset(buf, 0, sizeof(buf));
2312 set_company_id(pdu->company_id, IEEEID_BTSIG);
2313 pdu->pdu_id = AVRCP_GET_PLAY_STATUS;
2314 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2316 avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2317 AVC_SUBUNIT_PANEL, buf, sizeof(buf),
2318 avrcp_get_play_status_rsp,
2322 static const char *status_to_str(uint8_t status)
2325 case AVRCP_STATUS_INVALID_COMMAND:
2326 return "Invalid Command";
2327 case AVRCP_STATUS_INVALID_PARAM:
2328 return "Invalid Parameter";
2329 case AVRCP_STATUS_INTERNAL_ERROR:
2330 return "Internal Error";
2331 case AVRCP_STATUS_SUCCESS:
2338 static gboolean avrcp_player_value_rsp(struct avctp *conn,
2339 uint8_t code, uint8_t subunit,
2340 uint8_t *operands, size_t operand_count,
2343 struct avrcp *session = user_data;
2344 struct avrcp_player *player = session->controller->player;
2345 struct media_player *mp = player->user_data;
2346 struct avrcp_header *pdu = (void *) operands;
2351 media_player_set_setting(mp, "Error", "Timeout");
2355 if (code == AVC_CTYPE_REJECTED) {
2356 media_player_set_setting(mp, "Error",
2357 status_to_str(pdu->params[0]));
2361 count = pdu->params[0];
2363 if (pdu->params_len < count * 2)
2366 for (i = 1; count > 0; count--, i += 2) {
2370 key = attr_to_str(pdu->params[i]);
2374 value = attrval_to_str(pdu->params[i], pdu->params[i + 1]);
2378 media_player_set_setting(mp, key, value);
2384 static void avrcp_get_current_player_value(struct avrcp *session,
2385 uint8_t *attrs, uint8_t count)
2387 uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_ATTRIBUTE_LAST + 1];
2388 struct avrcp_header *pdu = (void *) buf;
2389 uint16_t length = AVRCP_HEADER_LENGTH + count + 1;
2391 memset(buf, 0, sizeof(buf));
2393 set_company_id(pdu->company_id, IEEEID_BTSIG);
2394 pdu->pdu_id = AVRCP_GET_CURRENT_PLAYER_VALUE;
2395 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2396 pdu->params_len = htons(count + 1);
2397 pdu->params[0] = count;
2399 memcpy(pdu->params + 1, attrs, count);
2401 avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2402 AVC_SUBUNIT_PANEL, buf, length,
2403 avrcp_player_value_rsp, session);
2406 static gboolean avrcp_list_player_attributes_rsp(struct avctp *conn,
2407 uint8_t code, uint8_t subunit,
2408 uint8_t *operands, size_t operand_count,
2411 uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
2412 struct avrcp *session = user_data;
2413 struct avrcp_header *pdu = (void *) operands;
2414 uint8_t len, count = 0;
2417 if (code == AVC_CTYPE_REJECTED)
2420 len = pdu->params[0];
2422 if (ntohs(pdu->params_len) < count) {
2423 error("Invalid parameters");
2427 for (i = 0; len > 0; len--, i++) {
2428 /* Don't query invalid attributes */
2429 if (pdu->params[i + 1] == AVRCP_ATTRIBUTE_ILEGAL ||
2430 pdu->params[i + 1] > AVRCP_ATTRIBUTE_LAST)
2433 attrs[count++] = pdu->params[i + 1];
2436 avrcp_get_current_player_value(session, attrs, count);
2441 static void avrcp_list_player_attributes(struct avrcp *session)
2443 uint8_t buf[AVRCP_HEADER_LENGTH];
2444 struct avrcp_header *pdu = (void *) buf;
2446 memset(buf, 0, sizeof(buf));
2448 set_company_id(pdu->company_id, IEEEID_BTSIG);
2449 pdu->pdu_id = AVRCP_LIST_PLAYER_ATTRIBUTES;
2450 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2452 avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2453 AVC_SUBUNIT_PANEL, buf, sizeof(buf),
2454 avrcp_list_player_attributes_rsp,
2458 static void avrcp_parse_attribute_list(struct avrcp_player *player,
2459 uint8_t *operands, uint8_t count)
2461 struct media_player *mp = player->user_data;
2462 struct media_item *item;
2465 item = media_player_set_playlist_item(mp, player->uid);
2467 for (i = 0; count > 0; count--) {
2469 uint16_t charset, len;
2471 id = get_be32(&operands[i]);
2472 i += sizeof(uint32_t);
2474 charset = get_be16(&operands[i]);
2475 i += sizeof(uint16_t);
2477 len = get_be16(&operands[i]);
2478 i += sizeof(uint16_t);
2480 if (charset == 106) {
2481 const char *key = metadata_to_str(id);
2484 media_player_set_metadata(mp, item,
2485 metadata_to_str(id),
2493 static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn,
2494 uint8_t code, uint8_t subunit,
2496 size_t operand_count,
2499 struct avrcp *session = user_data;
2500 struct avrcp_player *player = session->controller->player;
2501 struct avrcp_header *pdu = (void *) operands;
2504 if (code == AVC_CTYPE_REJECTED)
2507 count = pdu->params[0];
2509 if (ntohs(pdu->params_len) - 1 < count * 8) {
2510 error("Invalid parameters");
2514 avrcp_parse_attribute_list(player, &pdu->params[1], count);
2516 avrcp_get_play_status(session);
2521 static void avrcp_get_element_attributes(struct avrcp *session)
2523 uint8_t buf[AVRCP_HEADER_LENGTH + 9];
2524 struct avrcp_header *pdu = (void *) buf;
2527 memset(buf, 0, sizeof(buf));
2529 set_company_id(pdu->company_id, IEEEID_BTSIG);
2530 pdu->pdu_id = AVRCP_GET_ELEMENT_ATTRIBUTES;
2531 pdu->params_len = htons(9);
2532 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2534 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
2536 avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2537 AVC_SUBUNIT_PANEL, buf, length,
2538 avrcp_get_element_attributes_rsp,
2542 static const char *type_to_string(uint8_t type)
2544 switch (type & 0x0F) {
2550 return "Audio, Video";
2552 return "Audio Broadcasting";
2554 return "Audio, Audio Broadcasting";
2556 return "Video, Audio Broadcasting";
2558 return "Audio, Video, Audio Broadcasting";
2560 return "Video Broadcasting";
2562 return "Audio, Video Broadcasting";
2564 return "Video, Video Broadcasting";
2566 return "Audio, Video, Video Broadcasting";
2568 return "Audio Broadcasting, Video Broadcasting";
2570 return "Audio, Audio Broadcasting, Video Broadcasting";
2572 return "Video, Audio Broadcasting, Video Broadcasting";
2574 return "Audio, Video, Audio Broadcasting, Video Broadcasting";
2580 static const char *subtype_to_string(uint32_t subtype)
2582 switch (subtype & 0x03) {
2584 return "Audio Book";
2588 return "Audio Book, Podcast";
2594 static struct media_item *parse_media_element(struct avrcp *session,
2595 uint8_t *operands, uint16_t len)
2597 struct avrcp_player *player;
2598 struct media_player *mp;
2599 struct media_item *item;
2607 uid = get_be64(&operands[0]);
2609 namelen = MIN(get_be16(&operands[11]), sizeof(name) - 1);
2611 memcpy(name, &operands[13], namelen);
2612 name[namelen] = '\0';
2615 player = session->controller->player;
2616 mp = player->user_data;
2618 item = media_player_create_item(mp, name, PLAYER_ITEM_TYPE_AUDIO, uid);
2622 media_item_set_playable(item, true);
2627 static struct media_item *parse_media_folder(struct avrcp *session,
2628 uint8_t *operands, uint16_t len)
2630 struct avrcp_player *player = session->controller->player;
2631 struct media_player *mp = player->user_data;
2632 struct media_item *item;
2642 uid = get_be64(&operands[0]);
2644 playable = operands[9];
2646 namelen = MIN(get_be16(&operands[12]), sizeof(name) - 1);
2648 memcpy(name, &operands[14], namelen);
2649 name[namelen] = '\0';
2652 item = media_player_create_folder(mp, name, type, uid);
2656 media_item_set_playable(item, playable & 0x01);
2661 static void avrcp_list_items(struct avrcp *session, uint32_t start,
2663 static gboolean avrcp_list_items_rsp(struct avctp *conn, uint8_t *operands,
2664 size_t operand_count, void *user_data)
2666 struct avrcp_browsing_header *pdu = (void *) operands;
2667 struct avrcp *session = user_data;
2668 struct avrcp_player *player = session->controller->player;
2669 struct pending_list_items *p = player->p;
2680 /* AVRCP 1.5 - Page 76:
2681 * If the TG receives a GetFolderItems command for an empty folder then
2682 * the TG shall return the error (= Range Out of Bounds) in the status
2683 * field of the GetFolderItems response.
2685 if (pdu->params[0] == AVRCP_STATUS_OUT_OF_BOUNDS)
2688 if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 5) {
2693 count = get_be16(&operands[6]);
2697 for (i = 8; count && i + 3 < operand_count; count--) {
2698 struct media_item *item;
2702 type = operands[i++];
2703 len = get_be16(&operands[i]);
2706 if (type != 0x03 && type != 0x02) {
2711 if (i + len > operand_count) {
2712 error("Invalid item length");
2717 item = parse_media_element(session, &operands[i], len);
2719 item = parse_media_folder(session, &operands[i], len);
2722 if (g_slist_find(p->items, item))
2724 p->items = g_slist_append(p->items, item);
2730 items = g_slist_length(p->items);
2732 DBG("start %u end %u items %" PRIu64 " total %" PRIu64 "", p->start,
2733 p->end, items, p->total);
2735 if (items < p->total) {
2736 avrcp_list_items(session, p->start + items, p->end);
2741 media_player_list_complete(player->user_data, p->items, err);
2743 g_slist_free(p->items);
2750 static void avrcp_list_items(struct avrcp *session, uint32_t start,
2753 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10 +
2754 AVRCP_MEDIA_ATTRIBUTE_LAST * sizeof(uint32_t)];
2755 struct avrcp_player *player = session->controller->player;
2756 struct avrcp_browsing_header *pdu = (void *) buf;
2757 uint16_t length = AVRCP_BROWSING_HEADER_LENGTH + 10;
2760 memset(buf, 0, sizeof(buf));
2762 pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
2763 pdu->param_len = htons(10 + sizeof(uint32_t));
2765 pdu->params[0] = player->scope;
2767 put_be32(start, &pdu->params[1]);
2768 put_be32(end, &pdu->params[5]);
2772 /* Only the title (0x01) is mandatory. This can be extended to
2773 * support AVRCP_MEDIA_ATTRIBUTE_* attributes */
2774 attribute = htonl(AVRCP_MEDIA_ATTRIBUTE_TITLE);
2775 memcpy(&pdu->params[10], &attribute, sizeof(uint32_t));
2777 length += sizeof(uint32_t);
2779 avctp_send_browsing_req(session->conn, buf, length,
2780 avrcp_list_items_rsp, session);
2783 static gboolean avrcp_change_path_rsp(struct avctp *conn,
2784 uint8_t *operands, size_t operand_count,
2787 struct avrcp_browsing_header *pdu = (void *) operands;
2788 struct avrcp *session = user_data;
2789 struct avrcp_player *player = session->controller->player;
2790 struct media_player *mp = player->user_data;
2798 if (pdu->params[0] != AVRCP_STATUS_SUCCESS) {
2803 ret = get_be32(&pdu->params[1]);
2807 g_free(player->change_path);
2808 player->change_path = NULL;
2810 g_free(player->path);
2811 player->path = player->change_path;
2812 player->change_path = NULL;
2815 media_player_change_folder_complete(mp, player->path, ret);
2820 static gboolean avrcp_set_browsed_player_rsp(struct avctp *conn,
2822 size_t operand_count,
2825 struct avrcp *session = user_data;
2826 struct avrcp_player *player = session->controller->player;
2827 struct media_player *mp = player->user_data;
2828 struct avrcp_browsing_header *pdu = (void *) operands;
2831 uint8_t depth, count;
2834 if (pdu == NULL || pdu->params[0] != AVRCP_STATUS_SUCCESS ||
2838 player->uid_counter = get_be16(&pdu->params[1]);
2839 player->browsed = true;
2841 items = get_be32(&pdu->params[3]);
2843 depth = pdu->params[9];
2845 folders = g_new0(char *, depth + 2);
2846 folders[0] = g_strdup("/Filesystem");
2848 for (i = 10, count = 1; count - 1 < depth && i < operand_count;
2852 len = pdu->params[i++];
2854 if (i + len > operand_count || len == 0) {
2855 error("Invalid folder length");
2859 folders[count] = g_memdup(&pdu->params[i], len);
2863 player->path = g_build_pathv("/", folders);
2864 g_strfreev(folders);
2866 media_player_set_folder(mp, player->path, items);
2871 static void avrcp_set_browsed_player(struct avrcp *session,
2872 struct avrcp_player *player)
2874 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 2];
2875 struct avrcp_browsing_header *pdu = (void *) buf;
2878 memset(buf, 0, sizeof(buf));
2880 pdu->pdu_id = AVRCP_SET_BROWSED_PLAYER;
2881 id = htons(player->id);
2882 memcpy(pdu->params, &id, 2);
2883 pdu->param_len = htons(2);
2885 avctp_send_browsing_req(session->conn, buf, sizeof(buf),
2886 avrcp_set_browsed_player_rsp, session);
2889 static gboolean avrcp_get_item_attributes_rsp(struct avctp *conn,
2891 size_t operand_count,
2894 struct avrcp *session = user_data;
2895 struct avrcp_player *player = session->controller->player;
2896 struct avrcp_browsing_header *pdu = (void *) operands;
2900 avrcp_get_element_attributes(session);
2904 if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 4) {
2905 avrcp_get_element_attributes(session);
2909 count = pdu->params[1];
2911 if (ntohs(pdu->param_len) - 1 < count * 8) {
2912 error("Invalid parameters");
2916 avrcp_parse_attribute_list(player, &pdu->params[2], count);
2918 avrcp_get_play_status(session);
2923 static void avrcp_get_item_attributes(struct avrcp *session, uint64_t uid)
2925 struct avrcp_player *player = session->controller->player;
2926 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 12];
2927 struct avrcp_browsing_header *pdu = (void *) buf;
2929 memset(buf, 0, sizeof(buf));
2931 pdu->pdu_id = AVRCP_GET_ITEM_ATTRIBUTES;
2932 pdu->params[0] = 0x03;
2933 put_be64(uid, &pdu->params[1]);
2934 put_be16(player->uid_counter, &pdu->params[9]);
2935 pdu->param_len = htons(12);
2937 avctp_send_browsing_req(session->conn, buf, sizeof(buf),
2938 avrcp_get_item_attributes_rsp, session);
2941 static void avrcp_player_parse_features(struct avrcp_player *player,
2944 struct media_player *mp = player->user_data;
2946 player->features = g_memdup(features, 16);
2948 if (features[7] & 0x08) {
2949 media_player_set_browsable(mp, true);
2950 media_player_create_folder(mp, "/Filesystem",
2951 PLAYER_FOLDER_TYPE_MIXED, 0);
2954 if (features[7] & 0x10)
2955 media_player_set_searchable(mp, true);
2957 if (features[8] & 0x02) {
2958 media_player_create_folder(mp, "/NowPlaying",
2959 PLAYER_FOLDER_TYPE_MIXED, 0);
2960 media_player_set_playlist(mp, "/NowPlaying");
2964 static void avrcp_set_player_value(struct avrcp *session, uint8_t attr,
2967 uint8_t buf[AVRCP_HEADER_LENGTH + 3];
2968 struct avrcp_header *pdu = (void *) buf;
2971 memset(buf, 0, sizeof(buf));
2973 set_company_id(pdu->company_id, IEEEID_BTSIG);
2974 pdu->pdu_id = AVRCP_SET_PLAYER_VALUE;
2975 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2977 pdu->params[1] = attr;
2978 pdu->params[2] = val;
2979 pdu->params_len = htons(3);
2981 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
2983 avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
2984 AVC_SUBUNIT_PANEL, buf, length,
2985 avrcp_player_value_rsp, session);
2988 static bool ct_set_setting(struct media_player *mp, const char *key,
2989 const char *value, void *user_data)
2991 struct avrcp_player *player = user_data;
2994 struct avrcp *session;
2996 session = player->sessions->data;
2997 if (session == NULL)
3000 if (session->controller->version < 0x0103)
3003 attr = attr_to_val(key);
3007 val = attrval_to_val(attr, value);
3011 avrcp_set_player_value(session, attr, val);
3016 static int ct_press(struct avrcp_player *player, uint8_t op)
3019 struct avrcp *session;
3021 session = player->sessions->data;
3022 if (session == NULL)
3025 err = avctp_send_passthrough(session->conn, op);
3031 #ifdef __TIZEN_PATCH__
3032 static int ct_release(struct avrcp_player *player, uint8_t op)
3036 struct avrcp *session;
3038 session = player->sessions->data;
3039 if (session == NULL)
3042 err = avctp_send_release_passthrough(session->conn, op);
3050 static int ct_play(struct media_player *mp, void *user_data)
3052 struct avrcp_player *player = user_data;
3054 return ct_press(player, AVC_PLAY);
3057 static int ct_pause(struct media_player *mp, void *user_data)
3059 struct avrcp_player *player = user_data;
3061 return ct_press(player, AVC_PAUSE);
3064 static int ct_stop(struct media_player *mp, void *user_data)
3066 struct avrcp_player *player = user_data;
3068 return ct_press(player, AVC_STOP);
3071 static int ct_next(struct media_player *mp, void *user_data)
3073 struct avrcp_player *player = user_data;
3075 return ct_press(player, AVC_FORWARD);
3078 static int ct_previous(struct media_player *mp, void *user_data)
3080 struct avrcp_player *player = user_data;
3082 return ct_press(player, AVC_BACKWARD);
3084 #ifdef __TIZEN_PATCH__
3085 static int ct_press_fast_forward(struct media_player *mp, void *user_data)
3088 struct avrcp_player *player = user_data;
3091 return ct_press(player, AVC_FAST_FORWARD);
3094 static int ct_release_fast_forward(struct media_player *mp, void *user_data)
3097 struct avrcp_player *player = user_data;
3100 return ct_release(player, AVC_FAST_FORWARD);
3103 static int ct_press_rewind(struct media_player *mp, void *user_data)
3106 struct avrcp_player *player = user_data;
3109 return ct_press(player, AVC_REWIND);
3112 static int ct_release_rewind(struct media_player *mp, void *user_data)
3115 struct avrcp_player *player = user_data;
3118 return ct_release(player, AVC_REWIND);
3121 static int ct_fast_forward(struct media_player *mp, void *user_data)
3123 struct avrcp_player *player = user_data;
3125 return ct_press(player, AVC_FAST_FORWARD);
3128 static int ct_rewind(struct media_player *mp, void *user_data)
3130 struct avrcp_player *player = user_data;
3132 return ct_press(player, AVC_REWIND);
3135 static int ct_list_items(struct media_player *mp, const char *name,
3136 uint32_t start, uint32_t end, void *user_data)
3138 struct avrcp_player *player = user_data;
3139 struct avrcp *session;
3140 struct pending_list_items *p;
3142 if (player->p != NULL)
3145 session = player->sessions->data;
3147 if (g_str_has_prefix(name, "/NowPlaying"))
3148 player->scope = 0x03;
3149 else if (g_str_has_suffix(name, "/search"))
3150 player->scope = 0x02;
3152 player->scope = 0x01;
3154 avrcp_list_items(session, start, end);
3156 p = g_new0(struct pending_list_items, 1);
3159 p->total = (uint64_t) (p->end - p->start) + 1;
3165 static void avrcp_change_path(struct avrcp *session, uint8_t direction,
3168 struct avrcp_player *player = session->controller->player;
3169 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 11];
3170 struct avrcp_browsing_header *pdu = (void *) buf;
3172 memset(buf, 0, sizeof(buf));
3173 put_be16(player->uid_counter, &pdu->params[0]);
3174 pdu->params[2] = direction;
3175 put_be64(uid, &pdu->params[3]);
3176 pdu->pdu_id = AVRCP_CHANGE_PATH;
3177 pdu->param_len = htons(11);
3179 avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3180 avrcp_change_path_rsp, session);
3183 static int ct_change_folder(struct media_player *mp, const char *path,
3184 uint64_t uid, void *user_data)
3186 struct avrcp_player *player = user_data;
3187 struct avrcp *session;
3190 session = player->sessions->data;
3191 player->change_path = g_strdup(path);
3193 direction = g_str_has_prefix(path, player->path) ? 0x01 : 0x00;
3195 avrcp_change_path(session, direction, uid);
3200 static gboolean avrcp_search_rsp(struct avctp *conn, uint8_t *operands,
3201 size_t operand_count, void *user_data)
3203 struct avrcp_browsing_header *pdu = (void *) operands;
3204 struct avrcp *session = (void *) user_data;
3205 struct avrcp_player *player = session->controller->player;
3206 struct media_player *mp = player->user_data;
3214 if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 7) {
3219 player->uid_counter = get_be16(&pdu->params[1]);
3220 ret = get_be32(&pdu->params[3]);
3223 media_player_search_complete(mp, ret);
3228 static void avrcp_search(struct avrcp *session, const char *string)
3230 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 255];
3231 struct avrcp_browsing_header *pdu = (void *) buf;
3232 uint16_t len, stringlen;
3234 memset(buf, 0, sizeof(buf));
3235 len = AVRCP_BROWSING_HEADER_LENGTH + 4;
3236 stringlen = strnlen(string, sizeof(buf) - len);
3239 put_be16(AVRCP_CHARSET_UTF8, &pdu->params[0]);
3240 put_be16(stringlen, &pdu->params[2]);
3241 memcpy(&pdu->params[4], string, stringlen);
3242 pdu->pdu_id = AVRCP_SEARCH;
3243 pdu->param_len = htons(len - AVRCP_BROWSING_HEADER_LENGTH);
3245 avctp_send_browsing_req(session->conn, buf, len, avrcp_search_rsp,
3249 static int ct_search(struct media_player *mp, const char *string,
3252 struct avrcp_player *player = user_data;
3253 struct avrcp *session;
3255 session = player->sessions->data;
3257 avrcp_search(session, string);
3262 static void avrcp_play_item(struct avrcp *session, uint64_t uid)
3264 uint8_t buf[AVRCP_HEADER_LENGTH + 11];
3265 struct avrcp_player *player = session->controller->player;
3266 struct avrcp_header *pdu = (void *) buf;
3269 memset(buf, 0, sizeof(buf));
3271 set_company_id(pdu->company_id, IEEEID_BTSIG);
3272 pdu->pdu_id = AVRCP_PLAY_ITEM;
3273 pdu->params_len = htons(11);
3274 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3276 pdu->params[0] = player->scope;
3277 put_be64(uid, &pdu->params[1]);
3278 put_be16(player->uid_counter, &pdu->params[9]);
3280 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3282 avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3283 AVC_SUBUNIT_PANEL, buf, length,
3287 static int ct_play_item(struct media_player *mp, const char *name,
3288 uint64_t uid, void *user_data)
3290 struct avrcp_player *player = user_data;
3291 struct avrcp *session;
3293 if (player->p != NULL)
3296 session = player->sessions->data;
3298 if (g_strrstr(name, "/NowPlaying"))
3299 player->scope = 0x03;
3301 player->scope = 0x01;
3303 avrcp_play_item(session, uid);
3308 static void avrcp_add_to_nowplaying(struct avrcp *session, uint64_t uid)
3310 uint8_t buf[AVRCP_HEADER_LENGTH + 11];
3311 struct avrcp_player *player = session->controller->player;
3312 struct avrcp_header *pdu = (void *) buf;
3315 memset(buf, 0, sizeof(buf));
3317 set_company_id(pdu->company_id, IEEEID_BTSIG);
3318 pdu->pdu_id = AVRCP_ADD_TO_NOW_PLAYING;
3319 pdu->params_len = htons(11);
3320 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3322 pdu->params[0] = player->scope;
3323 put_be64(uid, &pdu->params[1]);
3324 put_be16(player->uid_counter, &pdu->params[9]);
3326 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3328 avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3329 AVC_SUBUNIT_PANEL, buf, length,
3333 static int ct_add_to_nowplaying(struct media_player *mp, const char *name,
3334 uint64_t uid, void *user_data)
3336 struct avrcp_player *player = user_data;
3337 struct avrcp *session;
3339 if (player->p != NULL)
3342 session = player->sessions->data;
3344 if (g_strrstr(name, "/NowPlaying"))
3345 player->scope = 0x03;
3347 player->scope = 0x01;
3349 avrcp_add_to_nowplaying(session, uid);
3354 static gboolean avrcp_get_total_numberofitems_rsp(struct avctp *conn,
3355 uint8_t *operands, size_t operand_count,
3358 struct avrcp_browsing_header *pdu = (void *) operands;
3359 struct avrcp *session = user_data;
3360 struct avrcp_player *player = session->controller->player;
3361 struct media_player *mp = player->user_data;
3362 uint32_t num_of_items;
3367 if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 7)
3370 if (pdu->params[0] == AVRCP_STATUS_OUT_OF_BOUNDS)
3373 player->uid_counter = get_be16(&pdu->params[1]);
3374 num_of_items = get_be32(&pdu->params[3]);
3380 media_player_total_items_complete(mp, num_of_items);
3384 static void avrcp_get_total_numberofitems(struct avrcp *session)
3386 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 7];
3387 struct avrcp_player *player = session->controller->player;
3388 struct avrcp_browsing_header *pdu = (void *) buf;
3390 memset(buf, 0, sizeof(buf));
3392 pdu->pdu_id = AVRCP_GET_TOTAL_NUMBER_OF_ITEMS;
3393 pdu->param_len = htons(7 + sizeof(uint32_t));
3395 pdu->params[0] = player->scope;
3397 avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3398 avrcp_get_total_numberofitems_rsp, session);
3401 static int ct_get_total_numberofitems(struct media_player *mp, const char *name,
3404 struct avrcp_player *player = user_data;
3405 struct avrcp *session;
3407 session = player->sessions->data;
3409 if (session->controller->version != 0x0106) {
3410 error("version not supported");
3414 if (g_str_has_prefix(name, "/NowPlaying"))
3415 player->scope = 0x03;
3416 else if (g_str_has_suffix(name, "/search"))
3417 player->scope = 0x02;
3419 player->scope = 0x01;
3421 avrcp_get_total_numberofitems(session);
3426 static const struct media_player_callback ct_cbs = {
3427 .set_setting = ct_set_setting,
3432 .previous = ct_previous,
3433 #ifdef __TIZEN_PATCH__
3434 .press_fast_forward = ct_press_fast_forward,
3435 .release_fast_forward = ct_release_fast_forward,
3436 .press_rewind = ct_press_rewind,
3437 .release_rewind = ct_release_rewind,
3439 .fast_forward = ct_fast_forward,
3440 .rewind = ct_rewind,
3442 .list_items = ct_list_items,
3443 .change_folder = ct_change_folder,
3444 .search = ct_search,
3445 .play_item = ct_play_item,
3446 .add_to_nowplaying = ct_add_to_nowplaying,
3447 .total_items = ct_get_total_numberofitems,
3450 static void set_ct_player(struct avrcp *session, struct avrcp_player *player)
3452 struct btd_service *service;
3454 session->controller->player = player;
3455 service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
3456 control_set_player(service, media_player_get_path(player->user_data));
3459 static struct avrcp_player *create_ct_player(struct avrcp *session,
3462 struct avrcp_player *player;
3463 struct media_player *mp;
3466 player = g_new0(struct avrcp_player, 1);
3467 player->sessions = g_slist_prepend(player->sessions, session);
3469 path = device_get_path(session->dev);
3471 mp = media_player_controller_create(path, id);
3475 media_player_set_callbacks(mp, &ct_cbs, player);
3476 player->user_data = mp;
3477 player->destroy = (GDestroyNotify) media_player_destroy;
3479 if (session->controller->player == NULL)
3480 set_ct_player(session, player);
3482 session->controller->players = g_slist_prepend(
3483 session->controller->players,
3489 static struct avrcp_player *find_ct_player(struct avrcp *session, uint16_t id)
3493 for (l = session->controller->players; l; l = l->next) {
3494 struct avrcp_player *player = l->data;
3496 if (player->id == 0) {
3501 if (player->id == id)
3508 static struct avrcp_player *
3509 avrcp_parse_media_player_item(struct avrcp *session, uint8_t *operands,
3512 struct avrcp_player *player;
3513 struct media_player *mp;
3514 uint16_t id, namelen;
3516 const char *curval, *strval;
3522 id = get_be16(&operands[0]);
3524 player = find_ct_player(session, id);
3525 if (player == NULL) {
3526 player = create_ct_player(session, id);
3529 } else if (player->features != NULL)
3532 mp = player->user_data;
3534 media_player_set_type(mp, type_to_string(operands[2]));
3536 subtype = get_be32(&operands[3]);
3538 media_player_set_subtype(mp, subtype_to_string(subtype));
3540 curval = media_player_get_status(mp);
3541 strval = status_to_string(operands[7]);
3543 if (g_strcmp0(curval, strval) != 0) {
3544 media_player_set_status(mp, strval);
3545 avrcp_get_play_status(session);
3548 avrcp_player_parse_features(player, &operands[8]);
3550 namelen = get_be16(&operands[26]);
3551 if (namelen > 0 && namelen + 28 == len) {
3552 namelen = MIN(namelen, sizeof(name) - 1);
3553 memcpy(name, &operands[28], namelen);
3554 name[namelen] = '\0';
3555 media_player_set_name(mp, name);
3558 if (session->controller->player == player && !player->browsed)
3559 avrcp_set_browsed_player(session, player);
3564 static void player_destroy(gpointer data)
3566 struct avrcp_player *player = data;
3568 if (player->destroy)
3569 player->destroy(player->user_data);
3571 #ifdef __TIZEN_PATCH__
3572 avrcp_stop_position_timer();
3575 if (player->changed_id > 0)
3576 g_source_remove(player->changed_id);
3578 g_slist_free(player->sessions);
3579 g_free(player->path);
3580 g_free(player->change_path);
3581 g_free(player->features);
3585 static void player_remove(gpointer data)
3587 struct avrcp_player *player = data;
3590 for (l = player->sessions; l; l = l->next) {
3591 struct avrcp *session = l->data;
3592 struct avrcp_data *controller = session->controller;
3594 controller->players = g_slist_remove(controller->players,
3597 /* Check if current player is being removed */
3598 if (controller->player == player)
3599 set_ct_player(session, g_slist_nth_data(
3600 controller->players, 0));
3603 player_destroy(player);
3606 static gboolean avrcp_get_media_player_list_rsp(struct avctp *conn,
3608 size_t operand_count,
3611 struct avrcp_browsing_header *pdu = (void *) operands;
3612 struct avrcp *session = user_data;
3617 if (pdu == NULL || pdu->params[0] != AVRCP_STATUS_SUCCESS ||
3621 removed = g_slist_copy(session->controller->players);
3622 count = get_be16(&operands[6]);
3624 for (i = 8; count && i < operand_count; count--) {
3625 struct avrcp_player *player;
3629 type = operands[i++];
3630 len = get_be16(&operands[i]);
3638 if (i + len > operand_count) {
3639 error("Invalid player item length");
3643 player = avrcp_parse_media_player_item(session, &operands[i],
3646 removed = g_slist_remove(removed, player);
3651 g_slist_free_full(removed, player_remove);
3656 static void avrcp_get_media_player_list(struct avrcp *session)
3658 uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10];
3659 struct avrcp_browsing_header *pdu = (void *) buf;
3661 memset(buf, 0, sizeof(buf));
3663 pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
3664 put_be32(0, &pdu->params[1]);
3665 put_be32(UINT32_MAX, &pdu->params[5]);
3666 pdu->param_len = htons(10);
3668 avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3669 avrcp_get_media_player_list_rsp, session);
3672 static void avrcp_volume_changed(struct avrcp *session,
3673 struct avrcp_header *pdu)
3675 struct avrcp_player *player = target_get_player(session);
3681 volume = pdu->params[1] & 0x7F;
3683 player->cb->set_volume(volume, session->dev, player->user_data);
3686 static void avrcp_status_changed(struct avrcp *session,
3687 struct avrcp_header *pdu)
3689 struct avrcp_player *player = session->controller->player;
3690 struct media_player *mp = player->user_data;
3692 const char *curval, *strval;
3694 value = pdu->params[1];
3696 curval = media_player_get_status(mp);
3697 strval = status_to_string(value);
3699 if (g_strcmp0(curval, strval) == 0)
3702 media_player_set_status(mp, strval);
3703 avrcp_get_play_status(session);
3706 static void avrcp_track_changed(struct avrcp *session,
3707 struct avrcp_header *pdu)
3709 if (session->browsing_id) {
3710 struct avrcp_player *player = session->controller->player;
3711 player->uid = get_be64(&pdu->params[1]);
3712 avrcp_get_item_attributes(session, player->uid);
3714 avrcp_get_element_attributes(session);
3717 static void avrcp_playback_pos_changed(struct avrcp *session,
3718 struct avrcp_header *pdu)
3720 struct avrcp_player *player = session->controller->player;
3721 struct media_player *mp = player->user_data;
3724 position = get_be32(&pdu->params[1]);
3725 media_player_set_position(mp, position);
3728 static void avrcp_setting_changed(struct avrcp *session,
3729 struct avrcp_header *pdu)
3731 struct avrcp_player *player = session->controller->player;
3732 struct media_player *mp = player->user_data;
3733 uint8_t count = pdu->params[1];
3736 for (i = 2; count > 0; count--, i += 2) {
3740 key = attr_to_str(pdu->params[i]);
3744 value = attrval_to_str(pdu->params[i], pdu->params[i + 1]);
3748 media_player_set_setting(mp, key, value);
3752 static void avrcp_available_players_changed(struct avrcp *session,
3753 struct avrcp_header *pdu)
3755 avrcp_get_media_player_list(session);
3758 static void avrcp_addressed_player_changed(struct avrcp *session,
3759 struct avrcp_header *pdu)
3761 struct avrcp_player *player = session->controller->player;
3762 uint16_t id = get_be16(&pdu->params[1]);
3764 if (player != NULL && player->id == id)
3767 player = find_ct_player(session, id);
3768 if (player == NULL) {
3769 player = create_ct_player(session, id);
3774 player->uid_counter = get_be16(&pdu->params[3]);
3775 set_ct_player(session, player);
3777 if (player->features != NULL)
3780 avrcp_get_media_player_list(session);
3783 static void avrcp_uids_changed(struct avrcp *session, struct avrcp_header *pdu)
3785 struct avrcp_player *player = session->controller->player;
3787 player->uid_counter = get_be16(&pdu->params[1]);
3790 static gboolean avrcp_handle_event(struct avctp *conn,
3791 uint8_t code, uint8_t subunit,
3792 uint8_t *operands, size_t operand_count,
3795 struct avrcp *session = user_data;
3796 struct avrcp_header *pdu = (void *) operands;
3799 if ((code != AVC_CTYPE_INTERIM && code != AVC_CTYPE_CHANGED) ||
3803 event = pdu->params[0];
3805 if (code == AVC_CTYPE_CHANGED) {
3806 session->registered_events ^= (1 << event);
3807 avrcp_register_notification(session, event);
3812 case AVRCP_EVENT_VOLUME_CHANGED:
3813 avrcp_volume_changed(session, pdu);
3815 case AVRCP_EVENT_STATUS_CHANGED:
3816 avrcp_status_changed(session, pdu);
3818 case AVRCP_EVENT_TRACK_CHANGED:
3819 avrcp_track_changed(session, pdu);
3821 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
3822 avrcp_playback_pos_changed(session, pdu);
3824 case AVRCP_EVENT_SETTINGS_CHANGED:
3825 avrcp_setting_changed(session, pdu);
3827 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
3828 avrcp_available_players_changed(session, pdu);
3830 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
3831 avrcp_addressed_player_changed(session, pdu);
3833 case AVRCP_EVENT_UIDS_CHANGED:
3834 avrcp_uids_changed(session, pdu);
3838 session->registered_events |= (1 << event);
3843 static void avrcp_register_notification(struct avrcp *session, uint8_t event)
3845 uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH];
3846 struct avrcp_header *pdu = (void *) buf;
3849 memset(buf, 0, sizeof(buf));
3851 set_company_id(pdu->company_id, IEEEID_BTSIG);
3852 pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
3853 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3854 pdu->params[0] = event;
3857 * Set maximum interval possible for position changed as we only
3860 if (event == AVRCP_EVENT_PLAYBACK_POS_CHANGED)
3861 bt_put_be32(UINT32_MAX / 1000, &pdu->params[1]);
3863 pdu->params_len = htons(AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH);
3865 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3867 avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
3868 AVC_SUBUNIT_PANEL, buf, length,
3869 avrcp_handle_event, session);
3872 #ifdef __TIZEN_PATCH__
3873 static char *avrcp_event_to_string(uint8_t event)
3877 case AVRCP_EVENT_STATUS_CHANGED:
3878 return "AVRCP EVENT STATUS CHANGED";
3879 case AVRCP_EVENT_TRACK_CHANGED:
3880 return "AVRCP EVENT TRACK CHANGED";
3881 case AVRCP_EVENT_SETTINGS_CHANGED:
3882 return "AVRCP EVENT SETTINGS CHANGED";
3883 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
3884 return "AVRCP EVENT ADDRESSED PLAYER CHANGED";
3885 case AVRCP_EVENT_UIDS_CHANGED:
3886 return "AVRCP EVENT UIDS CHANGED";
3887 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
3888 return "AVRCP EVENT AVAILABLE PLAYERS CHANGED";
3889 case AVRCP_EVENT_VOLUME_CHANGED:
3890 return "AVRCP EVENT VOLUME CHANGED";
3892 return "Unknown Event";
3896 static gboolean avrcp_get_playback_status(struct avrcp *session)
3898 avrcp_get_play_status(session);
3903 static gboolean avrcp_get_capabilities_resp(struct avctp *conn,
3904 uint8_t code, uint8_t subunit,
3905 uint8_t *operands, size_t operand_count,
3908 struct avrcp *session = user_data;
3909 struct avrcp_header *pdu = (void *) operands;
3910 uint16_t events = 0;
3913 if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED ||
3914 pdu == NULL || pdu->params[0] != CAP_EVENTS_SUPPORTED)
3917 /* Connect browsing if pending */
3918 if (session->browsing_timer > 0) {
3919 g_source_remove(session->browsing_timer);
3920 session->browsing_timer = 0;
3921 avctp_connect_browsing(session->conn);
3924 count = pdu->params[1];
3926 for (; count > 0; count--) {
3927 uint8_t event = pdu->params[1 + count];
3929 events |= (1 << event);
3930 #ifdef __TIZEN_PATCH__
3931 DBG("Supported Event %s", avrcp_event_to_string(event));
3934 case AVRCP_EVENT_STATUS_CHANGED:
3935 case AVRCP_EVENT_TRACK_CHANGED:
3936 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
3937 case AVRCP_EVENT_SETTINGS_CHANGED:
3938 #ifndef __TIZEN_PATCH__
3939 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
3940 case AVRCP_EVENT_UIDS_CHANGED:
3941 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
3942 /* These events above are controller specific */
3943 if (!session->controller)
3945 case AVRCP_EVENT_VOLUME_CHANGED:
3947 avrcp_register_notification(session, event);
3952 if (!session->controller)
3955 if (!(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED)))
3956 avrcp_list_player_attributes(session);
3958 if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)))
3959 avrcp_get_play_status(session);
3961 if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)))
3962 avrcp_get_element_attributes(session);
3963 #ifdef __TIZEN_PATCH__
3964 if ((events & (1 << AVRCP_EVENT_STATUS_CHANGED)) == 0) {
3965 session->playback_status_id = g_timeout_add_seconds(1,
3966 avrcp_get_playback_status, session);
3972 static void avrcp_get_capabilities(struct avrcp *session)
3974 uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_GET_CAPABILITIES_PARAM_LENGTH];
3975 struct avrcp_header *pdu = (void *) buf;
3978 memset(buf, 0, sizeof(buf));
3980 set_company_id(pdu->company_id, IEEEID_BTSIG);
3981 pdu->pdu_id = AVRCP_GET_CAPABILITIES;
3982 pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3983 pdu->params[0] = CAP_EVENTS_SUPPORTED;
3984 pdu->params_len = htons(AVRCP_GET_CAPABILITIES_PARAM_LENGTH);
3986 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3988 avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
3989 AVC_SUBUNIT_PANEL, buf, length,
3990 avrcp_get_capabilities_resp,
3994 static struct avrcp *find_session(GSList *list, struct btd_device *dev)
3996 for (; list; list = list->next) {
3997 struct avrcp *session = list->data;
3999 if (session->dev == dev)
4006 static void destroy_browsing(void *data)
4008 struct avrcp *session = data;
4010 session->browsing_id = 0;
4013 static void session_init_browsing(struct avrcp *session)
4015 if (session->browsing_timer > 0) {
4016 g_source_remove(session->browsing_timer);
4017 session->browsing_timer = 0;
4020 session->browsing_id = avctp_register_browsing_pdu_handler(
4022 handle_browsing_pdu,
4027 static struct avrcp_data *data_init(struct avrcp *session, const char *uuid)
4029 struct avrcp_data *data;
4030 const sdp_record_t *rec;
4032 sdp_profile_desc_t *desc;
4034 data = g_new0(struct avrcp_data, 1);
4036 rec = btd_device_get_record(session->dev, uuid);
4040 if (sdp_get_profile_descs(rec, &list) == 0) {
4042 data->version = desc->version;
4045 sdp_get_int_attr(rec, SDP_ATTR_SUPPORTED_FEATURES, &data->features);
4046 sdp_list_free(list, free);
4051 static gboolean connect_browsing(gpointer user_data)
4053 struct avrcp *session = user_data;
4055 session->browsing_timer = 0;
4057 avctp_connect_browsing(session->conn);
4062 static void avrcp_connect_browsing(struct avrcp *session)
4064 /* Immediately connect browsing channel if initiator otherwise delay
4065 * it to avoid possible collisions
4067 if (avctp_is_initiator(session->conn)) {
4068 avctp_connect_browsing(session->conn);
4072 if (session->browsing_timer > 0)
4075 session->browsing_timer = g_timeout_add_seconds(AVRCP_BROWSING_TIMEOUT,
4080 #ifdef SUPPORT_AVRCP_TARGET
4081 static void target_init(struct avrcp *session)
4083 struct avrcp_server *server = session->server;
4084 struct avrcp_data *target;
4085 struct avrcp_player *player;
4086 struct btd_service *service;
4088 if (session->target != NULL)
4091 target = data_init(session, AVRCP_REMOTE_UUID);
4092 session->target = target;
4094 DBG("%p version 0x%04x", target, target->version);
4096 service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
4097 btd_service_connecting_complete(service, 0);
4099 player = g_slist_nth_data(server->players, 0);
4100 if (player != NULL) {
4101 target->player = player;
4102 player->sessions = g_slist_prepend(player->sessions, session);
4105 session->supported_events |= (1 << AVRCP_EVENT_STATUS_CHANGED) |
4106 (1 << AVRCP_EVENT_TRACK_CHANGED) |
4107 #ifndef __TIZEN_PATCH__
4108 (1 << AVRCP_EVENT_TRACK_REACHED_START) |
4109 (1 << AVRCP_EVENT_TRACK_REACHED_END) |
4111 #ifdef __TIZEN_PATCH__
4112 (1 << AVRCP_EVENT_PLAYBACK_POS_CHANGED) |
4114 (1 << AVRCP_EVENT_SETTINGS_CHANGED);
4116 if (target->version < 0x0104)
4119 #ifdef __TIZEN_PATCH__
4120 if (adapter_avrcp_tg_ver < 0x0104)
4124 session->supported_events |=
4125 (1 << AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED) |
4126 (1 << AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED) |
4127 (1 << AVRCP_EVENT_VOLUME_CHANGED);
4129 /* Only check capabilities if controller is not supported */
4130 if (session->controller == NULL)
4131 avrcp_get_capabilities(session);
4133 if (!(target->features & AVRCP_FEATURE_BROWSING))
4136 avrcp_connect_browsing(session);
4140 #ifdef SUPPORT_AVRCP_CONTROL
4141 static void controller_init(struct avrcp *session)
4143 struct avrcp_player *player;
4144 struct btd_service *service;
4145 struct avrcp_data *controller;
4147 if (session->controller != NULL)
4150 controller = data_init(session, AVRCP_TARGET_UUID);
4151 session->controller = controller;
4153 DBG("%p version 0x%04x", controller, controller->version);
4155 #ifdef __TIZEN_PATCH__
4156 if ((controller->version >= 0x0104) && (adapter_avrcp_ct_ver >= 0x0104))
4157 session->supported_events |= (1 << AVRCP_EVENT_VOLUME_CHANGED);
4160 service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
4161 btd_service_connecting_complete(service, 0);
4163 /* Only create player if category 1 is supported */
4164 if (!(controller->features & AVRCP_FEATURE_CATEGORY_1))
4167 player = create_ct_player(session, 0);
4171 if (controller->version < 0x0103)
4174 avrcp_get_capabilities(session);
4176 if (controller->version < 0x0104)
4179 #ifdef __TIZEN_PATCH__
4180 if (adapter_avrcp_ct_ver < 0x0104)
4184 if (!(controller->features & AVRCP_FEATURE_BROWSING))
4187 avrcp_connect_browsing(session);
4191 static void session_init_control(struct avrcp *session)
4193 session->passthrough_id = avctp_register_passthrough_handler(
4197 session->passthrough_handlers = passthrough_handlers;
4198 session->control_id = avctp_register_pdu_handler(session->conn,
4200 handle_vendordep_pdu,
4202 session->control_handlers = control_handlers;
4203 #ifdef SUPPORT_AVRCP_CONTROL
4204 if (btd_device_get_service(session->dev, AVRCP_TARGET_UUID) != NULL)
4205 controller_init(session);
4207 #ifdef SUPPORT_AVRCP_TARGET
4208 if (btd_device_get_service(session->dev, AVRCP_REMOTE_UUID) != NULL)
4209 target_init(session);
4213 static void controller_destroy(struct avrcp *session)
4215 struct avrcp_data *controller = session->controller;
4217 DBG("%p", controller);
4219 g_slist_free_full(controller->players, player_destroy);
4224 static void target_destroy(struct avrcp *session)
4226 struct avrcp_data *target = session->target;
4227 struct avrcp_player *player = target->player;
4232 player->sessions = g_slist_remove(player->sessions, session);
4237 static void session_destroy(struct avrcp *session, int err)
4239 struct avrcp_server *server = session->server;
4240 struct btd_service *service;
4242 server->sessions = g_slist_remove(server->sessions, session);
4244 #ifdef __TIZEN_PATCH__
4245 if (session->playback_status_id > 0) {
4246 DBG("Removing the timer for playback status polling");
4247 g_source_remove(session->playback_status_id);
4248 session->playback_status_id = 0;
4252 session_abort_pending_pdu(session);
4254 service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
4255 if (service != NULL) {
4256 if (session->control_id == 0)
4257 btd_service_connecting_complete(service, err);
4259 btd_service_disconnecting_complete(service, 0);
4262 service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
4263 if (service != NULL) {
4264 if (session->control_id == 0)
4265 btd_service_connecting_complete(service, err);
4267 btd_service_disconnecting_complete(service, 0);
4270 if (session->browsing_timer > 0)
4271 g_source_remove(session->browsing_timer);
4273 if (session->controller != NULL)
4274 controller_destroy(session);
4276 if (session->target != NULL)
4277 target_destroy(session);
4279 if (session->passthrough_id > 0)
4280 avctp_unregister_passthrough_handler(session->passthrough_id);
4282 if (session->control_id > 0)
4283 avctp_unregister_pdu_handler(session->control_id);
4285 if (session->browsing_id > 0)
4286 avctp_unregister_browsing_pdu_handler(session->browsing_id);
4291 static struct avrcp *session_create(struct avrcp_server *server,
4292 struct btd_device *device)
4294 struct avrcp *session;
4296 session = g_new0(struct avrcp, 1);
4297 session->server = server;
4298 session->conn = avctp_connect(device);
4299 session->dev = device;
4301 server->sessions = g_slist_append(server->sessions, session);
4306 static void state_changed(struct btd_device *device, avctp_state_t old_state,
4307 avctp_state_t new_state, int err,
4310 struct avrcp_server *server;
4311 struct avrcp *session;
4313 server = find_server(servers, device_get_adapter(device));
4317 session = find_session(server->sessions, device);
4319 switch (new_state) {
4320 case AVCTP_STATE_DISCONNECTED:
4321 if (session == NULL)
4324 session_destroy(session, err);
4327 case AVCTP_STATE_CONNECTING:
4328 if (session != NULL)
4331 session_create(server, device);
4334 case AVCTP_STATE_CONNECTED:
4335 if (session == NULL || session->control_id > 0)
4338 session_init_control(session);
4341 case AVCTP_STATE_BROWSING_CONNECTED:
4342 if (session == NULL || session->browsing_id > 0)
4345 session_init_browsing(session);
4348 case AVCTP_STATE_BROWSING_CONNECTING:
4354 static struct avrcp_server *avrcp_server_register(struct btd_adapter *adapter)
4356 struct avrcp_server *server;
4358 if (avctp_register(adapter, TRUE) < 0)
4361 server = g_new0(struct avrcp_server, 1);
4362 server->adapter = btd_adapter_ref(adapter);
4364 servers = g_slist_append(servers, server);
4367 avctp_id = avctp_add_state_cb(NULL, state_changed, NULL);
4372 static void avrcp_server_unregister(struct avrcp_server *server)
4374 g_slist_free_full(server->sessions, g_free);
4375 g_slist_free_full(server->players, player_destroy);
4377 servers = g_slist_remove(servers, server);
4379 avctp_unregister(server->adapter);
4380 btd_adapter_unref(server->adapter);
4387 avctp_remove_state_cb(avctp_id);
4392 struct avrcp_player *avrcp_register_player(struct btd_adapter *adapter,
4393 struct avrcp_player_cb *cb,
4395 GDestroyNotify destroy)
4397 struct avrcp_server *server;
4398 struct avrcp_player *player;
4400 static uint16_t id = 0;
4402 server = find_server(servers, adapter);
4406 player = g_new0(struct avrcp_player, 1);
4408 player->server = server;
4410 player->user_data = user_data;
4411 player->destroy = destroy;
4413 server->players = g_slist_append(server->players, player);
4415 /* Assign player to session without current player */
4416 for (l = server->sessions; l; l = l->next) {
4417 struct avrcp *session = l->data;
4418 struct avrcp_data *target = session->target;
4423 if (target->player == NULL) {
4424 target->player = player;
4425 player->sessions = g_slist_append(player->sessions,
4430 avrcp_player_event(player,
4431 AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED, NULL);
4436 void avrcp_unregister_player(struct avrcp_player *player)
4438 struct avrcp_server *server = player->server;
4441 server->players = g_slist_remove(server->players, player);
4443 /* Remove player from sessions using it */
4444 for (l = player->sessions; l; l = l->next) {
4445 struct avrcp *session = l->data;
4446 struct avrcp_data *target = session->target;
4451 if (target->player == player)
4452 target->player = g_slist_nth_data(server->players, 0);
4455 avrcp_player_event(player,
4456 AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED, NULL);
4458 player_destroy(player);
4461 static gboolean avrcp_handle_set_volume(struct avctp *conn,
4462 uint8_t code, uint8_t subunit,
4463 uint8_t *operands, size_t operand_count,
4466 struct avrcp *session = user_data;
4467 struct avrcp_player *player = target_get_player(session);
4468 struct avrcp_header *pdu = (void *) operands;
4471 if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED ||
4475 volume = pdu->params[0] & 0x7F;
4478 player->cb->set_volume(volume, session->dev, player->user_data);
4483 static int avrcp_event(struct avrcp *session, uint8_t id, const void *data)
4485 uint8_t buf[AVRCP_HEADER_LENGTH + 2];
4486 struct avrcp_header *pdu = (void *) buf;
4491 /* Verify that the event is registered */
4492 if (!(session->registered_events & (1 << id)))
4495 memset(buf, 0, sizeof(buf));
4497 set_company_id(pdu->company_id, IEEEID_BTSIG);
4498 pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
4499 code = AVC_CTYPE_CHANGED;
4500 pdu->params[0] = id;
4505 case AVRCP_EVENT_VOLUME_CHANGED:
4507 memcpy(&pdu->params[1], data, sizeof(uint8_t));
4510 error("Unknown event %u", id);
4514 pdu->params_len = htons(size);
4516 err = avctp_send_vendordep(session->conn,
4517 session->transaction_events[id],
4518 code, AVC_SUBUNIT_PANEL,
4519 buf, size + AVRCP_HEADER_LENGTH);
4523 /* Unregister event as per AVRCP 1.3 spec, section 5.4.2 */
4524 session->registered_events ^= 1 << id;
4529 int avrcp_set_volume(struct btd_device *dev, uint8_t volume, bool notify)
4531 struct avrcp_server *server;
4532 struct avrcp *session;
4533 uint8_t buf[AVRCP_HEADER_LENGTH + 1];
4534 struct avrcp_header *pdu = (void *) buf;
4536 server = find_server(servers, device_get_adapter(dev));
4540 session = find_session(server->sessions, dev);
4541 if (session == NULL)
4545 if (!session->target)
4547 return avrcp_event(session, AVRCP_EVENT_VOLUME_CHANGED,
4551 if (!session->controller || session->controller->version < 0x0104)
4554 memset(buf, 0, sizeof(buf));
4556 set_company_id(pdu->company_id, IEEEID_BTSIG);
4558 pdu->pdu_id = AVRCP_SET_ABSOLUTE_VOLUME;
4559 pdu->params[0] = volume;
4560 pdu->params_len = htons(1);
4562 return avctp_send_vendordep_req(session->conn,
4563 AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
4565 avrcp_handle_set_volume, session);
4568 static int avrcp_connect(struct btd_service *service)
4570 struct btd_device *dev = btd_service_get_device(service);
4571 const char *path = device_get_path(dev);
4572 #ifdef __TIZEN_PATCH__
4575 DBG("path %s", path);
4577 #ifdef __TIZEN_PATCH__
4578 device_get_name(dev, name, sizeof(name));
4579 DBG("name : %s", name);
4580 if (g_str_equal(name, "PLT_M50")) {
4581 DBG("Don't initiate avrcp connection with this headset");
4585 return control_connect(service);
4588 static int avrcp_disconnect(struct btd_service *service)
4590 struct btd_device *dev = btd_service_get_device(service);
4591 const char *path = device_get_path(dev);
4593 DBG("path %s", path);
4595 return control_disconnect(service);
4598 static int avrcp_target_probe(struct btd_service *service)
4600 struct btd_device *dev = btd_service_get_device(service);
4602 DBG("path %s", device_get_path(dev));
4604 return control_init_target(service);
4607 static void avrcp_target_remove(struct btd_service *service)
4609 control_unregister(service);
4612 #ifdef SUPPORT_AVRCP_TARGET
4613 static void avrcp_target_server_remove(struct btd_profile *p,
4614 struct btd_adapter *adapter)
4616 struct avrcp_server *server;
4618 DBG("path %s", adapter_get_path(adapter));
4620 server = find_server(servers, adapter);
4624 if (server->tg_record_id != 0) {
4625 adapter_service_remove(adapter, server->tg_record_id);
4626 server->tg_record_id = 0;
4629 if (server->ct_record_id == 0)
4630 avrcp_server_unregister(server);
4634 #ifdef SUPPORT_AVRCP_TARGET
4635 static int avrcp_target_server_probe(struct btd_profile *p,
4636 struct btd_adapter *adapter)
4638 sdp_record_t *record;
4639 struct avrcp_server *server;
4641 DBG("path %s", adapter_get_path(adapter));
4643 server = find_server(servers, adapter);
4647 server = avrcp_server_register(adapter);
4649 return -EPROTONOSUPPORT;
4652 record = avrcp_tg_record();
4654 error("Unable to allocate new service record");
4655 avrcp_target_server_remove(p, adapter);
4659 if (adapter_service_add(adapter, record) < 0) {
4660 error("Unable to register AVRCP target service record");
4661 avrcp_target_server_remove(p, adapter);
4662 sdp_record_free(record);
4665 server->tg_record_id = record->handle;
4671 static struct btd_profile avrcp_target_profile = {
4672 .name = "audio-avrcp-target",
4674 .remote_uuid = AVRCP_TARGET_UUID,
4675 .device_probe = avrcp_target_probe,
4676 .device_remove = avrcp_target_remove,
4678 .connect = avrcp_connect,
4679 .disconnect = avrcp_disconnect,
4680 #ifdef SUPPORT_AVRCP_TARGET
4681 .adapter_probe = avrcp_target_server_probe,
4682 .adapter_remove = avrcp_target_server_remove,
4686 static int avrcp_controller_probe(struct btd_service *service)
4688 struct btd_device *dev = btd_service_get_device(service);
4690 DBG("path %s", device_get_path(dev));
4692 return control_init_remote(service);
4695 static void avrcp_controller_remove(struct btd_service *service)
4697 control_unregister(service);
4700 #ifdef SUPPORT_AVRCP_CONTROL
4701 static void avrcp_controller_server_remove(struct btd_profile *p,
4702 struct btd_adapter *adapter)
4704 struct avrcp_server *server;
4706 DBG("path %s", adapter_get_path(adapter));
4708 server = find_server(servers, adapter);
4712 if (server->ct_record_id != 0) {
4713 adapter_service_remove(adapter, server->ct_record_id);
4714 server->ct_record_id = 0;
4717 if (server->tg_record_id == 0)
4718 avrcp_server_unregister(server);
4722 #ifdef SUPPORT_AVRCP_CONTROL
4723 static int avrcp_controller_server_probe(struct btd_profile *p,
4724 struct btd_adapter *adapter)
4726 sdp_record_t *record;
4727 struct avrcp_server *server;
4729 DBG("path %s", adapter_get_path(adapter));
4731 server = find_server(servers, adapter);
4735 server = avrcp_server_register(adapter);
4737 return -EPROTONOSUPPORT;
4740 record = avrcp_ct_record();
4742 error("Unable to allocate new service record");
4743 avrcp_controller_server_remove(p, adapter);
4747 if (adapter_service_add(adapter, record) < 0) {
4748 error("Unable to register AVRCP service record");
4749 avrcp_controller_server_remove(p, adapter);
4750 sdp_record_free(record);
4753 server->ct_record_id = record->handle;
4759 static struct btd_profile avrcp_controller_profile = {
4760 .name = "avrcp-controller",
4762 .remote_uuid = AVRCP_REMOTE_UUID,
4763 .device_probe = avrcp_controller_probe,
4764 .device_remove = avrcp_controller_remove,
4766 .connect = avrcp_connect,
4767 .disconnect = avrcp_disconnect,
4768 #ifdef SUPPORT_AVRCP_CONTROL
4769 .adapter_probe = avrcp_controller_server_probe,
4770 .adapter_remove = avrcp_controller_server_remove,
4774 static int avrcp_init(void)
4776 btd_profile_register(&avrcp_controller_profile);
4777 btd_profile_register(&avrcp_target_profile);
4782 static void avrcp_exit(void)
4784 btd_profile_unregister(&avrcp_controller_profile);
4785 btd_profile_unregister(&avrcp_target_profile);
4788 BLUETOOTH_PLUGIN_DEFINE(avrcp, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
4789 avrcp_init, avrcp_exit)