434b31241a7f2a583ff79365c9c174d40d14ee55
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-avrcp.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <dbus/dbus-glib-lowlevel.h>
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus.h>
27 #include <glib.h>
28 #include <dlog.h>
29 #include <string.h>
30 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
31 #include <syspopup_caller.h>
32 #endif
33
34 #include "bluetooth-api.h"
35 #include "bt-internal-types.h"
36
37 #include "bt-service-common.h"
38 #include "bt-service-avrcp.h"
39 #include "bt-service-event.h"
40 #include "bt-service-util.h"
41 #include "bt-service-audio.h"
42
43 struct player_settinngs_t {
44         int key;
45         const char *property;
46 };
47
48 static struct player_settinngs_t loopstatus_settings[] = {
49         { REPEAT_INVALID, "" },
50         { REPEAT_MODE_OFF, "None" },
51         { REPEAT_SINGLE_TRACK, "Track" },
52         { REPEAT_ALL_TRACK, "Playlist" },
53         { REPEAT_INVALID, "" }
54 };
55
56
57 static struct player_settinngs_t shuffle_settings[] = {
58         { SHUFFLE_INVALID, "" },
59         { SHUFFLE_MODE_OFF, "off" },
60         { SHUFFLE_ALL_TRACK, "alltracks" },
61         { SHUFFLE_GROUP, "group" },
62         { SHUFFLE_INVALID, "" }
63 };
64
65 static struct player_settinngs_t player_status[] = {
66         { STATUS_STOPPED, "stopped" },
67         { STATUS_PLAYING, "playing" },
68         { STATUS_PAUSED, "paused" },
69         { STATUS_FORWARD_SEEK, "forward-seek" },
70         { STATUS_REVERSE_SEEK, "reverse-seek" },
71         { STATUS_ERROR, "error" },
72         { STATUS_INVALID, "" }
73 };
74
75 static struct player_settinngs_t repeat_status[] = {
76         { REPEAT_INVALID, "" },
77         { REPEAT_MODE_OFF, "off" },
78         { REPEAT_SINGLE_TRACK, "singletrack" },
79         { REPEAT_ALL_TRACK, "alltracks" },
80         { REPEAT_GROUP, "group" },
81         { REPEAT_INVALID, "" }
82 };
83
84 static struct player_settinngs_t equalizer_status[] = {
85         { EQUALIZER_INVALID, "" },
86         { EQUALIZER_OFF, "off" },
87         { EQUALIZER_ON, "on" },
88         { EQUALIZER_INVALID, "" },
89 };
90
91 static struct player_settinngs_t scan_status[] = {
92         { SCAN_INVALID, "" },
93         { SCAN_MODE_OFF, "off" },
94         { SCAN_ALL_TRACK, "alltracks" },
95         { SCAN_GROUP, "group" },
96         { SCAN_INVALID, "" },
97 };
98
99 DBusConnection *g_bt_dbus_conn = NULL;
100 static char *avrcp_control_path = NULL;
101
102 static DBusHandlerResult _bt_avrcp_handle_set_property(DBusConnection *connection,
103                                 DBusMessage *message, void *user_data)
104 {
105         BT_DBG("+");
106         const gchar *value;
107         unsigned int status;
108         gboolean shuffle_status;
109         DBusMessageIter args;
110         const char *property = NULL;
111         const char *interface = NULL;
112         DBusMessage *reply = NULL;
113         DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
114         DBusMessageIter entry;
115         int type;
116
117
118         dbus_message_iter_init(message, &args);
119         dbus_message_iter_get_basic(&args, &interface);
120         dbus_message_iter_next(&args);
121
122         if (g_strcmp0(interface, BT_MEDIA_PLAYER_INTERFACE) != 0) {
123                 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
124                 goto finish;
125         }
126
127         dbus_message_iter_get_basic(&args, &property);
128         dbus_message_iter_next(&args);
129         dbus_message_iter_recurse(&args, &entry);
130         type = dbus_message_iter_get_arg_type(&entry);
131
132         BT_DBG("property %s\n", property);
133
134         if (g_strcmp0(property, "Shuffle") == 0) {
135                 if (type != DBUS_TYPE_BOOLEAN) {
136                         BT_DBG("Error");
137                         reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
138                                         "Invalid arguments");
139                         dbus_connection_send(connection, reply, NULL);
140                         result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
141                         goto finish;
142                 }
143                 dbus_message_iter_get_basic(&entry, &shuffle_status);
144                 BT_DBG("value %d\n", shuffle_status);
145                 if (shuffle_status == TRUE)
146                         status = SHUFFLE_ALL_TRACK;
147                 else
148                         status = SHUFFLE_MODE_OFF;
149
150                 _bt_send_event(BT_AVRCP_EVENT,
151                                 BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
152                                 DBUS_TYPE_UINT32, &status,
153                                 DBUS_TYPE_INVALID);
154
155         } else if (g_strcmp0(property, "LoopStatus") == 0) {
156                 if (type != DBUS_TYPE_STRING) {
157                         BT_DBG("Error");
158                         reply = dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
159                                         "Invalid arguments");
160                         dbus_connection_send(connection, reply, NULL);
161                         result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
162                         goto finish;
163                 }
164                 dbus_message_iter_get_basic(&entry, &value);
165                 BT_DBG("value %s\n", value);
166
167                 if (g_strcmp0(value, "Track") == 0)
168                         status = REPEAT_SINGLE_TRACK;
169                 else if (g_strcmp0(value, "Playlist") == 0)
170                         status = REPEAT_ALL_TRACK;
171                 else if (g_strcmp0(value, "None") == 0)
172                         status = REPEAT_MODE_OFF;
173                 else
174                         status = REPEAT_INVALID;
175
176                 _bt_send_event(BT_AVRCP_EVENT,
177                                 BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
178                                 DBUS_TYPE_UINT32, &status,
179                                 DBUS_TYPE_INVALID);
180         }
181 finish:
182         if (reply)
183                 dbus_message_unref(reply);
184
185         return result;
186 }
187
188 static DBusHandlerResult _bt_avrcp_message_handle(DBusConnection *conn, DBusMessage *msg, void *user_data)
189 {
190         BT_DBG("+");
191
192         if (dbus_message_is_method_call(msg, DBUS_INTERFACE_PROPERTIES, "Set"))
193                 return _bt_avrcp_handle_set_property(conn, msg, user_data);
194
195         BT_DBG("-");
196         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
197 }
198
199 static DBusObjectPathVTable bt_object_table = {
200         .message_function       = _bt_avrcp_message_handle,
201 };
202
203 gboolean bt_dbus_register_object_path(DBusConnection *connection,
204                                                 const char *path)
205 {
206         if (!dbus_connection_register_object_path(connection, path,
207                                 &bt_object_table, NULL))
208                 return FALSE;
209         return TRUE;
210 }
211
212 void bt_dbus_unregister_object_path(DBusConnection *connection,
213                                                 const char *path)
214 {
215         dbus_connection_unregister_object_path(connection, path);
216 }
217
218 static void __bt_media_append_variant(DBusMessageIter *iter,
219                         int type, void *value)
220 {
221         char sig[2] = { type, '\0'};
222         DBusMessageIter value_iter;
223
224         dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig,
225                                                         &value_iter);
226
227         dbus_message_iter_append_basic(&value_iter, type, value);
228
229         dbus_message_iter_close_container(iter, &value_iter);
230 }
231
232 static void __bt_media_append_dict_entry(DBusMessageIter *iter,
233                         const char *key, int type, void *property)
234 {
235         DBusMessageIter dict_entry;
236         const char *str_ptr;
237
238         if (type == DBUS_TYPE_STRING) {
239                 str_ptr = *((const char **)property);
240                 ret_if(str_ptr == NULL);
241         }
242
243         dbus_message_iter_open_container(iter,
244                                         DBUS_TYPE_DICT_ENTRY,
245                                         NULL, &dict_entry);
246
247         dbus_message_iter_append_basic(&dict_entry, DBUS_TYPE_STRING, &key);
248
249         __bt_media_append_variant(&dict_entry, type, property);
250
251         dbus_message_iter_close_container(iter, &dict_entry);
252 }
253
254 static gboolean __bt_media_emit_property_changed(
255                                 DBusConnection *connection,
256                                 const char *path,
257                                 const char *interface,
258                                 const char *name,
259                                 int type,
260                                 void *property)
261 {
262         DBusMessage *sig;
263         DBusMessageIter entry, dict;
264         gboolean ret;
265
266         sig = dbus_message_new_signal(path, DBUS_INTERFACE_PROPERTIES,
267                                                 "PropertiesChanged");
268         retv_if(sig == NULL, FALSE);
269
270         dbus_message_iter_init_append(sig, &entry);
271         dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &interface);
272         dbus_message_iter_open_container(&entry, DBUS_TYPE_ARRAY,
273                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
274                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
275                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
276
277         __bt_media_append_dict_entry(&dict,
278                                         name, type, property);
279
280         dbus_message_iter_close_container(&entry, &dict);
281
282         ret = dbus_connection_send(connection, sig, NULL);
283         dbus_message_unref(sig);
284
285         return ret;
286 }
287
288 void _bt_set_control_device_path(const char *path)
289 {
290
291         ret_if(path == NULL);
292
293         g_free(avrcp_control_path);
294         BT_DBG("control_path = %s", path);
295         avrcp_control_path = g_strdup(path);
296 }
297
298 void _bt_remove_control_device_path(const char *path)
299 {
300         ret_if(path == NULL);
301
302         if (avrcp_control_path &&
303                         !g_strcmp0(avrcp_control_path, path)) {
304                 BT_DBG("control_path = %s", path);
305                 g_free(avrcp_control_path);
306                 avrcp_control_path = NULL;
307         }
308 }
309
310 static char *__bt_get_control_device_path(void)
311 {
312         char *adapter_path;
313         char *control_path;
314         char connected_address[BT_ADDRESS_STRING_SIZE + 1];
315
316         BT_DBG("+");
317
318         retv_if(avrcp_control_path != NULL, avrcp_control_path);
319
320         retv_if(!_bt_is_headset_type_connected(BT_AVRCP,
321                         connected_address), NULL);
322
323         BT_DBG("device address = %s", connected_address);
324
325         adapter_path = _bt_get_device_object_path(connected_address);
326         retv_if(adapter_path == NULL, NULL);
327
328         control_path = g_strdup_printf(BT_MEDIA_CONTROL_PATH, adapter_path);
329         g_free(adapter_path);
330
331         avrcp_control_path = control_path;
332         BT_DBG("control_path = %s", control_path);
333         return control_path;
334 }
335
336 static int __bt_media_send_control_msg(const char *name)
337 {
338         DBusMessage *msg;
339         DBusMessage *reply;
340         DBusError err;
341         DBusConnection *conn;
342         char *control_path;
343
344         retv_if(name == NULL, BLUETOOTH_ERROR_INTERNAL);
345
346         conn = _bt_get_system_conn();
347         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
348
349         control_path = __bt_get_control_device_path();
350         retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
351         BT_DBG("control_path %s", control_path);
352
353         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, control_path,
354                                 BT_PLAYER_CONTROL_INTERFACE, name);
355
356         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
357
358         dbus_error_init(&err);
359         reply = dbus_connection_send_with_reply_and_block(conn,
360                                 msg, -1, &err);
361         dbus_message_unref(msg);
362
363         if (!reply) {
364                 BT_ERR("Error in Sending Control Command");
365
366                 if (dbus_error_is_set(&err)) {
367                         BT_ERR("%s", err.message);
368                         dbus_error_free(&err);
369                 }
370                 return BLUETOOTH_ERROR_INTERNAL;
371         }
372
373         dbus_message_unref(reply);
374
375         BT_DBG("-");
376         return BLUETOOTH_ERROR_NONE;
377 }
378
379
380 int _bt_register_media_player(void)
381 {
382         BT_DBG("+");
383         DBusMessage *msg;
384         DBusMessage *reply;
385         DBusMessageIter iter;
386         DBusMessageIter property_dict;
387         DBusError err;
388         char *object;
389         char *adapter_path;
390         DBusConnection *conn;
391         DBusGConnection *gconn;
392         gboolean shuffle_status;
393
394         media_player_settings_t player_settings = {0,};
395
396         player_settings.repeat  = REPEAT_MODE_OFF;
397
398         player_settings.shuffle = SHUFFLE_MODE_OFF;
399         player_settings.status = STATUS_STOPPED;
400         player_settings.position = 0;
401
402
403         gconn = _bt_get_system_gconn();
404         retv_if(gconn  == NULL, BLUETOOTH_ERROR_INTERNAL);
405
406         conn = _bt_get_system_conn();
407         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
408         g_bt_dbus_conn = conn;
409
410
411         if (!bt_dbus_register_object_path(conn, BT_MEDIA_OBJECT_PATH)){
412                 BT_DBG("Could not register interface %s",
413                                 BT_MEDIA_PLAYER_INTERFACE);
414         }
415
416         adapter_path = _bt_get_adapter_path();
417         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
418
419         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, adapter_path,
420                                 BT_MEDIA_INTERFACE, "RegisterPlayer");
421
422         g_free(adapter_path);
423
424         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
425
426         object = g_strdup(BT_MEDIA_OBJECT_PATH);
427
428         dbus_message_iter_init_append(msg, &iter);
429         dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &object);
430         g_free(object);
431
432         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
433                         DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
434                         DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
435                         DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &property_dict);
436
437         __bt_media_append_dict_entry(&property_dict,
438                 "LoopStatus",
439                 DBUS_TYPE_STRING,
440                 &loopstatus_settings[player_settings.repeat].property);
441
442         if (player_settings.shuffle == SHUFFLE_MODE_OFF)
443                 shuffle_status = FALSE;
444         else
445                 shuffle_status = TRUE;
446
447         __bt_media_append_dict_entry(&property_dict,
448                 "Shuffle",
449                 DBUS_TYPE_BOOLEAN,
450                 &shuffle_status);
451
452         __bt_media_append_dict_entry(&property_dict,
453                 "PlaybackStatus",
454                 DBUS_TYPE_STRING,
455                 &player_status[player_settings.status].property);
456
457
458         __bt_media_append_dict_entry(&property_dict,
459                 "Position",
460                 DBUS_TYPE_UINT32, &player_settings.position);
461
462         dbus_message_iter_close_container(&iter, &property_dict);
463
464         dbus_error_init(&err);
465         reply = dbus_connection_send_with_reply_and_block(conn,
466                                 msg, -1, &err);
467         dbus_message_unref(msg);
468
469         if (!reply) {
470                 BT_ERR("Error in registering the Music Player \n");
471
472                 if (dbus_error_is_set(&err)) {
473                         BT_ERR("%s", err.message);
474                         dbus_error_free(&err);
475                         return BLUETOOTH_ERROR_INTERNAL;
476                 }
477         }
478
479         if (reply)
480                 dbus_message_unref(reply);
481
482         BT_DBG("-");
483         return BLUETOOTH_ERROR_NONE;
484 }
485
486 int _bt_unregister_media_player(void)
487 {
488         BT_DBG("+");
489         DBusMessage *msg;
490         DBusMessage *reply;
491         DBusError err;
492         char *object;
493         char *adapter_path;
494         DBusConnection *conn;
495
496         conn = g_bt_dbus_conn;
497         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
498
499         adapter_path = _bt_get_adapter_path();
500         retv_if(adapter_path == NULL, BLUETOOTH_ERROR_INTERNAL);
501
502         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, adapter_path,
503                                 BT_MEDIA_INTERFACE, "UnregisterPlayer");
504
505
506         g_free(adapter_path);
507
508         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
509
510         object = g_strdup(BT_MEDIA_OBJECT_PATH);
511
512         dbus_message_append_args(msg,
513                                 DBUS_TYPE_OBJECT_PATH, &object,
514                                 DBUS_TYPE_INVALID);
515
516         g_free(object);
517
518         dbus_error_init(&err);
519         reply = dbus_connection_send_with_reply_and_block(conn,
520                                 msg, -1, &err);
521         dbus_message_unref(msg);
522
523         if (!reply) {
524                 BT_ERR("Error in unregistering the Music Player \n");
525
526                 if (dbus_error_is_set(&err)) {
527                         BT_ERR("%s", err.message);
528                         dbus_error_free(&err);
529                         return BLUETOOTH_ERROR_INTERNAL;
530                 }
531         } else {
532                 dbus_message_unref(reply);
533         }
534
535         bt_dbus_unregister_object_path(conn, BT_MEDIA_OBJECT_PATH);
536         g_bt_dbus_conn = NULL;
537
538         BT_DBG("-");
539         return BLUETOOTH_ERROR_NONE;
540 }
541
542 static void __bt_media_append_metadata_entry(DBusMessageIter *metadata,
543                         void *key_type, void *value, int type)
544 {
545         BT_DBG("+");
546         DBusMessageIter string_entry;
547
548         dbus_message_iter_open_container(metadata,
549                                 DBUS_TYPE_DICT_ENTRY,
550                                 NULL, &string_entry);
551
552         dbus_message_iter_append_basic(&string_entry, DBUS_TYPE_STRING, key_type);
553
554         __bt_media_append_variant(&string_entry, type, value);
555
556         dbus_message_iter_close_container(metadata, &string_entry);
557         BT_DBG("-");
558 }
559
560 static void __bt_media_append_metadata_array(DBusMessageIter *metadata,
561                         void *key_type, void *value, int type)
562 {
563         BT_DBG("+");
564         DBusMessageIter string_entry, variant, array;
565         char array_sig[3] = { type, DBUS_TYPE_STRING, '\0' };
566
567         dbus_message_iter_open_container(metadata,
568                                 DBUS_TYPE_DICT_ENTRY,
569                                 NULL, &string_entry);
570         dbus_message_iter_append_basic(&string_entry, DBUS_TYPE_STRING, key_type);
571
572         dbus_message_iter_open_container(&string_entry, DBUS_TYPE_VARIANT,
573                         array_sig, &variant);
574
575         dbus_message_iter_open_container(&variant, type,
576                                 DBUS_TYPE_STRING_AS_STRING, &array);
577         dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, value);
578
579         dbus_message_iter_close_container(&variant, &array);
580         dbus_message_iter_close_container(&string_entry, &variant);
581         dbus_message_iter_close_container(metadata, &string_entry);
582         BT_DBG("-");
583 }
584
585 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
586 {
587         BT_DBG("+");
588         DBusMessage *sig;
589         DBusMessageIter iter;
590         DBusMessageIter property_dict, metadata_dict, metadata_variant, metadata;
591         DBusConnection *conn;
592         char *interface = BT_MEDIA_PLAYER_INTERFACE;
593         char * metadata_str = "Metadata";
594         const char *key_type;
595
596         retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
597
598         conn = g_bt_dbus_conn;
599         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
600
601         sig = dbus_message_new_signal(BT_MEDIA_OBJECT_PATH, DBUS_INTERFACE_PROPERTIES,
602                                 "PropertiesChanged");
603         retv_if(sig == NULL, FALSE);
604
605         dbus_message_iter_init_append(sig, &iter);
606         dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface);
607
608         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
609                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
610                                 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
611                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &property_dict);
612
613         dbus_message_iter_open_container(&property_dict,
614                                 DBUS_TYPE_DICT_ENTRY,
615                                 NULL, &metadata_dict);
616
617         dbus_message_iter_append_basic(&metadata_dict, DBUS_TYPE_STRING, &metadata_str);
618
619         dbus_message_iter_open_container(&metadata_dict, DBUS_TYPE_VARIANT, "a{sv}",
620                                 &metadata_variant);
621
622         dbus_message_iter_open_container(&metadata_variant, DBUS_TYPE_ARRAY,
623                                 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
624                                 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
625                                 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &metadata);
626
627         if (meta_data->title) {
628                 key_type = "xesam:title";
629                 __bt_media_append_metadata_entry(&metadata, &key_type,
630                                 &meta_data->title, DBUS_TYPE_STRING);
631         }
632
633         if (meta_data->artist) {
634                 key_type = "xesam:artist";
635                 __bt_media_append_metadata_array(&metadata, &key_type,
636                                 &meta_data->artist, DBUS_TYPE_ARRAY);
637         }
638
639         if (meta_data->album) {
640                 key_type = "xesam:album";
641                 __bt_media_append_metadata_entry(&metadata, &key_type,
642                                 &meta_data->album, DBUS_TYPE_STRING);
643         }
644
645         if (meta_data->genre) {
646                 key_type = "xesam:genre";
647                 __bt_media_append_metadata_array(&metadata, &key_type,
648                                 &meta_data->genre, DBUS_TYPE_ARRAY);
649         }
650
651         if (0 != meta_data->total_tracks) {
652                 key_type = "xesam:totalTracks";
653                 __bt_media_append_metadata_entry(&metadata, &key_type,
654                                 &meta_data->total_tracks, DBUS_TYPE_INT32);
655         }
656
657         if (0 != meta_data->number) {
658                 key_type = "xesam:trackNumber";
659                 __bt_media_append_metadata_entry(&metadata, &key_type,
660                                 &meta_data->number, DBUS_TYPE_INT32);
661         }
662
663         if (0 != meta_data->duration) {
664                 key_type = "mpris:length";
665                 __bt_media_append_metadata_entry(&metadata, &key_type,
666                                 &meta_data->duration, DBUS_TYPE_INT64);
667         }
668
669         dbus_message_iter_close_container(&metadata_variant, &metadata);
670         dbus_message_iter_close_container(&metadata_dict, &metadata_variant);
671         dbus_message_iter_close_container(&property_dict, &metadata_dict);
672         dbus_message_iter_close_container(&iter, &property_dict);
673
674         if (!dbus_connection_send(conn, sig, NULL))
675                 BT_ERR("Unable to send TrackChanged signal\n");
676
677         dbus_message_unref(sig);
678         BT_DBG("-");
679         return BLUETOOTH_ERROR_NONE;
680 }
681
682
683 int _bt_avrcp_set_interal_property(int type, media_player_settings_t *properties)
684 {
685         BT_DBG("+");
686         DBusConnection *conn;
687         int value;
688         media_metadata_attributes_t meta_data;
689         dbus_bool_t shuffle;
690
691         conn = g_bt_dbus_conn;
692         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
693
694         switch (type) {
695         case REPEAT:
696                 value = properties->repeat;
697                 if (!__bt_media_emit_property_changed(
698                         conn,
699                         BT_MEDIA_OBJECT_PATH,
700                         BT_MEDIA_PLAYER_INTERFACE,
701                         "LoopStatus",
702                         DBUS_TYPE_STRING,
703                         &loopstatus_settings[value].property)) {
704                         BT_ERR("Error sending the PropertyChanged signal \n");
705                         return BLUETOOTH_ERROR_INTERNAL;
706                 }
707                 break;
708         case SHUFFLE:
709                 value = properties->shuffle;
710                 if (g_strcmp0(shuffle_settings[value].property, "off") == 0)
711                         shuffle = 0;
712                 else
713                         shuffle = 1;
714
715                 if (!__bt_media_emit_property_changed(
716                         conn,
717                         BT_MEDIA_OBJECT_PATH,
718                         BT_MEDIA_PLAYER_INTERFACE,
719                         "Shuffle",
720                         DBUS_TYPE_BOOLEAN,
721                         &shuffle)) {
722                         BT_DBG("Error sending the PropertyChanged signal \n");
723                         return BLUETOOTH_ERROR_INTERNAL;
724                 }
725                 break;
726         case STATUS:
727                 value = properties->status;
728                 if (!__bt_media_emit_property_changed(
729                         conn,
730                         BT_MEDIA_OBJECT_PATH,
731                         BT_MEDIA_PLAYER_INTERFACE,
732                         "PlaybackStatus",
733                         DBUS_TYPE_STRING,
734                         &player_status[value].property)) {
735                         BT_DBG("Error sending the PropertyChanged signal \n");
736                         return BLUETOOTH_ERROR_INTERNAL;
737                 }
738                 break;
739         case POSITION:
740                 value = properties->position;
741                 if (!__bt_media_emit_property_changed(
742                         conn,
743                         BT_MEDIA_OBJECT_PATH,
744                         BT_MEDIA_PLAYER_INTERFACE,
745                         "Position",
746                         DBUS_TYPE_UINT32,
747                         &value)) {
748                         BT_DBG("Error sending the PropertyChanged signal \n");
749                         return BLUETOOTH_ERROR_INTERNAL;
750                 }
751                 break;
752         case METADATA:
753                 meta_data = properties->metadata;
754                 if (!__bt_media_emit_property_changed(
755                         conn,
756                         BT_MEDIA_OBJECT_PATH,
757                         BT_MEDIA_PLAYER_INTERFACE,
758                         "Metadata",
759                         DBUS_TYPE_ARRAY,
760                         &meta_data)) {
761                         BT_DBG("Error sending the PropertyChanged signal \n");
762                         return BLUETOOTH_ERROR_INTERNAL;
763                 }
764                 break;
765         default:
766                 BT_DBG("Invalid Type\n");
767                 return BLUETOOTH_ERROR_INTERNAL;
768         }
769         BT_DBG("-");
770         return BLUETOOTH_ERROR_NONE;
771 }
772
773 int _bt_avrcp_set_properties(media_player_settings_t *properties)
774 {
775         BT_DBG("+");
776
777         if (_bt_avrcp_set_interal_property(REPEAT,
778                                 properties) != BLUETOOTH_ERROR_NONE) {
779                         return BLUETOOTH_ERROR_INTERNAL;
780         }
781         if (_bt_avrcp_set_interal_property(SHUFFLE,
782                         properties) != BLUETOOTH_ERROR_NONE) {
783                 return BLUETOOTH_ERROR_INTERNAL;
784         }
785
786         if (_bt_avrcp_set_interal_property(STATUS,
787                         properties) != BLUETOOTH_ERROR_NONE) {
788                 return BLUETOOTH_ERROR_INTERNAL;
789         }
790
791         if (_bt_avrcp_set_interal_property(POSITION,
792                         properties) != BLUETOOTH_ERROR_NONE) {
793                 return BLUETOOTH_ERROR_INTERNAL;
794         }
795
796         if (_bt_avrcp_set_interal_property(METADATA,
797                         properties) != BLUETOOTH_ERROR_NONE) {
798                 return BLUETOOTH_ERROR_INTERNAL;
799         }
800         BT_DBG("-");
801         return BLUETOOTH_ERROR_NONE;
802 }
803
804 int _bt_avrcp_set_property(int type, unsigned int value)
805 {
806         BT_DBG("+");
807         media_player_settings_t properties;
808
809         switch (type) {
810         case REPEAT:
811                 properties.repeat = value;
812                 break;
813         case SHUFFLE:
814                 properties.shuffle = value;
815                 break;
816         case STATUS:
817                 properties.status = value;
818                 break;
819         case POSITION:
820                 properties.position = value;
821                 break;
822         default:
823                 BT_DBG("Invalid Type\n");
824                 return BLUETOOTH_ERROR_INTERNAL;
825         }
826
827         if (_bt_avrcp_set_interal_property(type,
828                         &properties) != BLUETOOTH_ERROR_NONE)
829                 return BLUETOOTH_ERROR_INTERNAL;
830
831         BT_DBG("-");
832
833         return BLUETOOTH_ERROR_NONE;
834 }
835
836 int _bt_avrcp_control_cmd(int type)
837 {
838         int ret = BLUETOOTH_ERROR_INTERNAL;
839         BT_DBG("+");
840
841         switch (type) {
842         case PLAY:
843                 ret = __bt_media_send_control_msg("Play");
844                 break;
845         case PAUSE:
846                 ret = __bt_media_send_control_msg("Pause");
847                 break;
848         case STOP:
849                 ret = __bt_media_send_control_msg("Stop");
850                 break;
851         case NEXT:
852                 ret = __bt_media_send_control_msg("Next");
853                 break;
854         case PREVIOUS:
855                 ret = __bt_media_send_control_msg("Previous");
856                 break;
857         case FAST_FORWARD:
858                 ret = __bt_media_send_control_msg("FastForward");
859                 break;
860         case REWIND:
861                 ret = __bt_media_send_control_msg("Rewind");
862                 break;
863         default:
864                 BT_DBG("Invalid Type\n");
865                 return BLUETOOTH_ERROR_INTERNAL;
866         }
867         BT_DBG("-");
868         return ret;
869 }
870
871 DBusGProxy *__bt_get_control_properties_proxy(void)
872 {
873         DBusGProxy *proxy;
874         char *control_path;
875         DBusGConnection *conn;
876
877         control_path = __bt_get_control_device_path();
878         retv_if(control_path == NULL, NULL);
879         BT_DBG("control_path = %s", control_path);
880
881         conn = _bt_get_system_gconn();
882         retv_if(conn == NULL, NULL);
883
884         proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
885                                 control_path, BT_PROPERTIES_INTERFACE);
886         return proxy;
887 }
888
889 static int __bt_media_attr_to_event(const char *str)
890 {
891         if (!strcasecmp(str, "Equalizer"))
892                 return BLUETOOTH_EVENT_AVRCP_CONTROL_EQUALIZER_STATUS;
893         else if (!strcasecmp(str, "Repeat"))
894                 return BLUETOOTH_EVENT_AVRCP_CONTROL_REPEAT_STATUS;
895         else if (!strcasecmp(str, "Shuffle"))
896                 return BLUETOOTH_EVENT_AVRCP_CONTROL_SHUFFLE_STATUS;
897         else if (!strcasecmp(str, "Scan"))
898                 return BLUETOOTH_EVENT_AVRCP_CONTROL_SCAN_STATUS;
899         else if (!strcasecmp(str, "Position"))
900                 return BLUETOOTH_EVENT_AVRCP_SONG_POSITION_STATUS;
901         else if (!strcasecmp(str, "Track"))
902                 return BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED;
903         else if (!strcasecmp(str, "Status"))
904                 return BLUETOOTH_EVENT_AVRCP_PLAY_STATUS_CHANGED;
905
906         return 0;
907 }
908
909 static int __bt_media_attr_to_type(const char *str)
910 {
911         if (!strcasecmp(str, "Equalizer"))
912                 return EQUALIZER;
913         else if (!strcasecmp(str, "Repeat"))
914                 return REPEAT;
915         else if (!strcasecmp(str, "Shuffle"))
916                 return SHUFFLE;
917         else if (!strcasecmp(str, "Scan"))
918                 return SCAN;
919         else if (!strcasecmp(str, "Position"))
920                 return POSITION;
921         else if (!strcasecmp(str, "Track"))
922                 return METADATA;
923         else if (!strcasecmp(str, "Status"))
924                 return STATUS;
925
926         return 0;
927 }
928
929 static const char *__bt_media_type_to_str(int type)
930 {
931         switch (type) {
932         case EQUALIZER:
933                 return "Equalizer";
934         case REPEAT:
935                 return "Repeat";
936         case SHUFFLE:
937                 return "Shuffle";
938         case SCAN:
939                 return "Scan";
940         case POSITION:
941                 return "Position";
942         case METADATA:
943                 return "Track";
944         case STATUS:
945                 return "Status";
946         }
947         return NULL;
948 }
949
950 static int __bt_media_attrval_to_val(int type, const char *value)
951 {
952         int ret = 0;
953
954         switch (type) {
955         case EQUALIZER:
956                 if (!strcmp(value, "off"))
957                         ret = EQUALIZER_OFF;
958                 else if (!strcmp(value, "on"))
959                         ret = EQUALIZER_ON;
960                 else
961                         ret = EQUALIZER_INVALID;
962                 break;
963
964         case REPEAT:
965                 if (!strcmp(value, "off"))
966                         ret = REPEAT_MODE_OFF;
967                 else if (!strcmp(value, "singletrack"))
968                         ret = REPEAT_SINGLE_TRACK;
969                 else if (!strcmp(value, "alltracks"))
970                         ret = REPEAT_ALL_TRACK;
971                 else if (!strcmp(value, "group"))
972                         ret = REPEAT_GROUP;
973                 else
974                         ret = REPEAT_INVALID;
975                 break;
976
977         case SHUFFLE:
978                 if (!strcmp(value, "off"))
979                         ret = SHUFFLE_MODE_OFF;
980                 else if (!strcmp(value, "alltracks"))
981                         ret = SHUFFLE_ALL_TRACK;
982                 else if (!strcmp(value, "group"))
983                         ret = SHUFFLE_GROUP;
984                 else
985                         ret = SHUFFLE_INVALID;
986                 break;
987
988         case SCAN:
989                 if (!strcmp(value, "off"))
990                         ret = SCAN_MODE_OFF;
991                 else if (!strcmp(value, "alltracks"))
992                         ret = SCAN_ALL_TRACK;
993                 else if (!strcmp(value, "group"))
994                         ret = SCAN_GROUP;
995                 else
996                         ret = SCAN_INVALID;
997                 break;
998
999         case STATUS:
1000                 if (!strcmp(value, "stopped"))
1001                         ret = STATUS_STOPPED;
1002                 else if (!strcmp(value, "playing"))
1003                         ret = STATUS_PLAYING;
1004                 else if (!strcmp(value, "paused"))
1005                         ret = STATUS_PAUSED;
1006                 else if (!strcmp(value, "forward-seek"))
1007                         ret = STATUS_FORWARD_SEEK;
1008                 else if (!strcmp(value, "reverse-seek"))
1009                         ret = STATUS_REVERSE_SEEK;
1010                 else if (!strcmp(value, "error"))
1011                         ret = STATUS_ERROR;
1012                 else
1013                         ret = STATUS_INVALID;
1014         }
1015         return ret;
1016 }
1017
1018 int _bt_avrcp_control_get_property(int type, unsigned int *value)
1019 {
1020         DBusGProxy *proxy;
1021         char *name = NULL;
1022         int ret = BLUETOOTH_ERROR_NONE;
1023         GError *err = NULL;
1024         GValue attr_value = { 0 };
1025
1026         BT_CHECK_PARAMETER(value, return);
1027
1028         proxy = __bt_get_control_properties_proxy();
1029         retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1030
1031         if (!dbus_g_proxy_call(proxy, "Get", &err,
1032                         G_TYPE_STRING, BT_PLAYER_CONTROL_INTERFACE,
1033                         G_TYPE_STRING, __bt_media_type_to_str(type),
1034                         G_TYPE_INVALID,
1035                         G_TYPE_VALUE, &attr_value,
1036                         G_TYPE_INVALID)) {
1037                 if (err != NULL) {
1038                         BT_ERR("Getting property failed: [%s]\n", err->message);
1039                         g_error_free(err);
1040                 }
1041                 g_object_unref(proxy);
1042                 return BLUETOOTH_ERROR_INTERNAL;
1043         }
1044         g_object_unref(proxy);
1045
1046         switch (type) {
1047         case EQUALIZER:
1048         case REPEAT:
1049         case SHUFFLE:
1050         case SCAN:
1051         case STATUS:
1052                 name = (char *)g_value_get_string(&attr_value);
1053                 *value = __bt_media_attrval_to_val(type, name);
1054                 BT_DBG("Type[%s] and Value[%s]", __bt_media_type_to_str(type), name);
1055                 break;
1056         case POSITION:
1057                 *value = g_value_get_uint(&attr_value);
1058                 break;
1059         default:
1060                 BT_DBG("Invalid Type\n");
1061                 ret =  BLUETOOTH_ERROR_INTERNAL;
1062         }
1063
1064         return ret;
1065 }
1066
1067 int _bt_avrcp_control_set_property(int type, unsigned int value)
1068 {
1069         GValue attr_value = { 0 };
1070         DBusGProxy *proxy;
1071         GError *error = NULL;
1072
1073         proxy = __bt_get_control_properties_proxy();
1074
1075         retv_if(proxy == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1076         g_value_init(&attr_value, G_TYPE_STRING);
1077
1078         switch (type) {
1079         case EQUALIZER:
1080                 g_value_set_string(&attr_value, equalizer_status[value].property);
1081                 BT_DBG("equalizer_status %s", equalizer_status[value].property);
1082                 break;
1083         case REPEAT:
1084                 g_value_set_string(&attr_value, repeat_status[value].property);
1085                 BT_DBG("repeat_status %s", repeat_status[value].property);
1086                 break;
1087         case SHUFFLE:
1088                 g_value_set_string(&attr_value, shuffle_settings[value].property);
1089                 BT_DBG("shuffle_settings %s", shuffle_settings[value].property);
1090                 break;
1091         case SCAN:
1092                 g_value_set_string(&attr_value, scan_status[value].property);
1093                 BT_DBG("scan_status %s", scan_status[value].property);
1094                 break;
1095         default:
1096                 BT_ERR("Invalid property type: %d", type);
1097                 return BLUETOOTH_ERROR_INTERNAL;
1098         }
1099
1100         dbus_g_proxy_call(proxy, "Set", &error,
1101                         G_TYPE_STRING, BT_PLAYER_CONTROL_INTERFACE,
1102                         G_TYPE_STRING, __bt_media_type_to_str(type),
1103                         G_TYPE_VALUE, &attr_value,
1104                         G_TYPE_INVALID, G_TYPE_INVALID);
1105
1106         g_value_unset(&attr_value);
1107         g_object_unref(proxy);
1108
1109         if (error) {
1110                 BT_ERR("SetProperty Fail: %s", error->message);
1111                 g_error_free(error);
1112                 return BLUETOOTH_ERROR_INTERNAL;
1113         }
1114
1115         return BLUETOOTH_ERROR_NONE;
1116 }
1117
1118 static gboolean __bt_avrcp_control_parse_metadata(
1119                                         char **value_string,
1120                                         unsigned int *value_uint,
1121                                         int type,
1122                                         DBusMessageIter *iter)
1123 {
1124         if (dbus_message_iter_get_arg_type(iter) != type)
1125                 return FALSE;
1126
1127         if (type == DBUS_TYPE_STRING) {
1128                 char *value;
1129                 dbus_message_iter_get_basic(iter, &value);
1130                 *value_string = g_strdup(value);
1131         } else if (type == DBUS_TYPE_UINT32) {
1132                 int value;
1133                 dbus_message_iter_get_basic(iter, &value);
1134                 *value_uint = value;
1135         } else
1136                 return FALSE;
1137
1138         return TRUE;
1139 }
1140
1141
1142 static int __bt_avrcp_control_parse_properties(
1143                                 media_metadata_attributes_t *metadata,
1144                                 DBusMessageIter *iter)
1145 {
1146         DBusMessageIter dict;
1147         DBusMessageIter var;
1148         int ctype;
1149         char *value_string;
1150         unsigned int value_uint;
1151
1152         ctype = dbus_message_iter_get_arg_type(iter);
1153         if (ctype != DBUS_TYPE_ARRAY) {
1154                 BT_ERR("ctype error %d", ctype);
1155                 return BLUETOOTH_ERROR_INTERNAL;
1156         }
1157
1158         dbus_message_iter_recurse(iter, &dict);
1159
1160         while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
1161                                                         DBUS_TYPE_INVALID) {
1162                 DBusMessageIter entry;
1163                 const char *key;
1164
1165                 if (ctype != DBUS_TYPE_DICT_ENTRY) {
1166                         BT_ERR("ctype error %d", ctype);
1167                         return BLUETOOTH_ERROR_INTERNAL;
1168                 }
1169
1170                 dbus_message_iter_recurse(&dict, &entry);
1171                 if (dbus_message_iter_get_arg_type(&entry) !=
1172                                                         DBUS_TYPE_STRING) {
1173                         BT_ERR("ctype not DBUS_TYPE_STRING");
1174                         return BLUETOOTH_ERROR_INTERNAL;
1175                 }
1176
1177                 dbus_message_iter_get_basic(&entry, &key);
1178                 dbus_message_iter_next(&entry);
1179
1180                 if (dbus_message_iter_get_arg_type(&entry) !=
1181                                                         DBUS_TYPE_VARIANT) {
1182                         BT_ERR("ctype not DBUS_TYPE_VARIANT");
1183                         return FALSE;
1184                 }
1185
1186                 dbus_message_iter_recurse(&entry, &var);
1187
1188                 BT_ERR("Key value is %s", key);
1189
1190                 if (strcasecmp(key, "Title") == 0) {
1191                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1192                                         &value_uint, DBUS_TYPE_STRING, &var))
1193                                 return BLUETOOTH_ERROR_INTERNAL;
1194                         BT_DBG("Value : %s ", value_string);
1195                         metadata->title = value_string;
1196                 } else if (strcasecmp(key, "Artist") == 0) {
1197                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1198                                         &value_uint, DBUS_TYPE_STRING, &var))
1199                                 return BLUETOOTH_ERROR_INTERNAL;
1200                         BT_DBG("Value : %s ", value_string);
1201                         metadata->artist = value_string;
1202                 } else if (strcasecmp(key, "Album") == 0) {
1203                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1204                                         &value_uint, DBUS_TYPE_STRING, &var))
1205                                 return BLUETOOTH_ERROR_INTERNAL;
1206                         BT_DBG("Value : %s ", value_string);
1207                         metadata->album = value_string;
1208                 } else if (strcasecmp(key, "Genre") == 0) {
1209                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1210                                         &value_uint, DBUS_TYPE_STRING, &var))
1211                                 return BLUETOOTH_ERROR_INTERNAL;
1212                         BT_DBG("Value : %s ", value_string);
1213                         metadata->genre = value_string;
1214                 } else if (strcasecmp(key, "Duration") == 0) {
1215                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1216                                         &value_uint, DBUS_TYPE_UINT32, &var))
1217                                 return BLUETOOTH_ERROR_INTERNAL;
1218                         metadata->duration = value_uint;
1219                 } else if (strcasecmp(key, "NumberOfTracks") == 0) {
1220                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1221                                         &value_uint, DBUS_TYPE_UINT32, &var))
1222                                 return BLUETOOTH_ERROR_INTERNAL;
1223                         metadata->total_tracks = value_uint;
1224                 } else if (strcasecmp(key, "TrackNumber") == 0) {
1225                         if (!__bt_avrcp_control_parse_metadata(&value_string,
1226                                         &value_uint, DBUS_TYPE_UINT32, &var))
1227                                 return BLUETOOTH_ERROR_INTERNAL;
1228                         metadata->number = value_uint;
1229                 } else
1230                         BT_DBG("%s not supported, ignoring", key);
1231                 dbus_message_iter_next(&dict);
1232         }
1233
1234         if (!metadata->title)
1235                 metadata->title = g_strdup("");
1236         if (!metadata->artist)
1237                 metadata->artist = g_strdup("");
1238         if (!metadata->album)
1239                 metadata->album = g_strdup("");
1240         if (!metadata->genre)
1241                 metadata->genre = g_strdup("");
1242
1243         return BLUETOOTH_ERROR_NONE;
1244 }
1245
1246 int _bt_avrcp_control_get_track_info(media_metadata_attributes_t *metadata)
1247 {
1248         DBusMessage *msg;
1249         DBusMessage *reply;
1250         DBusError err;
1251         DBusConnection *conn;
1252         char *control_path;
1253         char *interface_name;
1254         char *property_name;
1255         DBusMessageIter arr, iter;
1256         int ret = BLUETOOTH_ERROR_NONE;
1257
1258         retv_if(metadata == NULL, BLUETOOTH_ERROR_INTERNAL);
1259
1260         conn = _bt_get_system_conn();
1261         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1262
1263         control_path = __bt_get_control_device_path();
1264         retv_if(control_path == NULL, BLUETOOTH_ERROR_NOT_CONNECTED);
1265         BT_DBG("control_path %s", control_path);
1266
1267         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, control_path,
1268                                 BT_PROPERTIES_INTERFACE, "Get");
1269
1270         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1271
1272         interface_name = g_strdup(BT_PLAYER_CONTROL_INTERFACE);
1273         property_name = g_strdup("Track");
1274
1275         dbus_message_append_args(msg,
1276                 DBUS_TYPE_STRING, &interface_name,
1277                 DBUS_TYPE_STRING, &property_name,
1278                 DBUS_TYPE_INVALID);
1279
1280         dbus_error_init(&err);
1281         reply = dbus_connection_send_with_reply_and_block(conn,
1282                                 msg, -1, &err);
1283
1284         g_free(interface_name);
1285         g_free(property_name);
1286         dbus_message_unref(msg);
1287
1288         if (!reply) {
1289                 BT_ERR("Error in getting Metadata");
1290                 if (dbus_error_is_set(&err)) {
1291                         BT_ERR("%s", err.message);
1292                         dbus_error_free(&err);
1293                 }
1294                 return BLUETOOTH_ERROR_INTERNAL;
1295         }
1296
1297         dbus_message_iter_init(reply, &iter);
1298         dbus_message_iter_recurse(&iter, &arr);
1299
1300         ret = __bt_avrcp_control_parse_properties(metadata, &arr);
1301         dbus_message_unref(reply);
1302
1303         BT_DBG("-");
1304         return ret;
1305 }
1306
1307 void _bt_handle_avrcp_control_event(DBusMessageIter *msg_iter, const char *path)
1308 {
1309         DBusMessageIter value_iter;
1310         DBusMessageIter dict_iter;
1311         DBusMessageIter item_iter;
1312         const char *property = NULL;
1313
1314         dbus_message_iter_recurse(msg_iter, &item_iter);
1315
1316         if (dbus_message_iter_get_arg_type(&item_iter)
1317                                         != DBUS_TYPE_DICT_ENTRY) {
1318                 BT_ERR("This is bad format dbus");
1319                 return;
1320         }
1321
1322         dbus_message_iter_recurse(&item_iter, &dict_iter);
1323
1324         dbus_message_iter_get_basic(&dict_iter, &property);
1325         ret_if(property == NULL);
1326
1327         BT_DBG("property : %s ", property);
1328         ret_if(!dbus_message_iter_next(&dict_iter));
1329
1330         if ((strcasecmp(property, "Equalizer") == 0) ||
1331                 (strcasecmp(property, "Repeat") == 0) ||
1332                 (strcasecmp(property, "Shuffle") == 0) ||
1333                 (strcasecmp(property, "Scan") == 0) ||
1334                 (strcasecmp(property, "Status") == 0)) {
1335
1336                 const char *valstr;
1337                 int type, value;
1338
1339                 dbus_message_iter_recurse(&dict_iter, &value_iter);
1340                 dbus_message_iter_get_basic(&value_iter, &valstr);
1341                 BT_DBG("Value : %s ", valstr);
1342                 type = __bt_media_attr_to_type(property);
1343                 value = __bt_media_attrval_to_val(type, valstr);
1344
1345                                 /* Send event to application */
1346                 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
1347                         __bt_media_attr_to_event(property),
1348                         DBUS_TYPE_UINT32, &value,
1349                         DBUS_TYPE_INVALID);
1350         } else if (strcasecmp(property, "Position") == 0) {
1351                 unsigned int value;
1352
1353                 dbus_message_iter_recurse(&dict_iter, &value_iter);
1354                 dbus_message_iter_get_basic(&value_iter, &value);
1355                 BT_DBG("Value : %d ", value);
1356
1357                                 /* Send event to application */
1358                 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
1359                         __bt_media_attr_to_event(property),
1360                         DBUS_TYPE_UINT32, &value,
1361                         DBUS_TYPE_INVALID);
1362         } else if (strcasecmp(property, "Track") == 0) {
1363                 int ret = BLUETOOTH_ERROR_NONE;
1364                 media_metadata_attributes_t metadata;
1365
1366                 dbus_message_iter_recurse(&dict_iter, &value_iter);
1367                 memset(&metadata, 0x00, sizeof(media_metadata_attributes_t));
1368
1369                 ret = __bt_avrcp_control_parse_properties(
1370                                                         &metadata, &value_iter);
1371                 if (BLUETOOTH_ERROR_NONE != ret)
1372                         return;
1373
1374                                 /* Send event to application */
1375                 _bt_send_event(BT_AVRCP_CONTROL_EVENT,
1376                         BLUETOOTH_EVENT_AVRCP_TRACK_CHANGED,
1377                         DBUS_TYPE_STRING, &metadata.title,
1378                         DBUS_TYPE_STRING, &metadata.artist,
1379                         DBUS_TYPE_STRING, &metadata.album,
1380                         DBUS_TYPE_STRING, &metadata.genre,
1381                         DBUS_TYPE_UINT32, &metadata.total_tracks,
1382                         DBUS_TYPE_UINT32, &metadata.number,
1383                         DBUS_TYPE_UINT32, &metadata.duration,
1384                         DBUS_TYPE_INVALID);
1385
1386                 g_free(metadata.title);
1387                 g_free(metadata.artist);
1388                 g_free(metadata.album);
1389                 g_free(metadata.genre);
1390         } else {
1391                 BT_DBG("Preprty not handled");
1392         }
1393
1394         BT_DBG("-");
1395 }