avrcp: include all player settings in notif event
[platform/upstream/bluez.git] / profiles / audio / avrcp.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2006-2010  Nokia Corporation
6  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
7  *  Copyright (C) 2011  Texas Instruments, Inc.
8  *
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29
30 #include <stdlib.h>
31 #include <stdint.h>
32 #include <inttypes.h>
33 #include <stdbool.h>
34 #include <errno.h>
35 #include <unistd.h>
36 #include <assert.h>
37 #include <signal.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41
42 #include <glib.h>
43 #include <dbus/dbus.h>
44
45 #include "bluetooth/bluetooth.h"
46 #include "bluetooth/sdp.h"
47 #include "bluetooth/sdp_lib.h"
48 #include "lib/uuid.h"
49
50 #include "gdbus/gdbus.h"
51
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"
57 #include "src/log.h"
58 #include "src/error.h"
59 #include "src/sdpd.h"
60 #include "src/dbus-common.h"
61 #include "src/shared/util.h"
62
63 #include "avctp.h"
64 #include "avrcp.h"
65 #include "control.h"
66 #include "media.h"
67 #include "player.h"
68 #include "transport.h"
69
70 /* Company IDs for vendor dependent commands */
71 #define IEEEID_BTSIG            0x001958
72
73 /* Status codes */
74 #define AVRCP_STATUS_INVALID_COMMAND            0x00
75 #define AVRCP_STATUS_INVALID_PARAM              0x01
76 #define AVRCP_STATUS_PARAM_NOT_FOUND            0x02
77 #define AVRCP_STATUS_INTERNAL_ERROR             0x03
78 #define AVRCP_STATUS_SUCCESS                    0x04
79 #define AVRCP_STATUS_UID_CHANGED                0x05
80 #define AVRCP_STATUS_DOES_NOT_EXIST             0x09
81 #define AVRCP_STATUS_OUT_OF_BOUNDS              0x0b
82 #define AVRCP_STATUS_INVALID_PLAYER_ID          0x11
83 #define AVRCP_STATUS_PLAYER_NOT_BROWSABLE       0x12
84 #define AVRCP_STATUS_NO_AVAILABLE_PLAYERS       0x15
85 #define AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED   0x16
86
87 /* Packet types */
88 #define AVRCP_PACKET_TYPE_SINGLE        0x00
89 #define AVRCP_PACKET_TYPE_START         0x01
90 #define AVRCP_PACKET_TYPE_CONTINUING    0x02
91 #define AVRCP_PACKET_TYPE_END           0x03
92
93 /* PDU types for metadata transfer */
94 #define AVRCP_GET_CAPABILITIES          0x10
95 #define AVRCP_LIST_PLAYER_ATTRIBUTES    0X11
96 #define AVRCP_LIST_PLAYER_VALUES        0x12
97 #define AVRCP_GET_CURRENT_PLAYER_VALUE  0x13
98 #define AVRCP_SET_PLAYER_VALUE          0x14
99 #define AVRCP_GET_PLAYER_ATTRIBUTE_TEXT 0x15
100 #define AVRCP_GET_PLAYER_VALUE_TEXT     0x16
101 #define AVRCP_DISPLAYABLE_CHARSET       0x17
102 #define AVRCP_CT_BATTERY_STATUS         0x18
103 #define AVRCP_GET_ELEMENT_ATTRIBUTES    0x20
104 #define AVRCP_GET_PLAY_STATUS           0x30
105 #define AVRCP_REGISTER_NOTIFICATION     0x31
106 #define AVRCP_REQUEST_CONTINUING        0x40
107 #define AVRCP_ABORT_CONTINUING          0x41
108 #define AVRCP_SET_ABSOLUTE_VOLUME       0x50
109 #define AVRCP_SET_ADDRESSED_PLAYER      0x60
110 #define AVRCP_SET_BROWSED_PLAYER        0x70
111 #define AVRCP_GET_FOLDER_ITEMS          0x71
112 #define AVRCP_CHANGE_PATH               0x72
113 #define AVRCP_GET_ITEM_ATTRIBUTES       0x73
114 #define AVRCP_PLAY_ITEM                 0x74
115 #define AVRCP_GET_TOTAL_NUMBER_OF_ITEMS 0x75
116 #define AVRCP_SEARCH                    0x80
117 #define AVRCP_ADD_TO_NOW_PLAYING        0x90
118 #define AVRCP_GENERAL_REJECT            0xA0
119
120 /* Capabilities for AVRCP_GET_CAPABILITIES pdu */
121 #define CAP_COMPANY_ID          0x02
122 #define CAP_EVENTS_SUPPORTED    0x03
123
124 #define AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH 5
125 #define AVRCP_GET_CAPABILITIES_PARAM_LENGTH 1
126
127 #define AVRCP_FEATURE_CATEGORY_1        0x0001
128 #define AVRCP_FEATURE_CATEGORY_2        0x0002
129 #define AVRCP_FEATURE_CATEGORY_3        0x0004
130 #define AVRCP_FEATURE_CATEGORY_4        0x0008
131 #define AVRCP_FEATURE_PLAYER_SETTINGS   0x0010
132 #define AVRCP_FEATURE_BROWSING                  0x0040
133
134 #define AVRCP_BATTERY_STATUS_NORMAL             0
135 #define AVRCP_BATTERY_STATUS_WARNING            1
136 #define AVRCP_BATTERY_STATUS_CRITICAL           2
137 #define AVRCP_BATTERY_STATUS_EXTERNAL           3
138 #define AVRCP_BATTERY_STATUS_FULL_CHARGE        4
139
140 #define AVRCP_CHARSET_UTF8              106
141
142 #define AVRCP_BROWSING_TIMEOUT          1
143 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
144 #define AVRCP_CT_VERSION                0x0104
145 #define AVRCP_TG_VERSION                0x0103
146 #else
147 #define AVRCP_CT_VERSION                0x0106
148 #define AVRCP_TG_VERSION                0x0105
149 #endif
150 #define AVRCP_SCOPE_MEDIA_PLAYER_LIST                   0x00
151 #define AVRCP_SCOPE_MEDIA_PLAYER_VFS                    0x01
152 #define AVRCP_SCOPE_SEARCH                              0x02
153 #define AVRCP_SCOPE_NOW_PLAYING                 0x03
154
155 #if __BYTE_ORDER == __LITTLE_ENDIAN
156
157 struct avrcp_header {
158         uint8_t company_id[3];
159         uint8_t pdu_id;
160         uint8_t packet_type:2;
161         uint8_t rsvd:6;
162         uint16_t params_len;
163         uint8_t params[0];
164 } __attribute__ ((packed));
165 #define AVRCP_HEADER_LENGTH 7
166
167 #elif __BYTE_ORDER == __BIG_ENDIAN
168
169 struct avrcp_header {
170         uint8_t company_id[3];
171         uint8_t pdu_id;
172         uint8_t rsvd:6;
173         uint8_t packet_type:2;
174         uint16_t params_len;
175         uint8_t params[0];
176 } __attribute__ ((packed));
177 #define AVRCP_HEADER_LENGTH 7
178
179 #else
180 #error "Unknown byte order"
181 #endif
182
183 #define AVRCP_MTU       (AVC_MTU - AVC_HEADER_LENGTH)
184 #define AVRCP_PDU_MTU   (AVRCP_MTU - AVRCP_HEADER_LENGTH)
185
186 struct avrcp_browsing_header {
187         uint8_t pdu_id;
188         uint16_t param_len;
189         uint8_t params[0];
190 } __attribute__ ((packed));
191 #define AVRCP_BROWSING_HEADER_LENGTH 3
192
193 struct get_folder_items_rsp {
194         uint8_t status;
195         uint16_t uid_counter;
196         uint16_t num_items;
197         uint8_t data[0];
198 } __attribute__ ((packed));
199
200 struct folder_item {
201         uint8_t type;
202         uint16_t len;
203         uint8_t data[0];
204 } __attribute__ ((packed));
205
206 struct player_item {
207         uint16_t player_id;
208         uint8_t type;
209         uint32_t subtype;
210         uint8_t status;
211         uint8_t features[16];
212         uint16_t charset;
213         uint16_t namelen;
214         char name[0];
215 } __attribute__ ((packed));
216
217 struct avrcp_server {
218         struct btd_adapter *adapter;
219         uint32_t tg_record_id;
220         uint32_t ct_record_id;
221         GSList *players;
222         GSList *sessions;
223 };
224
225 struct pending_pdu {
226         uint8_t pdu_id;
227         GList *attr_ids;
228         uint16_t offset;
229 };
230
231 struct pending_list_items {
232         GSList *items;
233         uint32_t start;
234         uint32_t end;
235         uint64_t total;
236 };
237
238 struct avrcp_player {
239         struct avrcp_server *server;
240         GSList *sessions;
241         uint16_t id;
242         uint8_t scope;
243         uint64_t uid;
244         uint16_t uid_counter;
245         bool browsed;
246         bool addressed;
247         uint8_t *features;
248         char *path;
249         guint changed_id;
250
251         struct pending_list_items *p;
252         char *change_path;
253         uint64_t change_uid;
254
255         struct avrcp_player_cb *cb;
256         void *user_data;
257         GDestroyNotify destroy;
258 };
259
260 struct avrcp_data {
261         struct avrcp_player *player;
262         uint16_t version;
263         int features;
264         GSList *players;
265 };
266
267 struct avrcp {
268         struct avrcp_server *server;
269         struct avctp *conn;
270         struct btd_device *dev;
271         struct avrcp_data *target;
272         struct avrcp_data *controller;
273
274         const struct passthrough_handler *passthrough_handlers;
275         const struct control_pdu_handler *control_handlers;
276
277         unsigned int passthrough_id;
278         unsigned int control_id;
279         unsigned int browsing_id;
280         unsigned int browsing_timer;
281         uint16_t supported_events;
282         uint16_t registered_events;
283         uint8_t transaction;
284         uint8_t transaction_events[AVRCP_EVENT_LAST + 1];
285         struct pending_pdu *pending_pdu;
286 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
287         uint16_t remote_supported_events;
288         uint32_t playback_status_id;
289 #endif
290 };
291
292 struct passthrough_handler {
293         uint8_t op;
294         bool (*func) (struct avrcp *session);
295 };
296
297 struct control_pdu_handler {
298         uint8_t pdu_id;
299         uint8_t code;
300         uint8_t (*func) (struct avrcp *session, struct avrcp_header *pdu,
301                                                         uint8_t transaction);
302 };
303
304 static struct {
305         uint8_t feature_bit;
306         uint8_t avc;
307 } passthrough_map[] = {
308         { 0, AVC_SELECT },
309         { 1, AVC_UP },
310         { 2, AVC_DOWN },
311         { 3, AVC_LEFT },
312         { 4, AVC_RIGHT },
313         { 5, AVC_RIGHT_UP },
314         { 6, AVC_RIGHT_DOWN },
315         { 7, AVC_LEFT_UP },
316         { 8, AVC_LEFT_DOWN },
317         { 9, AVC_ROOT_MENU },
318         { 10, AVC_SETUP_MENU },
319         { 11, AVC_CONTENTS_MENU },
320         { 12, AVC_FAVORITE_MENU },
321         { 13, AVC_EXIT },
322         { 14, AVC_0 },
323         { 15, AVC_1 },
324         { 16, AVC_2 },
325         { 17, AVC_3 },
326         { 18, AVC_4 },
327         { 19, AVC_5 },
328         { 20, AVC_6 },
329         { 21, AVC_7 },
330         { 22, AVC_8 },
331         { 23, AVC_9 },
332         { 24, AVC_DOT },
333         { 25, AVC_ENTER },
334         { 26, AVC_CLEAR },
335         { 27, AVC_CHANNEL_UP },
336         { 28, AVC_CHANNEL_DOWN },
337         { 29, AVC_CHANNEL_PREVIOUS },
338         { 30, AVC_SOUND_SELECT },
339         { 31, AVC_INPUT_SELECT },
340         { 32, AVC_INFO },
341         { 33, AVC_HELP },
342         { 34, AVC_PAGE_UP },
343         { 35, AVC_PAGE_DOWN },
344         { 36, AVC_POWER },
345         { 37, AVC_VOLUME_UP },
346         { 38, AVC_VOLUME_DOWN },
347         { 39, AVC_MUTE },
348         { 40, AVC_PLAY },
349         { 41, AVC_STOP },
350         { 42, AVC_PAUSE },
351         { 43, AVC_RECORD },
352         { 44, AVC_REWIND },
353         { 45, AVC_FAST_FORWARD },
354         { 46, AVC_EJECT },
355         { 47, AVC_FORWARD },
356         { 48, AVC_BACKWARD },
357         { 49, AVC_ANGLE },
358         { 50, AVC_SUBPICTURE },
359         { 51, AVC_F1 },
360         { 52, AVC_F2 },
361         { 53, AVC_F3 },
362         { 54, AVC_F4 },
363         { 55, AVC_F5 },
364         { 56, AVC_VENDOR_UNIQUE },
365         { 0xff, 0xff }
366 };
367
368 static GSList *servers = NULL;
369 static unsigned int avctp_id = 0;
370
371 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
372 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
373 static uint16_t adapter_avrcp_tg_ver = 0;
374 #endif
375 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
376 static uint16_t adapter_avrcp_ct_ver = 0;
377 #endif
378 #endif
379
380 /* Default feature bit mask for media player */
381 static uint8_t default_features[16];
382
383 /* Company IDs supported by this device */
384 static uint32_t company_ids[] = {
385         IEEEID_BTSIG,
386 };
387
388 static void avrcp_register_notification(struct avrcp *session, uint8_t event);
389 static GList *player_list_settings(struct avrcp_player *player);
390
391 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
392 void avrcp_stop_position_timer(void);
393 unsigned int pos_timer_id = 0;
394 #endif
395
396 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
397 static sdp_record_t *avrcp_ct_record(void)
398 {
399         sdp_list_t *svclass_id, *pfseq, *apseq, *apseq1, *root;
400         uuid_t root_uuid, l2cap, avctp, avrct, avrctr;
401         sdp_profile_desc_t profile[1];
402         sdp_list_t *aproto, *aproto1, *proto[2], *proto1[2];
403         sdp_record_t *record;
404         sdp_data_t *psm[2], *version, *features;
405         uint16_t lp = AVCTP_CONTROL_PSM, ap = AVCTP_BROWSING_PSM;
406 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
407         uint16_t avctp_ver = 0x0104;
408         uint16_t feat = 0;
409 #ifdef ENABLE_AVRCP_CATEGORY1
410         feat = AVRCP_FEATURE_CATEGORY_1;
411 #endif
412 #ifdef ENABLE_AVRCP_CATEGORY2
413         feat = feat | AVRCP_FEATURE_CATEGORY_2;
414 #endif
415 #else
416         uint16_t avctp_ver = 0x0103;
417         uint16_t feat = (AVRCP_FEATURE_CATEGORY_1 |
418                                                 AVRCP_FEATURE_CATEGORY_2 |
419                                                 AVRCP_FEATURE_CATEGORY_3 |
420                                                 AVRCP_FEATURE_CATEGORY_4 |
421                                                 AVRCP_FEATURE_BROWSING);
422 #endif
423
424         record = sdp_record_alloc();
425         if (!record)
426                 return NULL;
427
428         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
429         root = sdp_list_append(NULL, &root_uuid);
430         sdp_set_browse_groups(record, root);
431
432         /* Service Class ID List */
433         sdp_uuid16_create(&avrct, AV_REMOTE_SVCLASS_ID);
434         svclass_id = sdp_list_append(NULL, &avrct);
435         sdp_uuid16_create(&avrctr, AV_REMOTE_CONTROLLER_SVCLASS_ID);
436         svclass_id = sdp_list_append(svclass_id, &avrctr);
437         sdp_set_service_classes(record, svclass_id);
438
439         /* Protocol Descriptor List */
440         sdp_uuid16_create(&l2cap, L2CAP_UUID);
441         proto[0] = sdp_list_append(NULL, &l2cap);
442         psm[0] = sdp_data_alloc(SDP_UINT16, &lp);
443         proto[0] = sdp_list_append(proto[0], psm[0]);
444         apseq = sdp_list_append(NULL, proto[0]);
445
446         sdp_uuid16_create(&avctp, AVCTP_UUID);
447         proto[1] = sdp_list_append(NULL, &avctp);
448         version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
449         proto[1] = sdp_list_append(proto[1], version);
450         apseq = sdp_list_append(apseq, proto[1]);
451
452         aproto = sdp_list_append(NULL, apseq);
453         sdp_set_access_protos(record, aproto);
454
455         /* Additional Protocol Descriptor List */
456         sdp_uuid16_create(&l2cap, L2CAP_UUID);
457         proto1[0] = sdp_list_append(NULL, &l2cap);
458         psm[1] = sdp_data_alloc(SDP_UINT16, &ap);
459         proto1[0] = sdp_list_append(proto1[0], psm[1]);
460         apseq1 = sdp_list_append(NULL, proto1[0]);
461
462         sdp_uuid16_create(&avctp, AVCTP_UUID);
463         proto1[1] = sdp_list_append(NULL, &avctp);
464         proto1[1] = sdp_list_append(proto1[1], version);
465         apseq1 = sdp_list_append(apseq1, proto1[1]);
466
467         aproto1 = sdp_list_append(NULL, apseq1);
468         sdp_set_add_access_protos(record, aproto1);
469
470         /* Bluetooth Profile Descriptor List */
471         sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
472         profile[0].version = AVRCP_CT_VERSION;
473 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
474         adapter_avrcp_ct_ver = AVRCP_CT_VERSION;
475 #endif
476         pfseq = sdp_list_append(NULL, &profile[0]);
477         sdp_set_profile_descs(record, pfseq);
478
479         features = sdp_data_alloc(SDP_UINT16, &feat);
480         sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
481
482         sdp_set_info_attr(record, "AVRCP CT", NULL, NULL);
483
484         free(psm[0]);
485         free(psm[1]);
486         free(version);
487         sdp_list_free(proto[0], NULL);
488         sdp_list_free(proto[1], NULL);
489         sdp_list_free(apseq, NULL);
490         sdp_list_free(proto1[0], NULL);
491         sdp_list_free(proto1[1], NULL);
492         sdp_list_free(aproto1, NULL);
493         sdp_list_free(apseq1, NULL);
494         sdp_list_free(pfseq, NULL);
495         sdp_list_free(aproto, NULL);
496         sdp_list_free(root, NULL);
497         sdp_list_free(svclass_id, NULL);
498
499         return record;
500 }
501 #endif
502
503 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
504 static sdp_record_t *avrcp_tg_record(void)
505 {
506         sdp_list_t *svclass_id, *pfseq, *apseq, *root, *apseq_browsing;
507         uuid_t root_uuid, l2cap, avctp, avrtg;
508         sdp_profile_desc_t profile[1];
509         sdp_list_t *aproto_control, *proto_control[2];
510         sdp_record_t *record;
511         sdp_data_t *psm_control, *version, *features, *psm_browsing;
512 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
513         sdp_list_t *aproto_browsing;
514 #endif
515         sdp_list_t *proto_browsing[2] = {0};
516         uint16_t lp = AVCTP_CONTROL_PSM;
517         uint16_t lp_browsing = AVCTP_BROWSING_PSM;
518 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
519         uint16_t avctp_ver = 0x0104;
520         uint16_t feat = 0;
521 #ifdef ENABLE_AVRCP_CATEGORY1
522         feat = AVRCP_FEATURE_CATEGORY_1 |
523                 AVRCP_FEATURE_PLAYER_SETTINGS;
524 #endif
525 #ifdef ENABLE_AVRCP_CATEGORY2
526         feat = feat | AVRCP_FEATURE_CATEGORY_2;
527 #endif
528 #else
529         uint16_t avctp_ver = 0x0103;
530         uint16_t feat = (AVRCP_FEATURE_CATEGORY_1 |
531                                         AVRCP_FEATURE_CATEGORY_2 |
532                                         AVRCP_FEATURE_CATEGORY_3 |
533                                         AVRCP_FEATURE_CATEGORY_4 |
534                                         AVRCP_FEATURE_BROWSING |
535                                         AVRCP_FEATURE_PLAYER_SETTINGS);
536 #endif
537         record = sdp_record_alloc();
538         if (!record)
539                 return NULL;
540
541         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
542         root = sdp_list_append(NULL, &root_uuid);
543         sdp_set_browse_groups(record, root);
544
545         /* Service Class ID List */
546         sdp_uuid16_create(&avrtg, AV_REMOTE_TARGET_SVCLASS_ID);
547         svclass_id = sdp_list_append(NULL, &avrtg);
548         sdp_set_service_classes(record, svclass_id);
549
550         /* Protocol Descriptor List */
551         sdp_uuid16_create(&l2cap, L2CAP_UUID);
552         proto_control[0] = sdp_list_append(NULL, &l2cap);
553         psm_control = sdp_data_alloc(SDP_UINT16, &lp);
554         proto_control[0] = sdp_list_append(proto_control[0], psm_control);
555         apseq = sdp_list_append(NULL, proto_control[0]);
556
557         sdp_uuid16_create(&avctp, AVCTP_UUID);
558         proto_control[1] = sdp_list_append(NULL, &avctp);
559         version = sdp_data_alloc(SDP_UINT16, &avctp_ver);
560         proto_control[1] = sdp_list_append(proto_control[1], version);
561         apseq = sdp_list_append(apseq, proto_control[1]);
562
563         aproto_control = sdp_list_append(NULL, apseq);
564         sdp_set_access_protos(record, aproto_control);
565         proto_browsing[0] = sdp_list_append(NULL, &l2cap);
566         psm_browsing = sdp_data_alloc(SDP_UINT16, &lp_browsing);
567         proto_browsing[0] = sdp_list_append(proto_browsing[0], psm_browsing);
568         apseq_browsing = sdp_list_append(NULL, proto_browsing[0]);
569
570         proto_browsing[1] = sdp_list_append(NULL, &avctp);
571         proto_browsing[1] = sdp_list_append(proto_browsing[1], version);
572         apseq_browsing = sdp_list_append(apseq_browsing, proto_browsing[1]);
573
574 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
575         aproto_browsing = sdp_list_append(NULL, apseq_browsing);
576         sdp_set_add_access_protos(record, aproto_browsing);
577 #endif
578
579         /* Bluetooth Profile Descriptor List */
580         sdp_uuid16_create(&profile[0].uuid, AV_REMOTE_PROFILE_ID);
581         profile[0].version = AVRCP_TG_VERSION;
582 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
583         adapter_avrcp_tg_ver = AVRCP_TG_VERSION;
584 #endif
585         pfseq = sdp_list_append(NULL, &profile[0]);
586         sdp_set_profile_descs(record, pfseq);
587
588         features = sdp_data_alloc(SDP_UINT16, &feat);
589         sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
590
591         sdp_set_info_attr(record, "AVRCP TG", NULL, NULL);
592
593         free(psm_browsing);
594         sdp_list_free(proto_browsing[0], NULL);
595         sdp_list_free(proto_browsing[1], NULL);
596         sdp_list_free(apseq_browsing, NULL);
597 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
598         sdp_list_free(aproto_browsing, NULL);
599 #endif
600
601         free(psm_control);
602         free(version);
603         sdp_list_free(proto_control[0], NULL);
604         sdp_list_free(proto_control[1], NULL);
605         sdp_list_free(apseq, NULL);
606         sdp_list_free(aproto_control, NULL);
607         sdp_list_free(pfseq, NULL);
608         sdp_list_free(root, NULL);
609         sdp_list_free(svclass_id, NULL);
610
611         return record;
612 }
613 #endif
614
615 static void populate_default_features(void)
616 {
617         int i;
618
619         for (i = 0; passthrough_map[i].feature_bit != 0xff; i++) {
620                 if (avctp_supports_avc(passthrough_map[i].avc)) {
621                         uint8_t bit = passthrough_map[i].feature_bit;
622
623                         default_features[bit >> 3] |= (1 << (bit & 7));
624                 }
625         }
626
627         /* supports at least AVRCP 1.4 */
628         default_features[7] |= (1 << 2);
629 }
630
631 static unsigned int attr_get_max_val(uint8_t attr)
632 {
633         switch (attr) {
634         case AVRCP_ATTRIBUTE_EQUALIZER:
635                 return AVRCP_EQUALIZER_ON;
636         case AVRCP_ATTRIBUTE_REPEAT_MODE:
637 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
638                 return AVRCP_REPEAT_MODE_ALL;
639 #else
640                 return AVRCP_REPEAT_MODE_GROUP;
641 #endif
642         case AVRCP_ATTRIBUTE_SHUFFLE:
643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
644                 return AVRCP_SHUFFLE_ALL;
645 #else
646                 return AVRCP_SHUFFLE_GROUP;
647 #endif
648         case AVRCP_ATTRIBUTE_SCAN:
649                 return AVRCP_SCAN_GROUP;
650         }
651
652         return 0;
653 }
654
655 static const char *battery_status_to_str(uint8_t status)
656 {
657         switch (status) {
658         case AVRCP_BATTERY_STATUS_NORMAL:
659                 return "normal";
660         case AVRCP_BATTERY_STATUS_WARNING:
661                 return "warning";
662         case AVRCP_BATTERY_STATUS_CRITICAL:
663                 return "critical";
664         case AVRCP_BATTERY_STATUS_EXTERNAL:
665                 return "external";
666         case AVRCP_BATTERY_STATUS_FULL_CHARGE:
667                 return "fullcharge";
668         }
669
670         return NULL;
671 }
672
673 /*
674  * get_company_id:
675  *
676  * Get three-byte Company_ID from incoming AVRCP message
677  */
678 static uint32_t get_company_id(const uint8_t cid[3])
679 {
680         return cid[0] << 16 | cid[1] << 8 | cid[2];
681 }
682
683 /*
684  * set_company_id:
685  *
686  * Set three-byte Company_ID into outgoing AVRCP message
687  */
688 static void set_company_id(uint8_t cid[3], uint32_t cid_in)
689 {
690         cid[0] = (cid_in & 0xff0000) >> 16;
691         cid[1] = (cid_in & 0x00ff00) >> 8;
692         cid[2] = (cid_in & 0x0000ff);
693 }
694
695 static const char *attr_to_str(uint8_t attr)
696 {
697         switch (attr) {
698         case AVRCP_ATTRIBUTE_EQUALIZER:
699                 return "Equalizer";
700         case AVRCP_ATTRIBUTE_REPEAT_MODE:
701                 return "Repeat";
702         case AVRCP_ATTRIBUTE_SHUFFLE:
703                 return "Shuffle";
704         case AVRCP_ATTRIBUTE_SCAN:
705                 return "Scan";
706         }
707
708         return NULL;
709 }
710
711 static int attrval_to_val(uint8_t attr, const char *value)
712 {
713         int ret;
714
715         switch (attr) {
716         case AVRCP_ATTRIBUTE_EQUALIZER:
717                 if (!strcmp(value, "off"))
718                         ret = AVRCP_EQUALIZER_OFF;
719                 else if (!strcmp(value, "on"))
720                         ret = AVRCP_EQUALIZER_ON;
721                 else
722                         ret = -EINVAL;
723
724                 return ret;
725         case AVRCP_ATTRIBUTE_REPEAT_MODE:
726                 if (!strcmp(value, "off"))
727                         ret = AVRCP_REPEAT_MODE_OFF;
728                 else if (!strcmp(value, "singletrack"))
729                         ret = AVRCP_REPEAT_MODE_SINGLE;
730                 else if (!strcmp(value, "alltracks"))
731                         ret = AVRCP_REPEAT_MODE_ALL;
732                 else if (!strcmp(value, "group"))
733                         ret = AVRCP_REPEAT_MODE_GROUP;
734                 else
735                         ret = -EINVAL;
736
737                 return ret;
738         case AVRCP_ATTRIBUTE_SHUFFLE:
739                 if (!strcmp(value, "off"))
740                         ret = AVRCP_SHUFFLE_OFF;
741                 else if (!strcmp(value, "alltracks"))
742                         ret = AVRCP_SHUFFLE_ALL;
743                 else if (!strcmp(value, "group"))
744                         ret = AVRCP_SHUFFLE_GROUP;
745                 else
746                         ret = -EINVAL;
747
748                 return ret;
749         case AVRCP_ATTRIBUTE_SCAN:
750                 if (!strcmp(value, "off"))
751                         ret = AVRCP_SCAN_OFF;
752                 else if (!strcmp(value, "alltracks"))
753                         ret = AVRCP_SCAN_ALL;
754                 else if (!strcmp(value, "group"))
755                         ret = AVRCP_SCAN_GROUP;
756                 else
757                         ret = -EINVAL;
758
759                 return ret;
760         }
761
762         return -EINVAL;
763 }
764
765 static int attr_to_val(const char *str)
766 {
767         if (!strcasecmp(str, "Equalizer"))
768                 return AVRCP_ATTRIBUTE_EQUALIZER;
769         else if (!strcasecmp(str, "Repeat"))
770                 return AVRCP_ATTRIBUTE_REPEAT_MODE;
771         else if (!strcasecmp(str, "Shuffle"))
772                 return AVRCP_ATTRIBUTE_SHUFFLE;
773         else if (!strcasecmp(str, "Scan"))
774                 return AVRCP_ATTRIBUTE_SCAN;
775
776         return -EINVAL;
777 }
778
779 static int player_get_setting(struct avrcp_player *player, uint8_t id)
780 {
781         const char *key;
782         const char *value;
783
784         if (player == NULL)
785                 return -ENOENT;
786
787         key = attr_to_str(id);
788         if (key == NULL)
789                 return -EINVAL;
790
791         value = player->cb->get_setting(key, player->user_data);
792         if (value == NULL)
793                 return -EINVAL;
794
795         return attrval_to_val(id, value);
796 }
797
798 static int play_status_to_val(const char *status)
799 {
800         if (!strcasecmp(status, "stopped"))
801                 return AVRCP_PLAY_STATUS_STOPPED;
802         else if (!strcasecmp(status, "playing"))
803                 return AVRCP_PLAY_STATUS_PLAYING;
804         else if (!strcasecmp(status, "paused"))
805                 return AVRCP_PLAY_STATUS_PAUSED;
806         else if (!strcasecmp(status, "forward-seek"))
807                 return AVRCP_PLAY_STATUS_FWD_SEEK;
808         else if (!strcasecmp(status, "reverse-seek"))
809                 return AVRCP_PLAY_STATUS_REV_SEEK;
810         else if (!strcasecmp(status, "error"))
811                 return AVRCP_PLAY_STATUS_ERROR;
812
813         return -EINVAL;
814 }
815
816 static uint16_t player_settings_changed(struct avrcp_player *player,
817                                                 struct avrcp_header *pdu)
818 {
819         GList *settings = player_list_settings(player);
820         int size = 2;
821
822         for (; settings; settings = settings->next) {
823                 const char *key = settings->data;
824                 int attr;
825                 int val;
826
827                 attr = attr_to_val(key);
828                 if (attr < 0)
829                         continue;
830
831                 val = player_get_setting(player, attr);
832                 if (val < 0)
833                         continue;
834
835                 pdu->params[size++] = attr;
836                 pdu->params[size++] = val;
837         }
838
839         g_list_free(settings);
840
841         pdu->params[1] = (size - 2) >> 1;
842         return size;
843 }
844
845 void avrcp_player_event(struct avrcp_player *player, uint8_t id,
846                                                         const void *data)
847 {
848         uint8_t buf[AVRCP_HEADER_LENGTH + 9];
849         struct avrcp_header *pdu = (void *) buf;
850         uint8_t code;
851         uint16_t size;
852         GSList *l;
853 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
854         uint32_t *position_val = NULL;
855 #endif
856
857         if (player->sessions == NULL)
858                 return;
859
860         memset(buf, 0, sizeof(buf));
861
862         set_company_id(pdu->company_id, IEEEID_BTSIG);
863
864         pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
865
866         DBG("id=%u", id);
867
868         if (id != AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED && player->changed_id) {
869                 code = AVC_CTYPE_REJECTED;
870                 size = 1;
871                 pdu->params[0] = AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED;
872                 goto done;
873         }
874
875         code = AVC_CTYPE_CHANGED;
876         pdu->params[0] = id;
877
878         switch (id) {
879         case AVRCP_EVENT_STATUS_CHANGED:
880                 size = 2;
881                 pdu->params[1] = play_status_to_val(data);
882
883                 break;
884         case AVRCP_EVENT_TRACK_CHANGED:
885                 size = 9;
886                 memcpy(&pdu->params[1], data, sizeof(uint64_t));
887
888                 break;
889         case AVRCP_EVENT_TRACK_REACHED_END:
890         case AVRCP_EVENT_TRACK_REACHED_START:
891                 size = 1;
892                 break;
893         case AVRCP_EVENT_SETTINGS_CHANGED:
894 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
895                 size = player_settings_changed(player, pdu);
896 #else
897                 size = player_settings_changed(player, pdu);
898 #endif /* __TIZEN__PATCH__ */
899                 break;
900 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
901         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
902                 size = 5;
903                 position_val = (uint32_t *) data;
904                 *position_val = (*position_val & 0x000000ff) << 24 |
905                                  (*position_val & 0x0000ff00) << 8 |
906                                  (*position_val & 0x00ff0000) >> 8 |
907                                  (*position_val & 0xff000000) >> 24;
908                 memcpy(&pdu->params[1], position_val, sizeof(uint32_t));
909                 break;
910 #endif
911         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
912                 size = 5;
913                 memcpy(&pdu->params[1], &player->id, sizeof(uint16_t));
914                 memcpy(&pdu->params[3], &player->uid_counter, sizeof(uint16_t));
915                 break;
916         case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
917                 size = 1;
918                 break;
919         default:
920                 error("Unknown event %u", id);
921                 return;
922         }
923
924 done:
925         pdu->params_len = htons(size);
926 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
927         if (id == AVRCP_EVENT_PLAYBACK_POS_CHANGED &&
928                         pos_timer_id > 0) {
929                 /* Remove the timer function which was added for register notification.
930                  * As we are sending changed event eariler then time interval.
931                  */
932                 DBG("Removing the timer function added by register notification");
933                 g_source_remove(pos_timer_id);
934                 pos_timer_id = 0;
935         }
936 #endif
937
938         for (l = player->sessions; l; l = l->next) {
939                 struct avrcp *session = l->data;
940                 int err;
941
942                 if (!(session->registered_events & (1 << id)))
943                         continue;
944
945                 err = avctp_send_vendordep(session->conn,
946                                         session->transaction_events[id],
947                                         code, AVC_SUBUNIT_PANEL,
948                                         buf, size + AVRCP_HEADER_LENGTH);
949
950                 if (err < 0)
951                         continue;
952
953                 /* Unregister event as per AVRCP 1.3 spec, section 5.4.2 */
954                 session->registered_events ^= 1 << id;
955         }
956
957         return;
958 }
959
960 static const char *metadata_to_str(uint32_t id)
961 {
962         switch (id) {
963         case AVRCP_MEDIA_ATTRIBUTE_TITLE:
964                 return "Title";
965         case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
966                 return "Artist";
967         case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
968                 return "Album";
969         case AVRCP_MEDIA_ATTRIBUTE_GENRE:
970                 return "Genre";
971         case AVRCP_MEDIA_ATTRIBUTE_TRACK:
972                 return "TrackNumber";
973         case AVRCP_MEDIA_ATTRIBUTE_N_TRACKS:
974                 return "NumberOfTracks";
975         case AVRCP_MEDIA_ATTRIBUTE_DURATION:
976                 return "Duration";
977         }
978
979         return NULL;
980 }
981
982 static const char *player_get_metadata(struct avrcp_player *player,
983                                                                 uint32_t id)
984 {
985         const char *key;
986
987         key = metadata_to_str(id);
988         if (key == NULL)
989                 return NULL;
990
991         if (player != NULL)
992                 return player->cb->get_metadata(key, player->user_data);
993
994         if (id == AVRCP_MEDIA_ATTRIBUTE_TITLE)
995                 return "";
996
997         return NULL;
998 }
999
1000 static uint16_t player_write_media_attribute(struct avrcp_player *player,
1001                                                 uint32_t id, uint8_t *buf,
1002                                                 uint16_t *pos,
1003                                                 uint16_t *offset)
1004 {
1005         uint16_t len;
1006         uint16_t attr_len;
1007         const char *value = NULL;
1008
1009         DBG("%u", id);
1010
1011         value = player_get_metadata(player, id);
1012         if (value == NULL) {
1013                 *offset = 0;
1014                 return 0;
1015         }
1016
1017         attr_len = strlen(value);
1018         value = ((char *) value) + *offset;
1019         len = attr_len - *offset;
1020
1021         if (len > AVRCP_PDU_MTU - *pos) {
1022                 len = AVRCP_PDU_MTU - *pos;
1023                 *offset += len;
1024         } else {
1025                 *offset = 0;
1026         }
1027
1028         memcpy(&buf[*pos], value, len);
1029         *pos += len;
1030
1031         return attr_len;
1032 }
1033
1034 static GList *player_fill_media_attribute(struct avrcp_player *player,
1035                                         GList *attr_ids, uint8_t *buf,
1036                                         uint16_t *pos, uint16_t *offset)
1037 {
1038         struct media_attribute_header {
1039                 uint32_t id;
1040                 uint16_t charset;
1041                 uint16_t len;
1042         } *hdr = NULL;
1043         GList *l;
1044
1045         for (l = attr_ids; l != NULL; l = g_list_delete_link(l, l)) {
1046                 uint32_t attr = GPOINTER_TO_UINT(l->data);
1047                 uint16_t attr_len;
1048
1049                 if (*offset == 0) {
1050                         if (*pos + sizeof(*hdr) >= AVRCP_PDU_MTU)
1051                                 break;
1052
1053                         hdr = (void *) &buf[*pos];
1054                         hdr->id = htonl(attr);
1055                         /* Always use UTF-8 */
1056                         hdr->charset = htons(AVRCP_CHARSET_UTF8);
1057                         *pos += sizeof(*hdr);
1058                 }
1059
1060                 attr_len = player_write_media_attribute(player, attr, buf,
1061                                                                 pos, offset);
1062
1063                 if (hdr != NULL)
1064                         hdr->len = htons(attr_len);
1065
1066                 if (*offset > 0)
1067                         break;
1068         }
1069
1070         return l;
1071 }
1072
1073 static struct pending_pdu *pending_pdu_new(uint8_t pdu_id, GList *attr_ids,
1074                                                         unsigned int offset)
1075 {
1076         struct pending_pdu *pending = g_new(struct pending_pdu, 1);
1077
1078         pending->pdu_id = pdu_id;
1079         pending->attr_ids = attr_ids;
1080         pending->offset = offset;
1081
1082         return pending;
1083 }
1084
1085 static gboolean session_abort_pending_pdu(struct avrcp *session)
1086 {
1087         if (session->pending_pdu == NULL)
1088                 return FALSE;
1089
1090         g_list_free(session->pending_pdu->attr_ids);
1091         g_free(session->pending_pdu);
1092         session->pending_pdu = NULL;
1093
1094         return TRUE;
1095 }
1096
1097 static const char *attrval_to_str(uint8_t attr, uint8_t value)
1098 {
1099         switch (attr) {
1100         case AVRCP_ATTRIBUTE_EQUALIZER:
1101                 switch (value) {
1102                 case AVRCP_EQUALIZER_ON:
1103                         return "on";
1104                 case AVRCP_EQUALIZER_OFF:
1105                         return "off";
1106                 }
1107
1108                 break;
1109         case AVRCP_ATTRIBUTE_REPEAT_MODE:
1110                 switch (value) {
1111                 case AVRCP_REPEAT_MODE_OFF:
1112                         return "off";
1113                 case AVRCP_REPEAT_MODE_SINGLE:
1114                         return "singletrack";
1115                 case AVRCP_REPEAT_MODE_ALL:
1116                         return "alltracks";
1117 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1118                 case AVRCP_REPEAT_MODE_GROUP:
1119                         return "group";
1120 #endif
1121                 }
1122
1123                 break;
1124         /* Shuffle and scan have the same values */
1125         case AVRCP_ATTRIBUTE_SHUFFLE:
1126         case AVRCP_ATTRIBUTE_SCAN:
1127                 switch (value) {
1128                 case AVRCP_SCAN_OFF:
1129                         return "off";
1130                 case AVRCP_SCAN_ALL:
1131                         return "alltracks";
1132 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1133                 case AVRCP_SCAN_GROUP:
1134                         return "group";
1135 #endif
1136                 }
1137
1138                 break;
1139         }
1140
1141         return NULL;
1142 }
1143
1144 static int player_set_setting(struct avrcp_player *player, uint8_t id,
1145                                                                 uint8_t val)
1146 {
1147         const char *key, *value;
1148
1149         key = attr_to_str(id);
1150         if (key == NULL)
1151                 return -EINVAL;
1152
1153         value = attrval_to_str(id, val);
1154         if (value == NULL)
1155                 return -EINVAL;
1156
1157         if (player == NULL)
1158                 return -ENOENT;
1159
1160         return player->cb->set_setting(key, value, player->user_data);
1161 }
1162
1163 static uint8_t avrcp_handle_get_capabilities(struct avrcp *session,
1164                                                 struct avrcp_header *pdu,
1165                                                 uint8_t transaction)
1166 {
1167         uint16_t len = ntohs(pdu->params_len);
1168         unsigned int i;
1169
1170         if (len != 1)
1171                 goto err;
1172
1173         DBG("id=%u", pdu->params[0]);
1174
1175         switch (pdu->params[0]) {
1176         case CAP_COMPANY_ID:
1177                 for (i = 0; i < G_N_ELEMENTS(company_ids); i++) {
1178                         set_company_id(&pdu->params[2 + i * 3],
1179                                                         company_ids[i]);
1180                 }
1181
1182                 pdu->params_len = htons(2 + (3 * G_N_ELEMENTS(company_ids)));
1183                 pdu->params[1] = G_N_ELEMENTS(company_ids);
1184
1185                 return AVC_CTYPE_STABLE;
1186         case CAP_EVENTS_SUPPORTED:
1187                 pdu->params[1] = 0;
1188                 for (i = 1; i <= AVRCP_EVENT_LAST; i++) {
1189                         if (session->supported_events & (1 << i)) {
1190                                 pdu->params[1]++;
1191                                 pdu->params[pdu->params[1] + 1] = i;
1192                         }
1193                 }
1194
1195                 pdu->params_len = htons(2 + pdu->params[1]);
1196                 return AVC_CTYPE_STABLE;
1197         }
1198
1199 err:
1200         pdu->params_len = htons(1);
1201         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1202
1203         return AVC_CTYPE_REJECTED;
1204 }
1205
1206 static struct avrcp_player *target_get_player(struct avrcp *session)
1207 {
1208         if (!session->target)
1209                 return NULL;
1210
1211         return session->target->player;
1212 }
1213
1214 static uint8_t avrcp_handle_list_player_attributes(struct avrcp *session,
1215                                                 struct avrcp_header *pdu,
1216                                                 uint8_t transaction)
1217 {
1218         struct avrcp_player *player = target_get_player(session);
1219         uint16_t len = ntohs(pdu->params_len);
1220         unsigned int i;
1221
1222         if (len != 0) {
1223                 pdu->params_len = htons(1);
1224                 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1225                 return AVC_CTYPE_REJECTED;
1226         }
1227
1228         if (!player)
1229                 goto done;
1230
1231         for (i = 1; i <= AVRCP_ATTRIBUTE_SCAN; i++) {
1232                 if (player_get_setting(player, i) < 0)
1233                         continue;
1234
1235                 len++;
1236                 pdu->params[len] = i;
1237         }
1238
1239 done:
1240         pdu->params[0] = len;
1241         pdu->params_len = htons(len + 1);
1242
1243         return AVC_CTYPE_STABLE;
1244 }
1245
1246 static uint8_t avrcp_handle_list_player_values(struct avrcp *session,
1247                                                 struct avrcp_header *pdu,
1248                                                 uint8_t transaction)
1249 {
1250         struct avrcp_player *player = target_get_player(session);
1251         uint16_t len = ntohs(pdu->params_len);
1252         unsigned int i;
1253
1254         if (len != 1)
1255                 goto err;
1256
1257         if (player_get_setting(player, pdu->params[0]) < 0)
1258                 goto err;
1259
1260         len = attr_get_max_val(pdu->params[0]);
1261
1262         for (i = 1; i <= len; i++)
1263                 pdu->params[i] = i;
1264
1265         pdu->params[0] = len;
1266         pdu->params_len = htons(len + 1);
1267
1268         return AVC_CTYPE_STABLE;
1269
1270 err:
1271         pdu->params_len = htons(1);
1272         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1273         return AVC_CTYPE_REJECTED;
1274 }
1275
1276 static uint32_t str_to_metadata(const char *str)
1277 {
1278         if (strcasecmp(str, "Title") == 0)
1279                 return AVRCP_MEDIA_ATTRIBUTE_TITLE;
1280         else if (strcasecmp(str, "Artist") == 0)
1281                 return AVRCP_MEDIA_ATTRIBUTE_ARTIST;
1282         else if (strcasecmp(str, "Album") == 0)
1283                 return AVRCP_MEDIA_ATTRIBUTE_ALBUM;
1284         else if (strcasecmp(str, "Genre") == 0)
1285                 return AVRCP_MEDIA_ATTRIBUTE_GENRE;
1286         else if (strcasecmp(str, "TrackNumber") == 0)
1287                 return AVRCP_MEDIA_ATTRIBUTE_TRACK;
1288         else if (strcasecmp(str, "NumberOfTracks") == 0)
1289                 return AVRCP_MEDIA_ATTRIBUTE_N_TRACKS;
1290         else if (strcasecmp(str, "Duration") == 0)
1291                 return AVRCP_MEDIA_ATTRIBUTE_DURATION;
1292
1293         return 0;
1294 }
1295
1296 static GList *player_list_metadata(struct avrcp_player *player)
1297 {
1298         GList *l, *attrs = NULL;
1299
1300         if (player == NULL)
1301                 return g_list_prepend(NULL,
1302                                 GUINT_TO_POINTER(AVRCP_MEDIA_ATTRIBUTE_TITLE));
1303
1304         l = player->cb->list_metadata(player->user_data);
1305         for (; l; l = l->next) {
1306                 const char *key = l->data;
1307
1308                 attrs = g_list_append(attrs,
1309                                         GUINT_TO_POINTER(str_to_metadata(key)));
1310         }
1311
1312         return attrs;
1313 }
1314
1315 static uint8_t avrcp_handle_get_element_attributes(struct avrcp *session,
1316                                                 struct avrcp_header *pdu,
1317                                                 uint8_t transaction)
1318 {
1319         struct avrcp_player *player = target_get_player(session);
1320         uint16_t len = ntohs(pdu->params_len);
1321         uint64_t identifier = get_le64(&pdu->params[0]);
1322         uint16_t pos;
1323         uint8_t nattr;
1324         GList *attr_ids;
1325         uint16_t offset;
1326
1327         if (len < 9 || identifier != 0)
1328                 goto err;
1329
1330         nattr = pdu->params[8];
1331
1332         if (len < nattr * sizeof(uint32_t) + 1)
1333                 goto err;
1334
1335         if (!nattr) {
1336                 /*
1337                  * Return all available information, at least
1338                  * title must be returned if there's a track selected.
1339                  */
1340                 attr_ids = player_list_metadata(player);
1341                 len = g_list_length(attr_ids);
1342         } else {
1343                 unsigned int i;
1344                 for (i = 0, len = 0, attr_ids = NULL; i < nattr; i++) {
1345                         uint32_t id;
1346
1347                         id = get_be32(&pdu->params[9] + (i * sizeof(id)));
1348
1349                         /* Don't add invalid attributes */
1350                         if (id == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
1351                                         id > AVRCP_MEDIA_ATTRIBUTE_LAST)
1352                                 continue;
1353
1354                         len++;
1355                         attr_ids = g_list_prepend(attr_ids,
1356                                                         GUINT_TO_POINTER(id));
1357                 }
1358
1359                 attr_ids = g_list_reverse(attr_ids);
1360         }
1361
1362         if (!len)
1363                 goto err;
1364
1365         session_abort_pending_pdu(session);
1366         pos = 1;
1367         offset = 0;
1368         attr_ids = player_fill_media_attribute(player, attr_ids, pdu->params,
1369                                                                 &pos, &offset);
1370
1371         if (attr_ids != NULL) {
1372                 session->pending_pdu = pending_pdu_new(pdu->pdu_id, attr_ids,
1373                                                                 offset);
1374                 pdu->packet_type = AVRCP_PACKET_TYPE_START;
1375         }
1376
1377         pdu->params[0] = len;
1378         pdu->params_len = htons(pos);
1379
1380         return AVC_CTYPE_STABLE;
1381 err:
1382         pdu->params_len = htons(1);
1383         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1384         return AVC_CTYPE_REJECTED;
1385 }
1386
1387 static uint8_t avrcp_handle_get_current_player_value(struct avrcp *session,
1388                                                 struct avrcp_header *pdu,
1389                                                 uint8_t transaction)
1390 {
1391         struct avrcp_player *player = target_get_player(session);
1392         uint16_t len = ntohs(pdu->params_len);
1393         uint8_t *settings;
1394         unsigned int i;
1395
1396         if (len <= 1 || pdu->params[0] != len - 1)
1397                 goto err;
1398
1399         /*
1400          * Save a copy of requested settings because we can override them
1401          * while responding
1402          */
1403         settings = g_memdup(&pdu->params[1], pdu->params[0]);
1404         len = 0;
1405
1406         /*
1407          * From sec. 5.7 of AVRCP 1.3 spec, we should igore non-existent IDs
1408          * and send a response with the existent ones. Only if all IDs are
1409          * non-existent we should send an error.
1410          */
1411         for (i = 0; i < pdu->params[0]; i++) {
1412                 int val;
1413
1414                 if (settings[i] < AVRCP_ATTRIBUTE_EQUALIZER ||
1415                                         settings[i] > AVRCP_ATTRIBUTE_SCAN) {
1416                         DBG("Ignoring %u", settings[i]);
1417                         continue;
1418                 }
1419
1420                 val = player_get_setting(player, settings[i]);
1421                 if (val < 0)
1422                         continue;
1423
1424                 pdu->params[++len] = settings[i];
1425                 pdu->params[++len] = val;
1426         }
1427
1428         g_free(settings);
1429
1430         if (len) {
1431                 pdu->params[0] = len / 2;
1432                 pdu->params_len = htons(len + 1);
1433
1434                 return AVC_CTYPE_STABLE;
1435         }
1436
1437         error("No valid attributes in request");
1438
1439 err:
1440         pdu->params_len = htons(1);
1441         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1442
1443         return AVC_CTYPE_REJECTED;
1444 }
1445
1446 static uint8_t avrcp_handle_set_player_value(struct avrcp *session,
1447                                                 struct avrcp_header *pdu,
1448                                                 uint8_t transaction)
1449 {
1450         struct avrcp_player *player = target_get_player(session);
1451         uint16_t len = ntohs(pdu->params_len);
1452         unsigned int i;
1453         uint8_t *param;
1454
1455         if (len < 3 || len > 2 * pdu->params[0] + 1U || player == NULL)
1456                 goto err;
1457
1458         /*
1459          * From sec. 5.7 of AVRCP 1.3 spec, we should igore non-existent IDs
1460          * and set the existent ones. Sec. 5.2.4 is not clear however how to
1461          * indicate that a certain ID was not accepted. If at least one
1462          * attribute is valid, we respond with no parameters. Otherwise an
1463          * AVRCP_STATUS_INVALID_PARAM is sent.
1464          */
1465         for (len = 0, i = 0, param = &pdu->params[1]; i < pdu->params[0];
1466                                                         i++, param += 2) {
1467                 if (player_set_setting(player, param[0], param[1]) < 0)
1468                         continue;
1469
1470                 len++;
1471         }
1472
1473         if (len) {
1474                 pdu->params_len = 0;
1475
1476                 return AVC_CTYPE_ACCEPTED;
1477         }
1478
1479 err:
1480         pdu->params_len = htons(1);
1481         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1482         return AVC_CTYPE_REJECTED;
1483 }
1484
1485 static uint8_t avrcp_handle_displayable_charset(struct avrcp *session,
1486                                                 struct avrcp_header *pdu,
1487                                                 uint8_t transaction)
1488 {
1489         uint16_t len = ntohs(pdu->params_len);
1490
1491         if (len < 3) {
1492                 pdu->params_len = htons(1);
1493                 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1494                 return AVC_CTYPE_REJECTED;
1495         }
1496
1497         /*
1498          * We acknowledge the commands, but we always use UTF-8 for
1499          * encoding since CT is obliged to support it.
1500          */
1501         pdu->params_len = 0;
1502         return AVC_CTYPE_STABLE;
1503 }
1504
1505 static uint8_t avrcp_handle_ct_battery_status(struct avrcp *session,
1506                                                 struct avrcp_header *pdu,
1507                                                 uint8_t transaction)
1508 {
1509         uint16_t len = ntohs(pdu->params_len);
1510         const char *valstr;
1511
1512         if (len != 1)
1513                 goto err;
1514
1515         valstr = battery_status_to_str(pdu->params[0]);
1516         if (valstr == NULL)
1517                 goto err;
1518
1519         pdu->params_len = 0;
1520
1521         return AVC_CTYPE_STABLE;
1522
1523 err:
1524         pdu->params_len = htons(1);
1525         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1526         return AVC_CTYPE_REJECTED;
1527 }
1528
1529 static uint32_t player_get_position(struct avrcp_player *player)
1530 {
1531         if (player == NULL)
1532                 return 0;
1533
1534         return player->cb->get_position(player->user_data);
1535 }
1536
1537 static uint32_t player_get_duration(struct avrcp_player *player)
1538 {
1539         uint32_t num;
1540
1541         if (player == NULL)
1542                 return UINT32_MAX;
1543
1544         num = player->cb->get_duration(player->user_data);
1545         if (num == 0)
1546                 return UINT32_MAX;
1547
1548         return num;
1549 }
1550
1551 static uint8_t player_get_status(struct avrcp_player *player)
1552 {
1553         const char *value;
1554
1555         if (player == NULL)
1556                 return AVRCP_PLAY_STATUS_STOPPED;
1557
1558         value = player->cb->get_status(player->user_data);
1559         if (value == NULL)
1560                 return AVRCP_PLAY_STATUS_STOPPED;
1561
1562         return play_status_to_val(value);
1563 }
1564
1565 static uint16_t player_get_id(struct avrcp_player *player)
1566 {
1567         if (player == NULL)
1568                 return 0x0000;
1569
1570         return player->id;
1571 }
1572
1573 static uint16_t player_get_uid_counter(struct avrcp_player *player)
1574 {
1575         if (player == NULL)
1576                 return 0x0000;
1577
1578         return player->uid_counter;
1579 }
1580
1581 static uint8_t avrcp_handle_get_play_status(struct avrcp *session,
1582                                                 struct avrcp_header *pdu,
1583                                                 uint8_t transaction)
1584 {
1585         struct avrcp_player *player = target_get_player(session);
1586         uint16_t len = ntohs(pdu->params_len);
1587         uint32_t position;
1588         uint32_t duration;
1589
1590         if (len != 0) {
1591                 pdu->params_len = htons(1);
1592                 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1593                 return AVC_CTYPE_REJECTED;
1594         }
1595
1596         position = player_get_position(player);
1597         duration = player_get_duration(player);
1598
1599         position = htonl(position);
1600         duration = htonl(duration);
1601
1602         memcpy(&pdu->params[0], &duration, 4);
1603         memcpy(&pdu->params[4], &position, 4);
1604         pdu->params[8] = player_get_status(player);
1605
1606         pdu->params_len = htons(9);
1607
1608         return AVC_CTYPE_STABLE;
1609 }
1610
1611 static uint64_t player_get_uid(struct avrcp_player *player)
1612 {
1613         if (player == NULL)
1614                 return UINT64_MAX;
1615
1616         return player->cb->get_uid(player->user_data);
1617 }
1618
1619 static GList *player_list_settings(struct avrcp_player *player)
1620 {
1621         if (player == NULL)
1622                 return NULL;
1623
1624         return player->cb->list_settings(player->user_data);
1625 }
1626
1627 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1628 static uint32_t player_get_playback_position(struct avrcp_player *player)
1629 {
1630         if (player == NULL)
1631                 return UINT32_MAX;
1632
1633         return player->cb->get_position(player->user_data);
1634 }
1635 #endif
1636
1637 static bool avrcp_handle_play(struct avrcp *session)
1638 {
1639         struct avrcp_player *player = target_get_player(session);
1640
1641         if (player == NULL)
1642                 return false;
1643
1644         return player->cb->play(player->user_data);
1645 }
1646
1647 static bool avrcp_handle_stop(struct avrcp *session)
1648 {
1649         struct avrcp_player *player = target_get_player(session);
1650
1651         if (player == NULL)
1652                 return false;
1653
1654         return player->cb->stop(player->user_data);
1655 }
1656
1657 static bool avrcp_handle_pause(struct avrcp *session)
1658 {
1659         struct avrcp_player *player = target_get_player(session);
1660
1661         if (player == NULL)
1662                 return false;
1663
1664         return player->cb->pause(player->user_data);
1665 }
1666
1667 static bool avrcp_handle_next(struct avrcp *session)
1668 {
1669         struct avrcp_player *player = target_get_player(session);
1670
1671         if (player == NULL)
1672                 return false;
1673
1674         return player->cb->next(player->user_data);
1675 }
1676
1677 static bool avrcp_handle_previous(struct avrcp *session)
1678 {
1679         struct avrcp_player *player = target_get_player(session);
1680
1681         if (player == NULL)
1682                 return false;
1683
1684         return player->cb->previous(player->user_data);
1685 }
1686
1687 static const struct passthrough_handler passthrough_handlers[] = {
1688                 { AVC_PLAY, avrcp_handle_play },
1689                 { AVC_STOP, avrcp_handle_stop },
1690                 { AVC_PAUSE, avrcp_handle_pause },
1691                 { AVC_FORWARD, avrcp_handle_next },
1692                 { AVC_BACKWARD, avrcp_handle_previous },
1693                 { },
1694 };
1695
1696 static bool handle_passthrough(struct avctp *conn, uint8_t op, bool pressed,
1697                                                         void *user_data)
1698 {
1699         struct avrcp *session = user_data;
1700         const struct passthrough_handler *handler;
1701
1702         for (handler = session->passthrough_handlers; handler->func;
1703                                                                 handler++) {
1704                 if (handler->op == op)
1705                         break;
1706         }
1707
1708         if (handler->func == NULL)
1709                 return false;
1710
1711         /* Do not trigger handler on release */
1712         if (!pressed)
1713                 return true;
1714
1715         return handler->func(session);
1716 }
1717
1718 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1719 void avrcp_stop_position_timer(void)
1720 {
1721         if (pos_timer_id > 0) {
1722                 DBG("Removing position timer id");
1723                 g_source_remove(pos_timer_id);
1724                 pos_timer_id = 0;
1725         }
1726 }
1727 gboolean send_playback_position_event(gpointer user_data)
1728 {
1729         struct avrcp_player *player = user_data;
1730         uint32_t playback_position;
1731         uint8_t play_status;
1732
1733         play_status = player_get_status(player);
1734         if (play_status != AVRCP_PLAY_STATUS_PLAYING)
1735                 return FALSE;
1736
1737         playback_position = player_get_playback_position(player);
1738         pos_timer_id = 0;
1739         avrcp_player_event(player, AVRCP_EVENT_PLAYBACK_POS_CHANGED,
1740                                                 &playback_position);
1741         return FALSE;
1742 }
1743 #endif
1744
1745 static uint8_t avrcp_handle_register_notification(struct avrcp *session,
1746                                                 struct avrcp_header *pdu,
1747                                                 uint8_t transaction)
1748 {
1749         struct avrcp_player *player = target_get_player(session);
1750         struct btd_device *dev = session->dev;
1751         uint16_t len = ntohs(pdu->params_len);
1752         uint64_t uid;
1753         int8_t volume;
1754 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1755         uint32_t playback_interval;
1756         uint32_t playback_position;
1757         uint8_t play_status;
1758 #endif
1759
1760         /*
1761          * 1 byte for EventID, 4 bytes for Playback interval but the latest
1762          * one is applicable only for EVENT_PLAYBACK_POS_CHANGED. See AVRCP
1763          * 1.3 spec, section 5.4.2.
1764          */
1765         if (len != 5)
1766                 goto err;
1767
1768         /* Check if event is supported otherwise reject */
1769         if (!(session->supported_events & (1 << pdu->params[0])))
1770                 goto err;
1771
1772         switch (pdu->params[0]) {
1773         case AVRCP_EVENT_STATUS_CHANGED:
1774                 len = 2;
1775                 pdu->params[1] = player_get_status(player);
1776
1777                 break;
1778         case AVRCP_EVENT_TRACK_CHANGED:
1779                 len = 9;
1780                 uid = player_get_uid(player);
1781                 memcpy(&pdu->params[1], &uid, sizeof(uint64_t));
1782
1783                 break;
1784         case AVRCP_EVENT_TRACK_REACHED_END:
1785         case AVRCP_EVENT_TRACK_REACHED_START:
1786                 len = 1;
1787                 break;
1788         case AVRCP_EVENT_SETTINGS_CHANGED:
1789                 len = player_settings_changed(player, pdu);
1790                 break;
1791         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
1792                 len = 5;
1793                 bt_put_be16(player_get_id(player), &pdu->params[1]);
1794                 bt_put_be16(player_get_uid_counter(player), &pdu->params[3]);
1795                 break;
1796         case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
1797                 len = 1;
1798                 break;
1799         case AVRCP_EVENT_VOLUME_CHANGED:
1800                 volume = media_transport_get_device_volume(dev);
1801                 if (volume < 0)
1802                         goto err;
1803
1804                 pdu->params[1] = volume;
1805                 len = 2;
1806
1807                 break;
1808 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1809         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
1810                 len = 5;
1811
1812                 /* time interval in seconds at which the change in playback position
1813                 shall be notified */
1814                 memcpy(&playback_interval, &pdu->params[1], sizeof(uint32_t));
1815                 playback_interval = ((playback_interval>>24)&0xff) |
1816                                     ((playback_interval<<8)&0xff0000) |
1817                                     ((playback_interval>>8)&0xff00) |
1818                                     ((playback_interval<<24)&0xff000000);
1819
1820                 play_status = player_get_status(player);
1821
1822                 if (play_status != AVRCP_PLAY_STATUS_PLAYING) {
1823                         DBG("Play Pos Changed Event is skipped(%d)", play_status);
1824                 } else {
1825                         DBG("Playback interval : %d secs", playback_interval);
1826                         pos_timer_id = g_timeout_add_seconds(
1827                                         playback_interval,
1828                                         send_playback_position_event, player);
1829                 }
1830
1831                 /* retrieve current playback position for interim response */
1832                 playback_position = player_get_playback_position(player);
1833                 playback_position = (playback_position & 0x000000ff) << 24 |
1834                                 (playback_position & 0x0000ff00) << 8 |
1835                                 (playback_position & 0x00ff0000) >> 8 |
1836                                 (playback_position & 0xff000000) >> 24;
1837                 memcpy(&pdu->params[1], &playback_position, sizeof(uint32_t));
1838
1839                 break;
1840 #endif
1841
1842         default:
1843                 /* All other events are not supported yet */
1844                 goto err;
1845         }
1846
1847         /* Register event and save the transaction used */
1848         session->registered_events |= (1 << pdu->params[0]);
1849         session->transaction_events[pdu->params[0]] = transaction;
1850
1851         pdu->params_len = htons(len);
1852
1853         return AVC_CTYPE_INTERIM;
1854
1855 err:
1856         pdu->params_len = htons(1);
1857         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1858         return AVC_CTYPE_REJECTED;
1859 }
1860
1861 static uint8_t avrcp_handle_request_continuing(struct avrcp *session,
1862                                                 struct avrcp_header *pdu,
1863                                                 uint8_t transaction)
1864 {
1865         struct avrcp_player *player = target_get_player(session);
1866         uint16_t len = ntohs(pdu->params_len);
1867         struct pending_pdu *pending;
1868
1869         if (len != 1 || session->pending_pdu == NULL)
1870                 goto err;
1871
1872         pending = session->pending_pdu;
1873
1874         if (pending->pdu_id != pdu->params[0])
1875                 goto err;
1876
1877         len = 0;
1878         pending->attr_ids = player_fill_media_attribute(player,
1879                                                         pending->attr_ids,
1880                                                         pdu->params, &len,
1881                                                         &pending->offset);
1882         pdu->pdu_id = pending->pdu_id;
1883
1884         if (pending->attr_ids == NULL) {
1885                 g_free(session->pending_pdu);
1886                 session->pending_pdu = NULL;
1887                 pdu->packet_type = AVRCP_PACKET_TYPE_END;
1888         } else {
1889                 pdu->packet_type = AVRCP_PACKET_TYPE_CONTINUING;
1890         }
1891
1892         pdu->params_len = htons(len);
1893
1894         return AVC_CTYPE_STABLE;
1895 err:
1896         pdu->params_len = htons(1);
1897         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1898         return AVC_CTYPE_REJECTED;
1899 }
1900
1901 static uint8_t avrcp_handle_abort_continuing(struct avrcp *session,
1902                                                 struct avrcp_header *pdu,
1903                                                 uint8_t transaction)
1904 {
1905         uint16_t len = ntohs(pdu->params_len);
1906         struct pending_pdu *pending;
1907
1908         if (len != 1 || session->pending_pdu == NULL)
1909                 goto err;
1910
1911         pending = session->pending_pdu;
1912
1913         if (pending->pdu_id != pdu->params[0])
1914                 goto err;
1915
1916         session_abort_pending_pdu(session);
1917         pdu->params_len = 0;
1918
1919         return AVC_CTYPE_ACCEPTED;
1920
1921 err:
1922         pdu->params_len = htons(1);
1923         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1924         return AVC_CTYPE_REJECTED;
1925 }
1926
1927 static uint8_t avrcp_handle_set_absolute_volume(struct avrcp *session,
1928                                                 struct avrcp_header *pdu,
1929                                                 uint8_t transaction)
1930 {
1931         uint16_t len = ntohs(pdu->params_len);
1932         int8_t volume;
1933
1934         if (len != 1)
1935                 goto err;
1936
1937         volume = pdu->params[0] & 0x7F;
1938
1939         media_transport_update_device_volume(session->dev, volume);
1940
1941         return AVC_CTYPE_ACCEPTED;
1942
1943 err:
1944         pdu->params_len = htons(1);
1945         pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
1946         return AVC_CTYPE_REJECTED;
1947 }
1948
1949 static struct avrcp_player *find_tg_player(struct avrcp *session, uint16_t id)
1950 {
1951         struct avrcp_server *server = session->server;
1952         GSList *l;
1953
1954         for (l = server->players; l; l = l->next) {
1955                 struct avrcp_player *player = l->data;
1956
1957                 if (player->id == id)
1958                         return player;
1959         }
1960
1961         return NULL;
1962 }
1963
1964 static gboolean notify_addressed_player_changed(gpointer user_data)
1965 {
1966         struct avrcp_player *player = user_data;
1967         uint8_t events[6] = { AVRCP_EVENT_STATUS_CHANGED,
1968                                         AVRCP_EVENT_TRACK_CHANGED,
1969                                         AVRCP_EVENT_TRACK_REACHED_START,
1970                                         AVRCP_EVENT_TRACK_REACHED_END,
1971                                         AVRCP_EVENT_SETTINGS_CHANGED,
1972                                         AVRCP_EVENT_PLAYBACK_POS_CHANGED
1973                                 };
1974         uint8_t i;
1975
1976         avrcp_player_event(player, AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED, NULL);
1977
1978         /*
1979          * TG shall complete all player specific
1980          * notifications with AV/C C-Type REJECTED
1981          * with error code as Addressed Player Changed.
1982          */
1983         for (i = 0; i < sizeof(events); i++)
1984                 avrcp_player_event(player, events[i], NULL);
1985
1986         player->changed_id = 0;
1987
1988         return FALSE;
1989 }
1990
1991 static uint8_t avrcp_handle_set_addressed_player(struct avrcp *session,
1992                                                 struct avrcp_header *pdu,
1993                                                 uint8_t transaction)
1994 {
1995         struct avrcp_player *player;
1996         uint16_t len = ntohs(pdu->params_len);
1997         uint16_t player_id = 0;
1998         uint8_t status;
1999
2000         if (len < 1) {
2001                 status = AVRCP_STATUS_INVALID_PARAM;
2002                 goto err;
2003         }
2004
2005         player_id = bt_get_be16(&pdu->params[0]);
2006         player = find_tg_player(session, player_id);
2007         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2008
2009         if (player) {
2010                 player->addressed = true;
2011                 status = AVRCP_STATUS_SUCCESS;
2012                 pdu->params_len = htons(len);
2013                 pdu->params[0] = status;
2014         } else {
2015                 status = AVRCP_STATUS_INVALID_PLAYER_ID;
2016                 goto err;
2017         }
2018
2019         /* Don't emit player changed immediately since PTS expect the
2020          * response of SetAddressedPlayer before the event.
2021          */
2022         player->changed_id = g_idle_add(notify_addressed_player_changed,
2023                                                                 player);
2024
2025         return AVC_CTYPE_ACCEPTED;
2026
2027 err:
2028         pdu->params_len = htons(sizeof(status));
2029         pdu->params[0] = status;
2030         return AVC_CTYPE_REJECTED;
2031 }
2032
2033 static const struct control_pdu_handler control_handlers[] = {
2034                 { AVRCP_GET_CAPABILITIES, AVC_CTYPE_STATUS,
2035                                         avrcp_handle_get_capabilities },
2036                 { AVRCP_LIST_PLAYER_ATTRIBUTES, AVC_CTYPE_STATUS,
2037                                         avrcp_handle_list_player_attributes },
2038                 { AVRCP_LIST_PLAYER_VALUES, AVC_CTYPE_STATUS,
2039                                         avrcp_handle_list_player_values },
2040                 { AVRCP_GET_ELEMENT_ATTRIBUTES, AVC_CTYPE_STATUS,
2041                                         avrcp_handle_get_element_attributes },
2042                 { AVRCP_GET_CURRENT_PLAYER_VALUE, AVC_CTYPE_STATUS,
2043                                         avrcp_handle_get_current_player_value },
2044                 { AVRCP_SET_PLAYER_VALUE, AVC_CTYPE_CONTROL,
2045                                         avrcp_handle_set_player_value },
2046                 { AVRCP_GET_PLAYER_ATTRIBUTE_TEXT, AVC_CTYPE_STATUS,
2047                                         NULL },
2048                 { AVRCP_GET_PLAYER_VALUE_TEXT, AVC_CTYPE_STATUS,
2049                                         NULL },
2050                 { AVRCP_DISPLAYABLE_CHARSET, AVC_CTYPE_STATUS,
2051                                         avrcp_handle_displayable_charset },
2052                 { AVRCP_CT_BATTERY_STATUS, AVC_CTYPE_STATUS,
2053                                         avrcp_handle_ct_battery_status },
2054                 { AVRCP_GET_PLAY_STATUS, AVC_CTYPE_STATUS,
2055                                         avrcp_handle_get_play_status },
2056                 { AVRCP_REGISTER_NOTIFICATION, AVC_CTYPE_NOTIFY,
2057                                         avrcp_handle_register_notification },
2058                 { AVRCP_SET_ABSOLUTE_VOLUME, AVC_CTYPE_CONTROL,
2059                                         avrcp_handle_set_absolute_volume },
2060                 { AVRCP_REQUEST_CONTINUING, AVC_CTYPE_CONTROL,
2061                                         avrcp_handle_request_continuing },
2062                 { AVRCP_ABORT_CONTINUING, AVC_CTYPE_CONTROL,
2063                                         avrcp_handle_abort_continuing },
2064                 { AVRCP_SET_ADDRESSED_PLAYER, AVC_CTYPE_CONTROL,
2065                                         avrcp_handle_set_addressed_player },
2066                 { },
2067 };
2068
2069 /* handle vendordep pdu inside an avctp packet */
2070 static size_t handle_vendordep_pdu(struct avctp *conn, uint8_t transaction,
2071                                         uint8_t *code, uint8_t *subunit,
2072                                         uint8_t *operands, size_t operand_count,
2073                                         void *user_data)
2074 {
2075         struct avrcp *session = user_data;
2076         const struct control_pdu_handler *handler;
2077         struct avrcp_header *pdu = (void *) operands;
2078         uint32_t company_id = get_company_id(pdu->company_id);
2079
2080         if (company_id != IEEEID_BTSIG) {
2081                 *code = AVC_CTYPE_NOT_IMPLEMENTED;
2082                 return 0;
2083         }
2084
2085         DBG("AVRCP PDU 0x%02X, company 0x%06X len 0x%04X",
2086                         pdu->pdu_id, company_id, ntohs(pdu->params_len));
2087
2088         pdu->packet_type = 0;
2089         pdu->rsvd = 0;
2090
2091         if (operand_count < AVRCP_HEADER_LENGTH) {
2092                 pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
2093                 goto err_metadata;
2094         }
2095
2096         for (handler = session->control_handlers; handler->pdu_id; handler++) {
2097                 if (handler->pdu_id == pdu->pdu_id)
2098                         break;
2099         }
2100
2101         if (handler->pdu_id != pdu->pdu_id || handler->code != *code) {
2102                 pdu->params[0] = AVRCP_STATUS_INVALID_COMMAND;
2103                 goto err_metadata;
2104         }
2105
2106         if (!handler->func) {
2107                 pdu->params[0] = AVRCP_STATUS_INVALID_PARAM;
2108                 goto err_metadata;
2109         }
2110
2111         *code = handler->func(session, pdu, transaction);
2112
2113         if (*code != AVC_CTYPE_REJECTED &&
2114                                 pdu->pdu_id != AVRCP_GET_ELEMENT_ATTRIBUTES &&
2115                                 pdu->pdu_id != AVRCP_REQUEST_CONTINUING &&
2116                                 pdu->pdu_id != AVRCP_ABORT_CONTINUING)
2117                 session_abort_pending_pdu(session);
2118
2119         return AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
2120
2121 err_metadata:
2122         pdu->params_len = htons(1);
2123         *code = AVC_CTYPE_REJECTED;
2124
2125         return AVRCP_HEADER_LENGTH + 1;
2126 }
2127
2128 static void avrcp_handle_media_player_list(struct avrcp *session,
2129                                 struct avrcp_browsing_header *pdu,
2130                                 uint32_t start_item, uint32_t end_item)
2131 {
2132         struct avrcp_player *player = session->target->player;
2133         struct get_folder_items_rsp *rsp;
2134         const char *name = NULL;
2135         GSList *l;
2136
2137         rsp = (void *)pdu->params;
2138         rsp->status = AVRCP_STATUS_SUCCESS;
2139         rsp->uid_counter = htons(player_get_uid_counter(player));
2140         rsp->num_items = 0;
2141         pdu->param_len = sizeof(*rsp);
2142
2143         for (l = g_slist_nth(session->server->players, start_item);
2144                                         l; l = g_slist_next(l)) {
2145                 struct avrcp_player *player = l->data;
2146                 struct folder_item *folder;
2147                 struct player_item *item;
2148                 uint16_t namelen;
2149
2150                 if (rsp->num_items == (end_item - start_item) + 1)
2151                         break;
2152
2153                 folder = (void *)&pdu->params[pdu->param_len];
2154                 folder->type = 0x01; /* Media Player */
2155
2156                 pdu->param_len += sizeof(*folder);
2157
2158                 item = (void *)folder->data;
2159                 item->player_id = htons(player->id);
2160                 item->type = 0x01; /* Audio */
2161                 item->subtype = htonl(0x01); /* Audio Book */
2162                 item->status = player_get_status(player);
2163                 /* Assign Default Feature Bit Mask */
2164                 memcpy(&item->features, &default_features,
2165                                         sizeof(default_features));
2166
2167                 item->charset = htons(AVRCP_CHARSET_UTF8);
2168
2169                 name = player->cb->get_name(player->user_data);
2170                 namelen = strlen(name);
2171                 item->namelen = htons(namelen);
2172                 memcpy(item->name, name, namelen);
2173
2174                 folder->len = htons(sizeof(*item) + namelen);
2175                 pdu->param_len += sizeof(*item) + namelen;
2176                 rsp->num_items++;
2177         }
2178
2179         /* If no player could be found respond with an error */
2180         if (!rsp->num_items)
2181                 goto failed;
2182
2183         rsp->num_items = htons(rsp->num_items);
2184         pdu->param_len = htons(pdu->param_len);
2185
2186         return;
2187
2188 failed:
2189         pdu->params[0] = AVRCP_STATUS_OUT_OF_BOUNDS;
2190         pdu->param_len = htons(1);
2191 }
2192
2193 static void avrcp_handle_get_folder_items(struct avrcp *session,
2194                                 struct avrcp_browsing_header *pdu,
2195                                 uint8_t transaction)
2196 {
2197         uint32_t start_item = 0;
2198         uint32_t end_item = 0;
2199         uint8_t scope;
2200         uint8_t status = AVRCP_STATUS_SUCCESS;
2201
2202         if (ntohs(pdu->param_len) < 10) {
2203                 status = AVRCP_STATUS_INVALID_PARAM;
2204                 goto failed;
2205         }
2206
2207         scope = pdu->params[0];
2208         start_item = bt_get_be32(&pdu->params[1]);
2209         end_item = bt_get_be32(&pdu->params[5]);
2210
2211         DBG("scope 0x%02x start_item 0x%08x end_item 0x%08x", scope,
2212                                 start_item, end_item);
2213
2214         if (end_item < start_item) {
2215                 status = AVRCP_STATUS_INVALID_PARAM;
2216                 goto failed;
2217         }
2218
2219         switch (scope) {
2220         case AVRCP_SCOPE_MEDIA_PLAYER_LIST:
2221                 avrcp_handle_media_player_list(session, pdu,
2222                                                 start_item, end_item);
2223                 break;
2224         case AVRCP_SCOPE_MEDIA_PLAYER_VFS:
2225         case AVRCP_SCOPE_SEARCH:
2226         case AVRCP_SCOPE_NOW_PLAYING:
2227         default:
2228                 status = AVRCP_STATUS_INVALID_PARAM;
2229                 goto failed;
2230         }
2231
2232         return;
2233
2234 failed:
2235         pdu->params[0] = status;
2236         pdu->param_len = htons(1);
2237 }
2238
2239 static struct browsing_pdu_handler {
2240         uint8_t pdu_id;
2241         void (*func) (struct avrcp *session, struct avrcp_browsing_header *pdu,
2242                                                         uint8_t transaction);
2243 } browsing_handlers[] = {
2244                 { AVRCP_GET_FOLDER_ITEMS, avrcp_handle_get_folder_items },
2245                 { },
2246 };
2247
2248 size_t avrcp_browsing_general_reject(uint8_t *operands)
2249 {
2250         struct avrcp_browsing_header *pdu = (void *) operands;
2251         uint8_t status;
2252
2253         pdu->pdu_id = AVRCP_GENERAL_REJECT;
2254         status = AVRCP_STATUS_INVALID_COMMAND;
2255
2256         pdu->param_len = htons(sizeof(status));
2257         memcpy(pdu->params, &status, (sizeof(status)));
2258         return AVRCP_BROWSING_HEADER_LENGTH + sizeof(status);
2259 }
2260
2261 static size_t handle_browsing_pdu(struct avctp *conn,
2262                                         uint8_t transaction, uint8_t *operands,
2263                                         size_t operand_count, void *user_data)
2264 {
2265         struct avrcp *session = user_data;
2266         struct browsing_pdu_handler *handler;
2267         struct avrcp_browsing_header *pdu = (void *) operands;
2268
2269         DBG("AVRCP Browsing PDU 0x%02X, len 0x%04X", pdu->pdu_id,
2270                                                         ntohs(pdu->param_len));
2271
2272         for (handler = browsing_handlers; handler->pdu_id; handler++) {
2273                 if (handler->pdu_id == pdu->pdu_id)
2274                         goto done;
2275         }
2276
2277         return avrcp_browsing_general_reject(operands);
2278
2279 done:
2280         session->transaction = transaction;
2281         handler->func(session, pdu, transaction);
2282         return AVRCP_BROWSING_HEADER_LENGTH + ntohs(pdu->param_len);
2283 }
2284
2285 size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands)
2286 {
2287         struct avrcp_header *pdu = (void *) operands;
2288         uint32_t company_id = get_company_id(pdu->company_id);
2289
2290         *code = AVC_CTYPE_REJECTED;
2291         pdu->params_len = htons(1);
2292         pdu->params[0] = AVRCP_STATUS_INTERNAL_ERROR;
2293
2294         DBG("rejecting AVRCP PDU 0x%02X, company 0x%06X len 0x%04X",
2295                         pdu->pdu_id, company_id, ntohs(pdu->params_len));
2296
2297         return AVRCP_HEADER_LENGTH + 1;
2298 }
2299
2300 static struct avrcp_server *find_server(GSList *list, struct btd_adapter *a)
2301 {
2302         for (; list; list = list->next) {
2303                 struct avrcp_server *server = list->data;
2304
2305                 if (server->adapter == a)
2306                         return server;
2307         }
2308
2309         return NULL;
2310 }
2311
2312 static const char *status_to_string(uint8_t status)
2313 {
2314         switch (status) {
2315         case AVRCP_PLAY_STATUS_STOPPED:
2316                 return "stopped";
2317         case AVRCP_PLAY_STATUS_PLAYING:
2318                 return "playing";
2319         case AVRCP_PLAY_STATUS_PAUSED:
2320                 return "paused";
2321         case AVRCP_PLAY_STATUS_FWD_SEEK:
2322                 return "forward-seek";
2323         case AVRCP_PLAY_STATUS_REV_SEEK:
2324                 return "reverse-seek";
2325         case AVRCP_PLAY_STATUS_ERROR:
2326                 return "error";
2327         default:
2328                 return NULL;
2329         }
2330 }
2331
2332 static gboolean avrcp_get_play_status_rsp(struct avctp *conn, uint8_t code,
2333                                         uint8_t subunit, uint8_t transaction,
2334                                         uint8_t *operands, size_t operand_count,
2335                                         void *user_data)
2336 {
2337         struct avrcp *session = user_data;
2338         struct avrcp_player *player = session->controller->player;
2339
2340 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2341         if (!player)
2342                 return FALSE;
2343 #endif
2344
2345         struct media_player *mp = player->user_data;
2346         struct avrcp_header *pdu = (void *) operands;
2347         uint32_t duration;
2348         uint32_t position;
2349         uint8_t status;
2350
2351         if (pdu == NULL || code == AVC_CTYPE_REJECTED ||
2352                                                 ntohs(pdu->params_len) != 9)
2353                 return FALSE;
2354
2355         memcpy(&duration, pdu->params, sizeof(uint32_t));
2356         duration = ntohl(duration);
2357         media_player_set_duration(mp, duration);
2358
2359         memcpy(&position, pdu->params + 4, sizeof(uint32_t));
2360         position = ntohl(position);
2361         media_player_set_position(mp, position);
2362
2363         memcpy(&status, pdu->params + 8, sizeof(uint8_t));
2364         media_player_set_status(mp, status_to_string(status));
2365
2366         return FALSE;
2367 }
2368
2369 static void avrcp_get_play_status(struct avrcp *session)
2370 {
2371         uint8_t buf[AVRCP_HEADER_LENGTH];
2372         struct avrcp_header *pdu = (void *) buf;
2373
2374         memset(buf, 0, sizeof(buf));
2375
2376         set_company_id(pdu->company_id, IEEEID_BTSIG);
2377         pdu->pdu_id = AVRCP_GET_PLAY_STATUS;
2378         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2379
2380         avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2381                                         AVC_SUBUNIT_PANEL, buf, sizeof(buf),
2382                                         avrcp_get_play_status_rsp,
2383                                         session);
2384 }
2385
2386 static const char *status_to_str(uint8_t status)
2387 {
2388         switch (status) {
2389         case AVRCP_STATUS_INVALID_COMMAND:
2390                 return "Invalid Command";
2391         case AVRCP_STATUS_INVALID_PARAM:
2392                 return "Invalid Parameter";
2393         case AVRCP_STATUS_INTERNAL_ERROR:
2394                 return "Internal Error";
2395         case AVRCP_STATUS_SUCCESS:
2396                 return "Success";
2397         default:
2398                 return "Unknown";
2399         }
2400 }
2401
2402 static gboolean avrcp_player_value_rsp(struct avctp *conn, uint8_t code,
2403                                         uint8_t subunit, uint8_t transaction,
2404                                         uint8_t *operands, size_t operand_count,
2405                                         void *user_data)
2406 {
2407         struct avrcp *session = user_data;
2408         struct avrcp_player *player = session->controller->player;
2409
2410 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2411         if (!player)
2412                 return FALSE;
2413 #endif
2414
2415         struct media_player *mp = player->user_data;
2416         struct avrcp_header *pdu = (void *) operands;
2417         uint8_t count;
2418         int i;
2419
2420         if (pdu == NULL) {
2421                 media_player_set_setting(mp, "Error", "Timeout");
2422                 return FALSE;
2423         }
2424
2425         if (code == AVC_CTYPE_REJECTED) {
2426                 media_player_set_setting(mp, "Error",
2427                                         status_to_str(pdu->params[0]));
2428                 return FALSE;
2429         }
2430
2431         count = pdu->params[0];
2432
2433         if (pdu->params_len < count * 2)
2434                 return FALSE;
2435
2436         for (i = 1; count > 0; count--, i += 2) {
2437                 const char *key;
2438                 const char *value;
2439
2440                 key = attr_to_str(pdu->params[i]);
2441                 if (key == NULL)
2442                         continue;
2443
2444                 value = attrval_to_str(pdu->params[i], pdu->params[i + 1]);
2445                 if (value == NULL)
2446                         continue;
2447
2448                 media_player_set_setting(mp, key, value);
2449         }
2450
2451         return FALSE;
2452 }
2453
2454 static void avrcp_get_current_player_value(struct avrcp *session,
2455                                                 uint8_t *attrs, uint8_t count)
2456 {
2457         uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_ATTRIBUTE_LAST + 1];
2458         struct avrcp_header *pdu = (void *) buf;
2459         uint16_t length = AVRCP_HEADER_LENGTH + count + 1;
2460
2461         memset(buf, 0, sizeof(buf));
2462
2463         set_company_id(pdu->company_id, IEEEID_BTSIG);
2464         pdu->pdu_id = AVRCP_GET_CURRENT_PLAYER_VALUE;
2465         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2466         pdu->params_len = htons(count + 1);
2467         pdu->params[0] = count;
2468
2469         memcpy(pdu->params + 1, attrs, count);
2470
2471         avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2472                                         AVC_SUBUNIT_PANEL, buf, length,
2473                                         avrcp_player_value_rsp, session);
2474 }
2475
2476 static gboolean avrcp_list_player_attributes_rsp(struct avctp *conn,
2477                                         uint8_t code, uint8_t subunit,
2478                                         uint8_t transaction, uint8_t *operands,
2479                                         size_t operand_count, void *user_data)
2480 {
2481         uint8_t attrs[AVRCP_ATTRIBUTE_LAST];
2482         struct avrcp *session = user_data;
2483         struct avrcp_header *pdu = (void *) operands;
2484         uint8_t len, count = 0;
2485         int i;
2486
2487         if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED)
2488                 return FALSE;
2489
2490         len = pdu->params[0];
2491
2492         if (ntohs(pdu->params_len) < count) {
2493                 error("Invalid parameters");
2494                 return FALSE;
2495         }
2496
2497         for (i = 0; len > 0; len--, i++) {
2498                 /* Don't query invalid attributes */
2499                 if (pdu->params[i + 1] == AVRCP_ATTRIBUTE_ILEGAL ||
2500                                 pdu->params[i + 1] > AVRCP_ATTRIBUTE_LAST)
2501                         continue;
2502
2503                 attrs[count++] = pdu->params[i + 1];
2504         }
2505
2506         avrcp_get_current_player_value(session, attrs, count);
2507
2508         return FALSE;
2509 }
2510
2511 static void avrcp_list_player_attributes(struct avrcp *session)
2512 {
2513         uint8_t buf[AVRCP_HEADER_LENGTH];
2514         struct avrcp_header *pdu = (void *) buf;
2515
2516         memset(buf, 0, sizeof(buf));
2517
2518         set_company_id(pdu->company_id, IEEEID_BTSIG);
2519         pdu->pdu_id = AVRCP_LIST_PLAYER_ATTRIBUTES;
2520         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2521
2522         avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2523                                         AVC_SUBUNIT_PANEL, buf, sizeof(buf),
2524                                         avrcp_list_player_attributes_rsp,
2525                                         session);
2526 }
2527
2528 static void avrcp_parse_attribute_list(struct avrcp_player *player,
2529                                         uint8_t *operands, uint8_t count)
2530 {
2531         struct media_player *mp = player->user_data;
2532         struct media_item *item;
2533         int i;
2534
2535         item = media_player_set_playlist_item(mp, player->uid);
2536
2537         for (i = 0; count > 0; count--) {
2538                 uint32_t id;
2539                 uint16_t charset, len;
2540
2541                 id = get_be32(&operands[i]);
2542                 i += sizeof(uint32_t);
2543
2544                 charset = get_be16(&operands[i]);
2545                 i += sizeof(uint16_t);
2546
2547                 len = get_be16(&operands[i]);
2548                 i += sizeof(uint16_t);
2549
2550                 if (charset == 106) {
2551                         const char *key = metadata_to_str(id);
2552
2553                         if (key != NULL)
2554                                 media_player_set_metadata(mp, item,
2555                                                         metadata_to_str(id),
2556                                                         &operands[i], len);
2557                 }
2558
2559                 i += len;
2560         }
2561 }
2562
2563 static gboolean avrcp_get_element_attributes_rsp(struct avctp *conn,
2564                                                 uint8_t code, uint8_t subunit,
2565                                                 uint8_t transaction,
2566                                                 uint8_t *operands,
2567                                                 size_t operand_count,
2568                                                 void *user_data)
2569 {
2570         struct avrcp *session = user_data;
2571         struct avrcp_player *player = session->controller->player;
2572         struct avrcp_header *pdu = (void *) operands;
2573         uint8_t count;
2574
2575 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2576         if (!player)
2577                 return FALSE;
2578 #endif
2579
2580         if (code == AVC_CTYPE_REJECTED)
2581                 return FALSE;
2582
2583         count = pdu->params[0];
2584
2585         if (ntohs(pdu->params_len) - 1 < count * 8) {
2586                 error("Invalid parameters");
2587                 return FALSE;
2588         }
2589
2590         avrcp_parse_attribute_list(player, &pdu->params[1], count);
2591
2592         avrcp_get_play_status(session);
2593
2594         return FALSE;
2595 }
2596
2597 static void avrcp_get_element_attributes(struct avrcp *session)
2598 {
2599         uint8_t buf[AVRCP_HEADER_LENGTH + 9];
2600         struct avrcp_header *pdu = (void *) buf;
2601         uint16_t length;
2602
2603         memset(buf, 0, sizeof(buf));
2604
2605         set_company_id(pdu->company_id, IEEEID_BTSIG);
2606         pdu->pdu_id = AVRCP_GET_ELEMENT_ATTRIBUTES;
2607         pdu->params_len = htons(9);
2608         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
2609
2610         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
2611
2612         avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
2613                                         AVC_SUBUNIT_PANEL, buf, length,
2614                                         avrcp_get_element_attributes_rsp,
2615                                         session);
2616 }
2617
2618 static const char *type_to_string(uint8_t type)
2619 {
2620         switch (type & 0x0F) {
2621         case 0x01:
2622                 return "Audio";
2623         case 0x02:
2624                 return "Video";
2625         case 0x03:
2626                 return "Audio, Video";
2627         case 0x04:
2628                 return "Audio Broadcasting";
2629         case 0x05:
2630                 return "Audio, Audio Broadcasting";
2631         case 0x06:
2632                 return "Video, Audio Broadcasting";
2633         case 0x07:
2634                 return "Audio, Video, Audio Broadcasting";
2635         case 0x08:
2636                 return "Video Broadcasting";
2637         case 0x09:
2638                 return "Audio, Video Broadcasting";
2639         case 0x0A:
2640                 return "Video, Video Broadcasting";
2641         case 0x0B:
2642                 return "Audio, Video, Video Broadcasting";
2643         case 0x0C:
2644                 return "Audio Broadcasting, Video Broadcasting";
2645         case 0x0D:
2646                 return "Audio, Audio Broadcasting, Video Broadcasting";
2647         case 0x0E:
2648                 return "Video, Audio Broadcasting, Video Broadcasting";
2649         case 0x0F:
2650                 return "Audio, Video, Audio Broadcasting, Video Broadcasting";
2651         }
2652
2653         return "None";
2654 }
2655
2656 static const char *subtype_to_string(uint32_t subtype)
2657 {
2658         switch (subtype & 0x03) {
2659         case 0x01:
2660                 return "Audio Book";
2661         case 0x02:
2662                 return "Podcast";
2663         case 0x03:
2664                 return "Audio Book, Podcast";
2665         }
2666
2667         return "None";
2668 }
2669
2670 static struct media_item *parse_media_element(struct avrcp *session,
2671                                         uint8_t *operands, uint16_t len)
2672 {
2673         struct avrcp_player *player;
2674         struct media_player *mp;
2675         struct media_item *item;
2676         uint16_t namelen;
2677         char name[255];
2678         uint64_t uid;
2679
2680         if (len < 13)
2681                 return NULL;
2682
2683         uid = get_be64(&operands[0]);
2684
2685         namelen = MIN(get_be16(&operands[11]), sizeof(name) - 1);
2686         if (namelen > 0) {
2687                 memcpy(name, &operands[13], namelen);
2688                 name[namelen] = '\0';
2689         }
2690
2691         player = session->controller->player;
2692
2693 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2694         if (!player)
2695                 return NULL;
2696 #endif
2697
2698         mp = player->user_data;
2699
2700         item = media_player_create_item(mp, name, PLAYER_ITEM_TYPE_AUDIO, uid);
2701         if (item == NULL)
2702                 return NULL;
2703
2704         media_item_set_playable(item, true);
2705
2706         return item;
2707 }
2708
2709 static struct media_item *parse_media_folder(struct avrcp *session,
2710                                         uint8_t *operands, uint16_t len)
2711 {
2712         struct avrcp_player *player = session->controller->player;
2713
2714 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2715         if (!player)
2716                 return NULL;
2717 #endif
2718
2719         struct media_player *mp = player->user_data;
2720         struct media_item *item;
2721         uint16_t namelen;
2722         char name[255];
2723         uint64_t uid;
2724         uint8_t type;
2725         uint8_t playable;
2726
2727         if (len < 12)
2728                 return NULL;
2729
2730         uid = get_be64(&operands[0]);
2731         type = operands[8];
2732         playable = operands[9];
2733
2734         namelen = MIN(get_be16(&operands[12]), sizeof(name) - 1);
2735         if (namelen > 0) {
2736                 memcpy(name, &operands[14], namelen);
2737                 name[namelen] = '\0';
2738         }
2739
2740         item = media_player_create_folder(mp, name, type, uid);
2741         if (!item)
2742                 return NULL;
2743
2744         media_item_set_playable(item, playable & 0x01);
2745
2746         return item;
2747 }
2748
2749 static void avrcp_list_items(struct avrcp *session, uint32_t start,
2750                                                                 uint32_t end);
2751 static gboolean avrcp_list_items_rsp(struct avctp *conn, uint8_t *operands,
2752                                         size_t operand_count, void *user_data)
2753 {
2754         struct avrcp_browsing_header *pdu = (void *) operands;
2755         struct avrcp *session = user_data;
2756         struct avrcp_player *player = session->controller->player;
2757
2758 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2759         if (!player)
2760                 return FALSE;
2761 #endif
2762
2763         struct pending_list_items *p = player->p;
2764         uint16_t count;
2765         uint64_t items;
2766         size_t i;
2767         int err = 0;
2768
2769         if (pdu == NULL) {
2770                 err = -ETIMEDOUT;
2771                 goto done;
2772         }
2773
2774         /* AVRCP 1.5 - Page 76:
2775          * If the TG receives a GetFolderItems command for an empty folder then
2776          * the TG shall return the error (= Range Out of Bounds) in the status
2777          * field of the GetFolderItems response.
2778          */
2779         if (pdu->params[0] == AVRCP_STATUS_OUT_OF_BOUNDS)
2780                 goto done;
2781
2782         if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 5) {
2783                 err = -EINVAL;
2784                 goto done;
2785         }
2786
2787         count = get_be16(&operands[6]);
2788         if (count == 0)
2789                 goto done;
2790
2791         for (i = 8; count && i + 3 < operand_count; count--) {
2792                 struct media_item *item;
2793                 uint8_t type;
2794                 uint16_t len;
2795
2796                 type = operands[i++];
2797                 len = get_be16(&operands[i]);
2798                 i += 2;
2799
2800                 if (type != 0x03 && type != 0x02) {
2801                         i += len;
2802                         continue;
2803                 }
2804
2805                 if (i + len > operand_count) {
2806                         error("Invalid item length");
2807                         break;
2808                 }
2809
2810                 if (type == 0x03)
2811                         item = parse_media_element(session, &operands[i], len);
2812                 else
2813                         item = parse_media_folder(session, &operands[i], len);
2814
2815                 if (item)
2816                         p->items = g_slist_append(p->items, item);
2817
2818                 i += len;
2819         }
2820
2821         items = g_slist_length(p->items);
2822
2823         DBG("start %u end %u items %" PRIu64 " total %" PRIu64 "", p->start,
2824                                                 p->end, items, p->total);
2825
2826         if (items < p->total) {
2827                 avrcp_list_items(session, p->start + items, p->end);
2828                 return FALSE;
2829         }
2830
2831 done:
2832         media_player_list_complete(player->user_data, p->items, err);
2833
2834         g_slist_free(p->items);
2835         g_free(p);
2836         player->p = NULL;
2837
2838         return FALSE;
2839 }
2840
2841 static void avrcp_list_items(struct avrcp *session, uint32_t start,
2842                                                                 uint32_t end)
2843 {
2844         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10 +
2845                         AVRCP_MEDIA_ATTRIBUTE_LAST * sizeof(uint32_t)];
2846         struct avrcp_player *player = session->controller->player;
2847         struct avrcp_browsing_header *pdu = (void *) buf;
2848         uint16_t length = AVRCP_BROWSING_HEADER_LENGTH + 10;
2849         uint32_t attribute;
2850
2851 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2852         if (!player)
2853                 return;
2854 #endif
2855
2856         memset(buf, 0, sizeof(buf));
2857
2858         pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
2859         pdu->param_len = htons(10 + sizeof(uint32_t));
2860
2861         pdu->params[0] = player->scope;
2862
2863         put_be32(start, &pdu->params[1]);
2864         put_be32(end, &pdu->params[5]);
2865
2866         pdu->params[9] = 1;
2867
2868         /* Only the title (0x01) is mandatory. This can be extended to
2869          * support AVRCP_MEDIA_ATTRIBUTE_* attributes */
2870         attribute = htonl(AVRCP_MEDIA_ATTRIBUTE_TITLE);
2871         memcpy(&pdu->params[10], &attribute, sizeof(uint32_t));
2872
2873         length += sizeof(uint32_t);
2874
2875         avctp_send_browsing_req(session->conn, buf, length,
2876                                         avrcp_list_items_rsp, session);
2877 }
2878
2879 static gboolean avrcp_change_path_rsp(struct avctp *conn,
2880                                         uint8_t *operands, size_t operand_count,
2881                                         void *user_data)
2882 {
2883         struct avrcp_browsing_header *pdu = (void *) operands;
2884         struct avrcp *session = user_data;
2885         struct avrcp_player *player = session->controller->player;
2886
2887 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2888         if (!player)
2889                 return FALSE;
2890 #endif
2891
2892         struct media_player *mp = player->user_data;
2893         int ret;
2894
2895         if (pdu == NULL) {
2896                 ret = -ETIMEDOUT;
2897                 goto done;
2898         }
2899
2900         if (pdu->params[0] != AVRCP_STATUS_SUCCESS) {
2901                 ret = -EINVAL;
2902                 goto done;
2903         }
2904
2905         ret = get_be32(&pdu->params[1]);
2906
2907 done:
2908         if (ret < 0) {
2909                 g_free(player->change_path);
2910                 player->change_path = NULL;
2911         } else {
2912                 g_free(player->path);
2913                 player->path = player->change_path;
2914                 player->change_path = NULL;
2915         }
2916
2917         media_player_change_folder_complete(mp, player->path,
2918                                                 player->change_uid, ret);
2919
2920         player->change_uid = 0;
2921
2922         return FALSE;
2923 }
2924
2925 static gboolean avrcp_set_browsed_player_rsp(struct avctp *conn,
2926                                                 uint8_t *operands,
2927                                                 size_t operand_count,
2928                                                 void *user_data)
2929 {
2930         struct avrcp *session = user_data;
2931         struct avrcp_player *player = session->controller->player;
2932
2933 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2934         if (!player)
2935                 return FALSE;
2936 #endif
2937
2938         struct media_player *mp = player->user_data;
2939         struct avrcp_browsing_header *pdu = (void *) operands;
2940         uint32_t items;
2941         char **folders;
2942         uint8_t depth, count;
2943         size_t i;
2944
2945         if (pdu == NULL || pdu->params[0] != AVRCP_STATUS_SUCCESS ||
2946                                                         operand_count < 13)
2947                 return FALSE;
2948
2949         player->uid_counter = get_be16(&pdu->params[1]);
2950         player->browsed = true;
2951
2952         items = get_be32(&pdu->params[3]);
2953
2954         depth = pdu->params[9];
2955
2956         folders = g_new0(char *, depth + 2);
2957         folders[0] = g_strdup("/Filesystem");
2958
2959         for (i = 10, count = 1; count - 1 < depth && i < operand_count;
2960                                                                 count++) {
2961                 uint8_t len;
2962
2963                 len = pdu->params[i++];
2964                 if (!len)
2965                         continue;
2966
2967                 if (i + len > operand_count) {
2968                         error("Invalid folder length");
2969                         break;
2970                 }
2971
2972                 folders[count] = g_memdup(&pdu->params[i], len);
2973                 i += len;
2974         }
2975
2976         player->path = g_build_pathv("/", folders);
2977         g_strfreev(folders);
2978
2979         media_player_set_folder(mp, player->path, items);
2980
2981         return FALSE;
2982 }
2983
2984 static void avrcp_set_browsed_player(struct avrcp *session,
2985                                                 struct avrcp_player *player)
2986 {
2987         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 2];
2988         struct avrcp_browsing_header *pdu = (void *) buf;
2989         uint16_t id;
2990
2991         memset(buf, 0, sizeof(buf));
2992
2993         pdu->pdu_id = AVRCP_SET_BROWSED_PLAYER;
2994         id = htons(player->id);
2995         memcpy(pdu->params, &id, 2);
2996         pdu->param_len = htons(2);
2997
2998         avctp_send_browsing_req(session->conn, buf, sizeof(buf),
2999                                 avrcp_set_browsed_player_rsp, session);
3000 }
3001
3002 static gboolean avrcp_get_item_attributes_rsp(struct avctp *conn,
3003                                                 uint8_t *operands,
3004                                                 size_t operand_count,
3005                                                 void *user_data)
3006 {
3007         struct avrcp *session = user_data;
3008         struct avrcp_player *player = session->controller->player;
3009
3010 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3011         if (!player)
3012                 return FALSE;
3013 #endif
3014
3015         struct avrcp_browsing_header *pdu = (void *) operands;
3016         uint8_t count;
3017
3018         if (pdu == NULL) {
3019                 avrcp_get_element_attributes(session);
3020                 return FALSE;
3021         }
3022
3023         if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 4) {
3024                 avrcp_get_element_attributes(session);
3025                 return FALSE;
3026         }
3027
3028         count = pdu->params[1];
3029
3030         if (ntohs(pdu->param_len) - 1 < count * 8) {
3031                 error("Invalid parameters");
3032                 return FALSE;
3033         }
3034
3035         avrcp_parse_attribute_list(player, &pdu->params[2], count);
3036
3037         avrcp_get_play_status(session);
3038
3039         return FALSE;
3040 }
3041
3042 static void avrcp_get_item_attributes(struct avrcp *session, uint64_t uid)
3043 {
3044         struct avrcp_player *player = session->controller->player;
3045         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 12];
3046         struct avrcp_browsing_header *pdu = (void *) buf;
3047
3048 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3049         if (!player)
3050                 return;
3051 #endif
3052
3053         memset(buf, 0, sizeof(buf));
3054
3055         pdu->pdu_id = AVRCP_GET_ITEM_ATTRIBUTES;
3056         pdu->params[0] = 0x03;
3057         put_be64(uid, &pdu->params[1]);
3058         put_be16(player->uid_counter, &pdu->params[9]);
3059         pdu->param_len = htons(12);
3060
3061         avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3062                                 avrcp_get_item_attributes_rsp, session);
3063 }
3064
3065 static void avrcp_player_parse_features(struct avrcp_player *player,
3066                                                         uint8_t *features)
3067 {
3068         struct media_player *mp = player->user_data;
3069
3070         player->features = g_memdup(features, 16);
3071
3072         if (features[7] & 0x08) {
3073                 media_player_set_browsable(mp, true);
3074                 media_player_create_folder(mp, "/Filesystem",
3075                                                 PLAYER_FOLDER_TYPE_MIXED, 0);
3076         }
3077
3078         if (features[7] & 0x10)
3079                 media_player_set_searchable(mp, true);
3080
3081         if (features[8] & 0x02) {
3082                 media_player_create_folder(mp, "/NowPlaying",
3083                                                 PLAYER_FOLDER_TYPE_MIXED, 0);
3084                 media_player_set_playlist(mp, "/NowPlaying");
3085         }
3086 }
3087
3088 static void avrcp_set_player_value(struct avrcp *session, uint8_t attr,
3089                                                                 uint8_t val)
3090 {
3091         uint8_t buf[AVRCP_HEADER_LENGTH + 3];
3092         struct avrcp_header *pdu = (void *) buf;
3093         uint8_t length;
3094
3095         memset(buf, 0, sizeof(buf));
3096
3097         set_company_id(pdu->company_id, IEEEID_BTSIG);
3098         pdu->pdu_id = AVRCP_SET_PLAYER_VALUE;
3099         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3100         pdu->params[0] = 1;
3101         pdu->params[1] = attr;
3102         pdu->params[2] = val;
3103         pdu->params_len = htons(3);
3104
3105         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3106
3107         avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3108                                         AVC_SUBUNIT_PANEL, buf, length,
3109                                         avrcp_player_value_rsp, session);
3110 }
3111
3112 static gboolean avrcp_set_addressed_player_rsp(struct avctp *conn, uint8_t code,
3113                                         uint8_t subunit, uint8_t transaction,
3114                                         uint8_t *operands, size_t operand_count,
3115                                         void *user_data)
3116 {
3117         struct avrcp *session = user_data;
3118         struct avrcp_player *player = session->controller->player;
3119         struct avrcp_header *pdu = (void *) operands;
3120
3121         if (!pdu || code != AVC_CTYPE_ACCEPTED)
3122                 return FALSE;
3123
3124 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3125         if (!player)
3126                 return FALSE;
3127 #endif
3128
3129         player->addressed = true;
3130
3131         return FALSE;
3132 }
3133
3134 static void avrcp_set_addressed_player(struct avrcp *session,
3135                                                 struct avrcp_player *player)
3136 {
3137         uint8_t buf[AVRCP_HEADER_LENGTH + 2];
3138         struct avrcp_header *pdu = (void *) buf;
3139         uint16_t id;
3140
3141         memset(buf, 0, sizeof(buf));
3142
3143         set_company_id(pdu->company_id, IEEEID_BTSIG);
3144         pdu->pdu_id = AVRCP_SET_ADDRESSED_PLAYER;
3145         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3146         id = htons(player->id);
3147         memcpy(pdu->params, &id, 2);
3148         pdu->params_len = htons(2);
3149
3150         avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3151                                         AVC_SUBUNIT_PANEL, buf, sizeof(buf),
3152                                         avrcp_set_addressed_player_rsp,
3153                                         session);
3154 }
3155
3156 static void set_addressed_player(struct avrcp *session,
3157                                         struct avrcp_player *player)
3158 {
3159         if (!player || !player->id || player->addressed ||
3160                                 session->controller->version < 0x0104)
3161                 return;
3162
3163         /* Set player as addressed */
3164         avrcp_set_addressed_player(session, player);
3165 }
3166
3167 static void set_browsed_player(struct avrcp *session,
3168                                         struct avrcp_player *player)
3169 {
3170         if (!player || !player->id || player->browsed)
3171                 return;
3172
3173         if (media_player_get_browsable(player->user_data))
3174                 avrcp_set_browsed_player(session, player);
3175 }
3176
3177 static void set_ct_player(struct avrcp *session, struct avrcp_player *player)
3178 {
3179         struct btd_service *service;
3180
3181         if (session->controller->player == player)
3182                 goto done;
3183
3184         session->controller->player = player;
3185         service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
3186         control_set_player(service, player ?
3187                         media_player_get_path(player->user_data) : NULL);
3188
3189 done:
3190         set_addressed_player(session, player);
3191         set_browsed_player(session, player);
3192 }
3193
3194 static bool ct_set_setting(struct media_player *mp, const char *key,
3195                                         const char *value, void *user_data)
3196 {
3197         struct avrcp_player *player = user_data;
3198         int attr;
3199         int val;
3200         struct avrcp *session;
3201
3202         session = player->sessions->data;
3203         if (session == NULL)
3204                 return false;
3205
3206         if (session->controller->version < 0x0103)
3207                 return false;
3208
3209         set_ct_player(session, player);
3210
3211         attr = attr_to_val(key);
3212         if (attr < 0)
3213                 return false;
3214
3215         val = attrval_to_val(attr, value);
3216         if (val < 0)
3217                 return false;
3218
3219         avrcp_set_player_value(session, attr, val);
3220
3221         return true;
3222 }
3223
3224 static int ct_press(struct avrcp_player *player, uint8_t op)
3225 {
3226         int err;
3227         struct avrcp *session;
3228
3229         session = player->sessions->data;
3230         if (session == NULL)
3231                 return -ENOTCONN;
3232
3233         set_ct_player(session, player);
3234
3235         err = avctp_send_passthrough(session->conn, op);
3236         if (err < 0)
3237                 return err;
3238
3239         return 0;
3240 }
3241
3242 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
3243 static int ct_press_send_atonce(struct avrcp_player *player, uint8_t op)
3244 {
3245         int err;
3246         struct avrcp *session;
3247
3248         session = player->sessions->data;
3249         if (session == NULL)
3250                 return -ENOTCONN;
3251
3252         set_ct_player(session, player);
3253
3254         err = avctp_send_passthrough_send_fast(session->conn, op);
3255         if (err < 0)
3256                 return err;
3257
3258         return 0;
3259 }
3260 #endif
3261
3262 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3263 static int ct_release(struct avrcp_player *player, uint8_t op)
3264 {
3265         DBG("+");
3266         int err;
3267         struct avrcp *session;
3268
3269         session = player->sessions->data;
3270         if (session == NULL)
3271                 return -ENOTCONN;
3272
3273         err = avctp_send_release_passthrough(session->conn, op);
3274         if (err < 0)
3275                 return err;
3276
3277         DBG("-");
3278         return 0;
3279 }
3280 #endif
3281
3282 static int ct_play(struct media_player *mp, void *user_data)
3283 {
3284         struct avrcp_player *player = user_data;
3285
3286         return ct_press(player, AVC_PLAY);
3287 }
3288
3289 static int ct_pause(struct media_player *mp, void *user_data)
3290 {
3291         struct avrcp_player *player = user_data;
3292
3293         return ct_press(player, AVC_PAUSE);
3294 }
3295
3296 static int ct_stop(struct media_player *mp, void *user_data)
3297 {
3298         struct avrcp_player *player = user_data;
3299
3300         return ct_press(player, AVC_STOP);
3301 }
3302
3303 static int ct_next(struct media_player *mp, void *user_data)
3304 {
3305         struct avrcp_player *player = user_data;
3306
3307         return ct_press(player, AVC_FORWARD);
3308 }
3309
3310 static int ct_previous(struct media_player *mp, void *user_data)
3311 {
3312         struct avrcp_player *player = user_data;
3313
3314         return ct_press(player, AVC_BACKWARD);
3315 }
3316
3317 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3318 static int ct_press_fast_forward(struct media_player *mp, void *user_data)
3319 {
3320         DBG("+");
3321         struct avrcp_player *player = user_data;
3322
3323         DBG("-");
3324         return ct_press(player, AVC_FAST_FORWARD);
3325 }
3326
3327 static int ct_release_fast_forward(struct media_player *mp, void *user_data)
3328 {
3329         DBG("+");
3330         struct avrcp_player *player = user_data;
3331
3332         DBG("-");
3333         return ct_release(player, AVC_FAST_FORWARD);
3334 }
3335
3336 static int ct_press_rewind(struct media_player *mp, void *user_data)
3337 {
3338         DBG("+");
3339         struct avrcp_player *player = user_data;
3340
3341         DBG("-");
3342         return ct_press(player, AVC_REWIND);
3343 }
3344
3345 static int ct_release_rewind(struct media_player *mp, void *user_data)
3346 {
3347         DBG("+");
3348         struct avrcp_player *player = user_data;
3349
3350         DBG("-");
3351         return ct_release(player, AVC_REWIND);
3352 }
3353
3354 static int ct_volume_up(struct media_player *mp, void *user_data)
3355 {
3356         DBG("+");
3357         struct avrcp_player *player = user_data;
3358
3359         DBG("-");
3360         return ct_press(player, AVC_VOLUME_UP);
3361 }
3362
3363 static int ct_volume_down(struct media_player *mp, void *user_data)
3364 {
3365         DBG("+");
3366         struct avrcp_player *player = user_data;
3367
3368         DBG("-");
3369         return ct_press(player, AVC_VOLUME_DOWN);
3370 }
3371 #else
3372 static int ct_fast_forward(struct media_player *mp, void *user_data)
3373 {
3374         struct avrcp_player *player = user_data;
3375
3376         return ct_press(player, AVC_FAST_FORWARD);
3377 }
3378
3379 static int ct_rewind(struct media_player *mp, void *user_data)
3380 {
3381         struct avrcp_player *player = user_data;
3382
3383         return ct_press(player, AVC_REWIND);
3384 }
3385 #endif
3386
3387 static int ct_list_items(struct media_player *mp, const char *name,
3388                                 uint32_t start, uint32_t end, void *user_data)
3389 {
3390         struct avrcp_player *player = user_data;
3391         struct avrcp *session;
3392         struct pending_list_items *p;
3393
3394         if (player->p != NULL)
3395                 return -EBUSY;
3396
3397         session = player->sessions->data;
3398
3399         set_ct_player(session, player);
3400
3401         if (g_str_has_prefix(name, "/NowPlaying"))
3402                 player->scope = 0x03;
3403         else if (g_str_has_suffix(name, "/search"))
3404                 player->scope = 0x02;
3405         else
3406                 player->scope = 0x01;
3407
3408         avrcp_list_items(session, start, end);
3409
3410         p = g_new0(struct pending_list_items, 1);
3411         p->start = start;
3412         p->end = end;
3413         p->total = (uint64_t) (p->end - p->start) + 1;
3414         player->p = p;
3415
3416         return 0;
3417 }
3418
3419 static void avrcp_change_path(struct avrcp *session, uint8_t direction,
3420                                                                 uint64_t uid)
3421 {
3422         struct avrcp_player *player = session->controller->player;
3423         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 11];
3424         struct avrcp_browsing_header *pdu = (void *) buf;
3425
3426 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3427         if (!player)
3428                 return;
3429 #endif
3430
3431         memset(buf, 0, sizeof(buf));
3432         put_be16(player->uid_counter, &pdu->params[0]);
3433         pdu->params[2] = direction;
3434         put_be64(uid, &pdu->params[3]);
3435         pdu->pdu_id = AVRCP_CHANGE_PATH;
3436         pdu->param_len = htons(11);
3437
3438         avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3439                                         avrcp_change_path_rsp, session);
3440 }
3441
3442 static int ct_change_folder(struct media_player *mp, const char *path,
3443                                         uint64_t uid, void *user_data)
3444 {
3445         struct avrcp_player *player = user_data;
3446         struct avrcp *session;
3447         uint8_t direction;
3448
3449         session = player->sessions->data;
3450         set_ct_player(session, player);
3451         player->change_path = g_strdup(path);
3452         player->change_uid = uid;
3453
3454         direction = g_str_has_prefix(path, player->path) ? 0x01 : 0x00;
3455
3456         avrcp_change_path(session, direction, uid);
3457
3458         return 0;
3459 }
3460
3461 static gboolean avrcp_search_rsp(struct avctp *conn, uint8_t *operands,
3462                                         size_t operand_count, void *user_data)
3463 {
3464         struct avrcp_browsing_header *pdu = (void *) operands;
3465         struct avrcp *session = (void *) user_data;
3466         struct avrcp_player *player = session->controller->player;
3467
3468 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3469         if (!player)
3470                 return FALSE;
3471 #endif
3472
3473         struct media_player *mp = player->user_data;
3474         int ret;
3475
3476         if (pdu == NULL) {
3477                 ret = -ETIMEDOUT;
3478                 goto done;
3479         }
3480
3481         if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 7) {
3482                 ret = -EINVAL;
3483                 goto done;
3484         }
3485
3486         player->uid_counter = get_be16(&pdu->params[1]);
3487         ret = get_be32(&pdu->params[3]);
3488
3489 done:
3490         media_player_search_complete(mp, ret);
3491
3492         return FALSE;
3493 }
3494
3495 static void avrcp_search(struct avrcp *session, const char *string)
3496 {
3497         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 255];
3498         struct avrcp_browsing_header *pdu = (void *) buf;
3499         uint16_t len, stringlen;
3500
3501         memset(buf, 0, sizeof(buf));
3502         len = AVRCP_BROWSING_HEADER_LENGTH + 4;
3503         stringlen = strnlen(string, sizeof(buf) - len);
3504         len += stringlen;
3505
3506         put_be16(AVRCP_CHARSET_UTF8, &pdu->params[0]);
3507         put_be16(stringlen, &pdu->params[2]);
3508         memcpy(&pdu->params[4], string, stringlen);
3509         pdu->pdu_id = AVRCP_SEARCH;
3510         pdu->param_len = htons(len - AVRCP_BROWSING_HEADER_LENGTH);
3511
3512         avctp_send_browsing_req(session->conn, buf, len, avrcp_search_rsp,
3513                                                                 session);
3514 }
3515
3516 static int ct_search(struct media_player *mp, const char *string,
3517                                                         void *user_data)
3518 {
3519         struct avrcp_player *player = user_data;
3520         struct avrcp *session;
3521
3522         session = player->sessions->data;
3523
3524         set_ct_player(session, player);
3525         avrcp_search(session, string);
3526
3527         return 0;
3528 }
3529
3530 static gboolean avrcp_play_item_rsp(struct avctp *conn, uint8_t code,
3531                                         uint8_t subunit, uint8_t transaction,
3532                                         uint8_t *operands, size_t operand_count,
3533                                         void *user_data)
3534 {
3535         struct avrcp_header *pdu = (void *) operands;
3536         struct avrcp *session = (void *) user_data;
3537         struct avrcp_player *player = session->controller->player;
3538         struct media_player *mp = player->user_data;
3539         int ret = 0;
3540
3541         if (pdu == NULL) {
3542                 ret = -ETIMEDOUT;
3543                 goto done;
3544         }
3545
3546         if (pdu->params[0] != AVRCP_STATUS_SUCCESS) {
3547                 switch (pdu->params[0]) {
3548                 case AVRCP_STATUS_UID_CHANGED:
3549                 case AVRCP_STATUS_DOES_NOT_EXIST:
3550                         ret = -ENOENT;
3551                         break;
3552                 default:
3553                         ret = -EINVAL;
3554                         break;
3555                 }
3556                 goto done;
3557         }
3558
3559 done:
3560         media_player_play_item_complete(mp, ret);
3561
3562         return FALSE;
3563 }
3564
3565 static void avrcp_play_item(struct avrcp *session, uint64_t uid)
3566 {
3567         uint8_t buf[AVRCP_HEADER_LENGTH + 11];
3568         struct avrcp_player *player = session->controller->player;
3569         struct avrcp_header *pdu = (void *) buf;
3570         uint16_t length;
3571
3572 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3573         if (!player)
3574                 return;
3575 #endif
3576
3577         memset(buf, 0, sizeof(buf));
3578
3579         set_company_id(pdu->company_id, IEEEID_BTSIG);
3580         pdu->pdu_id = AVRCP_PLAY_ITEM;
3581         pdu->params_len = htons(11);
3582         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3583
3584         pdu->params[0] = player->scope;
3585         put_be64(uid, &pdu->params[1]);
3586         put_be16(player->uid_counter, &pdu->params[9]);
3587
3588         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3589
3590         avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3591                                         AVC_SUBUNIT_PANEL, buf, length,
3592                                         avrcp_play_item_rsp, session);
3593 }
3594
3595 static int ct_play_item(struct media_player *mp, const char *name,
3596                                                 uint64_t uid, void *user_data)
3597 {
3598         struct avrcp_player *player = user_data;
3599         struct avrcp *session;
3600
3601         if (player->p != NULL)
3602                 return -EBUSY;
3603
3604         session = player->sessions->data;
3605         set_ct_player(session, player);
3606
3607         if (g_strrstr(name, "/NowPlaying"))
3608                 player->scope = 0x03;
3609         else if (g_strrstr(name, "/Search"))
3610                 player->scope = 0x02;
3611         else
3612                 player->scope = 0x01;
3613
3614         avrcp_play_item(session, uid);
3615
3616         return 0;
3617 }
3618
3619 static void avrcp_add_to_nowplaying(struct avrcp *session, uint64_t uid)
3620 {
3621         uint8_t buf[AVRCP_HEADER_LENGTH + 11];
3622         struct avrcp_player *player = session->controller->player;
3623         struct avrcp_header *pdu = (void *) buf;
3624         uint16_t length;
3625
3626 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3627         if (!player)
3628                 return;
3629 #endif
3630
3631         memset(buf, 0, sizeof(buf));
3632
3633         set_company_id(pdu->company_id, IEEEID_BTSIG);
3634         pdu->pdu_id = AVRCP_ADD_TO_NOW_PLAYING;
3635         pdu->params_len = htons(11);
3636         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
3637
3638         pdu->params[0] = player->scope;
3639         put_be64(uid, &pdu->params[1]);
3640         put_be16(player->uid_counter, &pdu->params[9]);
3641
3642         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3643
3644         avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3645                                         AVC_SUBUNIT_PANEL, buf, length,
3646                                         NULL, session);
3647 }
3648
3649 static int ct_add_to_nowplaying(struct media_player *mp, const char *name,
3650                                                 uint64_t uid, void *user_data)
3651 {
3652         struct avrcp_player *player = user_data;
3653         struct avrcp *session;
3654
3655         if (player->p != NULL)
3656                 return -EBUSY;
3657
3658         session = player->sessions->data;
3659
3660         if (g_strrstr(name, "/NowPlaying"))
3661                 player->scope = 0x03;
3662         else
3663                 player->scope = 0x01;
3664
3665         set_ct_player(session, player);
3666         avrcp_add_to_nowplaying(session, uid);
3667
3668         return 0;
3669 }
3670
3671 static gboolean avrcp_get_total_numberofitems_rsp(struct avctp *conn,
3672                                         uint8_t *operands, size_t operand_count,
3673                                         void *user_data)
3674 {
3675         struct avrcp_browsing_header *pdu = (void *) operands;
3676         struct avrcp *session = user_data;
3677         struct avrcp_player *player = session->controller->player;
3678
3679 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3680         if (!player)
3681                 return EINVAL;
3682 #endif
3683
3684         struct media_player *mp = player->user_data;
3685         uint32_t num_of_items = 0;
3686
3687         if (pdu == NULL)
3688                 return -ETIMEDOUT;
3689
3690         if (pdu->params[0] != AVRCP_STATUS_SUCCESS || operand_count < 7)
3691                 return -EINVAL;
3692
3693         if (pdu->params[0] == AVRCP_STATUS_OUT_OF_BOUNDS)
3694                 goto done;
3695
3696         player->uid_counter = get_be16(&pdu->params[1]);
3697         num_of_items = get_be32(&pdu->params[3]);
3698
3699         if (!num_of_items)
3700                 return -EINVAL;
3701
3702 done:
3703         media_player_total_items_complete(mp, num_of_items);
3704         return FALSE;
3705 }
3706
3707 static void avrcp_get_total_numberofitems(struct avrcp *session)
3708 {
3709         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 7];
3710         struct avrcp_player *player = session->controller->player;
3711         struct avrcp_browsing_header *pdu = (void *) buf;
3712
3713 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3714         if (!player)
3715                 return;
3716 #endif
3717
3718         memset(buf, 0, sizeof(buf));
3719
3720         pdu->pdu_id = AVRCP_GET_TOTAL_NUMBER_OF_ITEMS;
3721         pdu->param_len = htons(7 + sizeof(uint32_t));
3722
3723         pdu->params[0] = player->scope;
3724
3725         avctp_send_browsing_req(session->conn, buf, sizeof(buf),
3726                                 avrcp_get_total_numberofitems_rsp, session);
3727 }
3728
3729 static int ct_get_total_numberofitems(struct media_player *mp, const char *name,
3730                                                 void *user_data)
3731 {
3732         struct avrcp_player *player = user_data;
3733         struct avrcp *session;
3734
3735         session = player->sessions->data;
3736         set_ct_player(session, player);
3737
3738         if (session->controller->version != 0x0106) {
3739                 error("version not supported");
3740                 return -1;
3741         }
3742
3743         if (g_str_has_prefix(name, "/NowPlaying"))
3744                 player->scope = 0x03;
3745         else if (g_str_has_suffix(name, "/search"))
3746                 player->scope = 0x02;
3747         else
3748                 player->scope = 0x01;
3749
3750         avrcp_get_total_numberofitems(session);
3751
3752         return 0;
3753 }
3754
3755 static const struct media_player_callback ct_cbs = {
3756         .set_setting    = ct_set_setting,
3757         .play           = ct_play,
3758         .pause          = ct_pause,
3759         .stop           = ct_stop,
3760         .next           = ct_next,
3761         .previous       = ct_previous,
3762 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3763         .press_fast_forward     = ct_press_fast_forward,
3764         .release_fast_forward   = ct_release_fast_forward,
3765         .press_rewind           = ct_press_rewind,
3766         .release_rewind         = ct_release_rewind,
3767         .volume_up              = ct_volume_up,
3768         .volume_down            = ct_volume_down,
3769 #else
3770         .fast_forward   = ct_fast_forward,
3771         .rewind         = ct_rewind,
3772 #endif
3773         .list_items     = ct_list_items,
3774         .change_folder  = ct_change_folder,
3775         .search         = ct_search,
3776         .play_item      = ct_play_item,
3777         .add_to_nowplaying = ct_add_to_nowplaying,
3778         .total_items = ct_get_total_numberofitems,
3779 };
3780
3781 static struct avrcp_player *create_ct_player(struct avrcp *session,
3782                                                                 uint16_t id)
3783 {
3784         struct avrcp_player *player;
3785         struct media_player *mp;
3786         const char *path;
3787
3788         player = g_new0(struct avrcp_player, 1);
3789         player->id = id;
3790         player->sessions = g_slist_prepend(player->sessions, session);
3791
3792         path = device_get_path(session->dev);
3793
3794         mp = media_player_controller_create(path, id);
3795         if (mp == NULL)
3796                 return NULL;
3797
3798         media_player_set_callbacks(mp, &ct_cbs, player);
3799         player->user_data = mp;
3800         player->destroy = (GDestroyNotify) media_player_destroy;
3801
3802         if (session->controller->player == NULL)
3803                 set_ct_player(session, player);
3804
3805         session->controller->players = g_slist_prepend(
3806                                                 session->controller->players,
3807                                                 player);
3808
3809         return player;
3810 }
3811
3812 static struct avrcp_player *find_ct_player(struct avrcp *session, uint16_t id)
3813 {
3814         GSList *l;
3815
3816         for (l = session->controller->players; l; l = l->next) {
3817                 struct avrcp_player *player = l->data;
3818
3819                 if (player->id == 0) {
3820                         player->id = id;
3821                         return player;
3822                 }
3823
3824                 if (player->id == id)
3825                         return player;
3826         }
3827
3828         return NULL;
3829 }
3830
3831 static struct avrcp_player *
3832 avrcp_parse_media_player_item(struct avrcp *session, uint8_t *operands,
3833                                                         uint16_t len)
3834 {
3835         struct avrcp_player *player;
3836         struct media_player *mp;
3837         uint16_t id, namelen;
3838         uint32_t subtype;
3839         const char *curval, *strval;
3840         char name[255];
3841
3842         if (len < 28)
3843                 return NULL;
3844
3845         id = get_be16(&operands[0]);
3846
3847         player = find_ct_player(session, id);
3848         if (player == NULL) {
3849                 player = create_ct_player(session, id);
3850                 if (player == NULL)
3851                         return NULL;
3852         } else if (player->features != NULL)
3853                 return player;
3854
3855         mp = player->user_data;
3856
3857         media_player_set_type(mp, type_to_string(operands[2]));
3858
3859         subtype = get_be32(&operands[3]);
3860
3861         media_player_set_subtype(mp, subtype_to_string(subtype));
3862
3863         curval = media_player_get_status(mp);
3864         strval = status_to_string(operands[7]);
3865
3866         if (g_strcmp0(curval, strval) != 0) {
3867                 media_player_set_status(mp, strval);
3868                 avrcp_get_play_status(session);
3869         }
3870
3871         avrcp_player_parse_features(player, &operands[8]);
3872
3873         namelen = get_be16(&operands[26]);
3874         if (namelen > 0 && namelen + 28 == len) {
3875                 namelen = MIN(namelen, sizeof(name) - 1);
3876                 memcpy(name, &operands[28], namelen);
3877                 name[namelen] = '\0';
3878                 media_player_set_name(mp, name);
3879         }
3880
3881         if (player->addressed)
3882                 set_browsed_player(session, player);
3883
3884         return player;
3885 }
3886
3887 static void player_destroy(gpointer data)
3888 {
3889         struct avrcp_player *player = data;
3890
3891         if (player->destroy)
3892                 player->destroy(player->user_data);
3893
3894 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3895         avrcp_stop_position_timer();
3896 #endif
3897
3898         if (player->changed_id > 0)
3899                 g_source_remove(player->changed_id);
3900
3901         g_slist_free(player->sessions);
3902         g_free(player->path);
3903         g_free(player->change_path);
3904         g_free(player->features);
3905         g_free(player);
3906 }
3907
3908 static void player_remove(gpointer data)
3909 {
3910         struct avrcp_player *player = data;
3911         GSList *l;
3912
3913         /* Don't remove reserved player */
3914         if (!player->id)
3915                 return;
3916
3917         for (l = player->sessions; l; l = l->next) {
3918                 struct avrcp *session = l->data;
3919                 struct avrcp_data *controller = session->controller;
3920
3921                 controller->players = g_slist_remove(controller->players,
3922                                                                 player);
3923
3924                 /* Check if current player is being removed */
3925                 if (controller->player == player)
3926                         set_ct_player(session, g_slist_nth_data(
3927                                                 controller->players, 0));
3928         }
3929
3930         player_destroy(player);
3931 }
3932
3933 static gboolean avrcp_get_media_player_list_rsp(struct avctp *conn,
3934                                                 uint8_t *operands,
3935                                                 size_t operand_count,
3936                                                 void *user_data)
3937 {
3938         struct avrcp_browsing_header *pdu = (void *) operands;
3939         struct avrcp *session = user_data;
3940         uint16_t count;
3941         size_t i;
3942         GSList *removed;
3943
3944         if (pdu == NULL || pdu->params[0] != AVRCP_STATUS_SUCCESS ||
3945                                                         operand_count < 5)
3946                 return FALSE;
3947
3948         removed = g_slist_copy(session->controller->players);
3949         count = get_be16(&operands[6]);
3950
3951         for (i = 8; count && i < operand_count; count--) {
3952                 struct avrcp_player *player;
3953                 uint8_t type;
3954                 uint16_t len;
3955
3956                 type = operands[i++];
3957                 len = get_be16(&operands[i]);
3958                 i += 2;
3959
3960                 if (type != 0x01) {
3961                         i += len;
3962                         continue;
3963                 }
3964
3965                 if (i + len > operand_count) {
3966                         error("Invalid player item length");
3967                         return FALSE;
3968                 }
3969
3970                 player = avrcp_parse_media_player_item(session, &operands[i],
3971                                                                         len);
3972                 if (player)
3973                         removed = g_slist_remove(removed, player);
3974
3975                 i += len;
3976         }
3977
3978         g_slist_free_full(removed, player_remove);
3979
3980         /* There should always be an active player */
3981         if (!session->controller->player)
3982                 create_ct_player(session, 0);
3983
3984         return FALSE;
3985 }
3986
3987 static void avrcp_get_media_player_list(struct avrcp *session)
3988 {
3989         uint8_t buf[AVRCP_BROWSING_HEADER_LENGTH + 10];
3990         struct avrcp_browsing_header *pdu = (void *) buf;
3991
3992         memset(buf, 0, sizeof(buf));
3993
3994         pdu->pdu_id = AVRCP_GET_FOLDER_ITEMS;
3995         put_be32(0, &pdu->params[1]);
3996         put_be32(UINT32_MAX, &pdu->params[5]);
3997         pdu->param_len = htons(10);
3998
3999         avctp_send_browsing_req(session->conn, buf, sizeof(buf),
4000                                 avrcp_get_media_player_list_rsp, session);
4001 }
4002
4003 static void avrcp_volume_changed(struct avrcp *session,
4004                                                 struct avrcp_header *pdu)
4005 {
4006         struct avrcp_player *player = target_get_player(session);
4007         int8_t volume;
4008
4009         volume = pdu->params[1] & 0x7F;
4010
4011         /* Always attempt to update the transport volume */
4012         media_transport_update_device_volume(session->dev, volume);
4013
4014         if (player)
4015                 player->cb->set_volume(volume, session->dev, player->user_data);
4016 }
4017
4018 static void avrcp_status_changed(struct avrcp *session,
4019                                                 struct avrcp_header *pdu)
4020 {
4021         struct avrcp_player *player = session->controller->player;
4022
4023 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4024         if (!player)
4025                 return;
4026 #endif
4027
4028         struct media_player *mp = player->user_data;
4029         uint8_t value;
4030         const char *curval, *strval;
4031
4032         value = pdu->params[1];
4033
4034         curval = media_player_get_status(mp);
4035         strval = status_to_string(value);
4036
4037 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
4038         DBG("AVRCP status changed to : %s", strval);
4039
4040         if (value == AVRCP_PLAY_STATUS_PAUSED)
4041                 media_transport_set_stream_status(session->dev, true);
4042         else if ( value == AVRCP_PLAY_STATUS_PLAYING)
4043                 media_transport_set_stream_status(session->dev, false);
4044 #endif
4045
4046         if (g_strcmp0(curval, strval) == 0)
4047                 return;
4048
4049         media_player_set_status(mp, strval);
4050         avrcp_get_play_status(session);
4051 }
4052
4053 static void avrcp_track_changed(struct avrcp *session,
4054                                                 struct avrcp_header *pdu)
4055 {
4056         if (session->browsing_id) {
4057                 struct avrcp_player *player = session->controller->player;
4058
4059 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4060         if (!player)
4061                 return;
4062 #endif
4063                 player->uid = get_be64(&pdu->params[1]);
4064                 avrcp_get_item_attributes(session, player->uid);
4065         } else
4066                 avrcp_get_element_attributes(session);
4067 }
4068
4069 static void avrcp_playback_pos_changed(struct avrcp *session,
4070                                                 struct avrcp_header *pdu)
4071 {
4072         struct avrcp_player *player = session->controller->player;
4073
4074 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4075         if (!player)
4076                 return;
4077 #endif
4078
4079         struct media_player *mp = player->user_data;
4080         uint32_t position;
4081
4082         position = get_be32(&pdu->params[1]);
4083         media_player_set_position(mp, position);
4084 }
4085
4086 static void avrcp_setting_changed(struct avrcp *session,
4087                                                 struct avrcp_header *pdu)
4088 {
4089         struct avrcp_player *player = session->controller->player;
4090
4091 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4092         if (!player)
4093                 return;
4094 #endif
4095
4096         struct media_player *mp = player->user_data;
4097         uint8_t count = pdu->params[1];
4098         int i;
4099
4100         for (i = 2; count > 0; count--, i += 2) {
4101                 const char *key;
4102                 const char *value;
4103
4104                 key = attr_to_str(pdu->params[i]);
4105                 if (key == NULL)
4106                         continue;
4107
4108                 value = attrval_to_str(pdu->params[i], pdu->params[i + 1]);
4109                 if (value == NULL)
4110                         continue;
4111
4112                 media_player_set_setting(mp, key, value);
4113         }
4114 }
4115
4116 static void avrcp_available_players_changed(struct avrcp *session,
4117                                                 struct avrcp_header *pdu)
4118 {
4119         avrcp_get_media_player_list(session);
4120 }
4121
4122 static void avrcp_addressed_player_changed(struct avrcp *session,
4123                                                 struct avrcp_header *pdu)
4124 {
4125         struct avrcp_player *player = session->controller->player;
4126         uint16_t id = get_be16(&pdu->params[1]);
4127
4128         if (player != NULL && player->id == id)
4129                 return;
4130
4131         player = find_ct_player(session, id);
4132         if (player == NULL) {
4133                 player = create_ct_player(session, id);
4134                 if (player == NULL)
4135                         return;
4136         }
4137
4138         player->addressed = true;
4139         player->uid_counter = get_be16(&pdu->params[3]);
4140         set_ct_player(session, player);
4141
4142         if (player->features != NULL)
4143                 return;
4144
4145         avrcp_get_media_player_list(session);
4146 }
4147
4148 static void avrcp_uids_changed(struct avrcp *session, struct avrcp_header *pdu)
4149 {
4150         struct avrcp_player *player = session->controller->player;
4151
4152 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4153         if (!player)
4154                 return;
4155 #endif
4156
4157         player->uid_counter = get_be16(&pdu->params[1]);
4158 }
4159
4160 static gboolean avrcp_handle_event(struct avctp *conn, uint8_t code,
4161                                         uint8_t subunit, uint8_t transaction,
4162                                         uint8_t *operands, size_t operand_count,
4163                                         void *user_data)
4164 {
4165         struct avrcp *session = user_data;
4166         struct avrcp_header *pdu = (void *) operands;
4167         uint8_t event;
4168
4169         if (!pdu)
4170                 return FALSE;
4171
4172         if ((code != AVC_CTYPE_INTERIM && code != AVC_CTYPE_CHANGED)) {
4173                 if (pdu->params[0] == AVRCP_STATUS_ADDRESSED_PLAYER_CHANGED &&
4174                                 code == AVC_CTYPE_REJECTED) {
4175                         int i;
4176
4177                         /* Lookup event by transaction */
4178                         for (i = 0; i <= AVRCP_EVENT_LAST; i++) {
4179                                 if (session->transaction_events[i] ==
4180                                                                 transaction) {
4181                                         event = i;
4182                                         goto changed;
4183                                 }
4184                         }
4185                 }
4186                 return FALSE;
4187         }
4188
4189         event = pdu->params[0];
4190
4191         if (code == AVC_CTYPE_CHANGED)
4192                 goto changed;
4193
4194         switch (event) {
4195         case AVRCP_EVENT_VOLUME_CHANGED:
4196                 avrcp_volume_changed(session, pdu);
4197                 break;
4198         case AVRCP_EVENT_STATUS_CHANGED:
4199                 avrcp_status_changed(session, pdu);
4200                 break;
4201         case AVRCP_EVENT_TRACK_CHANGED:
4202                 avrcp_track_changed(session, pdu);
4203                 break;
4204         case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
4205                 avrcp_playback_pos_changed(session, pdu);
4206                 break;
4207         case AVRCP_EVENT_SETTINGS_CHANGED:
4208                 avrcp_setting_changed(session, pdu);
4209                 break;
4210         case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
4211                 avrcp_available_players_changed(session, pdu);
4212                 break;
4213         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
4214                 avrcp_addressed_player_changed(session, pdu);
4215                 break;
4216         case AVRCP_EVENT_UIDS_CHANGED:
4217                 avrcp_uids_changed(session, pdu);
4218                 break;
4219         }
4220
4221         session->registered_events |= (1 << event);
4222         session->transaction_events[event] = transaction;
4223
4224         return TRUE;
4225
4226 changed:
4227         session->registered_events ^= (1 << event);
4228         session->transaction_events[event] = 0;
4229         avrcp_register_notification(session, event);
4230         return FALSE;
4231 }
4232
4233 static void avrcp_register_notification(struct avrcp *session, uint8_t event)
4234 {
4235         uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH];
4236         struct avrcp_header *pdu = (void *) buf;
4237         uint8_t length;
4238
4239         memset(buf, 0, sizeof(buf));
4240
4241         set_company_id(pdu->company_id, IEEEID_BTSIG);
4242         pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
4243         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
4244         pdu->params[0] = event;
4245
4246         /*
4247          * Set maximum interval possible for position changed as we only
4248          * use it to resync.
4249          */
4250         if (event == AVRCP_EVENT_PLAYBACK_POS_CHANGED)
4251                 bt_put_be32(UINT32_MAX / 1000, &pdu->params[1]);
4252
4253         pdu->params_len = htons(AVRCP_REGISTER_NOTIFICATION_PARAM_LENGTH);
4254
4255         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
4256
4257         avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
4258                                         AVC_SUBUNIT_PANEL, buf, length,
4259                                         avrcp_handle_event, session);
4260 }
4261
4262 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4263 static char *avrcp_event_to_string(uint8_t event)
4264 {
4265
4266         switch (event) {
4267         case AVRCP_EVENT_STATUS_CHANGED:
4268                 return "AVRCP EVENT STATUS CHANGED";
4269         case AVRCP_EVENT_TRACK_CHANGED:
4270                 return "AVRCP EVENT TRACK CHANGED";
4271         case AVRCP_EVENT_SETTINGS_CHANGED:
4272                 return "AVRCP EVENT SETTINGS CHANGED";
4273         case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
4274                 return "AVRCP EVENT ADDRESSED PLAYER CHANGED";
4275         case AVRCP_EVENT_UIDS_CHANGED:
4276                 return "AVRCP EVENT UIDS CHANGED";
4277         case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
4278                 return "AVRCP EVENT AVAILABLE PLAYERS CHANGED";
4279         case AVRCP_EVENT_VOLUME_CHANGED:
4280                 return "AVRCP EVENT VOLUME CHANGED";
4281         default:
4282                 return "Unknown Event";
4283         }
4284 }
4285
4286 static gboolean avrcp_get_playback_status(gpointer user_data)
4287 {
4288         struct avrcp *session = user_data;
4289
4290         avrcp_get_play_status(session);
4291
4292         return TRUE;
4293 }
4294 #endif
4295
4296 static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code,
4297                                         uint8_t subunit, uint8_t transaction,
4298                                         uint8_t *operands, size_t operand_count,
4299                                         void *user_data)
4300 {
4301         struct avrcp *session = user_data;
4302         struct avrcp_header *pdu = (void *) operands;
4303         uint16_t events = 0;
4304         uint8_t count;
4305
4306         if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED ||
4307                         pdu == NULL || pdu->params[0] != CAP_EVENTS_SUPPORTED)
4308                 return FALSE;
4309
4310         /* Connect browsing if pending */
4311         if (session->browsing_timer > 0) {
4312                 g_source_remove(session->browsing_timer);
4313                 session->browsing_timer = 0;
4314                 avctp_connect_browsing(session->conn);
4315         }
4316
4317         count = pdu->params[1];
4318
4319         for (; count > 0; count--) {
4320                 uint8_t event = pdu->params[1 + count];
4321
4322                 events |= (1 << event);
4323 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4324                 DBG("Supported Event %s", avrcp_event_to_string(event));
4325 #endif
4326                 switch (event) {
4327                 case AVRCP_EVENT_STATUS_CHANGED:
4328                 case AVRCP_EVENT_TRACK_CHANGED:
4329                 case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
4330                 case AVRCP_EVENT_SETTINGS_CHANGED:
4331 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
4332                 case AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED:
4333                 case AVRCP_EVENT_UIDS_CHANGED:
4334                 case AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED:
4335                         /* These events above requires a player */
4336                         if (!session->controller ||
4337                                                 !session->controller->player)
4338                                 break;
4339 #endif
4340                         /* fall through */
4341                 case AVRCP_EVENT_VOLUME_CHANGED:
4342                         avrcp_register_notification(session, event);
4343                         break;
4344                 }
4345         }
4346
4347 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4348         session->remote_supported_events = events;
4349 #endif
4350
4351         if (!session->controller || !session->controller->player)
4352                 return FALSE;
4353
4354         /* Skip if player status/metadata if only volume changes is supported */
4355         if (events == (1 << AVRCP_EVENT_VOLUME_CHANGED))
4356                 return FALSE;
4357
4358         if ((session->controller->features & AVRCP_FEATURE_PLAYER_SETTINGS) &&
4359                         !(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED)))
4360                 avrcp_list_player_attributes(session);
4361
4362         if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)))
4363                 avrcp_get_play_status(session);
4364
4365         if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)))
4366                 avrcp_get_element_attributes(session);
4367
4368 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4369         if ((events & (1 << AVRCP_EVENT_STATUS_CHANGED)) == 0) {
4370                 session->playback_status_id = g_timeout_add_seconds(1,
4371                                 avrcp_get_playback_status, session);
4372         }
4373 #endif
4374         return FALSE;
4375 }
4376
4377 static void avrcp_get_capabilities(struct avrcp *session)
4378 {
4379         uint8_t buf[AVRCP_HEADER_LENGTH + AVRCP_GET_CAPABILITIES_PARAM_LENGTH];
4380         struct avrcp_header *pdu = (void *) buf;
4381         uint8_t length;
4382
4383         memset(buf, 0, sizeof(buf));
4384
4385         set_company_id(pdu->company_id, IEEEID_BTSIG);
4386         pdu->pdu_id = AVRCP_GET_CAPABILITIES;
4387         pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
4388         pdu->params[0] = CAP_EVENTS_SUPPORTED;
4389         pdu->params_len = htons(AVRCP_GET_CAPABILITIES_PARAM_LENGTH);
4390
4391         length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
4392
4393         avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
4394                                         AVC_SUBUNIT_PANEL, buf, length,
4395                                         avrcp_get_capabilities_resp,
4396                                         session);
4397 }
4398
4399 static struct avrcp *find_session(GSList *list, struct btd_device *dev)
4400 {
4401         for (; list; list = list->next) {
4402                 struct avrcp *session = list->data;
4403
4404                 if (session->dev == dev)
4405                         return session;
4406         }
4407
4408         return NULL;
4409 }
4410
4411 static void destroy_browsing(void *data)
4412 {
4413         struct avrcp *session = data;
4414
4415         session->browsing_id = 0;
4416 }
4417
4418 static void session_init_browsing(struct avrcp *session)
4419 {
4420         if (session->browsing_timer > 0) {
4421                 g_source_remove(session->browsing_timer);
4422                 session->browsing_timer = 0;
4423         }
4424
4425         session->browsing_id = avctp_register_browsing_pdu_handler(
4426                                                         session->conn,
4427                                                         handle_browsing_pdu,
4428                                                         session,
4429                                                         destroy_browsing);
4430 }
4431
4432 static struct avrcp_data *data_init(struct avrcp *session, const char *uuid)
4433 {
4434         struct avrcp_data *data;
4435         const sdp_record_t *rec;
4436         sdp_list_t *list;
4437         sdp_profile_desc_t *desc;
4438
4439         data = g_new0(struct avrcp_data, 1);
4440
4441         rec = btd_device_get_record(session->dev, uuid);
4442         if (rec == NULL)
4443                 return data;
4444
4445         if (sdp_get_profile_descs(rec, &list) == 0) {
4446                 desc = list->data;
4447                 data->version = desc->version;
4448         }
4449
4450         sdp_get_int_attr(rec, SDP_ATTR_SUPPORTED_FEATURES, &data->features);
4451         sdp_list_free(list, free);
4452
4453         return data;
4454 }
4455
4456 static gboolean connect_browsing(gpointer user_data)
4457 {
4458         struct avrcp *session = user_data;
4459
4460         session->browsing_timer = 0;
4461
4462         avctp_connect_browsing(session->conn);
4463
4464         return FALSE;
4465 }
4466
4467 static void avrcp_connect_browsing(struct avrcp *session)
4468 {
4469         /* Immediately connect browsing channel if initiator otherwise delay
4470          * it to avoid possible collisions
4471          */
4472         if (avctp_is_initiator(session->conn)) {
4473                 avctp_connect_browsing(session->conn);
4474                 return;
4475         }
4476
4477         if (session->browsing_timer > 0)
4478                 return;
4479
4480         session->browsing_timer = g_timeout_add_seconds(AVRCP_BROWSING_TIMEOUT,
4481                                                         connect_browsing,
4482                                                         session);
4483 }
4484
4485 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
4486 static void target_init(struct avrcp *session)
4487 {
4488         struct avrcp_server *server = session->server;
4489         struct avrcp_data *target;
4490         struct avrcp_player *player;
4491         struct btd_service *service;
4492
4493         if (session->target != NULL)
4494                 return;
4495
4496         target = data_init(session, AVRCP_REMOTE_UUID);
4497         session->target = target;
4498
4499         DBG("%p version 0x%04x", target, target->version);
4500
4501         service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
4502 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4503         if (service)
4504                 btd_service_connecting_complete(service, 0);
4505 #else
4506         btd_service_connecting_complete(service, 0);
4507 #endif
4508
4509         player = g_slist_nth_data(server->players, 0);
4510         if (player != NULL) {
4511                 int8_t init_volume;
4512                 target->player = player;
4513                 player->sessions = g_slist_prepend(player->sessions, session);
4514
4515                 init_volume = media_player_get_device_volume(session->dev);
4516                 media_transport_update_device_volume(session->dev, init_volume);
4517         }
4518
4519         session->supported_events |= (1 << AVRCP_EVENT_STATUS_CHANGED) |
4520                                 (1 << AVRCP_EVENT_TRACK_CHANGED) |
4521 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
4522                                 (1 << AVRCP_EVENT_TRACK_REACHED_START) |
4523                                 (1 << AVRCP_EVENT_TRACK_REACHED_END) |
4524 #endif
4525 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4526                                 (1 << AVRCP_EVENT_PLAYBACK_POS_CHANGED) |
4527 #endif
4528                                 (1 << AVRCP_EVENT_SETTINGS_CHANGED);
4529
4530         if (target->version < 0x0104)
4531                 return;
4532
4533 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4534         if (adapter_avrcp_tg_ver < 0x0104)
4535                 return;
4536 #endif
4537
4538         session->supported_events |=
4539                                 (1 << AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED) |
4540                                 (1 << AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED) |
4541                                 (1 << AVRCP_EVENT_VOLUME_CHANGED);
4542
4543         /* Only check capabilities if controller is not supported */
4544         if (session->controller == NULL)
4545                 avrcp_get_capabilities(session);
4546
4547         if (!(target->features & AVRCP_FEATURE_BROWSING))
4548                 return;
4549
4550         avrcp_connect_browsing(session);
4551 }
4552 #endif
4553
4554 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
4555 static void controller_init(struct avrcp *session)
4556 {
4557         struct avrcp_player *player;
4558         struct btd_service *service;
4559         struct avrcp_data *controller;
4560
4561         if (session->controller != NULL)
4562                 return;
4563
4564         controller = data_init(session, AVRCP_TARGET_UUID);
4565         session->controller = controller;
4566
4567         DBG("%p version 0x%04x", controller, controller->version);
4568
4569 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4570         session->controller->player = NULL;
4571
4572         if ((controller->version >= 0x0104) && (adapter_avrcp_ct_ver >= 0x0104))
4573                 session->supported_events |= (1 << AVRCP_EVENT_VOLUME_CHANGED);
4574 #endif
4575
4576         service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
4577         btd_service_connecting_complete(service, 0);
4578
4579         /* Only create player if category 1 is supported */
4580         if (controller->features & AVRCP_FEATURE_CATEGORY_1) {
4581                 player = create_ct_player(session, 0);
4582                 if (player == NULL)
4583                         return;
4584         }
4585
4586         if (controller->version < 0x0103)
4587                 return;
4588
4589         avrcp_get_capabilities(session);
4590
4591         if (controller->version < 0x0104)
4592                 return;
4593
4594 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4595         if (adapter_avrcp_ct_ver < 0x0104)
4596                 return;
4597 #endif
4598
4599         if (!(controller->features & AVRCP_FEATURE_BROWSING))
4600                 return;
4601
4602         avrcp_connect_browsing(session);
4603 }
4604 #endif
4605
4606 static void session_init_control(struct avrcp *session)
4607 {
4608         session->passthrough_id = avctp_register_passthrough_handler(
4609                                                         session->conn,
4610                                                         handle_passthrough,
4611                                                         session);
4612         session->passthrough_handlers = passthrough_handlers;
4613         session->control_id = avctp_register_pdu_handler(session->conn,
4614                                                         AVC_OP_VENDORDEP,
4615                                                         handle_vendordep_pdu,
4616                                                         session);
4617         session->control_handlers = control_handlers;
4618 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
4619         if (btd_device_get_service(session->dev, AVRCP_TARGET_UUID) != NULL)
4620                 controller_init(session);
4621 #endif
4622 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
4623         if (btd_device_get_service(session->dev, AVRCP_REMOTE_UUID) != NULL)
4624                 target_init(session);
4625 #endif
4626 }
4627
4628 static void controller_destroy(struct avrcp *session)
4629 {
4630         struct avrcp_data *controller = session->controller;
4631
4632         DBG("%p", controller);
4633
4634         g_slist_free_full(controller->players, player_destroy);
4635
4636         g_free(controller);
4637 }
4638
4639 static void target_destroy(struct avrcp *session)
4640 {
4641         struct avrcp_data *target = session->target;
4642         struct avrcp_player *player = target->player;
4643
4644         DBG("%p", target);
4645
4646         if (player != NULL)
4647                 player->sessions = g_slist_remove(player->sessions, session);
4648
4649         g_free(target);
4650 }
4651
4652 static void session_destroy(struct avrcp *session, int err)
4653 {
4654         struct avrcp_server *server = session->server;
4655         struct btd_service *service;
4656
4657         server->sessions = g_slist_remove(server->sessions, session);
4658
4659 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4660         if (session->playback_status_id > 0) {
4661                 DBG("Removing the timer for playback status polling");
4662                 g_source_remove(session->playback_status_id);
4663                 session->playback_status_id = 0;
4664         }
4665 #endif
4666
4667         session_abort_pending_pdu(session);
4668
4669         service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
4670         if (service != NULL) {
4671                 if (session->control_id == 0)
4672                         btd_service_connecting_complete(service, err);
4673                 else
4674                         btd_service_disconnecting_complete(service, 0);
4675         }
4676
4677         service = btd_device_get_service(session->dev, AVRCP_REMOTE_UUID);
4678         if (service != NULL) {
4679                 if (session->control_id == 0)
4680                         btd_service_connecting_complete(service, err);
4681                 else
4682                         btd_service_disconnecting_complete(service, 0);
4683         }
4684
4685         if (session->browsing_timer > 0)
4686                 g_source_remove(session->browsing_timer);
4687
4688         if (session->controller != NULL)
4689                 controller_destroy(session);
4690
4691         if (session->target != NULL)
4692                 target_destroy(session);
4693
4694         if (session->passthrough_id > 0)
4695                 avctp_unregister_passthrough_handler(session->passthrough_id);
4696
4697         if (session->control_id > 0)
4698                 avctp_unregister_pdu_handler(session->control_id);
4699
4700         if (session->browsing_id > 0)
4701                 avctp_unregister_browsing_pdu_handler(session->browsing_id);
4702
4703         g_free(session);
4704 }
4705
4706 static struct avrcp *session_create(struct avrcp_server *server,
4707                                                 struct btd_device *device)
4708 {
4709         struct avrcp *session;
4710
4711         session = g_new0(struct avrcp, 1);
4712         session->server = server;
4713         session->conn = avctp_connect(device);
4714         session->dev = device;
4715
4716         server->sessions = g_slist_append(server->sessions, session);
4717
4718         return session;
4719 }
4720
4721 static void state_changed(struct btd_device *device, avctp_state_t old_state,
4722                                         avctp_state_t new_state, int err,
4723                                         void *user_data)
4724 {
4725         struct avrcp_server *server;
4726         struct avrcp *session;
4727
4728         server = find_server(servers, device_get_adapter(device));
4729         if (!server)
4730                 return;
4731
4732         session = find_session(server->sessions, device);
4733
4734         switch (new_state) {
4735         case AVCTP_STATE_DISCONNECTED:
4736                 if (session == NULL)
4737                         break;
4738
4739                 session_destroy(session, err);
4740
4741                 break;
4742         case AVCTP_STATE_CONNECTING:
4743                 if (session != NULL)
4744                         break;
4745
4746                 session_create(server, device);
4747
4748                 break;
4749         case AVCTP_STATE_CONNECTED:
4750                 if (session == NULL || session->control_id > 0)
4751                         break;
4752
4753                 session_init_control(session);
4754
4755                 break;
4756         case AVCTP_STATE_BROWSING_CONNECTED:
4757                 if (session == NULL || session->browsing_id > 0)
4758                         break;
4759
4760                 session_init_browsing(session);
4761
4762                 break;
4763         case AVCTP_STATE_BROWSING_CONNECTING:
4764         default:
4765                 return;
4766         }
4767 }
4768
4769 static struct avrcp_server *avrcp_server_register(struct btd_adapter *adapter)
4770 {
4771         struct avrcp_server *server;
4772
4773         if (avctp_register(adapter, TRUE) < 0)
4774                 return NULL;
4775
4776         server = g_new0(struct avrcp_server, 1);
4777         server->adapter = btd_adapter_ref(adapter);
4778
4779         servers = g_slist_append(servers, server);
4780
4781         if (!avctp_id)
4782                 avctp_id = avctp_add_state_cb(NULL, state_changed, NULL);
4783
4784         return server;
4785 }
4786
4787 static void avrcp_server_unregister(struct avrcp_server *server)
4788 {
4789         g_slist_free_full(server->sessions, g_free);
4790         g_slist_free_full(server->players, player_destroy);
4791
4792         servers = g_slist_remove(servers, server);
4793
4794         avctp_unregister(server->adapter);
4795         btd_adapter_unref(server->adapter);
4796         g_free(server);
4797
4798         if (servers)
4799                 return;
4800
4801         if (avctp_id) {
4802                 avctp_remove_state_cb(avctp_id);
4803                 avctp_id = 0;
4804         }
4805 }
4806
4807 struct avrcp_player *avrcp_register_player(struct btd_adapter *adapter,
4808                                                 struct avrcp_player_cb *cb,
4809                                                 void *user_data,
4810                                                 GDestroyNotify destroy)
4811 {
4812         struct avrcp_server *server;
4813         struct avrcp_player *player;
4814         GSList *l;
4815         static uint16_t id = 0;
4816
4817         server = find_server(servers, adapter);
4818         if (!server)
4819                 return NULL;
4820
4821         player = g_new0(struct avrcp_player, 1);
4822         player->id = ++id;
4823         player->server = server;
4824         player->cb = cb;
4825         player->user_data = user_data;
4826         player->destroy = destroy;
4827
4828         server->players = g_slist_append(server->players, player);
4829
4830         /* Assign player to session without current player */
4831         for (l = server->sessions; l; l = l->next) {
4832                 struct avrcp *session = l->data;
4833                 struct avrcp_data *target = session->target;
4834
4835                 if (target == NULL)
4836                         continue;
4837
4838                 if (target->player == NULL) {
4839                         target->player = player;
4840                         player->sessions = g_slist_append(player->sessions,
4841                                                                 session);
4842                 }
4843         }
4844
4845         avrcp_player_event(player,
4846                                 AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED, NULL);
4847
4848         return player;
4849 }
4850
4851 void avrcp_unregister_player(struct avrcp_player *player)
4852 {
4853         struct avrcp_server *server = player->server;
4854         GSList *l;
4855
4856         server->players = g_slist_remove(server->players, player);
4857
4858         /* Remove player from sessions using it */
4859         for (l = player->sessions; l; l = l->next) {
4860                 struct avrcp *session = l->data;
4861                 struct avrcp_data *target = session->target;
4862
4863                 if (target == NULL)
4864                         continue;
4865
4866                 if (target->player == player)
4867                         target->player = g_slist_nth_data(server->players, 0);
4868         }
4869
4870         avrcp_player_event(player,
4871                                 AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED, NULL);
4872
4873         player_destroy(player);
4874 }
4875
4876 static gboolean avrcp_handle_set_volume(struct avctp *conn, uint8_t code,
4877                                         uint8_t subunit, uint8_t transaction,
4878                                         uint8_t *operands, size_t operand_count,
4879                                         void *user_data)
4880 {
4881         struct avrcp *session = user_data;
4882         struct avrcp_player *player = target_get_player(session);
4883         struct avrcp_header *pdu = (void *) operands;
4884         int8_t volume;
4885
4886         if (code == AVC_CTYPE_REJECTED || code == AVC_CTYPE_NOT_IMPLEMENTED ||
4887                                                                 pdu == NULL)
4888                 return FALSE;
4889
4890         volume = pdu->params[0] & 0x7F;
4891
4892         /* Always attempt to update the transport volume */
4893         media_transport_update_device_volume(session->dev, volume);
4894
4895         if (player != NULL)
4896                 player->cb->set_volume(volume, session->dev, player->user_data);
4897
4898         return FALSE;
4899 }
4900
4901 static int avrcp_event(struct avrcp *session, uint8_t id, const void *data)
4902 {
4903         uint8_t buf[AVRCP_HEADER_LENGTH + 2];
4904         struct avrcp_header *pdu = (void *) buf;
4905         uint8_t code;
4906         uint16_t size;
4907         int err;
4908
4909         /* Verify that the event is registered */
4910         if (!(session->registered_events & (1 << id)))
4911                 return -ENOENT;
4912
4913         memset(buf, 0, sizeof(buf));
4914
4915         set_company_id(pdu->company_id, IEEEID_BTSIG);
4916         pdu->pdu_id = AVRCP_REGISTER_NOTIFICATION;
4917         code = AVC_CTYPE_CHANGED;
4918         pdu->params[0] = id;
4919
4920         DBG("id=%u", id);
4921
4922         switch (id) {
4923         case AVRCP_EVENT_VOLUME_CHANGED:
4924                 size = 2;
4925                 memcpy(&pdu->params[1], data, sizeof(uint8_t));
4926                 break;
4927         default:
4928                 error("Unknown event %u", id);
4929                 return -EINVAL;
4930         }
4931
4932         pdu->params_len = htons(size);
4933
4934         err = avctp_send_vendordep(session->conn,
4935                                         session->transaction_events[id],
4936                                         code, AVC_SUBUNIT_PANEL,
4937                                         buf, size + AVRCP_HEADER_LENGTH);
4938         if (err < 0)
4939                 return err;
4940
4941         /* Unregister event as per AVRCP 1.3 spec, section 5.4.2 */
4942         session->registered_events ^= 1 << id;
4943
4944         return err;
4945 }
4946
4947 int avrcp_set_volume(struct btd_device *dev, int8_t volume, bool notify)
4948 {
4949         struct avrcp_server *server;
4950         struct avrcp *session;
4951         uint8_t buf[AVRCP_HEADER_LENGTH + 1];
4952         struct avrcp_header *pdu = (void *) buf;
4953
4954         if (volume < 0)
4955                 return -EINVAL;
4956
4957         server = find_server(servers, device_get_adapter(dev));
4958         if (server == NULL)
4959                 return -EINVAL;
4960
4961         session = find_session(server->sessions, dev);
4962         if (session == NULL)
4963                 return -ENOTCONN;
4964
4965         if (notify) {
4966                 if (!session->target)
4967                         return -ENOTSUP;
4968                 return avrcp_event(session, AVRCP_EVENT_VOLUME_CHANGED,
4969                                                                 &volume);
4970         }
4971
4972         if (!session->controller || session->controller->version < 0x0104)
4973                 return -ENOTSUP;
4974
4975         memset(buf, 0, sizeof(buf));
4976
4977         set_company_id(pdu->company_id, IEEEID_BTSIG);
4978
4979         pdu->pdu_id = AVRCP_SET_ABSOLUTE_VOLUME;
4980         pdu->params[0] = volume;
4981         pdu->params_len = htons(1);
4982
4983         return avctp_send_vendordep_req(session->conn,
4984                                         AVC_CTYPE_CONTROL, AVC_SUBUNIT_PANEL,
4985                                         buf, sizeof(buf),
4986                                         avrcp_handle_set_volume, session);
4987 }
4988
4989 struct avrcp_player *avrcp_get_target_player_by_device(struct btd_device *dev)
4990 {
4991         struct avrcp_server *server;
4992         struct avrcp *session;
4993         struct avrcp_data *target;
4994
4995         server = find_server(servers, device_get_adapter(dev));
4996         if (server == NULL)
4997                 return NULL;
4998
4999         session = find_session(server->sessions, dev);
5000         if (session == NULL)
5001                 return NULL;
5002
5003         target = session->target;
5004         if (target == NULL)
5005                 return NULL;
5006
5007         return target->player;
5008 }
5009
5010 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5011 int avrcp_get_target_volume(struct btd_device *dev, uint8_t* volume)
5012 {
5013         struct avrcp_server *server;
5014         struct avrcp *session;
5015         struct avrcp_player *player;
5016         uint8_t vol;
5017
5018         DBG("avrcp_get_target_volume");
5019
5020         server = find_server(servers, device_get_adapter(dev));
5021         if (server == NULL)
5022                 return -EINVAL;
5023
5024         session = find_session(server->sessions, dev);
5025         if (!session || !session->controller || !session->target->player)
5026                 return -ENOTCONN;
5027
5028         if (!(session->remote_supported_events & (1 << AVRCP_EVENT_VOLUME_CHANGED)))
5029                 return -ENOTSUP;
5030
5031         player = session->target->player;
5032         if (!player || !player->user_data || !player->cb)
5033                 return -ENOTSUP;
5034
5035         vol = player->cb->get_volume(session->dev, player->user_data);
5036
5037         DBG("avrcp_get_target_volume [%d]", vol);
5038         *volume = vol;
5039
5040         return 0;
5041 }
5042 #endif
5043
5044
5045 #if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
5046 int avrcp_pause(struct btd_device *dev)
5047 {
5048         struct avrcp_server *server;
5049         struct avrcp *session;
5050
5051         DBG("AVRCP pause");
5052
5053         server = find_server(servers, device_get_adapter(dev));
5054         if (server == NULL)
5055                 return -EINVAL;
5056
5057         session = find_session(server->sessions, dev);
5058         if (session == NULL)
5059                 return -ENOTCONN;
5060
5061         if (session->controller) {
5062                 DBG("Calling controller pause");
5063                 ct_press_send_atonce(session->controller->player, AVC_PAUSE);
5064         } else {
5065                 DBG("Controller not found");
5066         }
5067
5068         return 0;
5069 }
5070 #endif
5071
5072
5073 static int avrcp_connect(struct btd_service *service)
5074 {
5075         struct btd_device *dev = btd_service_get_device(service);
5076         const char *path = device_get_path(dev);
5077 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5078         char name[10];
5079 #endif
5080         DBG("path %s", path);
5081
5082 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5083         device_get_name(dev, name, sizeof(name));
5084         DBG("name : %s", name);
5085         if (g_str_equal(name, "PLT_M50")) {
5086                 DBG("Don't initiate avrcp connection with this headset");
5087                 return -ENOTSUP;
5088         }
5089
5090         /* Device unpairing failed if AVRCP connection is triggered
5091         during unpairing*/
5092         if (device_is_temporary(dev))
5093                 return -EPERM;
5094 #endif
5095         return control_connect(service);
5096 }
5097
5098 static int avrcp_disconnect(struct btd_service *service)
5099 {
5100         struct btd_device *dev = btd_service_get_device(service);
5101         const char *path = device_get_path(dev);
5102
5103         DBG("path %s", path);
5104
5105         return control_disconnect(service);
5106 }
5107
5108 static int avrcp_target_probe(struct btd_service *service)
5109 {
5110         struct btd_device *dev = btd_service_get_device(service);
5111
5112         DBG("path %s", device_get_path(dev));
5113
5114         return control_init_target(service);
5115 }
5116
5117 static void avrcp_target_remove(struct btd_service *service)
5118 {
5119         control_unregister(service);
5120 }
5121
5122 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
5123 static void avrcp_target_server_remove(struct btd_profile *p,
5124                                                 struct btd_adapter *adapter)
5125 {
5126         struct avrcp_server *server;
5127
5128         DBG("path %s", adapter_get_path(adapter));
5129
5130         server = find_server(servers, adapter);
5131         if (!server)
5132                 return;
5133
5134         if (server->tg_record_id != 0) {
5135                 adapter_service_remove(adapter, server->tg_record_id);
5136                 server->tg_record_id = 0;
5137         }
5138
5139         if (server->ct_record_id == 0)
5140                 avrcp_server_unregister(server);
5141 }
5142 #endif
5143
5144 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
5145 static int avrcp_target_server_probe(struct btd_profile *p,
5146                                                 struct btd_adapter *adapter)
5147 {
5148         sdp_record_t *record;
5149         struct avrcp_server *server;
5150
5151         DBG("path %s", adapter_get_path(adapter));
5152
5153         server = find_server(servers, adapter);
5154         if (server != NULL)
5155                 goto done;
5156
5157         server = avrcp_server_register(adapter);
5158         if (server == NULL)
5159                 return -EPROTONOSUPPORT;
5160
5161 done:
5162         record = avrcp_tg_record();
5163         if (!record) {
5164                 error("Unable to allocate new service record");
5165                 avrcp_target_server_remove(p, adapter);
5166                 return -1;
5167         }
5168
5169         if (adapter_service_add(adapter, record) < 0) {
5170                 error("Unable to register AVRCP target service record");
5171                 avrcp_target_server_remove(p, adapter);
5172                 sdp_record_free(record);
5173                 return -1;
5174         }
5175         server->tg_record_id = record->handle;
5176
5177         return 0;
5178 }
5179 #endif
5180
5181 static struct btd_profile avrcp_target_profile = {
5182         .name           = "audio-avrcp-target",
5183
5184         .remote_uuid    = AVRCP_TARGET_UUID,
5185         .device_probe   = avrcp_target_probe,
5186         .device_remove  = avrcp_target_remove,
5187
5188         .connect        = avrcp_connect,
5189         .disconnect     = avrcp_disconnect,
5190 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_TARGET
5191         .adapter_probe  = avrcp_target_server_probe,
5192         .adapter_remove = avrcp_target_server_remove,
5193 #endif
5194 };
5195
5196 static int avrcp_controller_probe(struct btd_service *service)
5197 {
5198         struct btd_device *dev = btd_service_get_device(service);
5199
5200         DBG("path %s", device_get_path(dev));
5201
5202         return control_init_remote(service);
5203 }
5204
5205 static void avrcp_controller_remove(struct btd_service *service)
5206 {
5207         control_unregister(service);
5208 }
5209
5210 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
5211 static void avrcp_controller_server_remove(struct btd_profile *p,
5212                                                 struct btd_adapter *adapter)
5213 {
5214         struct avrcp_server *server;
5215
5216         DBG("path %s", adapter_get_path(adapter));
5217
5218         server = find_server(servers, adapter);
5219         if (!server)
5220                 return;
5221
5222         if (server->ct_record_id != 0) {
5223                 adapter_service_remove(adapter, server->ct_record_id);
5224                 server->ct_record_id = 0;
5225         }
5226
5227         if (server->tg_record_id == 0)
5228                 avrcp_server_unregister(server);
5229 }
5230 #endif
5231
5232 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
5233 static int avrcp_controller_server_probe(struct btd_profile *p,
5234                                                 struct btd_adapter *adapter)
5235 {
5236         sdp_record_t *record;
5237         struct avrcp_server *server;
5238
5239         DBG("path %s", adapter_get_path(adapter));
5240
5241         server = find_server(servers, adapter);
5242         if (server != NULL)
5243                 goto done;
5244
5245         server = avrcp_server_register(adapter);
5246         if (server == NULL)
5247                 return -EPROTONOSUPPORT;
5248
5249 done:
5250         record = avrcp_ct_record();
5251         if (!record) {
5252                 error("Unable to allocate new service record");
5253                 avrcp_controller_server_remove(p, adapter);
5254                 return -1;
5255         }
5256
5257         if (adapter_service_add(adapter, record) < 0) {
5258                 error("Unable to register AVRCP service record");
5259                 avrcp_controller_server_remove(p, adapter);
5260                 sdp_record_free(record);
5261                 return -1;
5262         }
5263         server->ct_record_id = record->handle;
5264
5265         return 0;
5266 }
5267 #endif
5268
5269 static struct btd_profile avrcp_controller_profile = {
5270         .name           = "avrcp-controller",
5271
5272         .remote_uuid    = AVRCP_REMOTE_UUID,
5273         .device_probe   = avrcp_controller_probe,
5274         .device_remove  = avrcp_controller_remove,
5275
5276         .connect        = avrcp_connect,
5277         .disconnect     = avrcp_disconnect,
5278 #ifdef TIZEN_FEATURE_BLUEZ_AVRCP_CONTROL
5279         .adapter_probe  = avrcp_controller_server_probe,
5280         .adapter_remove = avrcp_controller_server_remove,
5281 #endif
5282 };
5283
5284 static int avrcp_init(void)
5285 {
5286         btd_profile_register(&avrcp_controller_profile);
5287         btd_profile_register(&avrcp_target_profile);
5288
5289         populate_default_features();
5290
5291         return 0;
5292 }
5293
5294 static void avrcp_exit(void)
5295 {
5296         btd_profile_unregister(&avrcp_controller_profile);
5297         btd_profile_unregister(&avrcp_target_profile);
5298 }
5299
5300 BLUETOOTH_PLUGIN_DEFINE(avrcp, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
5301                                                         avrcp_init, avrcp_exit)