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